summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/.config1
-rw-r--r--kernel/OS/.nomake0
-rw-r--r--kernel/OS/BeOS/.config1
-rw-r--r--kernel/OS/BeOS/driver_beos.c104
-rw-r--r--kernel/OS/BeOS/module.inc186
-rw-r--r--kernel/OS/BeOS/os_beos.c2222
-rw-r--r--kernel/OS/BeOS/os_beos.h471
-rw-r--r--kernel/OS/FreeBSD/.config1
-rw-r--r--kernel/OS/FreeBSD/os_freebsd.c1107
-rw-r--r--kernel/OS/FreeBSD/os_freebsd.h263
-rw-r--r--kernel/OS/FreeBSD/wrapper/bsddefs.h150
-rw-r--r--kernel/OS/Linux/.config1
-rw-r--r--kernel/OS/Linux/os_linux.c1034
-rw-r--r--kernel/OS/Linux/os_linux.h287
-rw-r--r--kernel/OS/Linux/oss_ddi.h46
-rw-r--r--kernel/OS/Linux/wrapper/.nomake0
-rw-r--r--kernel/OS/Linux/wrapper/wrap.h288
-rw-r--r--kernel/OS/SCO_SV/.config1
-rw-r--r--kernel/OS/SCO_SV/module.inc277
-rw-r--r--kernel/OS/SCO_SV/os_sco.c1679
-rw-r--r--kernel/OS/SCO_SV/os_sco.h408
-rw-r--r--kernel/OS/SunOS/.config1
-rw-r--r--kernel/OS/SunOS/module.inc389
-rw-r--r--kernel/OS/SunOS/os_solaris.c2401
-rw-r--r--kernel/OS/SunOS/os_solaris.h518
-rw-r--r--kernel/OS/SunOS/udi.c1365
-rw-r--r--kernel/OS/VxWorks/.config1
-rw-r--r--kernel/OS/VxWorks/linux/ioctl.h5
-rw-r--r--kernel/OS/VxWorks/module.inc127
-rw-r--r--kernel/OS/VxWorks/os_vxworks.c1133
-rw-r--r--kernel/OS/VxWorks/os_vxworks.h297
-rw-r--r--kernel/drv/.config1
-rw-r--r--kernel/drv/oss_ali5455/.devices1
-rw-r--r--kernel/drv/oss_ali5455/.name1
-rw-r--r--kernel/drv/oss_ali5455/oss_ali5455.c979
-rw-r--r--kernel/drv/oss_ali5455/oss_ali5455.man20
-rw-r--r--kernel/drv/oss_atiaudio/.config1
-rw-r--r--kernel/drv/oss_atiaudio/.devices3
-rw-r--r--kernel/drv/oss_atiaudio/.name1
-rw-r--r--kernel/drv/oss_atiaudio/oss_atiaudio.c1147
-rw-r--r--kernel/drv/oss_atiaudio/oss_atiaudio.man19
-rw-r--r--kernel/drv/oss_audigyls/.devices1
-rw-r--r--kernel/drv/oss_audigyls/.name1
-rw-r--r--kernel/drv/oss_audigyls/.params6
-rw-r--r--kernel/drv/oss_audigyls/oss_audigyls.c1860
-rw-r--r--kernel/drv/oss_audigyls/oss_audigyls.man45
-rw-r--r--kernel/drv/oss_audiocs/.config1
-rw-r--r--kernel/drv/oss_audiocs/.devices1
-rw-r--r--kernel/drv/oss_audiocs/.name1
-rw-r--r--kernel/drv/oss_audiocs/cs4231_mixer.h101
-rw-r--r--kernel/drv/oss_audiocs/oss_audiocs.c1808
-rw-r--r--kernel/drv/oss_audiocs/oss_audiocs.man21
-rw-r--r--kernel/drv/oss_audioloop/.config2
-rw-r--r--kernel/drv/oss_audioloop/.devices1
-rw-r--r--kernel/drv/oss_audioloop/.name1
-rw-r--r--kernel/drv/oss_audioloop/.params4
-rw-r--r--kernel/drv/oss_audioloop/oss_audioloop.c919
-rw-r--r--kernel/drv/oss_audioloop/oss_audioloop.man80
-rw-r--r--kernel/drv/oss_audiopci/.devices1
-rw-r--r--kernel/drv/oss_audiopci/.name1
-rw-r--r--kernel/drv/oss_audiopci/audiopci.h299
-rw-r--r--kernel/drv/oss_audiopci/oss_audiopci.c1536
-rw-r--r--kernel/drv/oss_audiopci/oss_audiopci.man20
-rw-r--r--kernel/drv/oss_cmi878x/.devices8
-rw-r--r--kernel/drv/oss_cmi878x/.name1
-rw-r--r--kernel/drv/oss_cmi878x/oss_cmi878x.c3104
-rw-r--r--kernel/drv/oss_cmi878x/oss_cmi878x.man54
-rw-r--r--kernel/drv/oss_cmpci/.devices5
-rw-r--r--kernel/drv/oss_cmpci/.name1
-rw-r--r--kernel/drv/oss_cmpci/oss_cmpci.c2379
-rw-r--r--kernel/drv/oss_cmpci/oss_cmpci.man56
-rw-r--r--kernel/drv/oss_cs4281/.devices1
-rw-r--r--kernel/drv/oss_cs4281/.name1
-rw-r--r--kernel/drv/oss_cs4281/cs4281.h1108
-rw-r--r--kernel/drv/oss_cs4281/oss_cs4281.c1061
-rw-r--r--kernel/drv/oss_cs4281/oss_cs4281.man21
-rw-r--r--kernel/drv/oss_cs461x/.devices7
-rw-r--r--kernel/drv/oss_cs461x/.name1
-rw-r--r--kernel/drv/oss_cs461x/.params6
-rw-r--r--kernel/drv/oss_cs461x/cs461x.h1668
-rw-r--r--kernel/drv/oss_cs461x/cs461x_dsp.h3474
-rw-r--r--kernel/drv/oss_cs461x/oss_cs461x.c1931
-rw-r--r--kernel/drv/oss_cs461x/oss_cs461x.man24
-rw-r--r--kernel/drv/oss_digi96/.devices4
-rw-r--r--kernel/drv/oss_digi96/.name1
-rw-r--r--kernel/drv/oss_digi96/oss_digi96.c1097
-rw-r--r--kernel/drv/oss_digi96/oss_digi96.man63
-rw-r--r--kernel/drv/oss_emu10k1x/.config1
-rw-r--r--kernel/drv/oss_emu10k1x/.devices1
-rw-r--r--kernel/drv/oss_emu10k1x/.name1
-rw-r--r--kernel/drv/oss_emu10k1x/.params5
-rw-r--r--kernel/drv/oss_emu10k1x/oss_emu10k1x.c1243
-rw-r--r--kernel/drv/oss_emu10k1x/oss_emu10k1x.man27
-rw-r--r--kernel/drv/oss_envy24/.config1
-rw-r--r--kernel/drv/oss_envy24/.devices13
-rw-r--r--kernel/drv/oss_envy24/.name1
-rw-r--r--kernel/drv/oss_envy24/.params80
-rw-r--r--kernel/drv/oss_envy24/envy24.h279
-rw-r--r--kernel/drv/oss_envy24/envy24_1010lt.c582
-rw-r--r--kernel/drv/oss_envy24/envy24_6fire.c781
-rw-r--r--kernel/drv/oss_envy24/envy24_default.c2384
-rw-r--r--kernel/drv/oss_envy24/envy24_direct.c415
-rw-r--r--kernel/drv/oss_envy24/envy24_ews88d.c377
-rw-r--r--kernel/drv/oss_envy24/envy24_tdif.c687
-rw-r--r--kernel/drv/oss_envy24/envy24_tdif.h5836
-rw-r--r--kernel/drv/oss_envy24/oss_envy24.c4043
-rw-r--r--kernel/drv/oss_envy24/oss_envy24.man334
-rw-r--r--kernel/drv/oss_envy24ht/.changelog1
-rw-r--r--kernel/drv/oss_envy24ht/.devices12
-rw-r--r--kernel/drv/oss_envy24ht/.name1
-rw-r--r--kernel/drv/oss_envy24ht/.params5
-rw-r--r--kernel/drv/oss_envy24ht/envy24ht.h230
-rw-r--r--kernel/drv/oss_envy24ht/envy24ht_ac97.c137
-rw-r--r--kernel/drv/oss_envy24ht/envy24ht_ap192.c617
-rw-r--r--kernel/drv/oss_envy24ht/envy24ht_aureon.c2536
-rw-r--r--kernel/drv/oss_envy24ht/envy24ht_julia.c547
-rw-r--r--kernel/drv/oss_envy24ht/envy24ht_revo51.c938
-rw-r--r--kernel/drv/oss_envy24ht/envy24ht_revo71.c338
-rw-r--r--kernel/drv/oss_envy24ht/envy24ht_via.c.save324
-rw-r--r--kernel/drv/oss_envy24ht/oss_envy24ht.c2411
-rw-r--r--kernel/drv/oss_envy24ht/oss_envy24ht.man24
-rw-r--r--kernel/drv/oss_fmedia/.devices2
-rw-r--r--kernel/drv/oss_fmedia/.name1
-rw-r--r--kernel/drv/oss_fmedia/.params6
-rw-r--r--kernel/drv/oss_fmedia/oss_fmedia.c1076
-rw-r--r--kernel/drv/oss_fmedia/oss_fmedia.man23
-rw-r--r--kernel/drv/oss_geode/.config1
-rw-r--r--kernel/drv/oss_geode/.devices3
-rw-r--r--kernel/drv/oss_geode/.name1
-rw-r--r--kernel/drv/oss_geode/oss_geode.c852
-rw-r--r--kernel/drv/oss_geode/oss_geode.man25
-rw-r--r--kernel/drv/oss_hdaudio/.changelog7
-rw-r--r--kernel/drv/oss_hdaudio/.config1
-rw-r--r--kernel/drv/oss_hdaudio/.devices27
-rw-r--r--kernel/drv/oss_hdaudio/.name1
-rw-r--r--kernel/drv/oss_hdaudio/.params24
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio.h168
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_abit_AA8.c347
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_asus_P4B_E.c395
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_asus_m9.c36
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_codec.c3580
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_codec.h379
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_codecids.h1154
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_dedicated.h74
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_eeepc.c293
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_ferrari5k.c303
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_generic.c868
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_gpio_handlers.c128
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_mixers.h20
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_scaleoP.c277
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_si3055.c206
-rwxr-xr-xkernel/drv/oss_hdaudio/hdaudio_thinkpad_r61.c301
-rw-r--r--kernel/drv/oss_hdaudio/hdaudio_vaio_vgn.c144
-rw-r--r--kernel/drv/oss_hdaudio/oss_hdaudio.c1996
-rw-r--r--kernel/drv/oss_hdaudio/oss_hdaudio.man77
-rw-r--r--kernel/drv/oss_ich/.changelog1
-rw-r--r--kernel/drv/oss_ich/.config1
-rw-r--r--kernel/drv/oss_ich/.devices21
-rw-r--r--kernel/drv/oss_ich/.name1
-rw-r--r--kernel/drv/oss_ich/.params16
-rw-r--r--kernel/drv/oss_ich/oss_ich.c1470
-rw-r--r--kernel/drv/oss_ich/oss_ich.man34
-rw-r--r--kernel/drv/oss_imux/.config2
-rw-r--r--kernel/drv/oss_imux/.devices1
-rw-r--r--kernel/drv/oss_imux/.name1
-rw-r--r--kernel/drv/oss_imux/.params24
-rw-r--r--kernel/drv/oss_imux/oss_imux.c1072
-rw-r--r--kernel/drv/oss_imux/oss_imux.man78
-rw-r--r--kernel/drv/oss_madi/.devices1
-rw-r--r--kernel/drv/oss_madi/.name1
-rw-r--r--kernel/drv/oss_madi/.params12
-rw-r--r--kernel/drv/oss_madi/madi.h246
-rw-r--r--kernel/drv/oss_madi/madi_mixer.c459
-rw-r--r--kernel/drv/oss_madi/oss_madi.c975
-rw-r--r--kernel/drv/oss_madi/oss_madi.man70
-rw-r--r--kernel/drv/oss_midiloop/.config1
-rw-r--r--kernel/drv/oss_midiloop/.devices1
-rw-r--r--kernel/drv/oss_midiloop/.name1
-rw-r--r--kernel/drv/oss_midiloop/.params5
-rw-r--r--kernel/drv/oss_midiloop/oss_midiloop.c412
-rw-r--r--kernel/drv/oss_midiloop/oss_midiloop.man44
-rw-r--r--kernel/drv/oss_midimix/.config1
-rw-r--r--kernel/drv/oss_midimix/.name1
-rw-r--r--kernel/drv/oss_midimix/oss_midimix.c346
-rw-r--r--kernel/drv/oss_midimix/oss_midimix.man40
-rw-r--r--kernel/drv/oss_sadasupport/.config3
-rw-r--r--kernel/drv/oss_sadasupport/.devices1
-rw-r--r--kernel/drv/oss_sadasupport/.name1
-rw-r--r--kernel/drv/oss_sadasupport/.params0
-rw-r--r--kernel/drv/oss_sadasupport/oss_sadasupport.c1277
-rw-r--r--kernel/drv/oss_sadasupport/oss_sadasupport.man26
-rw-r--r--kernel/drv/oss_sadasupport/sadasupport_sol9.h187
-rw-r--r--kernel/drv/oss_sblive/.devices7
-rw-r--r--kernel/drv/oss_sblive/.name1
-rw-r--r--kernel/drv/oss_sblive/.params25
-rw-r--r--kernel/drv/oss_sblive/emu10k1_dsp.h989
-rw-r--r--kernel/drv/oss_sblive/emu10k1_dsp_be.h989
-rw-r--r--kernel/drv/oss_sblive/emu10k2_dsp.h989
-rw-r--r--kernel/drv/oss_sblive/emu10k2_dsp_be.h989
-rw-r--r--kernel/drv/oss_sblive/oss_sblive.c3985
-rw-r--r--kernel/drv/oss_sblive/oss_sblive.man226
-rw-r--r--kernel/drv/oss_sblive/sblive.h535
-rw-r--r--kernel/drv/oss_sbpci/.devices5
-rw-r--r--kernel/drv/oss_sbpci/.name1
-rw-r--r--kernel/drv/oss_sbpci/.params12
-rw-r--r--kernel/drv/oss_sbpci/oss_sbpci.c1404
-rw-r--r--kernel/drv/oss_sbpci/oss_sbpci.man39
-rw-r--r--kernel/drv/oss_sbpci/sbpci.h181
-rw-r--r--kernel/drv/oss_sbxfi/.config1
-rw-r--r--kernel/drv/oss_sbxfi/.devices3
-rw-r--r--kernel/drv/oss_sbxfi/.name1
-rw-r--r--kernel/drv/oss_sbxfi/.params15
-rw-r--r--kernel/drv/oss_sbxfi/20k1reg.h911
-rw-r--r--kernel/drv/oss_sbxfi/hwaccess.h71
-rw-r--r--kernel/drv/oss_sbxfi/oss_sbxfi.c1078
-rw-r--r--kernel/drv/oss_sbxfi/oss_sbxfi.man20
-rw-r--r--kernel/drv/oss_sbxfi/sbxfi.h166
-rw-r--r--kernel/drv/oss_sbxfi/sbxfi_hwaccess.c1391
-rw-r--r--kernel/drv/oss_solo/.config1
-rw-r--r--kernel/drv/oss_solo/.devices1
-rw-r--r--kernel/drv/oss_solo/.name1
-rw-r--r--kernel/drv/oss_solo/oss_solo.c1230
-rw-r--r--kernel/drv/oss_solo/oss_solo.man19
-rw-r--r--kernel/drv/oss_trident/.devices5
-rw-r--r--kernel/drv/oss_trident/.name1
-rw-r--r--kernel/drv/oss_trident/.params6
-rw-r--r--kernel/drv/oss_trident/oss_trident.c1580
-rw-r--r--kernel/drv/oss_trident/oss_trident.man27
-rw-r--r--kernel/drv/oss_usb/.config3
-rw-r--r--kernel/drv/oss_usb/.devices28
-rw-r--r--kernel/drv/oss_usb/.name1
-rw-r--r--kernel/drv/oss_usb/.params2
-rwxr-xr-xkernel/drv/oss_usb/midisport1x1_fw.h677
-rwxr-xr-xkernel/drv/oss_usb/midisport2x2_fw.h756
-rw-r--r--kernel/drv/oss_usb/oss_usb.c2505
-rw-r--r--kernel/drv/oss_usb/oss_usb.man56
-rw-r--r--kernel/drv/oss_usb/ossusb.h246
-rw-r--r--kernel/drv/oss_usb/ossusb_audio.c1425
-rw-r--r--kernel/drv/oss_usb/ossusb_midi.c442
-rw-r--r--kernel/drv/oss_usb/ossusb_midisport.c957
-rw-r--r--kernel/drv/oss_usb/ossusb_ymhmidi.c653
-rwxr-xr-xkernel/drv/oss_usb/oxygen8_fw.h678
-rw-r--r--kernel/drv/oss_userdev/.config2
-rw-r--r--kernel/drv/oss_userdev/.devices1
-rw-r--r--kernel/drv/oss_userdev/.name1
-rw-r--r--kernel/drv/oss_userdev/.params11
-rw-r--r--kernel/drv/oss_userdev/oss_userdev.c352
-rw-r--r--kernel/drv/oss_userdev/oss_userdev.man37
-rw-r--r--kernel/drv/oss_userdev/oss_userdev_devicepair.c1255
-rw-r--r--kernel/drv/oss_userdev/userdev.h81
-rw-r--r--kernel/drv/oss_via823x/.config1
-rw-r--r--kernel/drv/oss_via823x/.devices5
-rw-r--r--kernel/drv/oss_via823x/.name1
-rw-r--r--kernel/drv/oss_via823x/oss_via823x.c1013
-rw-r--r--kernel/drv/oss_via823x/oss_via823x.man20
-rw-r--r--kernel/drv/oss_via823x/via8233.h97
-rw-r--r--kernel/drv/oss_via97/.config1
-rw-r--r--kernel/drv/oss_via97/.devices1
-rw-r--r--kernel/drv/oss_via97/.name1
-rw-r--r--kernel/drv/oss_via97/oss_via97.c944
-rw-r--r--kernel/drv/oss_via97/oss_via97.man19
-rw-r--r--kernel/drv/oss_ymf7xx/.devices7
-rw-r--r--kernel/drv/oss_ymf7xx/.name1
-rw-r--r--kernel/drv/oss_ymf7xx/.params17
-rw-r--r--kernel/drv/oss_ymf7xx/oss_ymf7xx.c1625
-rw-r--r--kernel/drv/oss_ymf7xx/oss_ymf7xx.man33
-rw-r--r--kernel/drv/oss_ymf7xx/ymf7xx.h1845
-rw-r--r--kernel/drv/osscore/.config2
-rw-r--r--kernel/drv/osscore/.devices1
-rw-r--r--kernel/drv/osscore/.name1
-rw-r--r--kernel/drv/osscore/.params133
-rw-r--r--kernel/drv/osscore/osscore.c39
-rw-r--r--kernel/drv/osscore/osscore.man86
-rw-r--r--kernel/framework/.config1
-rw-r--r--kernel/framework/ac97/.config1
-rw-r--r--kernel/framework/ac97/.params20
-rw-r--r--kernel/framework/ac97/ac97_ext.inc1453
-rw-r--r--kernel/framework/ac97/oss_ac97.c1228
-rw-r--r--kernel/framework/audio/.config1
-rw-r--r--kernel/framework/audio/audiocnv.inc160
-rw-r--r--kernel/framework/audio/fltdata1_m.inc1284
-rw-r--r--kernel/framework/audio/fltdata2_h.inc2503
-rw-r--r--kernel/framework/audio/fltdata3_l.inc689
-rw-r--r--kernel/framework/audio/fltdata4_p.inc4832
-rw-r--r--kernel/framework/audio/grc3code.inc384
-rw-r--r--kernel/framework/audio/grc3inc.inc165
-rw-r--r--kernel/framework/audio/oss_audio_core.c6639
-rw-r--r--kernel/framework/audio/oss_audiofmt.c1278
-rw-r--r--kernel/framework/audio/oss_grc3.c451
-rw-r--r--kernel/framework/audio/oss_spdif.c627
-rw-r--r--kernel/framework/audio/ulaw.h83
-rw-r--r--kernel/framework/include/.nomake0
-rw-r--r--kernel/framework/include/ac97.h179
-rw-r--r--kernel/framework/include/audio_core.h427
-rw-r--r--kernel/framework/include/eq1.h1059
-rw-r--r--kernel/framework/include/grc3.h339
-rw-r--r--kernel/framework/include/internal.h164
-rw-r--r--kernel/framework/include/midi_core.h337
-rw-r--r--kernel/framework/include/midiparser.h38
-rw-r--r--kernel/framework/include/mixer_core.h138
-rw-r--r--kernel/framework/include/oss_calls.h68
-rw-r--r--kernel/framework/include/oss_config.h377
-rw-r--r--kernel/framework/include/oss_memblk.h22
-rw-r--r--kernel/framework/include/oss_pci.h67
-rw-r--r--kernel/framework/include/oss_version.h13
-rw-r--r--kernel/framework/include/ossddk/oss_exports.h101
-rw-r--r--kernel/framework/include/ossddk/oss_limits.PHh35
-rw-r--r--kernel/framework/include/ossddk/ossddk.h267
-rw-r--r--kernel/framework/include/remux.h42
-rw-r--r--kernel/framework/include/spdif.h97
-rw-r--r--kernel/framework/include/uart401.h46
-rw-r--r--kernel/framework/include/udi.h111
-rw-r--r--kernel/framework/midi/.config2
-rw-r--r--kernel/framework/midi/oss_default_timer.c204
-rw-r--r--kernel/framework/midi/oss_midi_core.c1733
-rw-r--r--kernel/framework/midi/oss_midi_mapper.c109
-rw-r--r--kernel/framework/midi/oss_midi_parser.c406
-rw-r--r--kernel/framework/midi/oss_midi_queue.c567
-rw-r--r--kernel/framework/midi/oss_midi_timers.c607
-rw-r--r--kernel/framework/midi_stubs/.config1
-rw-r--r--kernel/framework/midi_stubs/oss_midi_stubs.c82
-rw-r--r--kernel/framework/mixer/.config1
-rw-r--r--kernel/framework/mixer/mixerdefs.h120
-rw-r--r--kernel/framework/mixer/oss_mixer_core.c2812
-rw-r--r--kernel/framework/osscore/.config1
-rw-r--r--kernel/framework/osscore/oss_core_options.c73
-rw-r--r--kernel/framework/osscore/oss_core_services.c84
-rw-r--r--kernel/framework/osscore/oss_memblk.c100
-rw-r--r--kernel/framework/remux/.config1
-rw-r--r--kernel/framework/remux/oss_remux.c544
-rw-r--r--kernel/framework/sndstat/.config1
-rw-r--r--kernel/framework/sndstat/oss_sndstat.c693
-rw-r--r--kernel/framework/uart401/.config1
-rw-r--r--kernel/framework/uart401/oss_uart401.c340
-rw-r--r--kernel/framework/vmix_core/.config1
-rw-r--r--kernel/framework/vmix_core/db_scale.h45
-rw-r--r--kernel/framework/vmix_core/outexport.inc83
-rw-r--r--kernel/framework/vmix_core/outexport_int.inc78
-rw-r--r--kernel/framework/vmix_core/playmix.inc115
-rw-r--r--kernel/framework/vmix_core/playmix_int.inc102
-rw-r--r--kernel/framework/vmix_core/playmix_src.inc152
-rw-r--r--kernel/framework/vmix_core/rec_export.inc76
-rw-r--r--kernel/framework/vmix_core/rec_export_int.inc72
-rw-r--r--kernel/framework/vmix_core/vmix.h242
-rw-r--r--kernel/framework/vmix_core/vmix_core.c2352
-rw-r--r--kernel/framework/vmix_core/vmix_import.inc77
-rw-r--r--kernel/framework/vmix_core/vmix_import_int.inc56
-rw-r--r--kernel/framework/vmix_core/vmix_input.c505
-rw-r--r--kernel/framework/vmix_core/vmix_output.c687
349 files changed, 156382 insertions, 0 deletions
diff --git a/kernel/.config b/kernel/.config
new file mode 100644
index 0000000..68cf5d3
--- /dev/null
+++ b/kernel/.config
@@ -0,0 +1 @@
+mode=kernelmode
diff --git a/kernel/OS/.nomake b/kernel/OS/.nomake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel/OS/.nomake
diff --git a/kernel/OS/BeOS/.config b/kernel/OS/BeOS/.config
new file mode 100644
index 0000000..816ac62
--- /dev/null
+++ b/kernel/OS/BeOS/.config
@@ -0,0 +1 @@
+mode=kernel
diff --git a/kernel/OS/BeOS/driver_beos.c b/kernel/OS/BeOS/driver_beos.c
new file mode 100644
index 0000000..61f4bf9
--- /dev/null
+++ b/kernel/OS/BeOS/driver_beos.c
@@ -0,0 +1,104 @@
+/*
+ * Purpose: devfs interface for BeOS/Haiku
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2007.
+ *
+ * This 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. Please contact sales@opensound.com for further info.
+ *
+ */
+
+#include "oss_config.h"
+#include "midi_core.h"
+#include <oss_pci.h>
+#include <KernelExport.h>
+#include <Drivers.h>
+
+#define DRIVER_NAME "ossdrv"
+
+int32 api_version = B_CUR_DRIVER_API_VERSION;
+
+oss_core_module_info *gOSSCore = NULL;
+
+// #pragma mark -
+
+// XXX: malloc it + update it from device list
+
+const char **
+publish_devices(void)
+{
+ return gOSSCore->oss_publish_devices();
+}
+
+
+device_hooks *
+find_device(const char *name)
+{
+ FENTRYA("%s", name);
+
+ FEXIT();
+ return gOSSCore->oss_get_driver_hooks();
+}
+
+// #pragma mark -
+
+status_t
+init_hardware(void)
+{
+ status_t err;
+ FENTRY();
+
+ err = get_module(OSS_CORE_MODULE_NAME, (module_info **)&gOSSCore);
+ if (err < B_OK) {
+ FEXIT();
+ return err;
+ }
+
+ put_module(OSS_CORE_MODULE_NAME);
+
+ FEXIT();
+ return B_OK;
+}
+
+status_t
+init_driver(void)
+{
+ status_t err = ENOMEM;
+ FENTRY();
+
+ err = get_module(OSS_CORE_MODULE_NAME, (module_info **)&gOSSCore);
+ if (err < B_OK)
+ goto err1;
+ err = gOSSCore->init_osscore();
+ dprintf("oss:init_osscore: 0x%08lx\n", err);
+ if (err < B_OK)
+ goto err2;
+ err = gOSSCore->oss_load_drivers();
+ err = B_OK;
+ FEXITR(err);
+ return err;
+
+err2:
+ put_module(OSS_CORE_MODULE_NAME);
+err1:
+ FEXITR(err);
+ return err;
+}
+
+void
+uninit_driver(void)
+{
+ status_t err;
+ FENTRY();
+
+ err = gOSSCore->oss_unload_all_drivers();
+ err = gOSSCore->uninit_osscore();
+ dprintf("oss:uninit_osscore: 0x%08lx\n", err);
+ put_module(OSS_CORE_MODULE_NAME);
+ FEXIT();
+}
diff --git a/kernel/OS/BeOS/module.inc b/kernel/OS/BeOS/module.inc
new file mode 100644
index 0000000..be7ab1b
--- /dev/null
+++ b/kernel/OS/BeOS/module.inc
@@ -0,0 +1,186 @@
+/* -*- c -*-
+ * Purpose: OSS module wrapper for BeOS/Haiku
+ *
+ * This file will be included from the auto-generated drv_cfg.c files. Under
+ * UnixWare and OpenServer this will will be compiled during the initial build
+ * of OSS (in the development system).
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2007.
+ *
+ * This 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. Please contact sales@opensound.com for further info.
+ *
+ */
+
+#include <PCI.h>
+
+//pci_module_info *gPCI = NULL;
+extern pci_module_info *gPCI;
+
+#if DRIVER_TYPE==DRV_VIRTUAL
+static oss_device_t *osdev = NULL;
+#endif
+
+#if DRIVER_TYPE==DRV_PCI
+int DRIVER_PROBE()
+{
+ oss_device_t *osdev;
+ pci_info pcii;
+ uint32 pci_index = 0;
+ uint32 count = 0;
+ int err = ENOENT;
+ static int instance = 0;
+ FENTRY();
+
+ /* while there are more pci devices */
+ while ((*gPCI->get_nth_pci_info)(pci_index, &pcii) == B_NO_ERROR)
+ {
+ int vendor;
+ bool match = false;
+ bool sub = true;
+
+ /* we first loop through all subsystem entries, then loop again */
+rescan:
+ vendor = 0;
+ /* if we match a supported vendor */
+ while (id_table[vendor].vendor)
+ {
+
+ /* check for function vendor & device id */
+ if (!sub &&
+ id_table[vendor].subsystem == false &&
+ id_table[vendor].vendor == pcii.vendor_id &&
+ id_table[vendor].product == pcii.device_id)
+ {
+ dprintf("oss: matching pci %04x,%04x\n", id_table[vendor].vendor, id_table[vendor].product);
+ match = true;
+ }
+
+ /* check for subsystem vendor & device id */
+ if (sub &&
+ id_table[vendor].subsystem == true &&
+ pcii.header_type == 0 &&
+ id_table[vendor].vendor == pcii.u.h0.subsystem_vendor_id &&
+ id_table[vendor].product == pcii.u.h0.subsystem_id)
+ {
+ dprintf("oss: matching pci subsystem %04x,%04x\n", id_table[vendor].vendor, id_table[vendor].product);
+ match = true;
+ }
+
+ if (match)
+ {
+ dev_info_t *di;
+ di = PMALLOC(NULL, sizeof(dev_info_t));
+ if (!di)
+ break;
+ memcpy(di, &pcii, sizeof(pcii));
+ if ((osdev =
+ osdev_create (di, DRIVER_TYPE, instance, DRIVER_NICK, NULL)) == NULL)
+ {
+ break;
+ }
+
+ /* should be called once, but we need an osdev */
+ oss_load_options (osdev, local_driver_options);
+
+ if (!DRIVER_ATTACH (osdev))
+ {
+ cmn_err (CE_WARN, "Attach failed\n");
+ osdev_delete (osdev);
+ break;
+ }
+
+ instance++;
+ count++;
+ break;
+ }
+ vendor++;
+ }
+ /* we've checked for subsystem IDs, now rescan for IDs */
+ if (!match && sub) {
+ sub = false;
+ goto rescan;
+ }
+ /* next pci_info struct, please */
+ pci_index++;
+ }
+
+ oss_audio_delayed_attach ();
+
+ if (count)
+ err = 0;
+err:
+ FEXITR(err);
+ return err;
+}
+#endif
+
+#if DRIVER_TYPE==DRV_VIRTUAL
+int DRIVER_PROBE()
+{
+ int err = EIO;
+ FENTRY();
+ if ((osdev =
+ osdev_create (NULL, DRIVER_TYPE, 0, DRIVER_NICK, NULL)) == NULL)
+ {
+ goto err;
+ }
+
+ oss_load_options (osdev, local_driver_options);
+
+ if (!DRIVER_ATTACH (osdev))
+ {
+ cmn_err (CE_WARN, "Attach failed\n");
+ osdev_delete (osdev);
+ goto err;
+ }
+
+ err = 0;
+err:
+ FEXITR(err);
+ return err;
+}
+#endif
+
+
+
+
+
+
+static status_t
+stdops(int32 op, ...)
+{
+ status_t err;
+ switch (op)
+ {
+ case B_MODULE_INIT:
+ err = get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI);
+ return err;
+
+ case B_MODULE_UNINIT:
+ //err = unload_driver(DRIVER_NICK);
+ //if (err < B_OK)
+ // return err;
+ put_module(B_PCI_MODULE_NAME);
+ return B_OK;
+
+ }
+ return B_ERROR;
+}
+
+oss_drv_module_info DRIVER_MODULE_OBJECT = {
+ {
+ OSS_MAKE_DRV_MOD_NAME(DRIVER_NICK),
+ 0,
+ stdops,
+ },
+ DRIVER_PROBE,
+ DRIVER_ATTACH,
+ DRIVER_DETACH
+};
+
diff --git a/kernel/OS/BeOS/os_beos.c b/kernel/OS/BeOS/os_beos.c
new file mode 100644
index 0000000..08587c5
--- /dev/null
+++ b/kernel/OS/BeOS/os_beos.c
@@ -0,0 +1,2222 @@
+/*
+ * Purpose: Operating system abstraction functions for BeOS/Haiku
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2007.
+ *
+ * This 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. Please contact sales@opensound.com for further info.
+ *
+ */
+
+#include "oss_config.h"
+#include "midi_core.h"
+#include <oss_pci.h>
+#include <Drivers.h>
+#include <KernelExport.h>
+#include <driver_settings.h>
+
+/*
+ * The BeOS and Haiku kernels are preemptible,
+ * therefore we must ensure safe access to global variables.
+ * Such variables are marked by GM.
+ * Other protected variables:
+ * - oss_cdevs
+ * - mixer_devs
+ * XXX: use a benaphore ??
+ */
+#if 0
+// spinlock
+static oss_mutex_t osscore_mutex;
+#define CORE_LOCK_VAR \
+ oss_native_word osscore_mutex_flags
+#define CORE_LOCK_INIT() \
+ MUTEX_INIT (osdev, osscore_mutex, MH_TOP)
+#define CORE_LOCK_CLEANUP() \
+ MUTEX_CLEANUP (osscore_mutex)
+#define LOCK_CORE() \
+ MUTEX_ENTER_IRQDISABLE (osscore_mutex, osscore_mutex_flags)
+#define UNLOCK_CORE() \
+ MUTEX_EXIT_IRQRESTORE (osscore_mutex, osscore_mutex_flags)
+#else
+// benaphore
+typedef struct benaphore {
+ sem_id sem;
+ int32 count;
+} benaphore;
+benaphore osscore_benaphore;
+#define CORE_LOCK_VAR \
+ int dummy_ocl
+#define CORE_LOCK_INIT() \
+ osscore_benaphore.count = 1; \
+ osscore_benaphore.sem = create_sem(0, "OSS CORE LOCK")
+#define CORE_LOCK_CLEANUP() \
+ delete_sem(osscore_benaphore.sem)
+#define LOCK_CORE() \
+ { \
+ if (atomic_add(&osscore_benaphore.count, -1) <= 0) \
+ acquire_sem(osscore_benaphore.sem); \
+ }
+#define UNLOCK_CORE() \
+ { \
+ if (atomic_add(&osscore_benaphore.count, 1) < 0) \
+ release_sem(osscore_benaphore.sem); \
+ }
+#endif
+
+#define DEBUG_IRQ 1
+#if DEBUG_IRQ
+vint32 irq_count = 0;
+#endif
+
+volatile int oss_open_devices = 0;
+#define MAX_CARDS 16
+int oss_num_cards = 0; /* GM */
+static oss_device_t *cards[MAX_CARDS]; /* GM */
+static int oss_expired = 0;
+extern int vmix_disabled;
+
+//static struct fileinfo files[OSS_MAX_CDEVS];
+//static volatile int open_count[OSS_MAX_CDEVS] = { 0 };
+//static volatile int open_devices = 0; /* GM */
+
+pci_module_info *gPCI = NULL;
+
+static char **gDeviceNames = NULL; // buffer for all names
+
+device_hooks oss_driver_hooks;
+
+/*
+ * Table for permanently allocated memory (to be freed by std_op(UNLOAD))
+ */
+#define MAX_MEMBLOCKS 4096
+static void *memblocks[MAX_MEMBLOCKS]; /* GM */
+static int nmemblocks = 0; /* GM */
+
+void *
+oss_contig_malloc (oss_device_t * osdev, int size, oss_uint64_t memlimit,
+ oss_native_word * phaddr)
+{
+ status_t err;
+ area_id id;
+ void *p = NULL;
+ uint32 lock = B_CONTIGUOUS;
+ physical_entry pent[1];
+
+ *phaddr = 0;
+
+ switch (memlimit)
+ {
+ case MEMLIMIT_ISA:
+ case MEMLIMIT_28BITS:
+ case MEMLIMIT_30BITS:
+ case MEMLIMIT_31BITS:
+ /* no known way to force a physical address limit other than <16M */
+ lock = B_LOMEM;
+ break;
+ case MEMLIMIT_32BITS:
+ lock = B_CONTIGUOUS;
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Bad DMA memlimit for %s\n", osdev->nick);
+ }
+
+ /* round up to page size */
+ size += B_PAGE_SIZE - 1;
+ size &= ~(B_PAGE_SIZE - 1);
+
+ if ((err = id = create_area(OSS_CONTIG_AREA_NAME, &p, B_ANY_KERNEL_ADDRESS,
+ size, lock, 0)) < B_OK)
+ {
+ cmn_err (CE_WARN, "create_area() failed\n");
+ return NULL;
+ }
+
+ if ((err = get_memory_map(p, size, pent, 1)) < B_OK)
+ {
+ cmn_err (CE_WARN, "get_memory_map() failed\n");
+ delete_area(id);
+ return NULL;
+ }
+ //XXX:DEBUG
+ *phaddr = (oss_native_word)pent[0].address;
+ dprintf("oss_contig_malloc: area %d @ va %p, pa %p, sz %d\n", id, p, (void *)(*phaddr), size);
+ return p;
+}
+
+void
+oss_contig_free (oss_device_t * osdev, void *p, int sz)
+{
+ area_id id;
+ if (p == NULL)
+ return;
+ id = area_for(p);
+ if (id < B_OK)
+ return;
+#ifdef MEMDEBUG
+ {
+ area_info ai;
+ if ((get_area_info(id, &ai) < B_OK) || strncmp(ai.name, OSS_CONTIG_AREA_NAME))
+ {
+ cmn_err (CE_NOTE, "oss_contig_free: bad area (%ld)!\n", id);
+ return;
+ }
+ }
+#endif
+ delete_area(id);
+}
+
+int
+__oss_alloc_dmabuf (int dev, dmap_p dmap, unsigned int alloc_flags,
+ oss_uint64_t maxaddr, int direction)
+{
+ void *tmpbuf;
+ oss_native_word phaddr;
+ int size = 64 * 1024;
+ extern int dma_buffsize;
+
+ if (dma_buffsize > 16 && dma_buffsize <= 128)
+ size = dma_buffsize * 1024;
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+/*
+ * Some applications and virtual drivers need shorter buffer.
+ */
+ if (dmap->flags & DMAP_SMALLBUF)
+ {
+ size = SMALL_DMABUF_SIZE;
+ }
+ else if (dmap->flags & DMAP_MEDIUMBUF)
+ {
+ size = MEDIUM_DMABUF_SIZE;
+ }
+
+ if ((alloc_flags & DMABUF_SIZE_16BITS) && size > 32 * 1024)
+ size = 32 * 1024;
+
+ tmpbuf = CONTIG_MALLOC (dmap->osdev, size, maxaddr, &phaddr, NULL);
+ if (tmpbuf == NULL)
+ return OSS_ENOMEM;
+ dmap->dmabuf = tmpbuf;
+ dmap->buffsize = size;
+ dmap->dmabuf_phys = phaddr;
+
+ return 0;
+}
+
+void
+oss_free_dmabuf (int dev, dmap_p dmap)
+{
+ if (dmap->dmabuf == NULL)
+ return;
+
+ CONTIG_FREE (dmap->osdev, dmap->dmabuf, dmap->buffsize, NULL);
+ dmap->dmabuf = NULL;
+ dmap->buffsize = 0;
+ dmap->dmabuf_phys = 0;
+}
+
+
+oss_native_word
+oss_virt_to_bus (void *addr)
+{
+ physical_entry pent[2];
+ status_t err;
+
+ if (addr == NULL)
+ return 0;
+
+ /* XXX: ROUNDUP(B_PAGE_SIZE) ? */
+ if ((err = get_memory_map(addr, 1, pent, 2)) < 1)
+ {
+ cmn_err (CE_WARN, "Virtual address %x not mapped\n", (int) addr);
+ return 0;
+ }
+ //XXX:which???
+ //return (oss_native_word)pent[0].address;
+ return (oss_native_word)(gPCI->ram_address(pent[0].address));
+}
+
+
+void *
+oss_pmalloc (size_t sz)
+{
+ void *tmp;
+
+ tmp = KERNEL_MALLOC (sz);
+
+ if (nmemblocks < MAX_MEMBLOCKS)
+ memblocks[nmemblocks++] = tmp;
+
+ return tmp;
+}
+
+int
+oss_create_uio (uio_t * uio, char *buf, size_t count, uio_rw_t rw,
+ int is_kernel)
+{
+ memset (uio, 0, sizeof (*uio));
+
+ if (is_kernel)
+ {
+ oss_cmn_err (CE_CONT,
+ "oss_create_uio: Kernel space buffers not supported\n");
+ return OSS_EIO;
+ }
+
+ uio->ptr = buf;
+ uio->resid = count;
+ uio->kernel_space = is_kernel;
+ uio->rw = rw;
+
+ return 0;
+}
+
+int
+oss_uiomove (void *address, size_t nbytes, enum uio_rw rwflag, uio_t * uio)
+{
+ int err = EFAULT;
+ FENTRY();
+
+ if (rwflag != uio->rw)
+ {
+ oss_cmn_err (CE_WARN, "uiomove: Bad direction\n");
+ goto err;
+ }
+
+ if (uio->resid < nbytes)
+ {
+ oss_cmn_err (CE_WARN, "uiomove: Bad count %d (%d)\n", nbytes,
+ uio->resid);
+ goto err;
+ }
+
+ if (uio->kernel_space)
+ goto err;
+
+ switch (rwflag)
+ {
+ case UIO_READ:
+ //XXX:user_memcpy...
+ memcpy (uio->ptr, address, nbytes);
+ break;
+
+ case UIO_WRITE:
+ //XXX:user_memcpy...
+ memcpy (address, uio->ptr, nbytes);
+ break;
+ }
+
+ uio->resid -= nbytes;
+ uio->ptr += nbytes;
+
+ err = B_OK;
+err:
+ FEXITR(err);
+ return err;
+}
+
+
+void
+oss_cmn_err (int level, char *s, ...)
+{
+ char tmp[1024], *a[6];
+ va_list ap;
+ int i, n = 0;
+
+ va_start (ap, s);
+
+ for (i = 0; i < strlen (s); i++)
+ if (s[i] == '%')
+ n++;
+
+ for (i = 0; i < n && i < 6; i++)
+ a[i] = va_arg (ap, char *);
+
+ for (i = n; i < 6; i++)
+ a[i] = NULL;
+
+ if (level == CE_CONT)
+ {
+ sprintf (tmp, s, a[0], a[1], a[2], a[3], a[4], a[5], NULL,
+ NULL, NULL, NULL);
+ dprintf ("%s", tmp);
+ }
+ else
+ {
+ strcpy (tmp, "osscore: ");
+ sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5],
+ NULL, NULL, NULL, NULL);
+ if (level == CE_PANIC)
+ panic (tmp);
+
+ dprintf ("%s", tmp);
+ }
+ va_end (ap);
+}
+
+
+/*
+ * Sleep/wakeup
+ */
+
+struct oss_wait_queue *
+oss_create_wait_queue (oss_device_t * osdev, const char *name)
+{
+ struct oss_wait_queue *wq;
+ status_t err;
+ FENTRYA(", %s", name);
+
+ if ((wq = malloc (sizeof (*wq))) == NULL)
+ {
+ oss_cmn_err (CE_WARN, "malloc(%d) failed (wq)\n", sizeof (*wq));
+ return NULL;
+ }
+ sprintf(wq->name, OSS_WQ_SEM_NAME "%-20s", name);
+ err = wq->sem = create_sem(0, wq->name);
+ if (err < B_OK)
+ {
+ free(wq);
+ oss_cmn_err (CE_WARN, "create_sem() failed (wq)\n");
+ return NULL;
+ }
+
+ return wq;
+}
+
+void
+oss_reset_wait_queue (struct oss_wait_queue *wq)
+{
+ sem_info si;
+ status_t err;
+ FENTRY();
+
+ wq->flags = 0;
+ err = create_sem(0, wq->name);
+ if (err >= 0) {
+ /* replace with the new one */
+ delete_sem(wq->sem);
+ wq->sem = err;
+ }
+
+ FEXIT();
+}
+
+void
+oss_remove_wait_queue (struct oss_wait_queue *wq)
+{
+ FENTRY();
+ delete_sem(wq->sem);
+ free (wq);
+}
+
+int
+oss_sleep (struct oss_wait_queue *wq, oss_mutex_t * mutex, int ticks,
+ oss_native_word * flags, unsigned int *status)
+{
+ bigtime_t timeout = B_INFINITE_TIMEOUT;
+ uint32 semflags = B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT;
+ int result = 0;
+ FENTRYA("(%s), , %d, , ", wq->name, ticks);
+ *status = 0;
+
+ if (wq == NULL)
+ return 0;
+
+#ifdef B_WAKE_ON_TIMEOUT
+ // Dano only; sure it's what we want ?
+ if (wq->flags & WK_WAKEUP)
+ semflags |= B_WAKE_ON_TIMEOUT;
+#endif
+
+ wq->flags = 0;
+ MUTEX_EXIT_IRQRESTORE(*mutex, *flags);
+
+ if (ticks > 0)
+ timeout = ticks * 1000000LL / OSS_HZ;
+ result = acquire_sem_etc (wq->sem, 1, semflags, timeout);
+ //dprintf("oss_sleep:acquire_sem(s:%ld, 1, %x, %Ld): 0x%08lx\n", wq->sem, semflags, timeout, result);
+
+ MUTEX_ENTER_IRQDISABLE (*mutex, *flags);
+
+ if (result == EINTR) /* Signal received */
+ {
+ *status |= WK_SIGNAL;
+ return 1;
+ }
+
+ if (result == B_TIMED_OUT)
+ //if (!(wq->flags & WK_WAKEUP)) /* Timeout */
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+int
+oss_register_poll (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ oss_native_word * flags, oss_poll_event_t * ev)
+{
+ FENTRYA("(%s), , , , ", wq->name);
+ dprintf("oss:UNIMPLEMENTED:%s\n", __FUNCTION__);
+ MUTEX_EXIT_IRQRESTORE(*mutex, *flags);
+ //poll_wait ((struct file *) ev->file, &wq->wq, (struct wait *) ev->wait);
+ MUTEX_ENTER_IRQDISABLE (*mutex, *flags);
+ return 0;
+}
+
+void
+oss_wakeup (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ oss_native_word * flags, short events)
+{
+ FENTRYA("(%s), , %x, , ", wq->name, events);
+ if (wq == NULL)
+ return;
+
+ wq->flags |= WK_WAKEUP;
+ MUTEX_EXIT_IRQRESTORE(*mutex, *flags);
+
+ //dprintf("oss_wakeup:release_sem(s:%ld)\n", wq->sem);
+ release_sem_etc (wq->sem, 1, B_DO_NOT_RESCHEDULE);
+ //XXX:handle select here
+
+ MUTEX_ENTER_IRQDISABLE (*mutex, *flags);
+}
+
+unsigned long
+oss_get_time (void)
+{
+ return (unsigned long) (system_time() / (1000000 / OSS_HZ));
+}
+
+typedef struct tmout_desc
+{
+ struct timer timer; /* MUST be first */
+
+ volatile int active;
+ int timestamp;
+ void (*func) (void *);
+ void *arg;
+} tmout_desc_t;
+
+static volatile int next_id = 0;
+#define MAX_TMOUTS 128
+
+tmout_desc_t tmouts[MAX_TMOUTS] = { {0} };
+
+int timeout_random = 0x12123400;
+
+int32
+oss_timer_callback (struct timer *timer)
+{
+ tmout_desc_t *tmout = (tmout_desc_t *)timer;
+ int ix;
+ void *arg;
+
+ timeout_random++;
+
+ if (!tmout->active)
+ return;
+
+ arg = tmout->arg;
+ tmout->active = 0;
+ tmout->timestamp = 0;
+
+ tmout->func (arg);
+ return B_HANDLED_INTERRUPT;//B_INVOKE_SCHEDULER ?;
+}
+
+timeout_id_t
+oss_timeout (void (*func) (void *), void *arg, unsigned long long ticks)
+{
+ tmout_desc_t *tmout = NULL;
+ bigtime_t period;
+ int id, n;
+
+ timeout_random++;
+
+ n = 0;
+ id = -1;
+
+ while (id == -1 && n < MAX_TMOUTS)
+ {
+ if (!tmouts[next_id].active)
+ {
+ tmouts[next_id].active = 1;
+ id = next_id++;
+ tmout = &tmouts[id];
+ break;
+ }
+
+ next_id = (next_id + 1) % MAX_TMOUTS;
+ }
+
+ if (id == -1) /* No timer slots available */
+ {
+ oss_cmn_err (CE_WARN, "Timeout table full\n");
+ return 0;
+ }
+
+ tmout->func = func;
+ tmout->arg = arg;
+ tmout->timestamp = id | (timeout_random & ~0xff);
+
+ period = ticks * 1000000LL / OSS_HZ;
+ add_timer (&tmout->timer, oss_timer_callback, period, B_ONE_SHOT_RELATIVE_TIMER);
+
+ return id | (timeout_random & ~0xff);
+}
+
+void
+oss_untimeout (timeout_id_t id)
+{
+ tmout_desc_t *tmout;
+ int ix;
+
+ ix = id & 0xff;
+ if (ix < 0 || ix >= MAX_TMOUTS)
+ return;
+
+ timeout_random++;
+ tmout = &tmouts[ix];
+
+ if (tmout->timestamp != id) /* Expired timer */
+ return;
+ if (tmout->active)
+ cancel_timer (&tmout->timer);
+ tmout->active = 0;
+ tmout->timestamp = 0;
+}
+
+
+caddr_t
+oss_map_pci_mem (oss_device_t * osdev, int nr, int phaddr, int size)
+{
+ status_t err;
+ void *va = NULL;
+ FENTRYA("%p,%d,%u,%d", osdev, nr, phaddr, size);
+ //XXX:align phaddr ?
+ /* round up to page size */
+ size += B_PAGE_SIZE - 1;
+ size &= ~(B_PAGE_SIZE - 1);
+
+ err = map_physical_memory(OSS_PCI_AREA_NAME, (void *)phaddr, size,
+ B_ANY_KERNEL_BLOCK_ADDRESS, 0, &va);
+ if (err < B_OK)
+ va = NULL;
+ FEXITR((uint32)va);
+ return (caddr_t)va;
+}
+
+void
+oss_unmap_pci_mem (void *addr)
+{
+ area_id id;
+ if (addr == NULL)
+ return;
+ id = area_for(addr);
+ if (id < B_OK)
+ return;
+#ifdef MEMDEBUG
+ {
+ area_info ai;
+ if ((get_area_info(id, &ai) < B_OK) || strncmp(ai.name, OSS_PCI_AREA_NAME))
+ {
+ cmn_err (CE_NOTE, "oss_unmap_pci_mem: bad area (%ld)!\n", id);
+ return;
+ }
+ }
+#endif
+ delete_area(id);
+}
+
+void
+oss_pci_byteswap (oss_device_t * osdev, int mode)
+{
+ // NOP
+}
+
+void
+oss_pcie_init (oss_device_t * osdev, int flags)
+{
+ /* TODO: Should we do something? */
+}
+
+int
+pci_read_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char *val)
+{
+ if (osdev->dev_type != DRV_PCI || osdev->dip == NULL)
+ return PCIBIOS_FAILED;
+ *val = (unsigned char)gPCI->read_pci_config (osdev->dip->pciinfo.bus,
+ osdev->dip->pciinfo.device,
+ osdev->dip->pciinfo.function,
+ (uchar)where, 1);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_read_config_irq (oss_device_t * osdev, offset_t where, unsigned char *val)
+{
+ int ret;
+
+ if (osdev->dev_type != DRV_PCI)
+ return PCIBIOS_FAILED;
+ ret = pci_read_config_byte (osdev, where, val);
+ return ret;
+}
+
+
+int
+pci_read_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short *val)
+{
+ if (osdev->dev_type != DRV_PCI || osdev->dip == NULL)
+ return PCIBIOS_FAILED;
+ *val = (unsigned short)gPCI->read_pci_config (osdev->dip->pciinfo.bus,
+ osdev->dip->pciinfo.device,
+ osdev->dip->pciinfo.function,
+ (uchar)where, 2);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_read_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int *val)
+{
+ if (osdev->dev_type != DRV_PCI || osdev->dip == NULL)
+ return PCIBIOS_FAILED;
+ *val = (unsigned int)gPCI->read_pci_config (osdev->dip->pciinfo.bus,
+ osdev->dip->pciinfo.device,
+ osdev->dip->pciinfo.function,
+ (uchar)where, 4);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_write_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char val)
+{
+ if (osdev->dev_type != DRV_PCI || osdev->dip == NULL)
+ return PCIBIOS_FAILED;
+ gPCI->write_pci_config (osdev->dip->pciinfo.bus,
+ osdev->dip->pciinfo.device,
+ osdev->dip->pciinfo.function,
+ (uchar)where, 1, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_write_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short val)
+{
+ if (osdev->dev_type != DRV_PCI || osdev->dip == NULL)
+ return PCIBIOS_FAILED;
+ gPCI->write_pci_config (osdev->dip->pciinfo.bus,
+ osdev->dip->pciinfo.device,
+ osdev->dip->pciinfo.function,
+ (uchar)where, 2, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_write_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int val)
+{
+ if (osdev->dev_type != DRV_PCI || osdev->dip == NULL)
+ return PCIBIOS_FAILED;
+ gPCI->write_pci_config (osdev->dip->pciinfo.bus,
+ osdev->dip->pciinfo.device,
+ osdev->dip->pciinfo.function,
+ (uchar)where, 4, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+
+#ifdef MUTEX_CHECKS
+static int oss_context = 0; /* 0=user context, 1=interrupt context */
+#endif
+
+static int32
+ossintr (void *idata)
+{
+ oss_device_t *osdev = idata;
+ oss_native_word flags;
+ //dprintf("oss:intr(%ld)!\n", osdev->irq);
+#ifdef MUTEX_CHECKS
+ int saved_context;
+ saved_context = oss_context;
+ if (oss_context == 1)
+ cmn_err (CE_WARN, "Recursive interrupt\n");
+ oss_context = 1;
+#endif
+
+ MUTEX_ENTER_IRQDISABLE (osdev->mutex, flags);
+
+ if (!osdev->tophalf_handler (osdev))
+ {
+ MUTEX_EXIT_IRQRESTORE (osdev->mutex, flags);
+#ifdef MUTEX_CHECKS
+ oss_context = saved_context;
+#endif
+ return B_UNHANDLED_INTERRUPT;
+ }
+
+ if (osdev->bottomhalf_handler != NULL)
+ osdev->bottomhalf_handler (osdev);
+
+ MUTEX_EXIT_IRQRESTORE (osdev->mutex, flags);
+#ifdef MUTEX_CHECKS
+ oss_context = saved_context;
+#endif
+
+ return B_HANDLED_INTERRUPT;
+}
+
+int
+oss_register_interrupts (oss_device_t * osdev, int intrnum,
+ oss_tophalf_handler_t top,
+ oss_bottomhalf_handler_t bottom)
+{
+ unsigned char pci_irq_line;
+ int err;
+ FENTRYA(", %d, , ", intrnum);
+
+ if (intrnum != 0)
+ {
+ cmn_err (CE_WARN, "Bad interrupt index (%d) for %s\n", intrnum,
+ osdev->name);
+ return OSS_EINVAL;
+ }
+
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "oss_register_interrupts: Bad osdev\n");
+ return OSS_EINVAL;
+ }
+
+ if (osdev->tophalf_handler != NULL || osdev->bottomhalf_handler != NULL)
+ {
+ cmn_err (CE_WARN, "Interrupts already registered for %s\n",
+ osdev->name);
+ return OSS_EINVAL;
+ }
+
+ if (top == NULL)
+ {
+ cmn_err (CE_WARN, "Bad interrupt handler for %s\n", osdev->name);
+ return OSS_EINVAL;
+ }
+
+ // could probably use osdev->dip->pciinfo...
+ if (pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line) > 0)
+ return OSS_EIO;
+
+ osdev->irq = pci_irq_line;
+ osdev->tophalf_handler = top;
+ osdev->bottomhalf_handler = bottom;
+ err = install_io_interrupt_handler (pci_irq_line, ossintr, osdev, 0);
+ dprintf("install_io_interrupt_handler (%d, %p, %p, 0) = 0x%08lx\n", pci_irq_line, ossintr, osdev, err);
+ if (err < B_OK)
+ {
+ cmn_err (CE_WARN, "install_io_interrupt_handler failed for %s\n", osdev->nick);
+ osdev->irq = -1;
+ osdev->tophalf_handler = NULL;
+ osdev->bottomhalf_handler = NULL;
+ return err;
+ }
+
+#if DEBUG_IRQ
+ atomic_add(&irq_count, 1);
+#endif
+
+ return 0;
+}
+
+void
+oss_unregister_interrupts (oss_device_t * osdev)
+{
+ status_t err = B_OK;
+ FENTRY();
+ dprintf("remove_io_interrupt_handler (%d, %p, %p)\n", osdev->irq, ossintr, osdev);
+ if (osdev->irq >= 0)
+ err = remove_io_interrupt_handler (osdev->irq, ossintr, osdev);
+ if (err < B_OK)
+ cmn_err (CE_WARN, "Error removing interrupt index (%d) for %s: %s\n",
+ osdev->irq, osdev->name, strerror(err));
+#if DEBUG_IRQ
+ atomic_add(&irq_count, -1);
+#endif
+ osdev->irq = -1;
+}
+
+int
+oss_register_device (oss_device_t * osdev, const char *name)
+{
+ static int dev_instance = 0;
+ FENTRYA(", %s", name);
+
+ DDB (cmn_err (CE_CONT, "OSS device %d is %s\n", dev_instance++, name));
+
+ if ((osdev->name = PMALLOC (NULL, strlen (name) + 1)) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate memory for device name\n");
+ osdev->name = "Unknown device";
+ }
+ strcpy (osdev->name, name);
+ FEXITR(0);
+ return 0;
+}
+
+int
+oss_disable_device (oss_device_t * osdev)
+{
+ int i;
+ CORE_LOCK_VAR;
+ FENTRY();
+/*
+ * This routine should check if the device is ready to be unloaded (no devices are in use).
+ * If the device cannot be unloaded this routine must return OSS_EBUSY.
+ *
+ * If the device can be unloaded then disable any timers or other features that may cause the
+ * device to be called. Also mark the audio/midi/mixer/etc devices of this device to be disabled.
+ * However the interrupt handler should still stay enabled. The low level driver will call
+ * oss_unregister_interrupts() after it has cleared the interrupt enable register.
+ */
+ LOCK_CORE();
+ if (osdev->refcount > 0 || oss_open_devices > 0)
+ {
+ UNLOCK_CORE();
+ cmn_err (CE_CONT, "Refcount %d, open_devices %d\n", osdev->refcount,
+ oss_open_devices);
+ return OSS_EBUSY;
+ }
+
+/*
+ * Now mark all devices unavailable (for the time being)
+ */
+
+ for (i = 0; i < num_mixers; i++)
+ if (mixer_devs[i]->osdev == osdev)
+ {
+ mixer_devs[i]->unloaded = 1;
+ }
+
+ for (i = 0; i < num_mididevs; i++)
+ {
+ if (midi_devs[i]->osdev == osdev)
+ {
+ midi_devs[i]->unloaded = 1;
+ }
+ }
+
+ for (i = 0; i < num_audio_engines; i++)
+ if (audio_engines[i]->osdev == osdev)
+ {
+ UNLOCK_CORE(); //needed until a benaphore is used.
+ audio_uninit_device (i);
+ LOCK_CORE();
+ }
+
+ UNLOCK_CORE();
+
+ FEXIT();
+ return 0;
+}
+
+void
+oss_unregister_device (oss_device_t * osdev)
+{
+ FENTRY();
+/*
+ * Notice! The driver calling this routine (the owner of the osdev parameter)
+ * has already uninitialized itself. Do not do any actions that may call this
+ * driver directly or indirectly.
+ */
+
+/*
+ * Force reload of all drivers if any application tries to open any
+ * of the devices.
+ */
+ //do_forceload = 1;
+ FEXIT();
+}
+
+void
+oss_reserve_device (oss_device_t * osdev)
+{
+ CORE_LOCK_VAR;
+
+ //XXX:use atomic_add() ?
+ LOCK_CORE();
+ osdev->refcount++;
+ UNLOCK_CORE();
+}
+
+void
+oss_unreserve_device (oss_device_t * osdev, int decrement)
+{
+ CORE_LOCK_VAR;
+
+ //XXX:use atomic_add() ?
+ LOCK_CORE();
+ osdev->refcount--;
+ if (osdev->refcount < 0)
+ osdev->refcount = 0;
+ UNLOCK_CORE();
+}
+
+void *
+oss_get_osid (oss_device_t * osdev)
+{
+// return osdev->osid;
+ return osdev->dip;
+ return NULL; // XXX:TODO
+}
+
+int
+oss_get_procinfo(int what)
+{
+ switch (what)
+ {
+ case OSS_GET_PROCINFO_UID:
+ return getuid();
+ break;
+ }
+
+ return OSS_EINVAL;
+}
+
+oss_device_t *
+osdev_create (dev_info_t * dip, int dev_type, int instance, const char *nick,
+ const char *handle)
+{
+ oss_device_t *osdev = NULL;
+ int i, err;
+ caddr_t addr;
+ off_t region_size;
+ CORE_LOCK_VAR;
+ FENTRYA(", %d, %d, %s, %s", dev_type, instance, nick, handle);
+
+ if (handle == NULL)
+ handle = nick;
+
+ /*
+ * Don't accept any more drivers if expired
+ */
+ if (oss_expired && oss_num_cards > 0)
+ return NULL;
+
+ LOCK_CORE();
+ for (i = 0; dip && (i < oss_num_cards); i++)
+ {
+ if (cards[i] == NULL)
+ continue;
+ if (cards[i]->available)
+ continue;
+ if (cards[i]->dip == dip)
+ {
+ osdev = cards[i];
+ break;
+ }
+ }
+ UNLOCK_CORE();
+
+ if (osdev == NULL)
+ {
+ if ((osdev = PMALLOC (NULL, sizeof (*osdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+
+ LOCK_CORE();
+ if (oss_num_cards >= MAX_CARDS)
+ {
+ UNLOCK_CORE();
+ cmn_err (CE_PANIC, "Too many OSS devices. At most %d permitted.\n",
+ MAX_CARDS);
+ return NULL;
+ }
+ memset (osdev, 0, sizeof (*osdev));
+
+ osdev->cardnum = oss_num_cards;
+ cards[oss_num_cards++] = osdev;
+ UNLOCK_CORE();
+ }
+
+ osdev->dip = dip;
+ //osdev->osid = dip;
+ osdev->unloaded = 0;
+ osdev->available = 1;
+ osdev->first_mixer = -1;
+ osdev->instance = instance;
+ osdev->dev_type = dev_type;
+ osdev->devc = NULL;
+ MUTEX_INIT (osdev, osdev->mutex, MH_GLOBAL);
+ sprintf (osdev->nick, "%s%d", nick, instance);
+ strcpy (osdev->modname, nick);
+
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ /* NOP */
+#ifdef __HAIKU__
+ if (gPCI->reserve_device(osdev->dip->pciinfo.bus,
+ osdev->dip->pciinfo.device,
+ osdev->dip->pciinfo.function,
+ "oss", osdev) != B_OK) {
+ cmn_err (CE_WARN, "Could not reserve PCI device\n");
+ /* XXX: CLEANUP! */
+ return NULL;
+ }
+#endif
+ break;
+
+ case DRV_VIRTUAL:
+ case DRV_STREAMS:
+ /* NOP */
+ break;
+
+ case DRV_USB:
+ /* NOP */
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Bad device type\n");
+ return NULL;
+ }
+
+/*
+ * Create the device handle
+ */
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ {
+ unsigned int subvendor;
+ pci_read_config_dword (osdev, 0x2c, &subvendor);
+
+ sprintf (osdev->handle, "PCI%08x-%d", subvendor, instance);
+ }
+ break;
+
+ case DRV_USB:
+ /* TODO: Get the vendor information */
+ sprintf (osdev->handle, "USB-%s%d", handle, instance);
+ break;
+
+ default:
+ sprintf (osdev->handle, "%s%d", handle, instance);
+ }
+
+ FEXIT();
+ return osdev;
+}
+
+oss_device_t *
+osdev_clone (oss_device_t * orig_osdev, int new_instance)
+{
+ oss_device_t *osdev;
+ FENTRYA(", %d", new_instance);
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+ memcpy (osdev, orig_osdev, sizeof (*osdev));
+ osdev->dev_type = DRV_CLONE;
+ osdev->instance = new_instance;
+ sprintf (osdev->nick, "%s%d", orig_osdev->modname, new_instance);
+ sprintf (osdev->handle, "%s%d", orig_osdev->modname, new_instance);
+
+ FEXIT();
+ return osdev;
+}
+
+void
+osdev_delete (oss_device_t * osdev)
+{
+ int i;
+ CORE_LOCK_VAR;
+
+ FENTRY();
+ if (osdev == NULL)
+ return;
+ osdev->available=0;
+
+ switch (osdev->dev_type)
+ {
+ case DRV_PCI:
+ /* NOP */
+ //pci_config_teardown (&osdev->pci_config_handle);
+ //osdev->pci_config_handle = NULL;
+#ifdef __HAIKU__
+ gPCI->unreserve_device(osdev->dip->pciinfo.bus,
+ osdev->dip->pciinfo.device,
+ osdev->dip->pciinfo.function,
+ "oss", osdev);
+#endif
+ break;
+ }
+
+/*
+ * Mark all minor nodes for this module as invalid.
+ */
+ LOCK_CORE();
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->osdev == osdev)
+ {
+ oss_cdevs[i]->d = NULL;
+ oss_cdevs[i]->osdev = NULL;
+ strcpy (oss_cdevs[i]->name, "Removed device");
+ }
+ UNLOCK_CORE();
+
+ MUTEX_CLEANUP (osdev->mutex);
+ osdev->unloaded = 1;
+ FEXIT();
+}
+
+static int
+grow_array(oss_device_t *osdev, oss_cdev_t ***arr, int *size, int element_size, int increment)
+{
+ oss_cdev_t **old=*arr, **new = *arr;
+ int old_size = *size;
+ int new_size = *size;
+
+ new_size += increment;
+
+ if ((new=PMALLOC(osdev, new_size * element_size))==NULL)
+ return 0;
+
+ memset(new, 0, new_size * element_size);
+ if (old != NULL)
+ memcpy(new, old, old_size * element_size);
+
+ *size = new_size;
+ *arr = new;
+
+ if (old != NULL)
+ PMFREE(osdev, old);
+
+ return 1;
+}
+
+void
+oss_install_chrdev (oss_device_t * osdev, char *name, int dev_class,
+ int instance, oss_cdev_drv_t * drv, int flags)
+{
+/*
+ * oss_install_chrdev creates a character device (minor). However if
+ * name==NULL the device will not be exported (made visible to userland
+ * clients).
+ */
+
+ int i, num;
+ oss_cdev_t *cdev = NULL;
+ CORE_LOCK_VAR;
+ FENTRYA(", %s, %d, %d, , %d", name, dev_class, instance, flags);
+
+ if (dev_class != OSS_DEV_STATUS)
+ if (oss_expired && instance > 0)
+ return;
+/*
+ * Find if this dev_class&instance already exists (after previous module
+ * detach).
+ */
+
+ LOCK_CORE();
+ for (num = 0; num < oss_num_cdevs; num++)
+ if (oss_cdevs[num]->d == NULL) /* Unloaded driver */
+ if (oss_cdevs[num]->dev_class == dev_class
+ && oss_cdevs[num]->instance == instance)
+ {
+ cdev = oss_cdevs[num];
+ //dprintf("oss:reusing cdev[%d]\n", num);
+ memset (cdev, 0, sizeof (*cdev));
+ cdev->dev_class = dev_class;
+ cdev->instance = instance;
+ cdev->d = drv;
+ cdev->osdev = osdev;
+ if (name != NULL)
+ strncpy (cdev->name, name, sizeof (cdev->name) - 1);
+ else
+ strcpy (cdev->name, "NONE");
+ cdev->name[sizeof (cdev->name) - 1] = 0;
+ oss_cdevs[num] = cdev;
+ break;
+ }
+ UNLOCK_CORE();
+
+ if (cdev == NULL)
+ {
+ /* must alloc before locking, the rest must be atomic */
+ if ((cdev = PMALLOC (NULL, sizeof (*cdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate character device desc.\n");
+ return;
+ }
+
+ LOCK_CORE();
+ if (oss_num_cdevs >= OSS_MAX_CDEVS)
+ {
+ if (!grow_array(osdev, &oss_cdevs, &oss_max_cdevs, sizeof(oss_cdev_t*), 100))
+ {
+ cmn_err (CE_WARN, "Cannot allocate new minor numbers.\n");
+ UNLOCK_CORE();
+ return;
+ }
+ }
+
+ num = oss_num_cdevs++;
+ memset (cdev, 0, sizeof (*cdev));
+ cdev->dev_class = dev_class;
+ cdev->instance = instance;
+ cdev->d = drv;
+ cdev->osdev = osdev;
+ if (name != NULL)
+ strncpy (cdev->name, name, sizeof (cdev->name) - 1);
+ else
+ strcpy (cdev->name, "NONE");
+ cdev->name[sizeof (cdev->name) - 1] = 0;
+ oss_cdevs[num] = cdev;
+ //dprintf("oss:reusing cdev[%d]: @%p\n", num, cdev);
+ UNLOCK_CORE();
+ }
+
+/*
+ * Export the device only if name != NULL
+ */
+#if 0
+ if (name != NULL)
+ {
+ char tmp[64], *s;
+ char *dev_type = "oss_sysdev";
+
+//XXX: maybe do something ??
+ }
+#endif
+ FEXIT();
+}
+
+int
+oss_get_cardinfo (int cardnum, oss_card_info * ci)
+{
+ CORE_LOCK_VAR;
+/*
+ * Print information about a 'card' in a format suitable for /dev/sndstat
+ */
+
+ LOCK_CORE();
+ if (cardnum < 0 || cardnum >= oss_num_cards)
+ {
+ UNLOCK_CORE();
+ return OSS_ENXIO;
+ }
+
+ if (cards[cardnum]->name != NULL)
+ strncpy (ci->longname, cards[cardnum]->name, 128);
+ ci->shortname[127] = 0;
+
+ if (cards[cardnum]->nick != NULL)
+ strncpy (ci->shortname, cards[cardnum]->nick, 16);
+ ci->shortname[15] = 0;
+
+ if (cards[cardnum]->hw_info != NULL)
+ strncpy (ci->hw_info, cards[cardnum]->hw_info, sizeof (ci->hw_info)-1);
+ ci->hw_info[sizeof(ci->hw_info)-1]=0;
+
+ UNLOCK_CORE();
+
+ return 0;
+}
+
+/* XXX: major/minors don't exist in BeOS, WTF */
+int
+oss_find_minor (int dev_class, int instance)
+{
+ int i, minor = -1;
+ CORE_LOCK_VAR;
+
+ LOCK_CORE();
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->d != NULL && oss_cdevs[i]->dev_class == dev_class
+ && oss_cdevs[i]->instance == instance)
+ {
+ minor = i;
+ break;
+ }
+ UNLOCK_CORE();
+
+ return minor;
+}
+
+
+#ifdef MUTEX_CHECKS
+void
+debug_mutex_init (oss_mutex_t * mutex, char *file, int line)
+{
+ memset (mutex, 0, sizeof (mutex));
+ mutex->lock = 0;
+ mutex->owner = -1;
+}
+
+void
+debug_mutex_destroy (oss_mutex_t * mutex, char *file, int line)
+{
+ if (find_thread(NULL) == mutex->owner)
+ {
+ cmn_err (CE_NOTE, "%s:%d: mutex still owned (%d)\n", file, line, mutex->owner);
+ }
+ if (mutex->lock)
+ {
+ cmn_err (CE_NOTE, "%s:%d: mutex still locked (%d)\n", file, line, mutex->lock);
+ }
+}
+
+void
+debug_mutex_enter (oss_mutex_t * mutex, char *file, int line, oss_native_word *flags)
+{
+ if (find_thread(NULL) == mutex->owner)
+ {
+ cmn_err (CE_NOTE, "%s:%d: Re-entrant mutex (%s:%d %d)\n", file, line,
+ mutex->file, mutex->line, mutex->busy_flags);
+ return;
+ }
+
+ mutex->file = file;
+ mutex->line = line;
+ mutex->busy_flags = flags ? CNTX_INTR : CNTX_USER;
+ if (flags)
+ *flags = (oss_native_word) disable_interrupts();
+ acquire_spinlock (&mutex->lock);
+
+}
+
+void
+debug_mutex_exit (oss_mutex_t * mutex, char *file, int line, oss_native_word *flags)
+{
+ if (find_thread(NULL) != mutex->owner)
+ {
+ cmn_err (CE_NOTE, "Mutex not owned %s:%d\n", file, line);
+ }
+ else
+ {
+ release_spinlock(&mutex->lock);
+ if (flags)
+ restore_interrupts((cpu_status)*flags);
+ }
+
+ mutex->owner = -1;
+ mutex->file = NULL;
+ mutex->line = 0;
+ mutex->busy_flags = 0;
+}
+#endif
+
+
+void
+oss_load_options (oss_device_t * osdev, oss_option_map_t map[])
+{
+ char name[32] = OSS_CONFIG_FILE_PREFIX "core";
+ void *handle;
+ const char *valstr;
+ int i;
+
+ if (osdev == NULL)
+ return;
+
+ /* if not core module, take the module name */
+ if (strcmp(osdev->modname, "oss"))
+ strncpy (name, osdev->modname, 16);
+
+ dprintf("oss_load_options(): %s\n", name);
+ handle = load_driver_settings (name);
+ /* not there */
+ if (handle == NULL)
+ return;
+
+ for (i = 0; map[i].name != NULL; i++)
+ {
+ /* discard given without value */
+ if ((valstr =
+ get_driver_parameter (handle,
+ map[i].name, NULL, NULL)) != NULL)
+ {
+ int base = 10;
+ if (!strncmp (valstr, "0x", 2))
+ {
+ base = 16;
+ valstr += 2;
+ }
+ *map[i].ptr = (int)strtol (valstr, NULL, base);
+ }
+ }
+ unload_driver_settings (handle);
+}
+
+#ifdef DEBUG_KDLCMD
+static int
+kdl_oss_dump_cards(int argc, char **argv)
+{
+ int i;
+ kprintf("oss_num_cards = %d\n", oss_num_cards);
+ for (i = 0; i < oss_num_cards; i++)
+ {
+ if (cards[i] == NULL)
+ continue;
+ kprintf("oss_cards[%d] = {\n", i);
+ kprintf(" cardnum= %d\n", cards[i]->cardnum);
+ kprintf(" dev_type= %d\n", cards[i]->dev_type);
+ kprintf(" instance= %d\n", cards[i]->instance);
+
+ kprintf(" unloaded= %d\n", cards[i]->unloaded);
+
+ kprintf(" name= %s\n", cards[i]->name);
+ kprintf(" nick= %-16s\n", cards[i]->nick);
+ kprintf(" modname= %-32s\n", cards[i]->modname);
+ kprintf(" handle= %-32s\n", cards[i]->handle);
+ kprintf(" num_audio_engines= %d\n", cards[i]->num_audio_engines);
+ kprintf(" num_audioplay= %d\n", cards[i]->num_audioplay);
+ kprintf(" num_audiorec= %d\n", cards[i]->num_audiorec);
+ kprintf(" num_audioduplex= %d\n", cards[i]->num_audioduplex);
+ kprintf(" num_mididevs= %d\n", cards[i]->num_mididevs);
+ kprintf(" num_mixerdevs= %d\n", cards[i]->num_mixerdevs);
+
+ kprintf(" refcount= %d\n", cards[i]->refcount);
+
+ kprintf(" irq= %d\n", cards[i]->irq);
+ kprintf("}\n");
+ }
+ return 0;
+}
+
+static int
+kdl_oss_dump_cdevs(int argc, char **argv)
+{
+ int i;
+ kprintf("oss_num_cdevs = %d\n", oss_num_cdevs);
+ for (i = 0; i < oss_num_cdevs; i++)
+ {
+ if (oss_cdevs[i] == NULL)
+ continue;
+ kprintf("oss_cdevs[%d] = {\n", i);
+ kprintf(" dev_class= %d\n", oss_cdevs[i]->dev_class);
+ kprintf(" instance= %d\n", oss_cdevs[i]->instance);
+ kprintf(" name= %-32s\n", oss_cdevs[i]->name);
+ kprintf(" osdev= %p\n", oss_cdevs[i]->osdev);
+ //kprintf(" opencount= %d\n", open_count[i]);
+ kprintf("}\n");
+ }
+ return 0;
+}
+#endif
+
+/*
+ * Driver entry point routines
+ */
+
+status_t
+init_osscore (void)
+{
+ int err = 0;
+ oss_device_t *osdev;
+ FENTRY();
+
+#ifdef LICENSED_VERSION
+/*WRITEME*/
+#endif
+
+ add_debugger_command("oss_dump_cards", &kdl_oss_dump_cards, "Dump the OSS cards[] array.");
+ add_debugger_command("oss_dump_cdevs", &kdl_oss_dump_cdevs, "Dump the OSS cdevs[] array.");
+
+ //MUTEX_INIT (osdev, osscore_mutex, MH_TOP);
+ CORE_LOCK_INIT();
+
+ if ((osdev = osdev_create (NULL, DRV_VIRTUAL, 0, "oss", NULL)) == NULL)
+ {
+ cmn_err (CE_WARN, "Creating osdev failed\n");
+ FEXITR(ENOMEM);
+ return OSS_ENOMEM;
+ }
+
+
+ oss_load_options (osdev, oss_global_options);
+
+ oss_common_init (osdev);
+
+ oss_register_device (osdev, "OSS core services");
+
+ FEXIT();
+ return 0;
+}
+
+status_t
+uninit_osscore (void)
+{
+ int i;
+ static int already_unloaded = 0;
+ FENTRY();
+
+ if (oss_open_devices > 0)
+ return EBUSY;
+
+ if (already_unloaded)
+ return 0;
+ already_unloaded = 1;
+
+ oss_unload_drivers ();
+
+ //LOCK_CORE();
+ for (i = 0; i < nmemblocks; i++)
+ KERNEL_FREE (memblocks[i]);
+ nmemblocks = 0;
+
+ CORE_LOCK_CLEANUP();
+ //MUTEX_CLEANUP (osscore_mutex);
+
+ remove_debugger_command("oss_dump_cdevs", &kdl_oss_dump_cdevs);
+ remove_debugger_command("oss_dump_cards", &kdl_oss_dump_cards);
+
+#if DEBUG_IRQ
+ dprintf("oss: %ld irq handlers left\n", irq_count);
+#endif
+
+
+ return 0;
+}
+
+const char **
+oss_publish_devices(void)
+{
+ int i, j;
+ char *name;
+ CORE_LOCK_VAR;
+
+ FENTRY();
+
+ LOCK_CORE();
+ gDeviceNames = realloc(gDeviceNames, (oss_num_cdevs + 1) * sizeof(char *)
+ + (oss_num_cdevs * DEVICE_NAME_LEN));
+ if (gDeviceNames == NULL) {
+ UNLOCK_CORE();
+ FEXIT();
+ return NULL;
+ }
+ name = (char *)(&gDeviceNames[oss_num_cdevs + 1]);
+ for (i = 0; i < oss_num_cdevs+1; i++)
+ gDeviceNames[i] = NULL;
+ //dprintf("oss_num_cdevs = %d\n", oss_num_cdevs);
+ for (i = 0, j = 0; i < oss_num_cdevs; i++)
+ {
+ oss_cdev_t *cdev = oss_cdevs[i];
+ if (cdev && cdev->d)
+ {
+ strcpy(name, DEVICE_PREFIX);
+ strncat(name, cdev->name, 32-1);
+ //dprintf("oss: publishing %s\n", name);
+ gDeviceNames[j++] = name;
+ name += DEVICE_NAME_LEN;
+ }
+ }
+ UNLOCK_CORE();
+
+ FEXIT();
+ return (const char**)gDeviceNames;
+}
+
+device_hooks *oss_get_driver_hooks (void)
+{
+ return &oss_driver_hooks;
+}
+
+status_t
+oss_load_drivers (void)
+{
+ oss_drv_module_info *drv;
+ char module[256];
+ size_t modulesz = sizeof(module);
+ void *cookie;
+ status_t err = ENOENT;
+ FENTRY();
+ cookie = open_module_list(OSS_MODULES_PREFIX);
+ if (cookie == NULL)
+ goto err1;
+ while (read_next_module_name(cookie, module, &modulesz) >= B_OK)
+ {
+ err = get_module(module, (module_info **)&drv);
+ if (err >= B_OK)
+ {
+ if (drv->driver_probe() < B_OK)
+ put_module(module);
+ }
+ modulesz = sizeof(module);
+ }
+ err = B_OK;
+err2:
+ close_module_list(cookie);
+err1:
+ FEXITR(err);
+ return B_OK;
+}
+
+status_t
+oss_probe_pci (void)
+{
+ FENTRY();
+ //XXX:TODO:remove me
+ //ali5455_probe();
+ //atiaudio_probe();
+ FEXIT();
+ return B_OK;
+}
+
+
+static status_t
+unload_driver (const char *nick)
+{
+ oss_drv_module_info *drv;
+ char module[256];
+ status_t err = B_OK;
+ int i;
+ CORE_LOCK_VAR;
+ FENTRYA("%s", nick);
+
+ /* skip ourselves */
+ if (!strcmp(nick, "oss"))
+ goto err1;
+
+ sprintf(module, "%s%s%s", OSS_MODULES_PREFIX, nick, OSS_MODULES_SUFFIX);
+ err = get_module(module, (module_info **)&drv);
+ if (err < B_OK)
+ goto err1;
+
+ err = EBUSY;
+
+ LOCK_CORE();
+ /* detach all osdevs for this driver */
+ for (i = 0; i < oss_num_cards; i++)
+ {
+ oss_device_t *osdev = cards[i];
+ if (!osdev)
+ continue;
+ if (strncmp(osdev->modname, nick, 32))
+ continue;
+ UNLOCK_CORE();
+ err = drv->driver_detach(osdev);
+ if (err < B_OK)
+ goto err2;
+ LOCK_CORE();
+ //cards[i] = NULL; // XXX: not sure...
+ }
+ UNLOCK_CORE();
+ err = B_OK;
+ put_module(module);
+ /* twice */
+err2:
+ put_module(module);
+err1:
+ FEXITR(err);
+ return err;
+}
+
+status_t
+oss_unload_all_drivers(void)
+{
+ char module[256];
+ status_t err = B_OK;
+ int i;
+ CORE_LOCK_VAR;
+ FENTRY();
+
+ /* for each osdev still around, unload the module it came from,
+ * which should delete them.
+ */
+ LOCK_CORE();
+ for (i = 0; i < oss_num_cards; i++)
+ {
+ if (!cards[i])
+ continue;
+ if (cards[i]->unloaded)
+ continue;
+ UNLOCK_CORE();
+ err = unload_driver(cards[i]->modname);
+ if (err < B_OK)
+ break;
+ LOCK_CORE();
+ }
+ UNLOCK_CORE();
+
+ FEXITR(err);
+ return err;
+}
+
+
+static status_t
+oss_stdops(int32 op, ...)
+{
+ status_t err;
+ switch (op)
+ {
+ case B_MODULE_INIT:
+ //vmix_disabled = 1; /* disable vmix */
+ err = get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI);
+ if (err >= B_OK)
+ {
+ //XXX:call init_osscore() here
+ return err;
+ put_module(B_PCI_MODULE_NAME);
+ }
+ return err;
+ case B_MODULE_UNINIT:
+ free(gDeviceNames);
+ put_module(B_PCI_MODULE_NAME);
+ return B_OK;
+
+ }
+ return B_ERROR;
+}
+
+oss_core_module_info gOSSCoreModule = {
+ {
+ OSS_CORE_MODULE_NAME,
+ /*B_KEEP_LOADED*/0,
+ oss_stdops,
+ },
+ init_osscore,
+ uninit_osscore,
+ oss_publish_devices,
+ oss_get_driver_hooks,
+ oss_probe_pci,
+ oss_load_drivers,
+ oss_unload_all_drivers,
+};
+
+// for f in kernel/drv/*; do echo "extern oss_drv_module_info gModule_$(basename $f);"; done
+extern oss_drv_module_info gModule_oss_ali5455;
+extern oss_drv_module_info gModule_oss_atiaudio;
+extern oss_drv_module_info gModule_oss_audigyls;
+//extern oss_drv_module_info gModule_oss_audiocs;
+extern oss_drv_module_info gModule_oss_audioloop;
+extern oss_drv_module_info gModule_oss_audiopci;
+extern oss_drv_module_info gModule_oss_cmi878x;
+extern oss_drv_module_info gModule_oss_cmpci;
+extern oss_drv_module_info gModule_oss_cs4281;
+extern oss_drv_module_info gModule_oss_cs461x;
+extern oss_drv_module_info gModule_oss_digi96;
+extern oss_drv_module_info gModule_oss_emu10k1x;
+extern oss_drv_module_info gModule_oss_envy24;
+extern oss_drv_module_info gModule_oss_envy24ht;
+extern oss_drv_module_info gModule_oss_fmedia;
+extern oss_drv_module_info gModule_oss_geode;
+extern oss_drv_module_info gModule_oss_hdaudio;
+extern oss_drv_module_info gModule_oss_ich;
+//extern oss_drv_module_info gModule_oss_imux;
+//extern oss_drv_module_info gModule_oss_midiloop;
+//extern oss_drv_module_info gModule_oss_midimix;
+//extern oss_drv_module_info gModule_oss_sadasupport;
+extern oss_drv_module_info gModule_oss_sblive;
+extern oss_drv_module_info gModule_oss_sbpci;
+extern oss_drv_module_info gModule_oss_sbxfi;
+extern oss_drv_module_info gModule_oss_solo;
+extern oss_drv_module_info gModule_oss_trident;
+//extern oss_drv_module_info gModule_oss_usb;
+//extern oss_drv_module_info gModule_oss_userdev;
+extern oss_drv_module_info gModule_oss_via823x;
+extern oss_drv_module_info gModule_oss_via97;
+extern oss_drv_module_info gModule_oss_ymf7xx;
+//extern oss_drv_module_info gModule_osscore;
+
+module_info *modules[] = {
+ (module_info *)&gOSSCoreModule,
+//for f in kernel/drv/*; do echo " (module_info *)&gModule_$(basename $f),"; done >> kernel/OS/BeOS/os_beos.c (module_info *)&gModule_oss_ali5455,
+ (module_info *)&gModule_oss_atiaudio,
+ (module_info *)&gModule_oss_audigyls,
+ //(module_info *)&gModule_oss_audiocs,
+ //(module_info *)&gModule_oss_audioloop,
+ (module_info *)&gModule_oss_audiopci,
+ (module_info *)&gModule_oss_cmi878x,
+ (module_info *)&gModule_oss_cmpci,
+ (module_info *)&gModule_oss_cs4281,
+ (module_info *)&gModule_oss_cs461x,
+ (module_info *)&gModule_oss_digi96,
+ (module_info *)&gModule_oss_emu10k1x,
+ (module_info *)&gModule_oss_envy24,
+ (module_info *)&gModule_oss_envy24ht,
+ (module_info *)&gModule_oss_fmedia,
+ (module_info *)&gModule_oss_geode,
+ (module_info *)&gModule_oss_hdaudio,
+ (module_info *)&gModule_oss_ich,
+ //(module_info *)&gModule_oss_imux,
+ //(module_info *)&gModule_oss_midiloop,
+ //(module_info *)&gModule_oss_midimix,
+ //(module_info *)&gModule_oss_sadasupport,
+ (module_info *)&gModule_oss_sblive,
+ (module_info *)&gModule_oss_sbpci,
+ (module_info *)&gModule_oss_sbxfi,
+ (module_info *)&gModule_oss_solo,
+ (module_info *)&gModule_oss_trident,
+ //(module_info *)&gModule_oss_usb,
+ //(module_info *)&gModule_oss_userdev,
+ (module_info *)&gModule_oss_via823x,
+ (module_info *)&gModule_oss_via97,
+ (module_info *)&gModule_oss_ymf7xx,
+// (module_info *)&gModule_osscore,
+
+#if 0 /* OLD */
+
+
+ (module_info *)&gModule_oss_ali5455,
+
+ (module_info *)&gModule_oss_allegro,
+ (module_info *)&gModule_oss_als300,
+ (module_info *)&gModule_oss_als4000,
+ (module_info *)&gModule_oss_apci97,
+
+ (module_info *)&gModule_oss_atiaudio,
+
+ (module_info *)&gModule_oss_audigyls,
+ //(module_info *)&gModule_oss_audioloop,
+ (module_info *)&gModule_oss_audiopci,
+ (module_info *)&gModule_oss_cmi8788,
+ (module_info *)&gModule_oss_cmpci,
+ (module_info *)&gModule_oss_cs4280,
+ (module_info *)&gModule_oss_cs4281,
+ (module_info *)&gModule_oss_digi32,
+ (module_info *)&gModule_oss_digi96,
+ (module_info *)&gModule_oss_emu10k1x,
+ (module_info *)&gModule_oss_envy24,
+ (module_info *)&gModule_oss_envy24ht,
+ (module_info *)&gModule_oss_fm801,
+ (module_info *)&gModule_oss_geode,
+ (module_info *)&gModule_oss_hdaudio,
+
+ (module_info *)&gModule_oss_ich,
+
+#ifdef ENABLE_IMUX
+ (module_info *)&gModule_oss_imux,
+#endif
+ (module_info *)&gModule_oss_maestro,
+ (module_info *)&gModule_oss_neomagic,
+ (module_info *)&gModule_oss_s3vibes,
+ (module_info *)&gModule_oss_sblive,
+#ifdef ENABLE_SOFTOSS
+ //(module_info *)&gModule_oss_softoss,
+#endif
+ (module_info *)&gModule_oss_solo,
+ (module_info *)&gModule_oss_trident,
+ (module_info *)&gModule_oss_via8233,
+ (module_info *)&gModule_oss_via97,
+ (module_info *)&gModule_oss_vortex,
+ (module_info *)&gModule_oss_ymf7xx,
+#endif
+
+ NULL
+};
+
+/*
+ * Driver hooks
+ */
+
+
+typedef struct ossdev_cookie {
+ int minor; /* index into cdevs[] */
+ oss_cdev_t *cdev;
+ struct fileinfo file;
+} ossdev_cookie_t;
+
+static int find_cdev(const char *name)
+{
+ int i, which = -1;
+ CORE_LOCK_VAR;
+// if (strlen(name) < strlen(DEVICE_PREFIX))
+// return -1;
+ name += strlen(DEVICE_PREFIX);
+
+ LOCK_CORE();
+ for (i = 0; i < oss_num_cdevs; i++)
+ {
+ oss_cdev_t *cdev = oss_cdevs[i];
+ //dprintf("oss:find_cdev: cdev %p, ->d %p, %s <> %s\n", cdev, cdev?cdev->d:NULL, cdev?cdev->name:"-", name);
+ if (cdev && cdev->d && !strncmp(cdev->name, name, 32))
+ {
+ which = i;
+ break;
+ }
+ }
+ UNLOCK_CORE();
+
+ return which;
+}
+
+static status_t
+ossdrv_open(const char *name, uint32 oflags, void **cookie)
+{
+ ossdev_cookie_t *c;
+ status_t err;
+ int dev, tmpdev;
+ oss_cdev_t *cdev;
+ CORE_LOCK_VAR;
+ FENTRYA("%s, %ld, ", name, oflags);
+
+ dev = find_cdev(name);
+ err = ENOENT;
+ if (dev < 0)
+ goto err1;
+ err = ENXIO;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ goto err1;
+
+ DDB (cmn_err
+ (CE_CONT, "oss_cdev_open(%d): %s, class=%d, instance=%d\n", dev,
+ cdev->name, cdev->dev_class, cdev->instance));
+
+ err = ENODEV;
+ if (cdev->d->open == NULL)
+ goto err1;
+
+ err = ENOMEM;
+ c = malloc(sizeof(ossdev_cookie_t));
+ if (!c)
+ goto err1;
+
+ switch (oflags & O_RWMASK)
+ {
+ case O_RDONLY:
+ c->file.mode = OPEN_READ;
+ break;
+ case O_WRONLY:
+ c->file.mode = OPEN_WRITE;
+ break;
+ case O_RDWR:
+ c->file.mode = OPEN_READWRITE;
+ break;
+ default:
+ err = EINVAL;
+ goto err2;
+ }
+ //c->file.flags = oflags;
+ c->file.acc_flags = oflags;
+
+ tmpdev = -1;
+ err =
+ cdev->d->open (cdev->instance, cdev->dev_class, &c->file, 0, 0, &tmpdev);
+ if (err < 0)
+ goto err3;
+ if (tmpdev > -1)
+ dev = tmpdev;
+
+ c->minor = dev;
+ c->cdev = cdev = oss_cdevs[dev];
+
+ //XXX:locking
+ LOCK_CORE();
+ oss_open_devices++;
+ //open_count[dev]++;
+ UNLOCK_CORE();
+
+ *cookie = c;
+ FEXITR(B_OK);
+ return B_OK;
+
+err3:
+err2:
+ free(c);
+err1:
+ FEXITR(err);
+ return err;
+}
+
+
+static status_t
+ossdrv_close(void *cookie)
+{
+ FENTRY();
+ FEXIT();
+ return B_OK;
+}
+
+
+static status_t
+ossdrv_freecookie(ossdev_cookie_t *cookie)
+{
+ oss_cdev_t *cdev = cookie->cdev;
+ int dev = cookie->minor;
+ CORE_LOCK_VAR;
+ status_t err;
+ FENTRY();
+
+ err = ENXIO;
+ if (dev >= OSS_MAX_CDEVS)
+ goto err;
+
+#if 0 // not safe (not locked)
+ err = B_OK;
+ if (open_count[dev] == 0) /* Not opened */
+ goto err;
+#endif
+
+ err = ENXIO;
+ if (cdev != oss_cdevs[dev])
+ goto err;
+
+ //in close or free ??
+ cdev->d->close (cdev->instance, &cookie->file);
+
+ LOCK_CORE();
+ oss_open_devices--;
+ //open_count[dev]--;
+ UNLOCK_CORE();
+
+ free(cookie);
+ err = B_OK;
+err:
+ FEXITR(err);
+ return B_OK;
+}
+
+/* note: IOC stuff seems to not collide with the base ioctls from Drivers.h
+ * as long as the type field is printable ascii (>32). Lucky are we.
+ */
+static status_t
+ossdrv_ioctl(ossdev_cookie_t *cookie, uint32 op, void *buffer, size_t length)
+{
+ oss_cdev_t *cdev = cookie->cdev;
+ status_t err = ENXIO;
+ uint32 cmd = op;
+ int len = 0;
+ char buf[4096];
+ FENTRYA(", %lx, , %ld", op, length);
+
+ if ((cdev != oss_cdevs[cookie->minor]) || cdev->d->ioctl == NULL)
+ goto err1;
+
+ if (cmd & (SIOC_OUT | SIOC_IN))
+ {
+
+ len = (cmd >> 16) & SIOCPARM_MASK;
+ if (len < 0)
+ len = 0;
+ if (len > sizeof (buf))
+ {
+ cmn_err (CE_WARN, "Bad ioctl buffer size %d\n", len);
+ err = EFAULT;
+ goto err1;
+ }
+
+ if ((cmd & SIOC_IN) && len > 0)
+ {
+ memcpy (buf, buffer, len);
+ //return EFAULT;
+ }
+
+ }
+
+ err = cdev->d->ioctl (cdev->instance, &cookie->file, cmd, (ioctl_arg) buf);
+
+ if ((cmd & SIOC_OUT) && len > 0)
+ {
+ memcpy (buffer, buf, len);
+ //return EFAULT;
+ }
+
+
+err1:
+ FEXITR(err);
+ return err;
+}
+
+
+static status_t
+ossdrv_read(ossdev_cookie_t *cookie, off_t pos, void *buffer, size_t *_length)
+{
+ oss_cdev_t *cdev = cookie->cdev;
+ uio_t uio;
+ int count = *_length;
+ int err;
+ FENTRYA(", %Ld, , %ld", pos, *_length);
+
+ err = ENXIO;
+ if ((cdev != oss_cdevs[cookie->minor]) || cdev->d->read == NULL)
+ goto err;
+ //files[dev].acc_flags = uiop->uio_fmode;
+ if ((err = oss_create_uio (&uio, buffer, count, UIO_READ, 0)) < 0)
+ goto err;
+
+ err = cdev->d->read (cdev->instance, &cookie->file, &uio, count);
+ //*_length = (err > 0) ? err : 0;
+ if (err < 0)
+ goto err;
+
+ *_length = err;
+ err = B_OK;
+ FEXITR(err);
+ return err;
+
+err:
+ *_length = 0;
+ FEXITR(err);
+ return err;
+}
+
+
+static status_t
+ossdrv_write(ossdev_cookie_t *cookie, off_t pos, const void *buffer, size_t *_length)
+{
+ oss_cdev_t *cdev = cookie->cdev;
+ uio_t uio;
+ int count = *_length;
+ int err;
+ FENTRYA(", %Ld, , %ld", pos, *_length);
+
+ err = ENXIO;
+ if ((cdev != oss_cdevs[cookie->minor]) || cdev->d->write == NULL)
+ goto err;
+ //files[dev].acc_flags = uiop->uio_fmode;
+ if ((err = oss_create_uio (&uio, (void *)buffer, count, UIO_WRITE, 0)) < 0)
+ goto err;
+
+ err = cdev->d->write (cdev->instance, &cookie->file, &uio, count);
+ //*_length = (err > 0) ? err : 0;
+ if (err < 0)
+ goto err;
+
+ *_length = err;
+ err = B_OK;
+ FEXITR(err);
+ return err;
+
+err:
+ *_length = 0;
+ FEXITR(err);
+ return err;
+}
+
+
+device_hooks oss_driver_hooks = {
+ &ossdrv_open,
+ &ossdrv_close,
+ (device_free_hook)&ossdrv_freecookie,
+ (device_control_hook)&ossdrv_ioctl,
+ (device_read_hook)&ossdrv_read,
+ (device_write_hook)&ossdrv_write,
+ /* Leave select/deselect/readv/writev undefined. The kernel will
+ * use its own default implementation. The basic hooks above this
+ * line MUST be defined, however. */
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
diff --git a/kernel/OS/BeOS/os_beos.h b/kernel/OS/BeOS/os_beos.h
new file mode 100644
index 0000000..1e8f0b5
--- /dev/null
+++ b/kernel/OS/BeOS/os_beos.h
@@ -0,0 +1,471 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+/*
+ * Purpose: OS specific definitions for BeOS/Haiku
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2007.
+ *
+ * This 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. Please contact sales@opensound.com for further info.
+ *
+ */
+#define OS_VERSION "5"
+#define __inline__ inline
+#define __inline inline
+#define EXTERN_C extern "C"
+
+/*
+ * Debugging and misc settings
+ */
+#undef DO_TIMINGS
+#undef MUTEX_CHECKS
+#undef MEMDEBUG
+/* very verbose */
+//#define DO_DEBUG_FUNC_CALLS
+/* XXX */
+#define DEBUG_KDLCMD 1
+//#define ENABLE_IMUX 1
+//#define ENABLE_SOFTOSS 1
+
+/*
+ * Disable support for per-application features such as /dev/dsp device
+ * selection based on command name. Requires working GET_PROCESS_NAME
+ * macro implementation.
+ */
+//Disable??
+//#define APPLIST_SUPPORT
+#define USE_DEVICE_SUBDIRS
+/* no VDEV */
+#undef VDEV_SUPPORT
+
+//XXX: try to avoid crashing
+#define MIDI_DISABLED 1
+
+#include <OS.h>
+#include <stdarg.h>
+//#include <stdint.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <oss_errno.h>
+#include <sys/uio.h>
+#include <fcntl.h>
+#ifdef __HAIKU__
+#include <poll.h>
+#endif
+//#include <sys/malloc.h>
+#include <malloc.h>
+
+
+#include <KernelExport.h>
+#include <Drivers.h>
+#include <PCI.h>
+
+#ifndef ENOTSUP
+#define ENOTSUP ENOSYS
+#endif
+
+#define OSS_CONTIG_AREA_NAME "OSS CONTIG MEM"
+#define OSS_PCI_AREA_NAME "OSS PCI MEM"
+#define OSS_WQ_SEM_NAME "OSS WAITQ: "
+
+//#define DEVICE_PREFIX "audio/oss/"
+#define DEVICE_PREFIX ""
+#define DEVICE_NAME_LEN (32+sizeof(DEVICE_PREFIX))
+
+#define OSS_CONFIG_FILE_PREFIX "oss_"
+
+#ifdef _KERNEL_MODE
+
+/* references to modules */
+extern pci_module_info *gPCI;
+
+#endif /* _KERNEL_MODE */
+
+/*
+ * Some integer types
+ */
+#if defined(amd64) || defined(sparc) // 64bit ? not yet
+typedef uint64 oss_native_word; /* Same as the address and status register size */
+#else
+typedef uint32 oss_native_word; /* Same as the address and status register size */
+#endif
+
+typedef int64 oss_int64_t; /* Signed 64 bit integer */
+typedef uint64 oss_uint64_t; /* Unsigned 64 bit integer */
+typedef unsigned long offset_t;
+
+
+extern void oss_cmn_err (int level, char *format, ...);
+#define CE_CONT 0
+#define CE_NOTE 1
+#define CE_WARN 2
+#define CE_PANIC 3
+#define cmn_err oss_cmn_err
+
+//snooze(1000000); \
+
+#ifdef DO_DEBUG_FUNC_CALLS
+/* verbose debugging */
+#define FENTRY() \
+dprintf("oss>%s()\n", __FUNCTION__)
+#define FENTRYA(f,a...) \
+dprintf("oss>%s(" f ")\n", __FUNCTION__, a)
+#define FEXIT() \
+dprintf("oss<%s\n", __FUNCTION__)
+#define FEXITR(e) \
+dprintf("oss<%s returned 0x%08lx\n", __FUNCTION__, (uint32)e)
+#else
+#define FENTRY() {}
+#define FENTRYA(f,a...) {}
+#define FEXIT() {}
+#define FEXITR(e) {}
+#endif
+
+struct _dev_info_t
+{
+ //struct pci_dev *pcidev;
+ struct pci_info pciinfo; //XXX: ptr or not ???
+};
+typedef struct _dev_info_t dev_info_t;
+
+
+/*
+ * timeout wrappers
+ */
+#undef timeout
+#define timeout oss_timeout
+#undef untimeout
+#define untimeout oss_untimeout
+typedef int timeout_id_t;
+extern timeout_id_t oss_timeout (void (*func) (void *), void *arg,
+ unsigned long long ticks);
+extern void oss_untimeout (timeout_id_t id);
+
+#define uiomove oss_uiomove
+typedef enum uio_rw
+{ UIO_READ, UIO_WRITE } uio_rw_t;
+struct uio
+{
+ char *ptr;
+ int resid;
+ int kernel_space; /* Set if this uio points to a kernel space buffer */
+ uio_rw_t rw;
+};
+typedef struct uio uio_t;
+extern int oss_uiomove (void *address, size_t nbytes, enum uio_rw rwflag,
+ uio_t * uio);
+extern int oss_create_uio (uio_t * uiop, char *buf, size_t count, uio_rw_t rw,
+ int is_kernel);
+
+
+
+/*
+ * Mutexes
+ */
+
+#ifdef MUTEX_CHECKS
+/* Debugging version */
+struct _oss_mutex_t
+{
+ spinlock lock;
+ thread_id owner;
+ char *file;
+ int line;
+ int busy_flags;
+#define CNTX_INTR 1
+#define CNTX_USER 2
+};
+
+typedef struct _oss_mutex_t oss_mutex_t;
+extern void debug_mutex_init (oss_mutex_t * mutex, char *file, int line);
+extern void debug_mutex_destroy (oss_mutex_t * mutex, char *file, int line);
+extern void debug_mutex_enter (oss_mutex_t * mutex, char *file, int line, oss_native_word *flags);
+extern void debug_mutex_exit (oss_mutex_t * mutex, char *file, int line, oss_native_word *flags);
+
+#define MUTEX_INIT(osdev, mutex, hier) debug_mutex_init(&mutex, NULL, __FILE__, __LINE__)
+#define MUTEX_CLEANUP(mutex) debug_mutex_destroy(&mutex, __FILE__, __LINE__)
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) debug_mutex_enter(&mutex, __FILE__, __LINE__, &flags)
+#define MUTEX_ENTER(mutex, flags) debug_mutex_enter(&mutex, __FILE__, __LINE__, NULL)
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) debug_mutex_exit(&mutex, __FILE__, __LINE__, &flags)
+#define MUTEX_EXIT(mutex, flags) debug_mutex_exit(&mutex, __FILE__, __LINE__, NULL)
+#else
+typedef spinlock oss_mutex_t;
+#define MUTEX_INIT(osdev, mutex, hier) { mutex = 0; }
+#define MUTEX_CLEANUP(mutex)
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) \
+{ \
+ flags = (oss_native_word) disable_interrupts(); \
+ acquire_spinlock(&(mutex)); \
+}
+#define MUTEX_ENTER(mutex, flags) acquire_spinlock(&(mutex))
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) \
+{ \
+ release_spinlock(&(mutex)); \
+ restore_interrupts((cpu_status)(flags)); \
+}
+#define MUTEX_EXIT(mutex, flags) release_spinlock(&(mutex))
+#endif
+
+/* The soundcard.h could be in a nonstandard place so include it here. */
+#include "soundcard.h"
+
+typedef struct udi_usb_devc udi_usb_devc;
+struct _oss_device_t
+{
+#ifdef NEEDED_FOR_DRIVERS
+ int instance;
+ void *devc;
+ char *name;
+#endif
+
+ int cardnum;
+ int dev_type;
+ int instance;
+ int available;
+ dev_info_t *dip;
+ int unloaded;
+ void *osid;
+ void *devc;
+ char *name;
+ char *hw_info;
+ char nick[16];
+ char modname[32];
+ char handle[32];
+ int num_audio_engines;
+ int num_audioplay, num_audiorec, num_audioduplex;
+ int num_mididevs;
+ int num_mixerdevs;
+ int num_loopdevs;
+ int first_mixer; /* This must be set to -1 by osdev_create() */
+
+ volatile int refcount; /* Nonzero means that the device is needed by some other (virtual) driver. */
+
+/* Interrupts */
+
+ long irq; //XXX:init =-1
+ oss_tophalf_handler_t tophalf_handler;
+ oss_bottomhalf_handler_t bottomhalf_handler;
+ oss_mutex_t mutex;
+
+};
+
+/* XXX we'll deal with select() later */
+#undef ALLOW_SELECT
+/* BeOS doesn't support mmap. Haiku does, so FIXME someday */
+#undef ALLOW_BUFFER_MAPPING
+
+/*
+ * Sleep/wakeup
+ */
+
+#ifdef _KERNEL
+struct oss_wait_queue
+{
+//XXX:
+// oss_mutex_t mutex;
+ char name[32];
+ sem_id sem;
+ unsigned long flags;
+// struct selinfo poll_info;
+};
+#endif
+
+/* Busy wait routine */
+#define oss_udelay(d) spin((bigtime_t)d)
+
+
+/* usec time base */
+#undef HZ
+/* XXX: might need to be lower to handle casts to long */
+#define OSS_HZ 1000000
+
+/* System wall timer access */
+extern unsigned long oss_get_time (void);
+#define GET_JIFFIES() oss_get_time()
+
+
+/*
+ * INB() and OUTB() should be obvious. NOTE! The order of
+ * paratemeters of OUTB() is different than on some other
+ * operating systems.
+ */
+
+/* I/O Mapped devices */
+#define INB(o, p) gPCI->read_io_8(p)
+#define INW(o, p) gPCI->read_io_16(p)
+#define INL(o, p) gPCI->read_io_32(p)
+
+#define OUTB(o, v, p) gPCI->write_io_8(p,v)
+#define OUTW(o, v, p) gPCI->write_io_16(p,v)
+#define OUTL(o, v, p) gPCI->write_io_32(p,v)
+
+/* Memory Mapped devices */
+#define PCI_READB(osdev, addr) *(volatile unsigned char *)(addr)
+#define PCI_READW(osdev, addr) *(volatile unsigned short *)(addr)
+#define PCI_READL(osdev, addr) *(volatile unsigned int *)(addr)
+
+#define PCI_WRITEB(osdev, addr, data) *(volatile unsigned char *)(addr)=data
+#define PCI_WRITEW(osdev, addr, data) *(volatile unsigned short *)(addr)=data
+#define PCI_WRITEL(osdev, addr, data) *(volatile unsigned int *)(addr)=data
+
+typedef void *oss_dma_handle_t;
+
+/*
+ * When a error (such as EINVAL) is returned by a function,
+ * the following macro is used. The driver assumes that a
+ * error is signalled by returning a negative value.
+ */
+
+/*
+ KERNEL_MALLOC() allocates requested number of memory and
+ KERNEL_FREE is used to free it.
+ These macros are never called from interrupt, in addition the
+ nbytes will never be more than 4096 bytes. Generally the driver
+ will allocate memory in blocks of 4k. If the kernel has just a
+ page level memory allocation, 4K can be safely used as the size
+ (the nbytes parameter can be ignored).
+*/
+#define KERNEL_MALLOC(nbytes) calloc(1,nbytes)
+#define KERNEL_FREE(addr) {if (addr)free(addr);addr=NULL;}
+
+extern void *oss_contig_malloc (oss_device_t * osdev, int sz,
+ oss_uint64_t memlimit,
+ oss_native_word * phaddr);
+extern void oss_contig_free (oss_device_t * osdev, void *p, int sz);
+extern oss_native_word oss_virt_to_bus (void *addr);
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(osdev, sz, memlimit, phaddr)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(osdev, p, sz)
+
+/*
+ * PMALLOC is used to allocate memory that will get automatically freed when
+ * OSS unloads. Usable for per-instance structures allocated when OSS modules
+ * are being loaded.
+ */
+extern void *oss_pmalloc (size_t sz);
+
+//#define PMALLOC(osdev, sz) oss_pmalloc(sz)
+
+/*
+ * Timer macros
+ *
+ * These macros are obsolete and should not be used in any new code.
+ * Use the timeout mechanism (see the timeout(9F) Solaris man page).
+ */
+#define DEFINE_TIMER(name, proc) static timeout_id_t name = 0
+#define REMOVE_TIMER(name, proc) {if (name != 0) untimeout(name);}
+#define INIT_TIMER(name,proc)
+typedef void (*timeout_func_t) (void *);
+#define ACTIVATE_TIMER(name, proc, time) \
+ name=timeout((timeout_func_t)proc, (void*)&name, time)
+#endif
+
+struct fileinfo
+{
+ int mode; /* Open mode */
+ //int flags;
+ int acc_flags;
+};
+#define ISSET_FILE_FLAG(fileinfo, flag) (fileinfo->acc_flags & (flag) ? 1:0)
+
+#define OSS_OS "BeOS"
+#define OSS_OS_LONGNAME "BeOS R" OS_VERSION
+
+typedef void (*softintr_func_t) (int);
+
+struct oss_softintr
+{
+ int id;
+ softintr_func_t func;
+ volatile int armed, running;
+};
+
+struct _oss_poll_event_t
+{
+ short events, revents;
+ struct thread *p;
+ struct cdev *bsd_dev;
+};
+typedef struct _oss_poll_event_t oss_poll_event_t;
+#ifndef POLLIN
+/* events & revents - compatible with the B_SELECT_xxx definitions in Drivers.h */
+#define POLLIN 0x0001 /* any readable data available */
+#define POLLOUT 0x0002 /* file descriptor is writeable */
+#define POLLRDNORM POLLIN
+#define POLLWRNORM POLLOUT
+#define POLLRDBAND 0x0008 /* priority readable data */
+#define POLLWRBAND 0x0010 /* priority data can be written */
+#define POLLPRI 0x0020 /* high priority readable data */
+#endif
+
+extern int detect_trace;
+#define DDB(x) if (detect_trace) x
+
+extern caddr_t oss_map_pci_mem (oss_device_t * osdev, int nr, int phaddr,
+ int size);
+extern void oss_unmap_pci_mem (void *addr);
+#define MAP_PCI_IOADDR(osdev, nr, io) (oss_native_word)io
+#define MAP_PCI_MEM(osdev, ix, phaddr, size) oss_map_pci_mem(osdev, ix, phaddr, size)
+#define UNMAP_PCI_MEM(osdev, ix, ph, virt, size) oss_unmap_pci_mem(virt)
+#define UNMAP_PCI_IOADDR(osdev, ix) {}
+
+#define GET_PROCESS_PID(f) find_thread(NULL)
+#define GET_PROCESS_UID() getuid()
+#define GET_PROCESS_NAME(f) NULL
+
+#define abs(x) ((x) >= 0 ? (x) : -(x))
+
+/*
+ * Interface with the front-end driver
+ */
+extern status_t init_osscore (void);
+extern status_t uninit_osscore (void);
+extern status_t oss_probe_pci (void);
+extern status_t oss_load_drivers (void);
+extern status_t oss_unload_all_drivers (void);
+
+/*
+ * osscore module for use by low-level driver
+ */
+#define OSS_CORE_MODULE_NAME "media/oss/oss_core/v1"
+#define OSS_MODULES_PREFIX "media/oss/drivers/"
+#define OSS_MODULES_SUFFIX "/v1"
+#define OSS_MAKE_DRV_MOD_NAME(nick) OSS_MODULES_PREFIX nick OSS_MODULES_SUFFIX
+typedef struct oss_drv_module_info {
+ module_info minfo;
+ int (*driver_probe)(void);
+ int (*driver_attach)(oss_device_t *osdev);
+ int (*driver_detach)(oss_device_t *osdev);
+} oss_drv_module_info;
+
+typedef struct oss_core_module_info {
+ module_info minfo;
+ status_t (*init_osscore) (void);
+ status_t (*uninit_osscore) (void);
+ const char **(*oss_publish_devices) (void);
+ device_hooks *(*oss_get_driver_hooks) (void);
+ status_t (*oss_probe_pci) (void);
+ status_t (*oss_load_drivers) (void);
+ status_t (*oss_unload_all_drivers) (void);
+} oss_core_module_info;
+extern oss_core_module_info *gOSSCore;
+
+//XXX: not yet
+#ifdef ASMODULES
+
+struct oss_core_module {
+ module_info minfo;
+ void (*oss_foo)(void);
+};
+extern struct oss_core_info *gOSSCore;
+#ifdef BUILDING_DRIVER
+ #define oss_foo gOSSCore->oss_foo
+#endif
+#endif /* ASMODULES */
diff --git a/kernel/OS/FreeBSD/.config b/kernel/OS/FreeBSD/.config
new file mode 100644
index 0000000..816ac62
--- /dev/null
+++ b/kernel/OS/FreeBSD/.config
@@ -0,0 +1 @@
+mode=kernel
diff --git a/kernel/OS/FreeBSD/os_freebsd.c b/kernel/OS/FreeBSD/os_freebsd.c
new file mode 100644
index 0000000..58b11cc
--- /dev/null
+++ b/kernel/OS/FreeBSD/os_freebsd.c
@@ -0,0 +1,1107 @@
+/*
+ * Purpose: Operating system abstraction functions for FreeBSD
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+#include <oss_pci.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/sx.h>
+#include <sys/mman.h>
+#include <sys/lockmgr.h>
+#include <fs/devfs/devfs.h>
+#include <sys/poll.h>
+#include <sys/param.h>
+#include <sys/filio.h>
+
+/* Function prototypes */
+static d_open_t oss_open;
+static d_close_t oss_close;
+static d_read_t oss_read;
+static d_write_t oss_write;
+static d_ioctl_t oss_ioctl;
+static d_poll_t oss_poll;
+static d_mmap_t oss_mmap;
+
+/* Character device entry points */
+
+static struct cdevsw oss_cdevsw = {
+ .d_version = D_VERSION,
+ .d_flags = D_TRACKCLOSE,
+ .d_open = oss_open,
+ .d_close = oss_close,
+ .d_read = oss_read,
+ .d_write = oss_write,
+ .d_ioctl = oss_ioctl,
+ .d_poll = oss_poll,
+ .d_mmap = oss_mmap,
+ .d_name = "oss"
+};
+
+static int oss_major = 30;
+oss_device_t *core_osdev = NULL;
+static int open_devices = 0;
+static int refcount = 0;
+
+#define MAX_CARDS 32
+int oss_num_cards = 0;
+static oss_device_t *cards[MAX_CARDS];
+static int oss_expired = 0;
+
+
+int
+__oss_alloc_dmabuf (int dev, dmap_p dmap, unsigned int alloc_flags,
+ oss_uint64_t maxaddr, int direction)
+{
+ void *tmpbuf;
+ oss_native_word phaddr;
+ int size = 64 * 1024;
+ extern int dma_buffsize;
+
+ if (dma_buffsize > 16 && dma_buffsize <= 128)
+ size = dma_buffsize * 1024;
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "oss_alloc_dmabuf: dmap==NULL\n");
+ return OSS_EIO;
+ }
+
+/*
+ * Some applications and virtual drivers need shorter buffer.
+ */
+ if (dmap->flags & DMAP_SMALLBUF)
+ {
+ size = SMALL_DMABUF_SIZE;
+ }
+ else if (dmap->flags & DMAP_MEDIUMBUF)
+ {
+ size = MEDIUM_DMABUF_SIZE;
+ }
+
+ if ((alloc_flags & DMABUF_SIZE_16BITS) && size > 32 * 1024)
+ size = 32 * 1024;
+
+ tmpbuf = CONTIG_MALLOC (dmap->osdev, size, maxaddr, &phaddr, NULL);
+ if (tmpbuf == NULL)
+ return OSS_ENOMEM;
+ dmap->dmabuf = tmpbuf;
+ dmap->buffsize = size;
+ dmap->dmabuf_phys = phaddr;
+
+ return 0;
+}
+
+void
+oss_free_dmabuf (int dev, dmap_p dmap)
+{
+ if (dmap->dmabuf == NULL)
+ return;
+
+ CONTIG_FREE (dmap->osdev, dmap->dmabuf, dmap->buffsize, NULL);
+ dmap->dmabuf = NULL;
+ dmap->buffsize = 0;
+ dmap->dmabuf_phys = 0;
+}
+
+oss_wait_queue_t *
+oss_create_wait_queue (oss_device_t * osdev, const char *name)
+{
+ oss_wait_queue_t *wq;
+
+ if ((wq = PMALLOC (NULL, sizeof (*wq))) == NULL)
+ return NULL;
+
+ MUTEX_INIT (osdev, wq->mutex, MH_TOP);
+
+ return wq;
+}
+
+void
+oss_reset_wait_queue (oss_wait_queue_t * wq)
+{
+ wq->flags = 0;
+}
+
+void
+oss_remove_wait_queue (oss_wait_queue_t * wq)
+{
+ MUTEX_CLEANUP (wq->mutex);
+}
+
+int
+oss_sleep (oss_wait_queue_t * wq, oss_mutex_t * mutex, int ticks,
+ oss_native_word * flags, unsigned int *status)
+{
+ int flag;
+ *status = 0;
+
+ if (wq == NULL)
+ return 0;
+
+ wq->flags = 0;
+#ifdef USE_SX_LOCK
+ flag = sx_sleep (wq, *mutex, PRIBIO | PCATCH, "oss", ticks);
+#else
+#if __FreeBSD_version >= 602000
+ flag = msleep_spin (wq, *mutex, "oss", ticks);
+#else
+ flag = msleep (wq, *mutex, PRIBIO | PCATCH, "oss", ticks);
+#endif
+#endif
+ if (flag == EWOULDBLOCK) /* Timeout */
+ {
+ return 0;
+ }
+
+ if (flag != 0)
+ {
+ *status |= WK_SIGNAL;
+ }
+
+ return 1;
+}
+
+int
+oss_register_poll (oss_wait_queue_t * wq, oss_mutex_t * mutex,
+ oss_native_word * flags, oss_poll_event_t * ev)
+{
+ MUTEX_EXIT_IRQRESTORE (*mutex, *flags);
+ selrecord (ev->p, &wq->poll_info);
+ MUTEX_ENTER_IRQDISABLE (*mutex, *flags);
+ return 0;
+}
+
+void
+oss_wakeup (oss_wait_queue_t * wq, oss_mutex_t * mutex,
+ oss_native_word * flags, short events)
+{
+ MUTEX_EXIT_IRQRESTORE (*mutex, *flags);
+ wakeup (wq);
+ selwakeup (&wq->poll_info);
+ MUTEX_ENTER_IRQDISABLE (*mutex, *flags);
+}
+
+void
+oss_register_module (char *name)
+{
+ refcount++;
+}
+
+void
+oss_unregister_module (char *name)
+{
+ refcount--;
+}
+
+void
+oss_reserve_device (oss_device_t * osdev)
+{
+ osdev->refcount++;
+}
+
+void
+oss_unreserve_device (oss_device_t * osdev, int decrement)
+{
+ osdev->refcount--;
+ if (osdev->refcount < 0)
+ osdev->refcount = 0;
+}
+
+int
+oss_register_device (oss_device_t * osdev, const char *name)
+{
+ if ((osdev->name = PMALLOC (NULL, strlen (name) + 1)) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate memory for device name\n");
+ osdev->name = "Unknown device";
+ }
+ strcpy (osdev->name, name);
+ if (osdev->dip != NULL)
+ device_set_desc (osdev->dip, name);
+ return OSS_ENXIO;
+}
+
+void
+oss_unregister_device (oss_device_t * osdev)
+{
+ // NOP
+}
+
+int
+oss_find_minor (int dev_class, int instance)
+{
+ int i;
+
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->d != NULL && oss_cdevs[i]->dev_class == dev_class
+ && oss_cdevs[i]->instance == instance)
+ return i;
+
+ return OSS_EIO;
+}
+
+void *
+oss_find_minor_info (int dev_class, int instance)
+{
+ int i;
+
+ for (i = 0; i < oss_num_cdevs; i++)
+ {
+ if (oss_cdevs[i]->d != NULL && oss_cdevs[i]->dev_class == dev_class
+ && oss_cdevs[i]->instance == instance)
+ return oss_cdevs[i]->info;
+ }
+
+ return NULL;
+}
+
+int
+oss_disable_device (oss_device_t * osdev)
+{
+ int i;
+
+ if (osdev->refcount > 0)
+ return OSS_EBUSY;
+
+ if (open_devices > 0)
+ return OSS_EBUSY;
+
+ for (i = 0; i < num_mixers; i++)
+ if (mixer_devs[i]->osdev == osdev)
+ {
+ mixer_devs[i]->unloaded = 1;
+ }
+
+ for (i = 0; i < num_mididevs; i++)
+ {
+ if (midi_devs[i]->osdev == osdev)
+ {
+ midi_devs[i]->unloaded = 1;
+ }
+ }
+
+ for (i = 0; i < num_audio_engines; i++)
+ if (audio_engines[i]->osdev == osdev)
+ {
+ audio_uninit_device (i);
+ }
+ return 0;
+}
+
+int
+oss_get_cardinfo (int cardnum, oss_card_info * ci)
+{
+/*
+ * Print information about a 'card' in a format suitable for /dev/sndstat
+ */
+
+ if (cardnum < 0 || cardnum >= oss_num_cards)
+ return OSS_ENXIO;
+
+ if (cards[cardnum]->name != NULL)
+ strncpy (ci->longname, cards[cardnum]->name, 128);
+ ci->shortname[127] = 0;
+
+ if (cards[cardnum]->nick != NULL)
+ strncpy (ci->shortname, cards[cardnum]->nick, 16);
+ ci->shortname[15] = 0;
+
+ if (cards[cardnum]->hw_info != NULL)
+ strncpy (ci->hw_info, cards[cardnum]->hw_info, sizeof (ci->hw_info));
+ ci->hw_info[sizeof (ci->hw_info) - 1] = 0;
+ ci->intr_count = cards[cardnum]->intrcount;
+ ci->ack_count = cards[cardnum]->ackcount;
+
+ return 0;
+}
+
+static int
+grow_array(oss_device_t *osdev, oss_cdev_t ***arr, int *size, int element_size, int increment)
+{
+ oss_cdev_t **old=*arr, **new = *arr;
+ int old_size = *size;
+ int new_size = *size;
+
+ new_size += increment;
+
+ if ((new=PMALLOC(osdev, new_size * element_size))==NULL)
+ return 0;
+
+ memset(new, 0, new_size * element_size);
+ if (old != NULL)
+ memcpy(new, old, old_size * element_size);
+
+ *size = new_size;
+ *arr = new;
+
+ if (old != NULL)
+ PMFREE(osdev, old);
+
+ return 1;
+}
+
+void
+oss_install_chrdev (oss_device_t * osdev, char *name, int dev_class,
+ int instance, oss_cdev_drv_t * drv, int flags)
+{
+ struct cdev *bsd_cdev;
+ oss_cdev_t *cdev = NULL;
+ int i, num;
+
+ if (dev_class != OSS_DEV_STATUS)
+ if (oss_expired && instance > 0)
+ return;
+/*
+ * Find if this dev_class&instance already exists (after previous module
+ * detach).
+ */
+
+ for (num = 0; num < oss_num_cdevs; num++)
+ if (oss_cdevs[num]->d == NULL) /* Unloaded driver */
+ if (oss_cdevs[num]->dev_class == dev_class
+ && oss_cdevs[num]->instance == instance)
+ {
+ cdev = oss_cdevs[num];
+ break;
+ }
+
+ if (cdev == NULL)
+ {
+ if (oss_num_cdevs >= OSS_MAX_CDEVS)
+ {
+ if (!grow_array(osdev, &oss_cdevs, &oss_max_cdevs, sizeof(oss_cdev_t*), 100))
+ {
+ cmn_err (CE_WARN, "Cannot allocate new minor numbers.\n");
+ return;
+ }
+ }
+
+ if ((cdev = PMALLOC (NULL, sizeof (*cdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate character device desc.\n");
+ return;
+ }
+ num = oss_num_cdevs++;
+ }
+
+ memset (cdev, 0, sizeof (*cdev));
+ cdev->dev_class = dev_class;
+ cdev->instance = instance;
+ cdev->d = drv;
+ cdev->osdev = osdev;
+ if (name != NULL)
+ strncpy (cdev->name, name, sizeof (cdev->name) - 1);
+ else
+ strcpy (cdev->name, "NONE");
+ cdev->name[sizeof (cdev->name) - 1] = 0;
+ oss_cdevs[num] = cdev;
+
+ if (!(flags & CHDEV_VIRTUAL) && (name != NULL))
+ {
+ bsd_cdev =
+ make_dev (&oss_cdevsw, num, UID_ROOT, GID_WHEEL, 0666, name, 0);
+ cdev->info = bsd_cdev;
+ }
+}
+
+#define MAX_MEMBLOCKS 4096
+static void *memblocks[MAX_MEMBLOCKS];
+static int nmemblocks = 0;
+
+void *
+oss_pmalloc (size_t sz)
+{
+ void *tmp;
+
+ tmp = KERNEL_MALLOC (sz);
+
+ if (nmemblocks < MAX_MEMBLOCKS)
+ memblocks[nmemblocks++] = tmp;
+
+ return tmp;
+}
+
+int
+oss_uiomove (void *address, size_t nbytes, enum uio_rw rwflag, uio_t * uio_p)
+{
+ int err;
+
+#undef uiomove
+ err = uiomove (address, nbytes, uio_p);
+
+ return err;
+}
+
+#undef timeout
+#undef untimeout
+
+typedef struct tmout_desc
+{
+ volatile int active;
+ int timestamp;
+ void (*func) (void *);
+ void *arg;
+
+ struct callout_handle timer;
+} tmout_desc_t;
+
+static volatile int next_id = 0;
+#define MAX_TMOUTS 128
+
+tmout_desc_t tmouts[MAX_TMOUTS] = { {0} };
+
+int timeout_random = 0x12123400;
+
+void
+oss_timer_callback (void *arg)
+{
+ int ix;
+ tmout_desc_t *tmout = arg;
+
+ timeout_random++;
+
+ if (!tmout->active)
+ return;
+
+ arg = tmout->arg;
+ tmout->active = 0;
+ tmout->timestamp = 0;
+
+ tmout->func (arg);
+}
+
+timeout_id_t
+oss_timeout (void (*func) (void *), void *arg, unsigned long long ticks)
+{
+ tmout_desc_t *tmout = NULL;
+ int id, n;
+
+ timeout_random++;
+
+ n = 0;
+ id = -1;
+
+ while (id == -1 && n < MAX_TMOUTS)
+ {
+ if (!tmouts[next_id].active)
+ {
+ tmouts[next_id].active = 1;
+ id = next_id++;
+ tmout = &tmouts[id];
+ break;
+ }
+
+ next_id = (next_id + 1) % MAX_TMOUTS;
+ }
+
+ if (id == -1) /* No timer slots available */
+ {
+ cmn_err (CE_CONT, "Timeout table full\n");
+ return 0;
+ }
+
+ tmout->func = func;
+ tmout->arg = arg;
+ tmout->timestamp = id | (timeout_random & ~0xff);
+
+ tmout->timer = timeout (oss_timer_callback, tmout, ticks);
+
+ return id | (timeout_random & ~0xff);
+}
+
+void
+oss_untimeout (timeout_id_t id)
+{
+ tmout_desc_t *tmout;
+ int ix;
+
+ ix = id & 0xff;
+ if (ix < 0 || ix >= MAX_TMOUTS)
+ return;
+
+ timeout_random++;
+ tmout = &tmouts[ix];
+
+ if (tmout->timestamp != id) /* Expired timer */
+ return;
+ if (tmout->active)
+ untimeout (oss_timer_callback, tmout, tmout->timer);
+ tmout->active = 0;
+ tmout->timestamp = 0;
+}
+
+int
+oss_get_procinfo (int what)
+{
+ switch (what)
+ {
+ case OSS_GET_PROCINFO_UID:
+ return oss_get_uid();
+ }
+
+ return EINVAL;
+}
+
+unsigned long
+oss_get_time (void)
+{
+ struct timeval timecopy;
+
+ getmicrotime (&timecopy);
+ return timecopy.tv_usec / (1000000 / hz) + (u_long) timecopy.tv_sec * hz;
+}
+
+caddr_t
+oss_map_pci_mem (oss_device_t * osdev, int nr, int paddr, int psize)
+{
+ void *vaddr = 0;
+ u_int32_t poffs;
+
+ poffs = paddr - trunc_page (paddr);
+ vaddr = (caddr_t) pmap_mapdev (paddr - poffs, psize + poffs) + poffs;
+
+ return vaddr;
+}
+
+void
+oss_pci_byteswap (oss_device_t * osdev, int mode)
+{
+ // NOP
+}
+
+void
+oss_pcie_init (oss_device_t * osdev, int flags)
+{
+ /* TODO: Should we do something? */
+}
+
+static time_t
+oss_get_walltime (void)
+{
+ struct timeval timecopy;
+
+ getmicrotime (&timecopy);
+ return timecopy.tv_sec;
+}
+
+int
+soundcard_attach (void)
+{
+ oss_device_t *osdev;
+
+ if ((osdev = PMALLOC (NULL, sizeof (*osdev))) == NULL)
+ {
+ return ENOSPC;
+ }
+
+ memset (osdev, 0, sizeof (*osdev));
+ core_osdev = osdev;
+
+#ifdef LICENSED_VERSION
+ if (!oss_license_handle_time (oss_get_walltime ()))
+ {
+ cmn_err (CE_WARN, "This version of Open Sound System has expired\n");
+ cmn_err (CE_CONT,
+ "Please download the latest version from www.opensound.com\n");
+ oss_expired = 1;
+ }
+#endif
+
+ osdev->major = oss_major;
+ oss_register_device (osdev, "OSS core services");
+
+ oss_common_init (osdev);
+
+ return 0;
+}
+
+int
+soundcard_detach (void)
+{
+ int i;
+
+ if (refcount > 0 || open_devices > 0)
+ return EBUSY;
+
+ oss_unload_drivers ();
+
+ osdev_delete (core_osdev);
+
+ for (i = 0; i < nmemblocks; i++)
+ KERNEL_FREE (memblocks[i]);
+ nmemblocks = 0;
+
+ return 0;
+}
+
+static void
+init_fileinfo (struct fileinfo *fi, int flags)
+{
+ memset (fi, 0, sizeof (*fi));
+ if ((flags & FREAD) && (flags & FWRITE))
+ fi->mode = OPEN_READWRITE;
+ else if (flags & FREAD)
+ fi->mode = OPEN_READ;
+ else if (flags & FWRITE)
+ fi->mode = OPEN_WRITE;
+ fi->acc_flags = flags;
+ fi->pid = -1;
+ fi->dev = -1;
+ fi->cmd = NULL;
+}
+
+static int
+oss_read (struct cdev *bsd_dev, struct uio *buf, int flags)
+{
+ int retval;
+ int dev;
+ oss_cdev_t *cdev;
+#ifndef VDEV_SUPPORT
+ struct fileinfo _fi, * fi = &_fi;
+ dev = MINOR (bsd_dev);
+ init_fileinfo (fi, flags);
+#else
+ struct fileinfo * fi;
+ if (oss_file_get_private ((void **)&fi)) return ENXIO;
+ dev = fi->dev;
+#endif
+
+ if (dev >= oss_num_cdevs)
+ return ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return ENXIO;
+
+ if (cdev->d->read == NULL)
+ {
+ return ENODEV;
+ }
+
+ retval = cdev->d->read (cdev->instance, fi, buf, buf->uio_resid);
+ if (retval < 0)
+ return -retval;
+ return 0;
+
+}
+
+static int
+oss_write (struct cdev *bsd_dev, struct uio *buf, int flags)
+{
+ int retval;
+ int dev;
+ oss_cdev_t *cdev;
+#ifndef VDEV_SUPPORT
+ struct fileinfo _fi, * fi = &_fi;
+ dev = MINOR (bsd_dev);
+ init_fileinfo (fi, flags);
+#else
+ struct fileinfo * fi;
+ if (oss_file_get_private ((void **)&fi)) return ENXIO;
+ dev = fi->dev;
+#endif
+
+ if (dev >= oss_num_cdevs)
+ return ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return ENXIO;
+
+ if (cdev->d->write == NULL)
+ {
+ return ENODEV;
+ }
+
+ retval = cdev->d->write (cdev->instance, fi, buf, buf->uio_resid);
+ if (retval < 0)
+ return -retval;
+ return 0;
+}
+
+static int
+oss_open (struct cdev *bsd_dev, int flags, int mode, struct thread *p)
+{
+ int dev = MINOR (bsd_dev);
+ oss_cdev_t *cdev;
+ struct fileinfo fi;
+ int tmpdev, retval;
+
+ if (dev >= oss_num_cdevs)
+ return ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return ENXIO;
+
+ if (cdev->d->open == NULL)
+ {
+ return ENODEV;
+ }
+
+ init_fileinfo (&fi, flags);
+ fi.pid = p->td_proc->p_pid;
+ fi.cmd = p->td_proc->p_comm;
+ tmpdev = dev;
+
+ retval =
+ cdev->d->open (cdev->instance, cdev->dev_class, &fi, 0, 0, &tmpdev);
+
+ if (tmpdev != -1) fi.dev = tmpdev;
+ else fi.dev = dev;
+ if (retval < 0)
+ return -retval;
+
+#ifdef VDEV_SUPPORT
+ if (oss_file_set_private (p, (void *)&fi, sizeof (struct fileinfo)))
+ return ENXIO;
+#endif
+
+ open_devices++;
+ return 0;
+}
+
+static int
+oss_close (struct cdev *bsd_dev, int flags, int mode, struct thread *p)
+{
+ int dev;
+ oss_cdev_t *cdev;
+#ifndef VDEV_SUPPORT
+ struct fileinfo _fi, * fi = &_fi;
+ dev = MINOR (bsd_dev);
+ init_fileinfo (fi, flags);
+#else
+ struct fileinfo * fi;
+ if (oss_file_get_private ((void **)&fi)) return ENXIO;
+ dev = fi->dev;
+#endif
+
+ if (dev >= oss_num_cdevs)
+ return ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return ENXIO;
+
+ if (cdev->d->close == NULL)
+ {
+ return ENODEV;
+ }
+
+ cdev->d->close (cdev->instance, fi);
+ open_devices--;
+ return 0;
+}
+
+static int
+oss_ioctl (struct cdev *bsd_dev, u_long cmd, caddr_t arg, int mode,
+ struct thread *p)
+{
+ int retval;
+ int dev;
+ oss_cdev_t *cdev;
+#ifndef VDEV_SUPPORT
+ struct fileinfo _fi, * fi = &_fi;
+ dev = MINOR (bsd_dev);
+ init_fileinfo (fi, mode);
+#else
+ struct fileinfo * fi;
+ if (oss_file_get_private ((void **)&fi)) return ENXIO;
+ dev = fi->dev;
+#endif
+
+ if (dev >= oss_num_cdevs)
+ return ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return ENXIO;
+
+ if (cdev->d->ioctl == NULL)
+ {
+ return ENODEV;
+ }
+
+ switch (cmd)
+ {
+ /*
+ * FreeBSD uses these ioctls to (un)set nonblocking I/O for devices. e.g.
+ * in case of fcntl (fd, F_SETFL, O_RDONLY|O_NONBLOCK) it will fire
+ * both ioctls.
+ * We deal with them here, and not in oss_audio_core because struct file
+ * isn't available in oss_audio_ioctl and we want the flags to remain
+ * accurate. oss_audio_core checks for O_NONBLOCK, and will pick
+ * up the change next read/write.
+ */
+ case FIONBIO:
+ if (arg != NULL)
+ {
+ if (*arg) fi->acc_flags |= O_NONBLOCK;
+ else fi->acc_flags &= ~O_NONBLOCK;
+ }
+ case FIOASYNC:
+ return 0;
+ default: break;
+ }
+
+ retval = cdev->d->ioctl (cdev->instance, fi, cmd, (ioctl_arg) arg);
+ if (retval < 0)
+ return -retval;
+ return 0;
+}
+
+static int
+oss_poll (struct cdev *bsd_dev, int events, struct thread *p)
+{
+ int retval;
+ int dev;
+ oss_cdev_t *cdev;
+ oss_poll_event_t ev;
+ int err;
+#ifndef VDEV_SUPPORT
+ struct fileinfo _fi, * fi = &_fi;
+ dev = MINOR (bsd_dev);
+ init_fileinfo (fi, 0);
+#else
+ struct fileinfo * fi;
+ if (oss_file_get_private ((void **)&fi)) return ENXIO;
+ dev = fi->dev;
+#endif
+
+ if (dev >= oss_num_cdevs)
+ return ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return ENXIO;
+
+ if (cdev->d->chpoll == NULL)
+ {
+ return ENODEV;
+ }
+
+ ev.events = events;
+ ev.revents = 0;
+ ev.p = p;
+ ev.bsd_dev = bsd_dev;
+
+ err = cdev->d->chpoll (cdev->instance, fi, &ev);
+ if (err < 0)
+ {
+ return -err;
+ }
+ return ev.revents;
+}
+
+#if defined(D_VERSION_03) && (D_VERSION == D_VERSION_03)
+static int
+oss_mmap (struct cdev *bsd_dev, vm_ooffset_t offset, vm_paddr_t * paddr,
+ int nprot, vm_memattr_t *memattr)
+#else
+static int
+oss_mmap (struct cdev *bsd_dev, vm_offset_t offset, vm_paddr_t * paddr,
+ int nprot)
+#endif
+{
+ int retval;
+ int dev;
+ oss_cdev_t *cdev;
+ oss_poll_event_t ev;
+ dmap_p dmap = NULL;
+ int err;
+#ifndef VDEV_SUPPORT
+ dev = MINOR (bsd_dev);
+#else
+ struct fileinfo * fi;
+ if (oss_file_get_private ((void **)&fi)) return ENXIO;
+ dev = fi->dev;
+#endif
+
+ if (dev >= oss_num_cdevs)
+ return ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return ENXIO;
+
+ if (nprot & PROT_EXEC)
+ return EACCES;
+
+ if ((cdev->dev_class != OSS_DEV_DSP) &&
+ (cdev->dev_class != OSS_DEV_DSP_ENGINE)) /* Only mmapable devices */
+ {
+ cmn_err (CE_NOTE, "mmap() is only possible with DSP devices (%d)\n",
+ cdev->dev_class);
+ return EINVAL;
+ }
+
+ dev = cdev->instance;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return ENODEV;
+
+ if (nprot & PROT_WRITE)
+ dmap = audio_engines[dev]->dmap_out;
+ else
+ dmap = audio_engines[dev]->dmap_in;
+
+ if (dmap == NULL)
+ return EIO;
+
+ if (dmap->dmabuf_phys == 0)
+ return EIO;
+
+ if (dmap->flags & DMAP_COOKED)
+ {
+ cmn_err (CE_WARN,
+ "mmap() not possible with currently selected sample format.\n");
+ return EIO;
+ }
+
+ dmap->mapping_flags |= DMA_MAP_MAPPED;
+ *paddr = dmap->dmabuf_phys + offset;
+
+ return 0;
+}
+
+oss_device_t *
+osdev_create (dev_info_t * dip, int dev_type, int instance, const char *nick,
+ const char *handle)
+{
+ oss_device_t *osdev = NULL;
+ int i, err;
+ caddr_t addr;
+ off_t region_size;
+
+ if (handle == NULL)
+ handle = nick;
+
+ /*
+ * Don't accept any more drivers if expired
+ */
+ if (oss_expired && oss_num_cards > 0)
+ return NULL;
+
+ for (i = 0; i < oss_num_cards; i++)
+ {
+ if (cards[i]->dip == dip)
+ {
+ osdev = cards[i];
+ break;
+ }
+ }
+
+ if (osdev == NULL)
+ {
+ if (oss_num_cards >= MAX_CARDS)
+ {
+ cmn_err (CE_WARN, "Too many OSS devices. At most %d permitted.\n",
+ MAX_CARDS);
+ return NULL;
+ }
+
+ if ((osdev = PMALLOC (NULL, sizeof (*osdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+
+ osdev->cardnum = oss_num_cards;
+ cards[oss_num_cards++] = osdev;
+ }
+
+ osdev->dip = dip;
+ osdev->osid = dip;
+ osdev->available = 1;
+ osdev->instance = instance;
+ osdev->dev_type = dev_type;
+ osdev->devc = NULL;
+ osdev->first_mixer = -1;
+ sprintf (osdev->nick, "%s%d", nick, instance);
+ strcpy (osdev->modname, nick);
+
+/*
+ * Create the device handle
+ */
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ {
+ sprintf (osdev->handle, "OSS-PCI");
+ }
+ break;
+
+ default:
+ sprintf (osdev->handle, "%s%d", handle, instance);
+ }
+
+ return osdev;
+}
+
+oss_device_t *
+osdev_clone (oss_device_t * orig_osdev, int new_instance)
+{
+ oss_device_t *osdev;
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+ memcpy (osdev, orig_osdev, sizeof (*osdev));
+ osdev->dev_type = DRV_CLONE;
+ osdev->instance = new_instance;
+ sprintf (osdev->nick, "%s%d", orig_osdev->modname, new_instance);
+ sprintf (osdev->handle, "%s%d", orig_osdev->modname, new_instance);
+
+ return osdev;
+}
+
+void
+osdev_delete (oss_device_t * osdev)
+{
+ int i;
+
+ if (osdev == NULL)
+ return;
+
+ osdev->available = 0;
+/*
+ * Mark all minor nodes for this module as invalid.
+ */
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->osdev == osdev)
+ {
+ if (oss_cdevs[i]->info != NULL)
+ destroy_dev (oss_cdevs[i]->info);
+ oss_cdevs[i]->d = NULL;
+ oss_cdevs[i]->info = NULL;
+ oss_cdevs[i]->osdev = NULL;
+ strcpy (oss_cdevs[i]->name, "Removed device");
+ }
+}
+
+void *
+oss_get_osid (oss_device_t * osdev)
+{
+ return osdev->osid;
+}
+
+void
+oss_inc_intrcount (oss_device_t * osdev, int claimed)
+{
+ osdev->intrcount++;
+
+ if (claimed)
+ osdev->ackcount++;
+}
diff --git a/kernel/OS/FreeBSD/os_freebsd.h b/kernel/OS/FreeBSD/os_freebsd.h
new file mode 100644
index 0000000..161a2e3
--- /dev/null
+++ b/kernel/OS/FreeBSD/os_freebsd.h
@@ -0,0 +1,263 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+/*
+ * Purpose: OS specific definitions for FreeBSD
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+#define OS_VERSION "6"
+#define __inline__ inline
+#define __inline inline
+#define EXTERN_C extern "C"
+
+/*
+ * Debugging and misc settings
+ */
+#undef MUTEX_CHECKS
+#undef MEMDEBUG
+
+#if (!defined(__i386__) && !defined(__x86_64__)) || defined(CONFIG_OSS_FIXDEPOINT)
+// Floating point is not supported or it's disabled
+#undef CONFIG_OSS_VMIX_FLOAT
+#endif
+
+/*
+ * Disable support for per-application features such as /dev/dsp device
+ * selection based on command name. Requires working GET_PROCESS_NAME
+ * macro implementation.
+ */
+#undef APPLIST_SUPPORT
+#define USE_DEVICE_SUBDIRS
+
+#include <stdarg.h>
+#include <sys/types.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#endif
+#include <sys/param.h>
+#include <sys/uio.h>
+#include <sys/fcntl.h>
+#include <sys/poll.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/kernel.h>
+#include <machine/cpufunc.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <sys/selinfo.h>
+#include <oss_errno.h>
+
+#if __FreeBSD_version >= 800062
+#define MINOR(x) dev2unit(x)
+#else
+#define MINOR(x) minor(x)
+#endif
+
+#undef timeout
+#define timeout oss_timeout
+#undef untimeout
+#define untimeout oss_untimeout
+typedef int timeout_id_t;
+extern timeout_id_t oss_timeout (void (*func) (void *), void *arg,
+ unsigned long long ticks);
+extern void oss_untimeout (timeout_id_t id);
+
+#include "kernel/OS/FreeBSD/wrapper/bsddefs.h"
+
+#ifdef USE_SX_LOCK
+#include <sys/proc.h> /* XXX for curthread */
+#include <sys/sx.h>
+#else
+#include <sys/mutex.h>
+#endif
+
+
+#define uiomove oss_uiomove
+typedef struct uio uio_t;
+extern int oss_uiomove (void *address, size_t nbytes, enum uio_rw rwflag,
+ uio_t * uio_p);
+
+#undef HZ
+#define OSS_HZ hz
+
+/* The soundcard.h could be in a nonstandard place so include it here. */
+#include "soundcard.h"
+
+typedef struct udi_usb_devc udi_usb_devc;
+
+#define ALLOW_SELECT
+#define ALLOW_BUFFER_MAPPING
+
+/*
+ * Sleep/wakeup
+ */
+
+#ifdef _KERNEL
+struct oss_wait_queue
+{
+ oss_mutex_t mutex;
+ unsigned long flags;
+ struct selinfo poll_info;
+};
+#endif
+
+/* Busy wait routine */
+
+/* System wall timer access */
+extern unsigned long oss_get_time (void);
+#define GET_JIFFIES() oss_get_time()
+
+/*
+ * Mutexes
+ */
+
+#ifdef USE_SX_LOCK
+struct sx;
+#define MUTEX_INIT(osdev, mutex, hier) \
+do { \
+ mutex = malloc(sizeof(*mutex), M_DEVBUF, M_WAITOK | M_ZERO); \
+ sx_init(mutex, "oss"); \
+} while (0)
+#define MUTEX_CLEANUP(mutex) \
+do { \
+ sx_destroy(mutex); \
+ free(mutex, M_DEVBUF); \
+} while (0)
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) sx_xlock(mutex)
+#define MUTEX_ENTER(mutex, flags) sx_slock(mutex)
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) sx_xunlock(mutex)
+#define MUTEX_EXIT(mutex, flags) sx_sunlock(mutex)
+#else /* !USE_SX_LOCK */
+struct mtx;
+#define MUTEX_INIT(osdev, mutex, hier) \
+do { \
+ mutex = malloc(sizeof(*mutex), M_DEVBUF, M_WAITOK | M_ZERO); \
+ mtx_init(mutex, "oss", NULL, MTX_RECURSE | MTX_SPIN); \
+} while (0)
+#define MUTEX_CLEANUP(mutex) \
+do { \
+ mtx_destroy(mutex); \
+ free(mutex, M_DEVBUF); \
+} while (0)
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) mtx_lock_spin_flags(mutex, flags)
+#define MUTEX_ENTER(mutex, flags) mtx_lock_spin(mutex)
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) mtx_unlock_spin_flags(mutex, flags)
+#define MUTEX_EXIT(mutex, flags) mtx_unlock_spin(mutex)
+#endif /* USE_SX_LOCK */
+
+
+/*
+ * INB() and OUTB() should be obvious. NOTE! The order of
+ * paratemeters of OUTB() is different than on some other
+ * operating systems.
+ */
+
+/* I/O Mapped devices */
+#define INB(o, p) inb(p)
+#define INW(o, p) inw(p)
+#define INL(o, p) inl(p)
+
+#define OUTB(o, v, p) outb(p,v)
+#define OUTW(o, v, p) outw(p,v)
+#define OUTL(o, v, p) outl(p,v)
+
+/* Memory Mapped devices */
+#define PCI_READL(osp, p) readl(p)
+#define PCI_READW(osp, p) readw(p)
+#define PCI_READB(osp, p) readb(p)
+#define PCI_WRITEL(osp, addr, data) writel(addr, data)
+#define PCI_WRITEW(osp, addr, data) writew(addr, data)
+#define PCI_WRITEB(osp, addr, data) writeb(addr, data)
+
+typedef void *oss_dma_handle_t;
+
+/*
+ KERNEL_MALLOC() allocates requested number of memory and
+ KERNEL_FREE is used to free it.
+ These macros are never called from interrupt, in addition the
+ nbytes will never be more than 4096 bytes. Generally the driver
+ will allocate memory in blocks of 4k. If the kernel has just a
+ page level memory allocation, 4K can be safely used as the size
+ (the nbytes parameter can be ignored).
+*/
+#define KERNEL_MALLOC(nbytes) malloc(nbytes, M_DEVBUF, M_NOWAIT|M_ZERO)
+#define KERNEL_FREE(addr) {if (addr)free(addr, M_DEVBUF);addr=NULL;}
+
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(sz, memlimit, phaddr)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(p, sz)
+
+/*
+ * Timer macros
+ *
+ * These macros are obsolete and should not be used in any new code.
+ * Use the timeout mechanism (see the timeout(9F) Solaris man page).
+ */
+#define DEFINE_TIMER(name, proc) static timeout_id_t name = 0
+#define REMOVE_TIMER(name, proc) {if (name != 0) untimeout(name);}
+#define INIT_TIMER(name,proc)
+typedef void (*timeout_func_t) (void *);
+#define ACTIVATE_TIMER(name, proc, time) \
+ name=timeout((timeout_func_t)proc, (void*)&name, time)
+#endif
+
+struct fileinfo
+{
+ int mode; /* Open mode */
+ int acc_flags;
+ int pid;
+ int dev;
+ char *cmd;
+};
+#define ISSET_FILE_FLAG(fileinfo, flag) (fileinfo->acc_flags & (flag) ? 1:0)
+
+#define OSS_OS "FreeBSD"
+#define OSS_OS_LONGNAME "FreeBSD " OS_VERSION
+
+typedef void (*softintr_func_t) (int);
+
+struct oss_softintr
+{
+ int id;
+ softintr_func_t func;
+ volatile int armed, running;
+};
+
+struct _oss_poll_event_t
+{
+ short events, revents;
+ struct thread *p;
+ struct cdev *bsd_dev;
+};
+typedef struct _oss_poll_event_t oss_poll_event_t;
+
+extern int detect_trace;
+#define DDB(x) if (detect_trace) x
+
+extern caddr_t oss_map_pci_mem (oss_device_t * osdev, int nr, int phaddr,
+ int size);
+#define MAP_PCI_IOADDR(osdev, nr, io) (oss_native_word)(io)
+#define MAP_PCI_MEM(osdev, ix, phaddr, size) oss_map_pci_mem(osdev, ix, phaddr, size)
+#define UNMAP_PCI_MEM(osdev, ix, ph, virt, size) {}
+#define UNMAP_PCI_IOADDR(osdev, ix) {}
+
+#define GET_PROCESS_PID(f) f->pid
+#define GET_PROCESS_NAME(f) f->cmd
+
+#define abs(x) ((x) >= 0 ? (x) : -(x))
+
+/*
+ * PCI config space access (in os.c)
+ */
+extern char *oss_pci_read_devpath (dev_info_t * dip);
diff --git a/kernel/OS/FreeBSD/wrapper/bsddefs.h b/kernel/OS/FreeBSD/wrapper/bsddefs.h
new file mode 100644
index 0000000..c22965c
--- /dev/null
+++ b/kernel/OS/FreeBSD/wrapper/bsddefs.h
@@ -0,0 +1,150 @@
+/*
+ * Purpose: Definitions for routines and variables exported by osscore.c
+ *
+ * Do not make any modifications to these settings because OSS core modules
+ * have been compiled against them. Full rebuild of OSS will be required if
+ * this file is changed.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 <sys/types.h>
+#if 0 /* __FreeBSD_version >= 700031 */
+/* Some crashes have been reported with SX on 7-STABLE/8-CURRENT:
+ * http://4front-tech.com/forum/viewtopic.php?t=2718
+ * http://4front-tech.com/forum/viewtopic.php?t=2563
+ */
+#define USE_SX_LOCK 1
+#endif
+#undef VDEV_SUPPORT
+#if __FreeBSD_version >= 700111
+#define VDEV_SUPPORT
+extern int oss_file_set_private (struct thread *p, void *v, size_t l);
+extern int oss_file_get_private (void **v);
+#endif
+extern int oss_get_uid (void);
+
+typedef struct device dev_info_t;
+typedef long long oss_int64_t; /* Signed 64 bit integer */
+typedef unsigned long long oss_uint64_t; /* Unsigned 64 bit integer */
+typedef unsigned long offset_t;
+
+/*
+ * Some integer types
+ */
+#if defined(__amd64__)
+typedef unsigned long long oss_native_word; /* Same as the address and status register size */
+#else
+typedef unsigned long oss_native_word; /* Same as the address and status register size */
+#endif
+
+struct _oss_device_t
+{
+ int cardnum;
+ int dev_type;
+ int instance;
+ int available;
+ dev_info_t *dip;
+ void *osid;
+ void *devc;
+ char *name;
+ char *hw_info;
+ int major;
+ char nick[16];
+ char modname[16];
+ char handle[32];
+ int num_audio_engines;
+ int num_audioplay, num_audiorec, num_audioduplex;
+ int num_mididevs;
+ int num_mixerdevs;
+ int num_loopdevs;
+ int first_mixer; /* This must be set to -1 by osdev_create() */
+
+ int intrcount;
+ int ackcount;
+ volatile int refcount; /* Nonzero means that the device is needed by some other (virtual) driver. */
+
+};
+
+extern void cmn_err (int level, char *format, ...);
+#define CE_CONT 0
+#define CE_NOTE 1
+#define CE_WARN 2
+#define CE_PANIC 3
+
+#ifdef USE_SX_LOCK
+typedef struct sx *oss_mutex_t;
+#else
+typedef struct mtx *oss_mutex_t;
+#endif
+
+typedef int ddi_iblock_cookie_t;
+
+extern void oss_udelay (unsigned long t);
+
+#ifdef _KERNEL
+#define memset oss_memset
+extern void *oss_memset (void *t, int val, int l);
+#endif
+
+extern oss_device_t *osdev_create (dev_info_t * dip, int dev_type,
+ int instance, const char *nick,
+ const char *handle);
+extern void osdev_delete (oss_device_t * osdev);
+
+extern char *oss_pci_read_devpath (dev_info_t * dip);
+extern int pci_read_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char *val);
+extern int pci_read_config_irq (oss_device_t * osdev, offset_t where,
+ unsigned char *val);
+extern int pci_read_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short *val);
+extern int pci_read_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int *val);
+extern int pci_write_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char val);
+extern int pci_write_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short val);
+extern int pci_write_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int val);
+#ifndef OSS_CONFIG_H
+/* These definitions must match with oss_config.h */
+typedef int (*oss_tophalf_handler_t) (struct _oss_device_t * osdev);
+typedef void (*oss_bottomhalf_handler_t) (struct _oss_device_t * osdev);
+#endif
+
+extern int oss_register_interrupts (oss_device_t * osdev, int intrnum,
+ oss_tophalf_handler_t top,
+ oss_bottomhalf_handler_t bottom);
+extern void oss_unregister_interrupts (oss_device_t * osdev);
+
+extern void *oss_contig_malloc (unsigned long sz, unsigned long memlimit,
+ oss_native_word * phaddr);
+extern void oss_contig_free (void *p, unsigned long sz);
+
+extern void oss_register_module (char *name);
+extern void oss_unregister_module (char *name);
+extern void *oss_find_minor_info (int dev_class, int instance);
+extern int oss_find_minor (int dev_class, int instance);
+extern void oss_inc_intrcount (oss_device_t * osdev, int claimed);
+
+#define FP_SUPPORT
+
+#ifdef FP_SUPPORT
+typedef short fp_env_t[512];
+typedef unsigned int fp_flags_t[4];
+extern int oss_fp_check (void);
+extern void oss_fp_save (short *envbuf, fp_flags_t flags);
+extern void oss_fp_restore (short *envbuf, fp_flags_t flags);
+# define FP_SAVE(envbuf, flags) oss_fp_save(envbuf, flags)
+# define FP_RESTORE(envbuf, flags) oss_fp_restore(envbuf, flags)
+#endif
diff --git a/kernel/OS/Linux/.config b/kernel/OS/Linux/.config
new file mode 100644
index 0000000..816ac62
--- /dev/null
+++ b/kernel/OS/Linux/.config
@@ -0,0 +1 @@
+mode=kernel
diff --git a/kernel/OS/Linux/os_linux.c b/kernel/OS/Linux/os_linux.c
new file mode 100644
index 0000000..c47f3da
--- /dev/null
+++ b/kernel/OS/Linux/os_linux.c
@@ -0,0 +1,1034 @@
+/*
+ * Purpose: Operating system abstraction functions for Linux
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 <oss_config.h>
+#include <midi_core.h>
+
+/*
+ * OSS has traditionally used fixed character device number (14). However
+ * current OSS uses fully dynamic major number allocation. The legacy
+ * character device 14 is left for ALSA.
+ */
+static int osscore_major = 0;
+static int oss_expired = 0;
+
+/*
+ * Number of cards supported in the same system. This should be largish
+ * because unplugging/replugging USB cards in wrong way may create
+ * large number of card instances.
+ */
+#define MAX_CARDS 32
+
+static oss_device_t *cards[MAX_CARDS];
+int oss_num_cards = 0;
+
+void
+oss_pci_byteswap (oss_device_t * osdev, int mode)
+{
+ // NOP
+}
+
+int
+oss_pci_read_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char *val)
+{
+ return osscore_pci_read_config_byte (osdev->dip, where, val);
+}
+
+int
+oss_pci_read_config_irq (oss_device_t * osdev, offset_t where,
+ unsigned char *val)
+{
+ return osscore_pci_read_config_irq (osdev->dip, where, val);
+}
+
+int
+oss_pci_read_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short *val)
+{
+ if (osdev == NULL)
+ {
+ cmn_err (CE_CONT, "oss_pci_read_config_word: osdev==NULL\n");
+ return PCIBIOS_FAILED;
+ }
+
+ return osscore_pci_read_config_word (osdev->dip, where, val);
+}
+
+int
+oss_pci_read_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int *val)
+{
+ return osscore_pci_read_config_dword (osdev->dip, where, val);
+}
+
+int
+oss_pci_write_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char val)
+{
+ return osscore_pci_write_config_byte (osdev->dip, where, val);
+}
+
+int
+oss_pci_write_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short val)
+{
+ return osscore_pci_write_config_word (osdev->dip, where, val);
+}
+
+int
+oss_pci_write_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int val)
+{
+ return osscore_pci_write_config_dword (osdev->dip, where, val);
+}
+
+int
+oss_pci_enable_msi (oss_device_t * osdev)
+{
+ return osscore_pci_enable_msi (osdev->dip);
+}
+
+int
+oss_find_minor (int dev_class, int instance)
+{
+ int i;
+
+ for (i = 0; i < oss_num_cdevs; i++)
+ {
+ if (oss_cdevs[i]->d != NULL && oss_cdevs[i]->dev_class == dev_class
+ && oss_cdevs[i]->instance == instance)
+ return i;
+ }
+
+ return OSS_ENXIO;
+}
+
+oss_device_t *
+osdev_create (dev_info_t * dip, int dev_type,
+ int instance, const char *nick, const char *handle)
+{
+ oss_device_t *osdev;
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+
+ memset (osdev, 0, sizeof (*osdev));
+
+ sprintf (osdev->nick, "%s%d", nick, instance);
+ osdev->instance = instance;
+ osdev->dip = dip;
+ osdev->available = 1;
+ osdev->first_mixer = -1;
+
+ strcpy (osdev->modname, nick);
+
+ if (handle == NULL)
+ handle = nick;
+
+ if (oss_num_cards >= MAX_CARDS)
+ cmn_err (CE_WARN, "Too many OSS devices. At most %d permitted.\n",
+ MAX_CARDS);
+ else
+ {
+ osdev->cardnum = oss_num_cards;
+ cards[oss_num_cards++] = osdev;
+ }
+/*
+ * Create the device handle
+ */
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ {
+ unsigned int subvendor;
+ char *devpath;
+ devpath = oss_pci_read_devpath (osdev->dip);
+ oss_pci_read_config_dword (osdev, 0x2c, &subvendor);
+
+ sprintf (osdev->handle, "PCI%08x-%s", subvendor, devpath);
+ }
+ break;
+
+ case DRV_USB:
+ // TODO: Get the vendor information
+ sprintf (osdev->handle, "USB-%s%d", handle, instance);
+ break;
+
+ default:
+ sprintf (osdev->handle, "%s%d", handle, instance);
+ }
+
+ return osdev;
+}
+
+oss_device_t *
+osdev_clone (oss_device_t * orig_osdev, int new_instance)
+{
+ oss_device_t *osdev;
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+ memcpy (osdev, orig_osdev, sizeof (*osdev));
+ osdev->dev_type = DRV_CLONE;
+ osdev->instance = new_instance;
+ sprintf (osdev->nick, "%s%d", orig_osdev->modname, new_instance);
+ sprintf (osdev->handle, "%s%d", orig_osdev->modname, new_instance);
+
+ return osdev;
+}
+
+void
+osdev_delete (oss_device_t * osdev)
+{
+ int i;
+
+ if (osdev == NULL)
+ return;
+
+ osdev->available = 0;
+/*
+ * Mark all minor nodes for this module as invalid.
+ */
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->osdev == osdev)
+ {
+ oss_cdevs[i]->d = NULL;
+ oss_cdevs[i]->osdev = NULL;
+ strcpy (oss_cdevs[i]->name, "Removed device");
+ }
+}
+
+void
+osdev_set_owner (oss_device_t * osdev, struct module *owner)
+{
+ osdev->owner = owner;
+}
+
+void
+osdev_set_major (oss_device_t * osdev, int major)
+{
+ osdev->major = major;
+}
+
+void
+osdev_set_irqparms (oss_device_t * osdev, void *irqparms)
+{
+ osdev->irqparms = irqparms;
+}
+
+void *
+osdev_get_irqparms (oss_device_t * osdev)
+{
+ return osdev->irqparms;
+}
+
+char *
+osdev_get_nick (oss_device_t * osdev)
+{
+ return osdev->nick;
+}
+
+int
+osdev_get_instance (oss_device_t * osdev)
+{
+ return osdev->instance;
+}
+
+void
+oss_inc_intrcount (oss_device_t * osdev, int claimed)
+{
+ osdev->intrcount++;
+
+ if (claimed)
+ osdev->ackcount++;
+}
+
+struct module *
+osdev_get_owner (oss_device_t * osdev)
+{
+ return osdev->owner;
+}
+
+void *
+oss_get_osid (oss_device_t * osdev)
+{
+ return NULL; // TODO
+}
+
+int
+oss_get_procinfo(int what)
+{
+ switch (what)
+ {
+ case OSS_GET_PROCINFO_UID:
+ return oss_get_uid();
+ break;
+ }
+
+ return OSS_EINVAL;
+}
+
+int
+oss_disable_device (oss_device_t * osdev)
+{
+ int i;
+
+ if (osdev->major > 0)
+ oss_unregister_chrdev (osdev->major, osdev->nick);
+ osdev->major = 0;
+
+/*
+ * Now mark all devices unavailable (for the time being)
+ * TODO: Mobe this stuff to some common OSS module (also in Solaris)
+ */
+ if (osdev->refcount > 0)
+ {
+ return OSS_EBUSY;
+ }
+
+ for (i = 0; i < num_mixers; i++)
+ if (mixer_devs[i]->osdev == osdev)
+ {
+ mixer_devs[i]->unloaded = 1;
+ }
+
+ for (i = 0; i < num_mididevs; i++)
+ {
+ if (midi_devs[i]->osdev == osdev)
+ {
+ midi_devs[i]->unloaded = 1;
+ }
+ }
+
+ for (i = 0; i < num_audio_engines; i++)
+ if (audio_engines[i]->osdev == osdev)
+ {
+ audio_uninit_device (i);
+ }
+
+ return 0;
+}
+
+void
+oss_reserve_device (oss_device_t * osdev)
+{
+ osdev->refcount++;
+}
+
+void
+oss_unreserve_device (oss_device_t * osdev, int decrement)
+{
+ osdev->refcount--;
+ if (osdev->refcount < 0)
+ osdev->refcount = 0;
+}
+
+int
+oss_register_device (oss_device_t * osdev, const char *name)
+{
+ if (name == NULL)
+ {
+ cmn_err (CE_WARN, "oss_register_device: name==NULL\n");
+ osdev->name = "Undefined name";
+ return 0;
+ }
+
+ if ((osdev->name = PMALLOC (NULL, strlen (name) + 1)) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate memory for device name\n");
+ osdev->name = "Unknown device";
+ }
+ strcpy (osdev->name, name);
+ return 0;
+}
+
+void
+oss_unregister_device (oss_device_t * osdev)
+{
+/*
+ * Notice! The driver calling this routine (the owner of the osdev parameter)
+ * has already uninitialized itself. Do not do any actions that may call this
+ * driver directly or indirectly.
+ */
+
+// TODO: Move this to some common OSS module (also under Solaris)
+}
+
+int
+oss_get_cardinfo (int cardnum, oss_card_info * ci)
+{
+/*
+ * Print information about a 'card' in a format suitable for /dev/sndstat
+ */
+
+ if (cardnum < 0 || cardnum >= oss_num_cards)
+ return OSS_ENXIO;
+
+ if (cards[cardnum]->name != NULL)
+ strncpy (ci->longname, cards[cardnum]->name, 128);
+ ci->longname[127] = 0;
+
+ if (cards[cardnum]->nick != NULL)
+ strncpy (ci->shortname, cards[cardnum]->nick, 16);
+ ci->shortname[15] = 0;
+
+ if (cards[cardnum]->hw_info != NULL)
+ strncpy (ci->hw_info, cards[cardnum]->hw_info, sizeof (ci->hw_info));
+ ci->hw_info[sizeof (ci->hw_info) - 1] = 0;
+ ci->intr_count = cards[cardnum]->intrcount;
+ ci->ack_count = cards[cardnum]->ackcount;
+
+ return 0;
+}
+
+int
+__oss_alloc_dmabuf (int dev, dmap_p dmap, unsigned int alloc_flags,
+ oss_uint64_t maxaddr, int direction)
+{
+ void *buf;
+ int err;
+ oss_native_word phaddr;
+ int size = 64 * 1024;
+ extern int dma_buffsize;
+
+ if (dma_buffsize > 16 && dma_buffsize <= 128)
+ size = dma_buffsize * 1024;
+
+ if (dmap->dmabuf != NULL)
+ return 0; /* Already done */
+
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "oss_alloc_dmabuf: dmap==NULL\n");
+ return OSS_EIO;
+ }
+
+/*
+ * Some applications and virtual drivers need shorter buffer.
+ */
+ if (dmap->flags & DMAP_SMALLBUF)
+ {
+ size = SMALL_DMABUF_SIZE;
+ }
+ else if (dmap->flags & DMAP_MEDIUMBUF)
+ {
+ size = MEDIUM_DMABUF_SIZE;
+ }
+
+ if ((alloc_flags & DMABUF_SIZE_16BITS) && size > 32 * 1024)
+ size = 32 * 1024;
+
+ dmap->dmabuf = NULL;
+ dmap->buffsize = size;
+
+ err = -1;
+
+ while (err < 0 && dmap->dmabuf == NULL && dmap->buffsize >= 4 * 1024)
+ {
+ if ((buf =
+ oss_contig_malloc (dmap->osdev, dmap->buffsize, maxaddr,
+ &phaddr)) == NULL)
+ {
+ if ((dmap->buffsize = (dmap->buffsize / 2)) < 8 * 1024)
+ return OSS_ENOMEM;
+ cmn_err (CE_CONT, "Dropping DMA buffer size to %d bytes.\n",
+ dmap->buffsize);
+ continue;
+ }
+
+ dmap->dmabuf = buf;
+ dmap->dmabuf_phys = phaddr;
+
+ return 0;
+ }
+
+ return OSS_ENOMEM;
+}
+
+void
+oss_free_dmabuf (int dev, dmap_p dmap)
+{
+ void *buf = dmap->dmabuf;
+
+ if (dmap->dmabuf == NULL)
+ return;
+
+ dmap->dmabuf = NULL;
+ oss_contig_free (NULL, buf, dmap->buffsize);
+ dmap->dmabuf_phys = 0;
+}
+
+static inline int
+cpy_file (oss_file_handle_t * f, struct fileinfo *fi)
+{
+ // TODO: Handle acc_flags properly
+ fi->acc_flags = 0;
+ fi->mode = 0;
+ fi->acc_flags = oss_file_get_flags (f);
+
+ if ((fi->acc_flags & O_ACCMODE) == O_RDWR)
+ fi->mode = OPEN_READWRITE;
+ if ((fi->acc_flags & O_ACCMODE) == O_RDONLY)
+ fi->mode = OPEN_READ;
+ if ((fi->acc_flags & O_ACCMODE) == O_WRONLY)
+ fi->mode = OPEN_WRITE;
+
+ return fi->mode;
+}
+
+static int
+oss_cdev_open (oss_inode_handle_t * inode, oss_file_handle_t * file)
+{
+ int dev = oss_inode_get_minor (inode);
+ oss_native_word d;
+ int tmpdev, dev_class, retval;
+ struct fileinfo fi;
+ oss_cdev_t *cdev;
+
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+ if (oss_cdevs == NULL)
+ return OSS_ENXIO;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return OSS_ENXIO;
+
+ DDB (cmn_err
+ (CE_CONT, "oss_cdev_open(%d): %s, class=%d, instance=%d\n", dev,
+ cdev->name, cdev->dev_class, cdev->instance));
+
+ if (cdev->d->open == NULL)
+ {
+ return OSS_ENODEV;
+ }
+
+ dev_class = cdev->dev_class;
+
+ tmpdev = -1;
+ oss_inc_refcounts ();
+ retval =
+ cdev->d->open (cdev->instance, cdev->dev_class, &fi, 0, 0, &tmpdev);
+
+ if (retval < 0)
+ {
+ oss_dec_refcounts ();
+ return retval;
+ }
+
+ if (tmpdev != -1)
+ dev = tmpdev;
+
+ //open_devices++;
+ //open_count[dev]++;
+
+ d = dev;
+ oss_file_set_private (file, (void *) d);
+
+ return 0;
+}
+
+static int
+oss_cdev_release (oss_inode_handle_t * inode, oss_file_handle_t * file)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ struct fileinfo fi;
+ oss_cdev_t *cdev;
+
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return 0;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->close == NULL)
+ {
+ return 0;
+ }
+
+ cdev->d->close (cdev->instance, &fi);
+ oss_dec_refcounts ();
+
+ return 0;
+}
+
+static ssize_t
+oss_cdev_read (oss_file_handle_t * file, char *buf, size_t count,
+ loff_t * offs)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ int err;
+ uio_t uio;
+
+ struct fileinfo fi;
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->read == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ if ((err = oss_create_uio (&uio, buf, count, UIO_READ, 0)) < 0)
+ {
+ return err;
+ }
+
+ err = cdev->d->read (cdev->instance, &fi, &uio, count);
+
+ return err;
+}
+
+static ssize_t
+oss_cdev_write (oss_file_handle_t * file, char *buf, size_t count,
+ loff_t * offs)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ int err;
+ uio_t uio;
+
+ struct fileinfo fi;
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->write == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ if ((err = oss_create_uio (&uio, buf, count, UIO_WRITE, 0)) < 0)
+ {
+ return err;
+ }
+
+ err = cdev->d->write (cdev->instance, &fi, &uio, count);
+
+ return err;
+}
+
+static int
+oss_cdev_ioctl (oss_inode_handle_t * inode, oss_file_handle_t * file,
+ unsigned int cmd, unsigned long arg)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ int err;
+ int localbuf[64]; /* 256 bytes is the largest frequently used ioctl size */
+
+ int len = 0;
+ int alloced = 0;
+ int *ptr = (int *) arg;
+
+ struct fileinfo fi;
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->ioctl == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ if (__SIOC_DIR (cmd) != __SIOC_NONE && __SIOC_DIR (cmd) != 0)
+ {
+ len = __SIOC_SIZE (cmd);
+ if (len < 1 || len > 65536 || arg == 0)
+ {
+ cmn_err (CE_WARN, "Bad ioctl command %x, %d, %x\n", cmd, len, arg);
+ return OSS_EFAULT;
+ }
+
+ /* Use statically allocated buffer for short arguments */
+ if (len > sizeof (localbuf))
+ {
+ ptr = KERNEL_MALLOC (len);
+ alloced = 1;
+ }
+ else
+ ptr = localbuf;
+
+ if (ptr == NULL || arg == 0)
+ {
+ return OSS_EFAULT;
+ }
+
+ if (__SIOC_DIR (cmd) & __SIOC_WRITE)
+ {
+ if (oss_copy_from_user (ptr, (char *) arg, len))
+ {
+ if (alloced)
+ KERNEL_FREE (ptr);
+ return OSS_EFAULT;
+ }
+ }
+ }
+
+ if ((err = cdev->d->ioctl (cdev->instance, &fi, cmd, (ioctl_arg) ptr)) < 0)
+ {
+ if (alloced)
+ KERNEL_FREE (ptr);
+ return err;
+ }
+
+ if (__SIOC_DIR (cmd) & __SIOC_READ)
+ {
+ if (oss_copy_to_user ((char *) arg, ptr, len))
+ {
+ if (alloced)
+ KERNEL_FREE (ptr);
+ return OSS_EFAULT;
+ }
+ }
+
+ /* Free the local buffer unless it was statically allocated */
+ if (ptr != NULL && alloced)
+ if (len > sizeof (localbuf))
+ KERNEL_FREE (ptr);
+
+ return ((err < 0) ? err : 0);
+
+}
+
+/* No BKL if this is used */
+static long
+oss_cdev_unlocked_ioctl (oss_file_handle_t * file, unsigned int cmd,
+ unsigned long arg)
+{
+ return oss_cdev_ioctl (NULL, file, cmd, arg);
+}
+
+/* Used for 32 bit clients on a 64 bit kernel. No BKL here either */
+static long
+oss_cdev_compat_ioctl (oss_file_handle_t * file, unsigned int cmd,
+ unsigned long arg)
+{
+ return oss_cdev_ioctl (NULL, file, cmd, arg);
+}
+
+static unsigned int
+oss_cdev_poll (oss_file_handle_t * file, oss_poll_table_handle_t * wait)
+{
+ oss_poll_event_t ev;
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ int err;
+
+ struct fileinfo fi;
+ cpy_file (file, &fi);
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->chpoll == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ ev.wait = wait;
+ ev.file = file;
+ ev.events = POLLOUT | POLLWRNORM | POLLIN | POLLRDNORM;
+ ev.revents = 0;
+ err = cdev->d->chpoll (cdev->instance, &fi, &ev);
+ if (err < 0)
+ {
+ return err;
+ }
+
+ return ev.revents;
+}
+
+static int
+oss_cdev_mmap (oss_file_handle_t * file, oss_vm_area_handle_t * vma)
+{
+ oss_native_word d = (oss_native_word) oss_file_get_private (file);
+ int dev = d;
+ oss_cdev_t *cdev;
+ dmap_p dmap = NULL;
+ int err;
+
+ if (dev > oss_num_cdevs)
+ return OSS_ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ if (cdev->dev_class != OSS_DEV_DSP && cdev->dev_class != OSS_DEV_DSP_ENGINE) /* Only mmap audio devices */
+ {
+ return OSS_ENXIO;
+ }
+
+ dev = cdev->instance;
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ if (audio_engines[dev]->flags & ADEV_NOMMAP)
+ return OSS_EIO;
+
+ if (oss_vma_get_flags (vma) & VM_WRITE) /* Map write and read/write to the output buf */
+ {
+ dmap = audio_engines[dev]->dmap_out;
+ }
+ else if (oss_vma_get_flags (vma) & VM_READ)
+ {
+ dmap = audio_engines[dev]->dmap_in;
+ }
+ else
+ {
+ cmn_err (CE_WARN, "Undefined mmap() access\n");
+ return OSS_EINVAL;
+ }
+
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "mmap() error. dmap == NULL\n");
+ return OSS_EIO;
+ }
+
+ if (dmap->dmabuf == NULL)
+ {
+ cmn_err (CE_WARN, "mmap() called when raw_buf == NULL\n");
+ return OSS_EIO;
+ }
+
+ if (dmap->dmabuf_phys == 0)
+ {
+ cmn_err (CE_WARN, "mmap() not supported by device /dev/dsp%d.\n", dev);
+ return OSS_EIO;
+ }
+
+ if (dmap->mapping_flags)
+ {
+ cmn_err (CE_WARN, "mmap() called twice for the same DMA buffer\n");
+ return OSS_EIO;
+ }
+
+ if (dmap->flags & DMAP_COOKED)
+ {
+ cmn_err (CE_WARN,
+ "mmap() not possible with currently selected sample format.\n");
+ return OSS_EIO;
+ }
+
+ if ((err = oss_do_mmap (vma, dmap->dmabuf_phys, dmap->bytes_in_use)) < 0)
+ return err;
+
+ dmap->mapping_flags |= DMA_MAP_MAPPED;
+
+ memset (dmap->dmabuf, dmap->neutral_byte, dmap->bytes_in_use);
+ return 0;
+}
+
+oss_file_operation_handle_t oss_fops = {
+ oss_cdev_read,
+ oss_cdev_write,
+ NULL, /* oss_readdir */
+ oss_cdev_poll,
+ oss_cdev_ioctl,
+ oss_cdev_mmap,
+ oss_cdev_open,
+ oss_cdev_release,
+ oss_cdev_compat_ioctl,
+ oss_cdev_unlocked_ioctl
+};
+
+static int
+hookup_cdevsw (oss_device_t * osdev)
+{
+ return oss_register_chrdev (osdev, osscore_major, "osscore", &oss_fops);
+}
+
+int
+oss_request_major (oss_device_t * osdev, int major, char *module)
+{
+ int err;
+
+ err = oss_register_chrdev (osdev, major, module, &oss_fops);
+
+ return err;
+}
+
+static int
+grow_array(oss_device_t *osdev, oss_cdev_t ***arr, int *size, int increment)
+{
+ oss_cdev_t **old=*arr, **new = *arr;
+ int old_size = *size;
+ int new_size = *size;
+
+ new_size += increment;
+
+ if ((new=PMALLOC(osdev, new_size * sizeof (oss_cdev_t *)))==NULL)
+ return 0;
+
+ memset(new, 0, new_size * sizeof(oss_cdev_t *));
+ if (old != NULL)
+ memcpy(new, old, old_size * sizeof(oss_cdev_t *));
+
+ *size = new_size;
+ *arr = new;
+
+ if (old != NULL)
+ PMFREE(osdev, old);
+
+ return 1;
+}
+
+void
+oss_install_chrdev (oss_device_t * osdev, char *name, int dev_class,
+ int instance, oss_cdev_drv_t * drv, int flags)
+{
+/*
+ * oss_install_chrdev creates a character device (minor). However if
+ * name==NULL the device will not be exported (made visible to userland
+ * clients).
+ */
+
+ int num;
+ oss_cdev_t *cdev = NULL;
+
+ if (osdev->major == 0)
+ {
+ cmn_err (CE_WARN, "Module %s major=0\n", osdev->nick);
+ return;
+ }
+
+ if (osdev->major < 0)
+ {
+ cmn_err (CE_WARN, "Failed to allocate major device for %s\n",
+ osdev->nick);
+ }
+
+ if (dev_class != OSS_DEV_STATUS)
+ if (oss_expired && instance > 0)
+ return;
+/*
+ * Find if this dev_class&instance already exists (after previous module
+ * detach).
+ */
+
+ for (num = 0; num < oss_num_cdevs; num++)
+ if (oss_cdevs[num]->d == NULL) /* Unloaded driver */
+ if (oss_cdevs[num]->dev_class == dev_class
+ && oss_cdevs[num]->instance == instance)
+ {
+ cdev = oss_cdevs[num];
+ break;
+ }
+
+ if (cdev == NULL)
+ {
+ if (oss_num_cdevs >= OSS_MAX_CDEVS)
+ {
+ if (!grow_array(osdev, &oss_cdevs, &oss_max_cdevs, 100))
+ {
+ cmn_err (CE_WARN, "Out of minor numbers.\n");
+ return;
+ }
+ }
+
+ if ((cdev = PMALLOC (NULL, sizeof (*cdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate character device desc.\n");
+ return;
+ }
+
+ num = oss_num_cdevs++;
+ }
+
+ memset (cdev, 0, sizeof (*cdev));
+ cdev->dev_class = dev_class;
+ cdev->instance = instance;
+ cdev->d = drv;
+ cdev->osdev = osdev;
+ if (name != NULL)
+ strncpy (cdev->name, name, sizeof (cdev->name));
+ else
+ strcpy (cdev->name, "NONE");
+ cdev->name[sizeof (cdev->name) - 1] = 0;
+ oss_cdevs[num] = cdev;
+
+/*
+ * Export the device only if name != NULL
+ */
+ if (name != NULL)
+ {
+ strcpy (cdev->name, name);
+ oss_register_minor (osdev->major, num, name);
+ }
+}
+
+int
+oss_init_osscore (oss_device_t * osdev)
+{
+
+#ifdef LICENSED_VERSION
+ if (!oss_license_handle_time (oss_get_time ()))
+ {
+ cmn_err (CE_WARN, "This version of Open Sound System has expired\n");
+ cmn_err (CE_CONT,
+ "Please download the latest version from www.opensound.com\n");
+ oss_expired = 1;
+ }
+#endif
+
+ if ((osscore_major = hookup_cdevsw (osdev)) < 0)
+ {
+ cmn_err (CE_WARN, "Failed to allocate character major number %d\n",
+ osscore_major);
+ return OSS_EBUSY;
+ }
+
+ osdev->major = osscore_major;
+ oss_register_device (osdev, "OSS core services");
+
+ oss_common_init (osdev);
+
+ return 0;
+}
+
+void
+oss_uninit_osscore (oss_device_t * osdev)
+{
+ oss_unload_drivers ();
+
+ // free_all_irqs (); /* If something was left allocated by accident */
+ oss_unregister_chrdev (osscore_major, "osscore");
+}
+
+/*
+ * oss_pmalloc() is only used by usb_wraper.inc.
+ */
+void *
+oss_pmalloc (size_t sz)
+{
+ return oss_memblk_malloc(&oss_global_memblk, sz);
+}
diff --git a/kernel/OS/Linux/os_linux.h b/kernel/OS/Linux/os_linux.h
new file mode 100644
index 0000000..d881859
--- /dev/null
+++ b/kernel/OS/Linux/os_linux.h
@@ -0,0 +1,287 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+/*
+ * Purpose: OS specific definitions for Linux
+ *
+ * Under Linux os.h (this file) defines just the macros, functions and
+ * structures used by the code compiled in the development system. However
+ * there are other Linux specific definitions contained in {!nlink Linux/wrap.h}
+ * that are used both by the code compiled in the devlopment and target systems.
+ * This means that some definitions found in os.h under some other operating
+ * systems may be in wrap.h under Linux.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define OS_VERSION "2.6.x"
+#define __EXTENDED__
+#define OSS_MAINLINE_BUILD
+
+/*
+ * Debugging and misc settings
+ */
+#undef MUTEX_CHECKS
+#undef MEMDEBUG
+#define VDEV_SUPPORT
+
+#if (!defined(__i386__) && !defined(__x86_64__)) || defined(CONFIG_OSS_FIXDEPOINT)
+// Floating point is not supported or it's disabled
+#undef CONFIG_OSS_VMIX_FLOAT
+#endif
+
+/*
+ * Disable support for per-application features such as /dev/dsp device
+ * selection based on command name. Requires working GET_PROCESS_NAME
+ * macro implementation.
+ */
+
+#undef APPLIST_SUPPORT
+#define USE_DEVICE_SUBDIRS
+#define EXTERN_C
+
+#define __invalid_size_argument_for_IOC 0 /* Dummy define to cure some broken ioctl.h versions */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/signal.h>
+#include <oss_errno.h>
+#include <sys/file.h>
+#include "oss_ddi.h"
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <asm/poll.h>
+#include "kernel/OS/Linux/wrapper/wrap.h"
+
+#undef HZ
+extern int oss_hz;
+#define OSS_HZ oss_hz
+
+/* The soundcard.h could be in a nonstandard place so include it here. */
+#include "soundcard.h"
+
+struct _oss_device_t
+{
+ int cardnum;
+ int dev_type;
+ int available;
+ int instance;
+ dev_info_t *dip;
+ void *devc;
+ char *name;
+ char nick[16];
+ char handle[32];
+ int num_audio_engines;
+ int num_audioplay, num_audiorec, num_audioduplex;
+ int num_mididevs;
+ int num_mixerdevs;
+ int num_loopdevs;
+ int first_mixer; /* This must be set to -1 by osdev_create() */
+ int major;
+ struct module *owner; /* Pointer to THISMODULE (needed by osscore.c) */
+ char modname[32];
+ char *hw_info;
+
+ volatile int refcount; /* Nonzero means that the device is needed by some other (virtual) driver. */
+
+/* Interrupts */
+
+ ddi_iblock_cookie_t iblock_cookie; /* Dummy field under Linux */
+ void *irqparms;
+ int intrcount, ackcount;
+
+/* PCI related fields */
+
+#ifdef _KERNEL
+ ddi_acc_handle_t pci_config_handle;
+ ddi_acc_handle_t acc_handle;
+ int swap_mode; /* 0=DDI_STRUCTURE_NEVERSWAP_ACC, 1=DDI_STRUCTURE_LE_ACC */
+#endif
+};
+
+#define ALLOW_BUFFER_MAPPING
+#define ALLOW_SELECT
+#define SEL_IN 0
+#define SEL_OUT 1
+#define SEL_EX 0xffffffff
+
+/* Busy wait routine */
+#define oss_udelay drv_usecwait
+/* System wall timer access */
+#define GET_JIFFIES() oss_get_jiffies()
+
+extern inline unsigned int
+__inb (unsigned short port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("in" "b" " %" "w" "1,%" "b" "0":"=a" (_v):"d" (port),
+ "0" (0));
+ return _v;
+}
+extern inline unsigned int
+__inw (unsigned short port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("in" "w" " %" "w" "1,%" "w" "0":"=a" (_v):"d" (port),
+ "0" (0));
+ return _v;
+}
+extern inline unsigned int
+__inl (unsigned short port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("in" "l" " %" "w" "1,%" "" "0":"=a" (_v):"d" (port));
+ return _v;
+}
+
+extern inline void
+__outb (unsigned char value, unsigned short port)
+{
+ __asm__ __volatile__ ("out" "b" " %" "b" "0,%" "w" "1"::"a" (value),
+ "d" (port));
+}
+extern inline void
+__outw (unsigned short value, unsigned short port)
+{
+ __asm__ __volatile__ ("out" "w" " %" "w" "0,%" "w" "1"::"a" (value),
+ "d" (port));
+}
+extern inline void
+__outl (unsigned int value, unsigned short port)
+{
+ __asm__ __volatile__ ("out" "l" " %" "0,%" "w" "1"::"a" (value),
+ "d" (port));
+}
+
+#define INB(osdev,a) __inb(a)
+#define INW(osdev,a) __inw(a)
+#define INL(osdev,a) __inl(a)
+
+#define OUTB(osdev, d, a) __outb(d, a)
+
+#define OUTW(osdev, d, a) __outw(d, a)
+#define OUTL(osdev, d, a) __outl(d, a)
+
+#define PCI_READL(osdev, p) (*(volatile unsigned int *) (p))
+#define PCI_WRITEL(osdev, addr, data) (*(volatile unsigned int *) (addr) = (data))
+#define PCI_READW(osdev, p) (*(volatile unsigned short *) (p))
+#define PCI_WRITEW(osdev, addr, data) (*(volatile unsigned short *) (addr) = (data))
+#define PCI_READB(osdev, p) (*(volatile unsigned char *) (p))
+#define PCI_WRITEB(osdev, addr, data) (*(volatile unsigned char *) (addr) = (data))
+
+/*
+ KERNEL_MALLOC() allocates requested number of memory and
+ KERNEL_FREE is used to free it.
+ These macros are never called from interrupt, in addition the
+ nbytes will never be more than 4096 bytes. Generally the driver
+ will allocate memory in blocks of 4k. If the kernel has just a
+ page level memory allocation, 4K can be safely used as the size
+ (the nbytes parameter can be ignored).
+*/
+#ifdef MEMDEBUG
+extern void *oss_kmem_alloc (size_t size, char *file, int line);
+extern void oss_kmem_free (void *addr);
+#define KERNEL_MALLOC(nbytes) oss_kmem_alloc(nbytes, __FILE__, __LINE__)
+#define KERNEL_FREE(addr) oss_kmem_free(addr)
+extern void *oss_contig_malloc (oss_device_t * osdev, int sz,
+ oss_uint64_t memlimit,
+ oss_native_word * phaddr, char *file,
+ int line);
+extern void oss_contig_free (oss_device_t * osdev, void *p, int sz);
+extern oss_native_word oss_virt_to_bus (void *addr);
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(osdev, sz, memlimit, phaddr, __FILE__, __LINE__)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(osdev, p, sz)
+#else
+#define KERNEL_MALLOC(nbytes) oss_kmem_alloc(nbytes)
+#define KERNEL_FREE(addr) oss_kmem_free(addr)
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(osdev, sz, memlimit, phaddr)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(osdev, p, sz)
+#endif
+
+/*
+ * Timer macros
+ *
+ * These macros are obsolete and should not be used in any new code.
+ * Use the timeout mechanism (see the timeout(9F) Solaris man page).
+ */
+#define DEFINE_TIMER(name, proc) static timeout_id_t name = 0
+#define REMOVE_TIMER(name, proc) {if (name != 0) oss_untimeout(name);}
+#define INIT_TIMER(name,proc)
+typedef void (*timeout_func_t) (void *);
+#define ACTIVATE_TIMER(name, proc, time) \
+ name=oss_timeout((timeout_func_t)proc, (void*)&name, time)
+
+#endif
+
+#define OSS_OS "Linux"
+#define OSS_OS_LONGNAME "Linux"
+
+#undef DMA_TRY_PSEUDOINIT
+
+int get_dma_residue (int chn);
+void disable_dma (int chn);
+void enable_dma (int chn);
+
+typedef void (*softintr_func_t) (int);
+
+struct oss_softintr
+{
+ int id;
+ softintr_func_t func;
+ volatile int armed, running;
+};
+
+#define MUTEX_INIT(osdev, mutex, hier) mutex=oss_mutex_init()
+#define MUTEX_CLEANUP(mutex) {oss_mutex_cleanup(mutex);mutex=NULL;}
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) flags=0;oss_spin_lock_irqsave(mutex, &flags)
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) oss_spin_unlock_irqrestore(mutex, flags);(flags)++
+#define MUTEX_ENTER(mutex, flags) flags=0;oss_spin_lock(mutex)
+#define MUTEX_EXIT(mutex, flags) oss_spin_unlock(mutex);(flags)++
+
+extern int detect_trace;
+#define DDB(x) if (detect_trace) x
+
+#define MAP_PCI_IOADDR(osdev, nr, io) (oss_native_word)io
+#define MAP_PCI_MEM(osdev, ix, phaddr, size) oss_map_pci_mem(osdev, size, phaddr)
+#define UNMAP_PCI_MEM(osdev, ix, ph, virt, size) oss_unmap_pci_mem(virt)
+#define UNMAP_PCI_IOADDR(osdev, ix) {}
+
+#define GET_PROCESS_PID(x) oss_get_pid()
+#define GET_PROCESS_UID(x) oss_get_uid()
+
+#define GET_PROCESS_NAME(x) oss_get_procname()
+
+#define pci_read_config_irq oss_pci_read_config_irq
+#define pci_read_config_byte oss_pci_read_config_byte
+#define pci_read_config_word oss_pci_read_config_word
+#define pci_read_config_dword oss_pci_read_config_dword
+#define pci_write_config_byte oss_pci_write_config_byte
+#define pci_write_config_word oss_pci_write_config_word
+#define pci_write_config_dword oss_pci_write_config_dword
+#define pci_enable_msi oss_pci_enable_msi
+
+#define VM_READ 0x1
+#define VM_WRITE 0x2
+
+#define FP_SUPPORT
+
+#ifdef FP_SUPPORT
+typedef short fp_env_t[512];
+typedef unsigned int fp_flags_t[4];
+extern int oss_fp_check (void);
+extern void oss_fp_save (short *envbuf, fp_flags_t flags);
+extern void oss_fp_restore (short *envbuf, fp_flags_t flags);
+# define FP_SAVE(envbuf, flags) oss_fp_save(envbuf, flags)
+# define FP_RESTORE(envbuf, flags) oss_fp_restore(envbuf, flags)
+#endif
+
+#include "oss_pci.h"
diff --git a/kernel/OS/Linux/oss_ddi.h b/kernel/OS/Linux/oss_ddi.h
new file mode 100644
index 0000000..36111fe
--- /dev/null
+++ b/kernel/OS/Linux/oss_ddi.h
@@ -0,0 +1,46 @@
+/*
+ * Purpose: Solaris compatible partial DDI interface for OSS/Linux
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 NULL
+#define NULL 0
+#endif
+
+typedef int ddi_iblock_cookie_t;
+typedef int kmutex_t;
+typedef int cred_t;
+
+typedef int ddi_acc_handle_t;
+typedef int kcondvar_t;
+typedef int ddi_dma_handle_t;
+typedef int ddi_dma_cookie_t;
+typedef int ddi_dma_win_t;
+typedef int ddi_dma_seg_t;
+typedef int offset_t;
+typedef int ddi_info_cmd_t;
+typedef int ddi_attach_cmd_t;
+typedef int ddi_detach_cmd_t;
+
+#include <stdint.h>
+
+typedef struct _ddi_dma_attr_t
+{
+#define DMA_ATTR_V0 0
+ int a, b, c, d, e, f, g, h, i, j, k, l, m, n;
+} ddi_dma_attr_t;
+
+struct pollhead
+{
+ int dummy;
+};
diff --git a/kernel/OS/Linux/wrapper/.nomake b/kernel/OS/Linux/wrapper/.nomake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel/OS/Linux/wrapper/.nomake
diff --git a/kernel/OS/Linux/wrapper/wrap.h b/kernel/OS/Linux/wrapper/wrap.h
new file mode 100644
index 0000000..0a3d3b9
--- /dev/null
+++ b/kernel/OS/Linux/wrapper/wrap.h
@@ -0,0 +1,288 @@
+/*
+ * Purpose: Wrapper routines for Linux kernel services
+ *
+ * The functions and structures declared here are part of the osscore.c
+ * file that is compiled in the target system. This file must not be
+ * modified in the target system because the precompiled binaries included
+ * in the OSS installation package depend on it too.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * Some integer types
+ */
+#if defined(__x86_64__)
+typedef unsigned long long oss_native_word; /* Same as the address and status register size */
+#else
+typedef unsigned long oss_native_word; /* Same as the address and status register size */
+#endif
+typedef long long oss_int64_t; /* Signed 64 bit integer */
+typedef unsigned long long oss_uint64_t; /* Unsigned 64 bit integer */
+
+extern char *oss_strcpy (char *s1, const char *s2);
+extern void *oss_memcpy (void *t_, const void *f_, size_t l);
+extern void *oss_memset (void *t, int val, size_t l);
+extern int oss_strcmp (const char *s1, const char *s2);
+extern size_t oss_strlen (const char *s);
+extern char *oss_strncpy (char *s1, const char *s2, size_t l);
+extern void oss_udelay (unsigned long d);
+
+typedef struct _oss_mutex_t *oss_mutex_t;
+typedef struct _poll_table_handle oss_poll_table_handle_t;
+typedef struct _file_handle_t oss_file_handle_t;
+
+struct _oss_poll_event_t
+{
+ short events, revents;
+ oss_poll_table_handle_t *wait;
+ oss_file_handle_t *file;
+};
+typedef struct _oss_poll_event_t oss_poll_event_t;
+
+extern oss_mutex_t oss_mutex_init (void);
+extern void oss_mutex_cleanup (oss_mutex_t mutex);
+extern void oss_spin_lock_irqsave (oss_mutex_t mutex,
+ oss_native_word * flags);
+extern void oss_spin_unlock_irqrestore (oss_mutex_t mutex,
+ oss_native_word flags);
+extern void oss_spin_lock (oss_mutex_t mutex);
+extern void oss_spin_unlock (oss_mutex_t mutex);
+extern unsigned long long oss_get_jiffies (void);
+extern char *oss_get_procname (void);
+extern int oss_get_pid (void);
+extern int oss_get_uid (void);
+
+struct oss_wait_queue;
+struct module;
+struct _oss_device_t;
+struct pci_dev;
+
+typedef void *oss_dma_handle_t; /* Unused type */
+
+/*
+ * Sleep/wakeup/poll support. These definitions are duplicates from
+ * oss_config.h which is the official place. Both definitions must match.
+ */
+
+extern struct oss_wait_queue *oss_create_wait_queue (oss_device_t * osdev,
+ const char *name);
+extern void oss_reset_wait_queue (struct oss_wait_queue *wq);
+extern void oss_remove_wait_queue (struct oss_wait_queue *wq);
+extern int oss_sleep (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ int ticks, oss_native_word * flags,
+ unsigned int *status);
+extern int oss_register_poll (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ oss_native_word * flags, oss_poll_event_t * ev);
+extern void oss_wakeup (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ oss_native_word * flags, short events);
+
+extern void oss_cmn_err (int level, const char *format, ...);
+#define CE_CONT 0
+#define CE_NOTE 1
+#define CE_WARN 2
+#define CE_PANIC 3
+
+typedef int timeout_id_t;
+extern timeout_id_t oss_timeout (void (*func) (void *), void *arg,
+ unsigned long long ticks);
+extern void oss_untimeout (timeout_id_t id);
+
+extern int sprintf (char *buf, const char *s, ...);
+
+typedef enum uio_rw
+{ UIO_READ, UIO_WRITE } uio_rw_t;
+struct uio
+{
+ char *ptr;
+ int resid;
+ int kernel_space; /* Set if this uio points to a kernel space buffer */
+ uio_rw_t rw;
+};
+typedef struct uio uio_t;
+
+extern int oss_uiomove (void *address, size_t nbytes, enum uio_rw rwflag,
+ uio_t * uio_p);
+extern int oss_create_uio (uio_t * uiop, char *buf, size_t count, uio_rw_t rw,
+ int is_kernel);
+extern void *oss_kmem_alloc (size_t size);
+extern void oss_kmem_free (void *addr);
+extern void *oss_pmalloc (size_t sz);
+extern oss_native_word oss_virt_to_bus (void *addr);
+extern void oss_reserve_pages (oss_native_word start_addr,
+ oss_native_word end_addr);
+extern void oss_unreserve_pages (oss_native_word start_addr,
+ oss_native_word end_addr);
+extern void *oss_contig_malloc (oss_device_t * osdev, int sz,
+ oss_uint64_t memlimit,
+ oss_native_word * phaddr);
+extern void oss_contig_free (oss_device_t * osdev, void *p, int sz);
+
+extern time_t oss_get_time (void);
+
+typedef struct _inode_handle_t oss_inode_handle_t;
+typedef struct _vm_aread_handle oss_vm_area_handle_t;
+
+extern int oss_vma_get_flags (oss_vm_area_handle_t *);
+
+typedef struct oss_file_operation_handle
+{
+ ssize_t (*read) (oss_file_handle_t *, char *, size_t, loff_t *);
+ ssize_t (*write) (oss_file_handle_t *, char *, size_t, loff_t *);
+ int (*readdir) (oss_inode_handle_t *, oss_file_handle_t *, void *, int);
+ unsigned int (*poll) (oss_file_handle_t *, oss_poll_table_handle_t *);
+ int (*ioctl) (oss_inode_handle_t *, oss_file_handle_t *, unsigned int,
+ unsigned long);
+ int (*mmap) (oss_file_handle_t *, oss_vm_area_handle_t *);
+ int (*open) (oss_inode_handle_t *, oss_file_handle_t *);
+ int (*release) (oss_inode_handle_t *, oss_file_handle_t *);
+ long (*compat_ioctl) (oss_file_handle_t *, unsigned int, unsigned long);
+ long (*unlocked_ioctl) (oss_file_handle_t *, unsigned int, unsigned long);
+ int (*fsync) (oss_inode_handle_t *, oss_file_handle_t *);
+ int (*fasync) (oss_inode_handle_t *, oss_file_handle_t *, int);
+}
+oss_file_operation_handle_t;
+
+extern int oss_do_mmap (oss_vm_area_handle_t * vma,
+ oss_native_word dmabuf_phys, int bytes_in_use);
+extern int oss_register_chrdev (oss_device_t * osdev, unsigned int major,
+ const char *name,
+ oss_file_operation_handle_t * op);
+extern void oss_register_minor (int major, int minor, char *name);
+extern int oss_unregister_chrdev (unsigned int major, const char *name);
+
+extern int oss_inode_get_minor (oss_inode_handle_t * inode);
+extern int oss_file_get_flags (oss_file_handle_t * file);
+extern void *oss_file_get_private (oss_file_handle_t * file);
+extern void oss_file_set_private (oss_file_handle_t * file, void *v);
+
+extern void oss_inc_refcounts (void);
+extern void oss_dec_refcounts (void);
+
+/*
+ * Redefinitions of some routines defined in oss_config.h
+ * just to ensure they are defined in the same way in both places. The
+ * osscore/wrapper modules only include wrap.h so they can't see the "official"
+ * declarations in oss_config.h.
+ */
+
+typedef struct _dev_info_t dev_info_t;
+extern dev_info_t *oss_create_pcidip (struct pci_dev *pcidev);
+extern oss_device_t *osdev_create (dev_info_t * dip, int dev_type,
+ int instance, const char *nick,
+ const char *handle);
+
+extern void osdev_delete (oss_device_t * osdev);
+
+/*
+ * PCI config space access (in osscore.c)
+ */
+extern char *oss_pci_read_devpath (dev_info_t * dip);
+extern int osscore_pci_read_config_byte (dev_info_t * dip, unsigned int where,
+ unsigned char *val);
+extern int osscore_pci_read_config_irq (dev_info_t * dip, unsigned int where,
+ unsigned char *val);
+extern int osscore_pci_read_config_word (dev_info_t * dip, unsigned int where,
+ unsigned short *val);
+extern int osscore_pci_read_config_dword (dev_info_t * dip,
+ unsigned int where,
+ unsigned int *val);
+extern int osscore_pci_write_config_byte (dev_info_t * dip,
+ unsigned int where,
+ unsigned char val);
+extern int osscore_pci_write_config_word (dev_info_t * dip,
+ unsigned int where,
+ unsigned short val);
+extern int osscore_pci_write_config_dword (dev_info_t * dip,
+ unsigned int where,
+ unsigned int val);
+
+extern int osscore_pci_enable_msi (dev_info_t * dip);
+
+extern void *oss_map_pci_mem (oss_device_t * osdev, int size,
+ unsigned long offset);
+
+extern void oss_unmap_pci_mem (void *addr);
+
+extern int oss_copy_to_user (void *to, const void *from, unsigned long n);
+extern int oss_copy_from_user (void *to, const void *from, unsigned long n);
+
+extern void oss_register_module (struct module *mod);
+extern void oss_unregister_module (struct module *mod);
+
+#ifdef _KERNEL
+extern char *oss_strcpy (char *s1, const char *s2);
+#undef strcpy
+#define strcpy oss_strcpy
+
+extern void *oss_memcpy (void *t_, const void *f_, size_t l);
+#undef memcpy
+#define memcpy oss_memcpy
+
+extern void *oss_memset (void *t, int val, size_t l);
+#undef memset
+#define memset oss_memset
+
+extern int oss_strcmp (const char *s1, const char *s2);
+#undef strcmp
+#define strcmp oss_strcmp
+extern int oss_strncmp (const char *s1, const char *s2, size_t len);
+#undef strncmp
+#define strncmp oss_strncmp
+
+#undef strlen
+#define strlen oss_strlen
+
+#undef strncpy
+#define strncpy oss_strncpy
+#endif // KERNEL
+
+#undef timeout
+#define timeout oss_timeout
+
+#undef untimeout
+#define untimeout oss_untimeout
+
+#define drv_usecwait oss_udelay
+
+#define uiomove oss_uiomove
+
+#define cmn_err oss_cmn_err
+
+struct fileinfo
+{
+ int mode; /* Open mode */
+ int acc_flags;
+};
+#define ISSET_FILE_FLAG(fileinfo, flag) (fileinfo->acc_flags & (flag) ? 1:0)
+
+/*
+ * USB related definitions
+ */
+typedef struct udi_usb_devc udi_usb_devc;
+
+/*
+ * Functions exported by os.c
+ */
+extern int oss_init_osscore (oss_device_t * osdev);
+extern void oss_uninit_osscore (oss_device_t * osdev);
+extern void osdev_set_owner (oss_device_t * osdev, struct module *owner);
+extern void osdev_set_major (oss_device_t * osdev, int major);
+extern void osdev_set_irqparms (oss_device_t * osdev, void *irqparms);
+extern void *osdev_get_irqparms (oss_device_t * osdev);
+extern void oss_inc_intrcount(oss_device_t *osdev, int claimed);
+extern struct module *osdev_get_owner (oss_device_t * osdev);
+extern char *osdev_get_nick (oss_device_t * osdev);
+extern int osdev_get_instance (oss_device_t * osdev);
+extern int oss_request_major (oss_device_t * osdev, int major, char *module);
+extern int oss_register_device (oss_device_t * osdev, const char *name); /* from oss_config.h */
+
diff --git a/kernel/OS/SCO_SV/.config b/kernel/OS/SCO_SV/.config
new file mode 100644
index 0000000..816ac62
--- /dev/null
+++ b/kernel/OS/SCO_SV/.config
@@ -0,0 +1 @@
+mode=kernel
diff --git a/kernel/OS/SCO_SV/module.inc b/kernel/OS/SCO_SV/module.inc
new file mode 100644
index 0000000..8891691
--- /dev/null
+++ b/kernel/OS/SCO_SV/module.inc
@@ -0,0 +1,277 @@
+/*
+ * Purpose: OSS module wrapper for SCO OpenServer/UnixWare
+ *
+ * This file will be included from the auto-generated drv_cfg.c files. Under
+ * UnixWare and OpenServer this will will be compiled during the initial build
+ * of OSS (in the development system).
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 <errno.h>
+
+static int ossdrv_config (cfg_func_t func, void *idata, rm_key_t key);
+#if DRIVER_TYPE==DRV_VIRTUAL || DRIVER_TYPE==DRV_VMIX
+oss_device_t *osdev = NULL;
+#endif
+/*
+ * Driver information structures, for drv_attach().
+ */
+static const drvops_t oss_ops = {
+ ossdrv_config,
+ oss_open,
+ oss_close,
+ oss_devinfo,
+ oss_biostart,
+ oss_ioctl,
+ NULL, /* drvctl */
+ NULL /* mmap */
+};
+
+static const drvinfo_t oss_drvinfo = {
+ &oss_ops,
+ DRIVER_NICK,
+ D_MP, /* MP-safe */
+ NULL, /* Not a STREAMS driver */
+ 256 /* Must match $maxchan in Node file */
+};
+
+static int
+rd_hex (char *s)
+{
+/*
+ * Convert a 4 digit hexadecimal string to integer value
+ */
+ int v = 0;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ char c = *s++;
+
+ if (c >= '0' && c <= '9')
+ {
+ v = (v << 4) | (c - '0');
+ continue;
+ }
+
+ if (c >= 'A' && c <= 'F')
+ {
+ v = (v << 4) | (c - 'A' + 10);
+ continue;
+ }
+
+ if (c >= 'a' && c <= 'f')
+ {
+ v = (v << 4) | (c - 'a' + 10);
+ continue;
+ }
+ }
+
+ return v;
+}
+
+static int
+cfg_add (void *idata, rm_key_t key)
+{
+ int err;
+ cm_args_t cma;
+ cm_num_t btype;
+ char id[32];
+ int vendor, product;
+ static int instance = 0;
+ oss_device_t *osdev;
+
+ cm_begin_trans (key, RM_READ);
+ cma.cm_key = key;
+ cma.cm_param = CM_BRDBUSTYPE;
+ cma.cm_val = &btype;
+ cma.cm_vallen = sizeof (btype);
+ cma.cm_n = 0;
+ err = cm_getval (&cma);
+ cm_end_trans (key);
+
+ if (err != 0 || btype != CM_BUS_PCI)
+ {
+ cmn_err (CE_WARN, "Bad BUS type %d\n", btype);
+ return ENODEV;
+ }
+
+ if ((osdev =
+ osdev_create (&key, DRIVER_TYPE, instance, DRIVER_NICK, NULL)) == NULL)
+ {
+ return EIO;
+ }
+
+ cm_begin_trans (key, RM_READ);
+ cma.cm_key = key;
+ cma.cm_param = CM_BRDID;
+ cma.cm_val = id;
+ cma.cm_vallen = sizeof (id);
+ cma.cm_n = 0;
+ err = cm_getval (&cma);
+ cm_end_trans (key);
+
+ vendor = rd_hex (id + 2);
+ product = rd_hex (id + 6);
+
+ osdev->vendor = vendor;
+ osdev->product = product;
+ osdev->drvinfo = (drvinfo_t *) & oss_drvinfo;
+ osdev->key = key;
+
+ if (!DRIVER_ATTACH (osdev))
+ {
+ cmn_err (CE_WARN, "Attach failed\n");
+ osdev_delete (osdev);
+ return EIO;
+ }
+
+ *(void **) idata = osdev;
+ oss_audio_delayed_attach ();
+
+ instance++;
+
+ return 0;
+}
+
+static int
+cfg_remove (void *idata)
+{
+ oss_device_t *osdev = idata;
+
+ if (idata == NULL)
+ {
+ cmn_err (CE_WARN, DRIVER_NICK ": ossdrv_detach: dip==NULL\n");
+ return EIO;
+ }
+
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, DRIVER_NICK ": Bad idatata\n");
+ return 0;
+ }
+
+ if (DRIVER_DETACH (osdev) <= 0)
+ {
+ DDB (cmn_err (CE_WARN, "Driver busy - cannot detach\n"));
+ return EBUSY;
+ }
+
+ osdev_delete (osdev);
+
+ DDB (cmn_err (CE_CONT, "Detach done " DRIVER_NICK, "\n"));
+ return 0;
+}
+
+#if DRIVER_TYPE==DRV_VIRTUAL || DRIVER_TYPE==DRV_VMIX
+static int
+attach_virtual (void)
+{
+ DDB (cmn_err (CE_CONT, "Attach started " DRIVER_NICK "\n"));
+ if ((osdev =
+ osdev_create (NULL, DRIVER_TYPE, 0, DRIVER_NICK, NULL)) == NULL)
+ {
+ return EIO;
+ }
+
+ osdev->drvinfo = &oss_drvinfo;
+
+ if (!DRIVER_ATTACH (osdev))
+ {
+ cmn_err (CE_WARN, "Attach failed\n");
+ osdev_delete (osdev);
+ return EIO;
+ }
+
+ return 0;
+}
+
+static int
+detach_virtual (void)
+{
+ if (osdev == NULL)
+ {
+ return 0;
+ }
+
+ if (DRIVER_DETACH (osdev) <= 0)
+ {
+ DDB (cmn_err (CE_WARN, "Driver busy - cannot detach\n"));
+ return EBUSY;
+ }
+
+ osdev_delete (osdev);
+
+ return 0;
+}
+#endif
+
+static int
+ossdrv_config (cfg_func_t func, void *idata, rm_key_t key)
+{
+ switch (func)
+ {
+ case CFG_ADD:
+ return cfg_add (idata, key);
+ break;
+
+ case CFG_REMOVE:
+ return cfg_remove (idata);
+ break;
+
+ case CFG_VERIFY:
+ return 0;
+ break;
+
+ }
+
+ return EOPNOTSUPP;
+}
+
+/*
+ * Driver entry point routines
+ */
+
+int
+_load ()
+{
+ int err;
+
+ if ((err = drv_attach (&oss_drvinfo)) != 0)
+ {
+ cmn_err (CE_WARN, "drv_attach failed %d\n", err);
+ return err;
+ }
+
+#if DRIVER_TYPE==DRV_VIRTUAL || DRIVER_TYPE==DRV_VMIX
+ attach_virtual ();
+#endif
+
+ return 0;
+}
+
+int
+_unload ()
+{
+ extern volatile int oss_open_devices;
+
+ if (oss_open_devices > 0)
+ return EBUSY;
+
+#if DRIVER_TYPE==DRV_VIRTUAL || DRIVER_TYPE==DRV_VMIX
+ detach_virtual ();
+#endif
+
+ drv_detach (&oss_drvinfo);
+ return 0;
+}
diff --git a/kernel/OS/SCO_SV/os_sco.c b/kernel/OS/SCO_SV/os_sco.c
new file mode 100644
index 0000000..b5380ef
--- /dev/null
+++ b/kernel/OS/SCO_SV/os_sco.c
@@ -0,0 +1,1679 @@
+/*
+ * Purpose: Operating system abstraction functions for SCO OpenServer/UnixWare
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+#include <oss_pci.h>
+#include <sys/exec.h>
+#include <sys/user.h>
+#include <errno.h>
+
+/*
+ * MAX_CARDS must be larger than life. The system will panic if there are
+ * more sound devices (cards os sound chips) than MAX_CARDS.
+ */
+#define MAX_CARDS 32
+
+static oss_device_t *cards[MAX_CARDS];
+int oss_num_cards = 0;
+static int oss_expired = 0;
+
+volatile int oss_open_devices = 0;
+
+static bcb_t *oss_bcb;
+
+/*
+ * Driver information structures, for drv_attach().
+ */
+static int oss_config (cfg_func_t func, void *idata, rm_key_t key);
+
+static const drvops_t oss_ops = {
+ oss_config,
+ oss_open,
+ oss_close,
+ oss_devinfo,
+ oss_biostart,
+ oss_ioctl,
+ NULL, /* drvctl */
+ NULL /* mmap */
+};
+
+static const drvinfo_t oss_drvinfo = {
+ &oss_ops,
+ "osscore",
+ D_MP, /* MP-safe */
+ NULL, /* Not a STREAMS driver */
+ 10 /* Must match $maxchan in Node file */
+};
+
+static physreq_t *physreq_isa = NULL; /* 24 bits */
+static physreq_t *physreq_28bit = NULL;
+static physreq_t *physreq_30bit = NULL;
+static physreq_t *physreq_31bit = NULL;
+static physreq_t *physreq_32bit = NULL;
+
+#ifdef MEMDEBUG
+typedef struct
+{
+ void *addr;
+ int size;
+ char file[40];
+ int line;
+} mem_block_t;
+
+#define MAX_MEMBLOCKS 1024
+
+static mem_block_t memblocks[MAX_MEMBLOCKS];
+static int num_memblocks = 0;
+#endif
+
+#ifdef MEMDEBUG
+void *
+oss_kmem_alloc (size_t size, int flags, char *file, int line)
+#else
+void *
+oss_kmem_alloc (size_t size, int flags)
+#endif
+{
+/*
+ * This routine allocates a memory block and stores length of it in
+ * the beginning. This length information can be used when later unallocating
+ * the memory.
+ */
+
+ char *ptr;
+ uint64_t *len;
+
+ ptr = kmem_zalloc (size + sizeof (uint64_t), flags);
+#ifdef MEMDEBUG
+ cmn_err (CE_CONT, "kmalloc(%d, %s:%d)=%x\n", size, file, line, ptr);
+#endif
+
+ if (ptr == NULL)
+ return NULL;
+
+ len = (uint64_t *) ptr;
+
+ ptr += sizeof (uint64_t);
+ *len = size + sizeof (uint64_t);
+
+#ifdef MEMDEBUG
+#if 1
+ {
+ int i;
+ for (i = 0; i < num_memblocks; i++)
+ if (memblocks[i].addr == NULL)
+ {
+ memblocks[i].addr = ptr;
+ memblocks[i].size = size;
+ strncpy (memblocks[i].file, file, 39);
+ memblocks[i].line = line;
+ return ptr;
+ }
+ }
+#endif
+
+ if (num_memblocks < MAX_MEMBLOCKS)
+ {
+ memblocks[num_memblocks].addr = ptr;
+ memblocks[num_memblocks].size = size;
+ strncpy (memblocks[num_memblocks].file, file, 39);
+ memblocks[num_memblocks].line = line;
+ num_memblocks++;
+ }
+#endif
+
+ return ptr;
+}
+
+void
+#ifdef MEMDEBUG
+oss_kmem_free (void *addr, char *file, int line)
+#else
+oss_kmem_free (void *addr)
+#endif
+{
+ uint64_t *len;
+ int i;
+
+ char *ptr = addr;
+
+ if (addr == NULL)
+ return;
+
+ ptr -= sizeof (uint64_t);
+
+ len = (uint64_t *) ptr;
+
+ kmem_free (ptr, *len);
+#ifdef MEMDEBUG
+ {
+ int i;
+
+ for (i = 0; i < num_memblocks; i++)
+ if (addr == memblocks[i].addr)
+ {
+ memblocks[i].addr = NULL;
+ return;
+ }
+ }
+ cmn_err (CE_WARN, "Bad kfree(%x, %s:%d)\n", addr, file, line);
+#endif
+}
+
+/*
+ * Table for permanently allocated memory (to be freed by _fini)
+ */
+#define OSS_MAX_MEM 1024
+void *oss_mem_blocks[OSS_MAX_MEM];
+int oss_nblocks = 0;
+
+void *
+#ifdef MEMDEBUG
+oss_pmalloc (size_t size, char *file, int line)
+#else
+oss_pmalloc (size_t size)
+#endif
+{
+ void *mem_ptr;
+#ifdef MEMDEBUG
+ mem_ptr = (oss_mem_blocks[oss_nblocks] =
+ oss_kmem_alloc (size, KM_SLEEP, file, line));
+#else
+ mem_ptr = (oss_mem_blocks[oss_nblocks] = KERNEL_MALLOC (size));
+#endif
+
+ if (oss_nblocks <= OSS_MAX_MEM)
+ oss_nblocks++;
+ else
+ cmn_err (CE_NOTE, "Out of mem blocks\n");
+ return mem_ptr;
+}
+
+int
+__oss_alloc_dmabuf (int dev, dmap_p dmap, unsigned int alloc_flags,
+ oss_uint64_t maxaddr, int direction)
+{
+ void *p;
+ oss_native_word phaddr;
+ int size = 64 * 1024;
+ extern int dma_buffsize;
+
+ if (dma_buffsize > 16 && dma_buffsize <= 128)
+ size = dma_buffsize * 1024;
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+/*
+ * Some applications and virtual drivers need shorter buffer.
+ */
+ if (dmap->flags & DMAP_SMALLBUF)
+ {
+ size = SMALL_DMABUF_SIZE;
+ }
+ else if (dmap->flags & DMAP_MEDIUMBUF)
+ {
+ size = MEDIUM_DMABUF_SIZE;
+ }
+
+ if ((alloc_flags & DMABUF_SIZE_16BITS) && size > 32 * 1024)
+ size = 32 * 1024;
+
+ if ((p =
+ oss_contig_malloc (audio_engines[dev]->osdev, size, maxaddr,
+ &phaddr)) == NULL)
+ return OSS_ENOMEM;
+
+ dmap->dmabuf = p;
+ dmap->dmabuf_phys = phaddr;
+ dmap->buffsize = size;
+
+ return 0;
+}
+
+void
+oss_free_dmabuf (int dev, dmap_p dmap)
+{
+ if (dmap->dmabuf == NULL)
+ return;
+
+ oss_contig_free (audio_engines[dev]->osdev, dmap->dmabuf, dmap->buffsize);
+ dmap->dmabuf = NULL;
+ dmap->dmabuf_phys = 0;
+ dmap->buffsize = 0;
+}
+
+void *
+oss_contig_malloc (oss_device_t * osdev, int size, oss_uint64_t memlimit,
+ oss_native_word * phaddr)
+{
+ void *p = NULL;
+ physreq_t *preqp = physreq_32bit;
+ paddr32_t pa;
+
+ *phaddr = 0;
+
+ switch (memlimit)
+ {
+ case MEMLIMIT_ISA:
+ preqp = physreq_isa;
+ break;
+ case MEMLIMIT_28BITS:
+ preqp = physreq_28bit;
+ break;
+ case MEMLIMIT_30BITS:
+ preqp = physreq_30bit;
+ break;
+ case MEMLIMIT_31BITS:
+ preqp = physreq_31bit;
+ break;
+ case MEMLIMIT_32BITS:
+ preqp = physreq_32bit;
+ break;
+
+ default:
+ cmn_err (CE_WARN, "osscore: Bad DMA memlimit for %s\n", osdev->nick);
+ }
+
+ if ((p = kmem_alloc_phys (size, preqp, &pa, 0)) == NULL)
+ {
+ cmn_err (CE_WARN, "osscore: kmem_alloc_phys() failed\n");
+ return NULL;
+ }
+
+ *phaddr = pa;
+ return p;
+}
+
+void
+oss_contig_free (oss_device_t * osdev, void *p, int sz)
+{
+ if (p)
+ kmem_free (p, sz);
+}
+
+/*
+ * Wait queue support
+ */
+oss_wait_queue_t *
+oss_create_wait_queue (oss_device_t * osdev, const char *name)
+{
+ oss_wait_queue_t *q;
+
+ if ((q = KERNEL_MALLOC (sizeof (*q))) == NULL)
+ {
+ cmn_err (CE_WARN, "osscore: Cannot allocate memory for a wait queue\n");
+ return NULL;
+ }
+
+ memset (q, 0, sizeof (*q));
+
+ if ((q->sv = SV_ALLOC (KM_SLEEP)) == NULL)
+ {
+ cmn_err (CE_WARN,
+ "osscore: Cannot allocate synchronization variable\n");
+ return NULL;
+ }
+
+ return q;
+}
+
+void
+oss_reset_wait_queue (oss_wait_queue_t * wq)
+{
+ // NOP
+}
+
+void
+oss_remove_wait_queue (oss_wait_queue_t * wq)
+{
+ SV_DEALLOC (wq->sv);
+ KERNEL_FREE (wq);
+}
+
+static void
+sleep_timeout (caddr_t arg)
+{
+ oss_wait_queue_t *wq = (oss_wait_queue_t *) arg;
+
+ SV_BROADCAST (wq->sv, 0);
+}
+
+int
+oss_sleep (oss_wait_queue_t * wq, oss_mutex_t * mutex, int ticks,
+ oss_native_word * flags, unsigned int *status)
+{
+ timeout_id_t tid;
+
+ *status = 0;
+ wq->flags = 0;
+
+ if (wq == NULL)
+ {
+ cmn_err (CE_WARN, "osscore: Unallocated wait queue\n");
+ *status |= WK_SIGNAL;
+ return 1;
+ }
+ if (ticks > 0)
+ tid = timeout (sleep_timeout, wq, ticks);
+
+ /*
+ * Note SV_WAIT_SIG() will release the mutex/lock so we must re-acquire
+ * it before returning.
+ */
+#ifdef MUTEX_CHECKS
+ // Pop mutex because it will be released by SV_WAIT_SIG()
+ pop_mutex (*mutex, __FILE__, __LINE__);
+#endif
+ if (!SV_WAIT_SIG (wq->sv, prihi, *mutex)) /* Signal */
+ {
+ *status |= WK_SIGNAL;
+ wq->flags |= WK_WAKEUP; /* Needed to prevent false timeout messages */
+ }
+
+ MUTEX_ENTER_IRQDISABLE (*mutex, *flags);
+ if (ticks > 0 && (wq->flags & WK_WAKEUP))
+ untimeout (tid);
+
+ return (wq->flags & WK_WAKEUP);
+}
+
+int
+oss_register_poll (oss_wait_queue_t * wq, oss_mutex_t * mutex,
+ oss_native_word * flags, oss_poll_event_t * ev)
+{
+ // NOP: DDI8 doesn't support chpoll
+}
+
+void
+oss_wakeup (oss_wait_queue_t * wq, oss_mutex_t * mutex,
+ oss_native_word * flags, short events)
+{
+ wq->flags |= WK_WAKEUP;
+ SV_BROADCAST (wq->sv, 0);
+}
+
+void *
+oss_get_osid (oss_device_t * osdev)
+{
+ return osdev->osid;
+}
+
+static int
+grow_array(oss_device_t *osdev, oss_cdev_t ***arr, int *size, int element_size, int increment)
+{
+ oss_cdev_t **old=*arr, **new = *arr;
+ int old_size = *size;
+ int new_size = *size;
+
+ new_size += increment;
+
+ if ((new=PMALLOC(osdev, new_size * element_size))==NULL)
+ return 0;
+
+ memset(new, 0, new_size * element_size);
+ if (old != NULL)
+ memcpy(new, old, old_size * element_size);
+
+ *size = new_size;
+ *arr = new;
+
+ if (old != NULL)
+ PMFREE(osdev, old);
+
+ return 1;
+}
+
+void
+oss_install_chrdev (oss_device_t * osdev, char *name, int dev_class,
+ int instance, oss_cdev_drv_t * drv, int flags)
+{
+/*
+ * oss_install_chrdev creates a character device (minor). However if
+ * name==NULL the device will not be exported (made visible to userland
+ * clients).
+ */
+
+ int i, num;
+ oss_cdev_t *cdev = NULL;
+
+ if (dev_class != OSS_DEV_STATUS)
+ if (oss_expired && instance > 0)
+ return;
+/*
+ * Find if this dev_class&instance already exists (after previous module
+ * detach).
+ */
+
+ for (num = 0; num < oss_num_cdevs; num++)
+ if (oss_cdevs[num]->d == NULL) /* Unloaded driver */
+ if (oss_cdevs[num]->dev_class == dev_class
+ && oss_cdevs[num]->instance == instance)
+ {
+ cdev = oss_cdevs[num];
+ break;
+ }
+
+ if (cdev == NULL)
+ {
+ if (oss_num_cdevs >= OSS_MAX_CDEVS)
+ {
+ if (!grow_array(osdev, &oss_cdevs, &oss_max_cdevs, sizeof(oss_cdev_t*), 100))
+ {
+ cmn_err (CE_WARN, "Cannot allocate new minor numbers.\n");
+ return;
+ }
+ }
+
+ if ((cdev = PMALLOC (NULL, sizeof (*cdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate character device desc.\n");
+ return;
+ }
+ num = oss_num_cdevs++;
+ }
+
+ memset (cdev, 0, sizeof (*cdev));
+ cdev->dev_class = dev_class;
+ cdev->instance = instance;
+ cdev->d = drv;
+ cdev->osdev = osdev;
+ if (name != NULL)
+ strncpy (cdev->name, name, sizeof (cdev->name) - 1);
+ else
+ strcpy (cdev->name, "NONE");
+ cdev->name[sizeof (cdev->name) - 1] = 0;
+ oss_cdevs[num] = cdev;
+}
+
+int
+oss_find_minor (int dev_class, int instance)
+{
+ int i;
+
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->d != NULL && oss_cdevs[i]->dev_class == dev_class
+ && oss_cdevs[i]->instance == instance)
+ return i;
+
+ return OSS_EIO;
+}
+
+int
+oss_get_cardinfo (int cardnum, oss_card_info * ci)
+{
+/*
+ * Print information about a 'card' in a format suitable for /dev/sndstat
+ */
+
+ if (cardnum < 0 || cardnum >= oss_num_cards)
+ return OSS_ENXIO;
+
+ if (cards[cardnum]->name != NULL)
+ strncpy (ci->longname, cards[cardnum]->name, 128);
+ ci->shortname[127] = 0;
+
+ if (cards[cardnum]->nick != NULL)
+ strncpy (ci->shortname, cards[cardnum]->nick, 16);
+ ci->shortname[15] = 0;
+
+ if (cards[cardnum]->hw_info != NULL)
+ strncpy (ci->hw_info, cards[cardnum]->hw_info, sizeof (ci->hw_info) - 1);
+ ci->hw_info[sizeof (ci->hw_info) - 1] = 0;
+
+ return 0;
+}
+
+void
+oss_reserve_device (oss_device_t * osdev)
+{
+ osdev->refcount++;
+}
+
+void
+oss_unreserve_device (oss_device_t * osdev, int decrement)
+{
+ osdev->refcount--;
+ if (osdev->refcount < 0)
+ osdev->refcount = 0;
+}
+
+/*
+ * Some standard C library routines
+ */
+void *
+memset (void *t, int c, size_t l)
+{
+ int i;
+
+ if (t == NULL)
+ return NULL;
+
+ for (i = 0; i < l; i++)
+ ((char *) t)[i] = c;
+
+ return t;
+}
+
+void *
+memcpy (void *t, const void *s, size_t l)
+{
+ bcopy (s, t, l);
+ return t;
+}
+
+oss_device_t *
+osdev_create (dev_info_t * dip, int dev_type, int instance, const char *nick,
+ const char *handle)
+{
+ oss_device_t *osdev = NULL;
+ int i, err;
+ caddr_t addr;
+ dev_info_t ldip = 0;
+
+ if (dip == NULL)
+ dip = &ldip;
+
+ if (handle == NULL)
+ handle = nick;
+
+ /*
+ * Don't accept any more drivers if expired
+ */
+ if (oss_expired && oss_num_cards > 0)
+ return NULL;
+
+/*
+ * Check if a driver/device was reinserted
+ */
+ if (dip != &ldip) /* Not a virtual driver */
+ for (i = 0; i < oss_num_cards; i++)
+ {
+ if (!cards[i]->available && cards[i]->key == *dip)
+ {
+ osdev = cards[i];
+ break;
+ }
+ }
+
+ if (osdev == NULL)
+ {
+ if (oss_num_cards >= MAX_CARDS)
+ {
+ cmn_err (CE_WARN, "Too many OSS devices. At most %d permitted.\n",
+ MAX_CARDS);
+ return NULL;
+ }
+
+ if ((osdev = PMALLOC (NULL, sizeof (*osdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+
+ osdev->cardnum = oss_num_cards;
+ cards[oss_num_cards++] = osdev;
+ }
+ osdev->key = *dip;
+ osdev->osid = dip;
+ osdev->available = 1;
+ osdev->first_mixer = -1;
+ osdev->instance = instance;
+ osdev->dev_type = dev_type;
+ osdev->devc = NULL;
+ MUTEX_INIT (osdev, osdev->mutex, MH_GLOBAL);
+ sprintf (osdev->nick, "%s%d", nick, instance);
+ strcpy (osdev->modname, nick);
+
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ //pci_config_setup (dip, &osdev->pci_config_handle);
+ break;
+
+ case DRV_VIRTUAL:
+ case DRV_VMIX:
+ case DRV_STREAMS:
+ /* NOP */
+ break;
+
+ case DRV_USB:
+ /* NOP */
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Bad device type\n");
+ return NULL;
+ }
+
+/*
+ * Create the device handle
+ */
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ {
+ unsigned int subvendor = 0;
+ pci_read_config_dword (osdev, 0x2c, &subvendor);
+
+ sprintf (osdev->handle, "PCI%08x-%d", subvendor, instance);
+ }
+ break;
+
+#if 0
+ case DRV_USB:
+ sprintf (osdev->handle, "USB-%s%d", handle, instance);
+ break;
+#endif
+
+ default:
+ sprintf (osdev->handle, "%s%d", handle, instance);
+ }
+
+ return osdev;
+}
+
+oss_device_t *
+osdev_clone (oss_device_t * orig_osdev, int new_instance)
+{
+ oss_device_t *osdev;
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+ memcpy (osdev, orig_osdev, sizeof (*osdev));
+ osdev->dev_type = DRV_CLONE;
+ osdev->instance = new_instance;
+ sprintf (osdev->nick, "%s%d", orig_osdev->modname, new_instance);
+ sprintf (osdev->handle, "%s%d", orig_osdev->modname, new_instance);
+
+ return osdev;
+}
+
+void
+osdev_delete (oss_device_t * osdev)
+{
+ int i;
+
+ if (osdev == NULL)
+ return;
+
+ if (!osdev->available)
+ {
+ cmn_err (CE_WARN, "device %s, osdev already deleted\n", osdev->nick);
+ return;
+ }
+
+ osdev->available = 0;
+
+ switch (osdev->dev_type)
+ {
+ case DRV_PCI:
+ break;
+ }
+
+/*
+ * Mark all minor nodes for this module as invalid.
+ */
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->osdev == osdev)
+ {
+ oss_cdevs[i]->d = NULL;
+ oss_cdevs[i]->osdev = NULL;
+ strcpy (oss_cdevs[i]->name, "Removed device");
+ }
+ MUTEX_CLEANUP (osdev->mutex);
+}
+
+int
+oss_register_device (oss_device_t * osdev, const char *name)
+{
+ if ((osdev->name = PMALLOC (NULL, strlen (name) + 1)) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate memory for device name\n");
+ osdev->name = "Unknown device";
+ }
+ strcpy (osdev->name, name);
+ return 0;
+}
+
+int
+oss_disable_device (oss_device_t * osdev)
+{
+ int i;
+/*
+ * This routine should check if the device is ready to be unloaded (no devices are in use).
+ * If the device cannot be unloaded this routine must return OSS_EBUSY.
+ *
+ * If the device can be unloaded then disable any timers or other features that may cause the
+ * device to be called. Also mark the audio/midi/mixer/etc devices of this device to be disabled.
+ * However the interrupt handler should still stay enabled. The low level driver will call
+ * oss_unregister_interrupts() after it has cleared the interrupt enable register.
+ */
+ if (osdev->refcount > 0)
+ {
+ return OSS_EBUSY;
+ }
+
+/*
+ * Now mark all devices unavailable (for the time being)
+ */
+
+ for (i = 0; i < num_mixers; i++)
+ if (mixer_devs[i]->osdev == osdev)
+ {
+ mixer_devs[i]->unloaded = 1;
+ }
+
+ for (i = 0; i < num_mididevs; i++)
+ {
+ if (midi_devs[i]->osdev == osdev)
+ {
+ midi_devs[i]->unloaded = 1;
+ }
+ }
+
+ for (i = 0; i < num_audio_engines; i++)
+ if (audio_engines[i]->osdev == osdev)
+ {
+ audio_uninit_device (i);
+ }
+
+ return 0;
+}
+
+void
+oss_unregister_device (oss_device_t * osdev)
+{
+}
+
+#ifdef MUTEX_CHECKS
+static int oss_context = 0; /* 0=user context, 1=interrupt context */
+#endif
+
+static int
+ossintr (void *idata)
+{
+ oss_device_t *osdev = idata;
+ oss_native_word flags;
+#ifdef MUTEX_CHECKS
+ int saved_context;
+ saved_context = oss_context;
+ if (oss_context == 1)
+ cmn_err (CE_WARN, "Recursive interrupt\n");
+ oss_context = 1;
+#endif
+
+ MUTEX_ENTER_IRQDISABLE (osdev->mutex, flags);
+
+ if (!osdev->tophalf_handler (osdev))
+ {
+ MUTEX_EXIT_IRQRESTORE (osdev->mutex, flags);
+#ifdef MUTEX_CHECKS
+ oss_context = saved_context;
+#endif
+ return ISTAT_NONE;
+ }
+
+ if (osdev->bottomhalf_handler != NULL)
+ osdev->bottomhalf_handler (osdev);
+
+ MUTEX_EXIT_IRQRESTORE (osdev->mutex, flags);
+#ifdef MUTEX_CHECKS
+ oss_context = saved_context;
+#endif
+
+ return ISTAT_ASSERTED;
+}
+
+int
+oss_register_interrupts (oss_device_t * osdev, int intrnum,
+ oss_tophalf_handler_t top,
+ oss_bottomhalf_handler_t bottom)
+{
+ int err;
+
+ if (intrnum != 0)
+ {
+ cmn_err (CE_WARN, "Bad interrupt index (%d) for %s\n", intrnum,
+ osdev->name);
+ return OSS_EINVAL;
+ }
+
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "oss_register_interrupts: Bad osdev\n");
+ return OSS_EINVAL;
+ }
+
+ if (osdev->tophalf_handler != NULL || osdev->bottomhalf_handler != NULL)
+ {
+ cmn_err (CE_WARN, "Interrupts already registered for %s\n",
+ osdev->name);
+ return OSS_EINVAL;
+ }
+
+ if (top == NULL)
+ {
+ cmn_err (CE_WARN, "Bad interrupt handler for %s\n", osdev->name);
+ return OSS_EINVAL;
+ }
+
+ osdev->tophalf_handler = top;
+ osdev->bottomhalf_handler = bottom;
+ if (cm_intr_attach
+ (osdev->key, ossintr, osdev, osdev->drvinfo, &osdev->intr_cookie) == 0)
+ {
+ cmn_err (CE_WARN, "cm_intr_attach failed for %s\n", osdev->nick);
+ }
+
+ return 0;
+}
+
+void
+oss_unregister_interrupts (oss_device_t * osdev)
+{
+ if (osdev->intr_cookie != NULL)
+ cm_intr_detach (osdev->intr_cookie);
+ osdev->intr_cookie = NULL;
+}
+
+static char *
+ksprintn (ul, base, lenp)
+ register u_long ul;
+ register int base, *lenp;
+{ /* A long in base 8, plus NULL. */
+ static char buf[sizeof (long) * NBBY / 3 + 2];
+ register char *p;
+
+ p = buf;
+ do
+ {
+ *++p = "0123456789abcdef"[ul % base];
+ }
+ while (ul /= base);
+ if (lenp)
+ *lenp = p - buf;
+ return (p);
+}
+
+int
+oss_sprintf (char *buf, char *cfmt, ...)
+{
+ const char *fmt = cfmt;
+ register char *p, *bp;
+ register int ch, base;
+ unsigned long ul;
+ int lflag;
+ int count = 10;
+ va_list ap;
+
+ va_start (ap, fmt);
+ for (bp = buf;;)
+ {
+ while ((ch = *(unsigned char *) fmt++) != '%')
+ if ((*bp++ = ch) == '\0')
+ {
+ va_end (ap);
+ return ((bp - buf) - 1);
+ }
+
+ lflag = 0;
+ reswitch:
+ switch (ch = *(unsigned char *) fmt++)
+ {
+ case 'l':
+ lflag = 1;
+ goto reswitch;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ goto reswitch;
+
+ case 'c':
+ *bp++ = va_arg (ap, int);
+ break;
+
+ case 's':
+ p = va_arg (ap, char *);
+ while (*bp++ = *p++)
+ ;
+ --bp;
+ break;
+
+ case 'd':
+ ul = lflag ? va_arg (ap, long) : va_arg (ap, int);
+ if ((long) ul < 0)
+ {
+ *bp++ = '-';
+ ul = -(long) ul;
+ }
+ base = 10;
+ goto number;
+ break;
+
+ case 'o':
+ ul = lflag ? va_arg (ap, unsigned long) : va_arg (ap, unsigned int);
+ base = 8;
+ goto number;
+ break;
+
+ case 'u':
+ ul = lflag ? va_arg (ap, unsigned long) : va_arg (ap, unsigned int);
+ base = 10;
+ goto number;
+ break;
+
+ case 'x':
+ ul = lflag ? va_arg (ap, unsigned long) : va_arg (ap, unsigned int);
+ base = 16;
+ number:
+ for (p = (char *) ksprintn (ul, base, NULL); ch = *p--;)
+ *bp++ = ch;
+ break;
+
+ default:
+ *bp++ = '%';
+ if (lflag)
+ *bp++ = 'l';
+ /* FALLTHROUGH */
+
+ case '%':
+ *bp++ = ch;
+ }
+ }
+
+ /* va_end(ap); */
+}
+
+static physreq_t *
+build_physreq (int bits)
+{
+ physreq_t *pr;
+ long long tmp;
+
+ if ((pr = physreq_alloc (KM_SLEEP)) == NULL)
+ return NULL;
+
+ pr->phys_align = 4096;
+ pr->phys_boundary = 0;
+ pr->phys_dmasize = bits;
+ pr->phys_max_scgth = 0;
+ pr->phys_flags = PREQ_PHYSCONTIG;
+
+ if (physreq_prep (pr, KM_SLEEP) != B_TRUE)
+ {
+ cmn_err (CE_WARN, "osscore: physreq_prep failed\n");
+ }
+
+ return pr;
+}
+
+/*
+ * Driver info device file
+ */
+static int drvinfo_busy = 0;
+static int drvinfo_len = 0, drvinfo_ptr = 0;
+static char *drvinfo_buf = NULL;
+#define DRVINFO_SIZE 4096
+
+static int
+drvinfo_open (int dev, int dev_class, struct fileinfo *file,
+ int recursive, int open_flags, int *redirect)
+{
+ int i;
+
+ if (drvinfo_busy)
+ return OSS_EBUSY;
+ drvinfo_busy = 1;
+
+ if ((drvinfo_buf = KERNEL_MALLOC (DRVINFO_SIZE)) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate drvinfo buffer\n");
+ return OSS_ENOMEM;
+ }
+
+ drvinfo_len = 0;
+ drvinfo_ptr = 0;
+
+ for (i = 1; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->name[0] != 'N' || oss_cdevs[i]->name[1] != 'O' || oss_cdevs[i]->name[2] != 'N' || oss_cdevs[i]->name[3] != 'E') /* Not a dummy placeholder device */
+ if (DRVINFO_SIZE - drvinfo_len > 32)
+ {
+ char *s = drvinfo_buf + drvinfo_len;
+
+ drvinfo_len +=
+ oss_sprintf (s, "%s %s %d\n", oss_cdevs[i]->name,
+ oss_cdevs[i]->osdev->nick, i);
+
+ }
+
+ return 0;
+}
+
+static void
+drvinfo_close (int dev, struct fileinfo *file)
+{
+ KERNEL_FREE (drvinfo_buf);
+ drvinfo_buf = NULL;
+ drvinfo_len = 0;
+ drvinfo_ptr = 0;
+ drvinfo_busy = 0;
+}
+
+static int
+drvinfo_read (int dev, struct fileinfo *file, uio_t * buf, int count)
+{
+ /*
+ * Return at most 'count' bytes from the drvinfo_buf.
+ */
+ int l, c;
+
+ l = count;
+ c = drvinfo_len - drvinfo_ptr;
+
+ if (l > c)
+ l = c;
+ if (l <= 0)
+ return 0;
+
+ if (uiomove (&drvinfo_buf[drvinfo_ptr], l, UIO_READ, buf) != 0)
+ return OSS_EFAULT;
+ drvinfo_ptr += l;
+
+ return l;
+}
+
+static oss_cdev_drv_t drvinfo_cdev_drv = {
+ drvinfo_open,
+ drvinfo_close,
+ drvinfo_read
+};
+
+static void
+install_drvinfo (oss_device_t * osdev)
+{
+ oss_install_chrdev (osdev, "ossinfo", OSS_DEV_MISC, 0, &drvinfo_cdev_drv,
+ 0);
+}
+
+/*
+ * Driver entry point routines
+ */
+
+int
+_load ()
+{
+ int err = 0;
+ oss_device_t *osdev;
+ time_t t;
+
+ if ((err = drv_attach (&oss_drvinfo)) != 0)
+ {
+ cmn_err (CE_WARN, "drv_attach failed %d\n", err);
+ return err;
+ }
+
+#ifdef LICENSED_VERSION
+ if (drv_getparm (TIME, &t) != 0)
+ {
+ cmn_err (CE_WARN, "drv_getparm(TIME) failed\n");
+ return EBUSY;
+ }
+
+ if (!oss_license_handle_time (t))
+ {
+ cmn_err (CE_WARN, "This version of Open Sound System has expired\n");
+ cmn_err (CE_CONT,
+ "Please download the latest version from www.opensound.com\n");
+ oss_expired = 1;
+ }
+#endif
+
+ if ((osdev = osdev_create (NULL, DRV_VIRTUAL, 0, "oss", NULL)) == NULL)
+ {
+ cmn_err (CE_WARN, "Creating osdev failed\n");
+ return ENOMEM;
+ }
+
+/*
+ * Allocate physrec structures for various memory ranges. Remember to free them in the _load
+ * entry point.
+ */
+ physreq_isa = build_physreq (24);
+ physreq_28bit = build_physreq (28);
+ physreq_30bit = build_physreq (30);
+ physreq_31bit = build_physreq (31);
+ physreq_32bit = build_physreq (32);
+
+/*
+ * Create the BCB structure
+ */
+ oss_bcb = bcb_alloc (KM_SLEEP);
+ oss_bcb->bcb_addrtypes = BA_UIO;
+ oss_bcb->bcb_flags = 0;
+ oss_bcb->bcb_max_xfer = 0;
+ oss_bcb->bcb_granularity = 1;
+ oss_bcb->bcb_physreqp = physreq_32bit;
+ bcb_prep (oss_bcb, KM_SLEEP);
+
+ install_drvinfo (osdev);
+ oss_common_init (osdev);
+
+ oss_register_device (osdev, "OSS core services");
+
+ return 0;
+}
+
+int
+_unload ()
+{
+ int i;
+ static int already_unloaded = 0;
+
+ if (oss_open_devices > 0)
+ return EBUSY;
+ drv_detach (&oss_drvinfo);
+
+ if (already_unloaded)
+ return 0;
+ already_unloaded = 1;
+
+ oss_unload_drivers ();
+
+ physreq_free (physreq_isa);
+ physreq_free (physreq_28bit);
+ physreq_free (physreq_30bit);
+ physreq_free (physreq_31bit);
+ physreq_free (physreq_32bit);
+
+ bcb_free (oss_bcb);
+
+ for (i = 0; i < oss_nblocks; i++)
+ KERNEL_FREE (oss_mem_blocks[i]);
+ oss_nblocks = 0;
+
+ return 0;
+}
+
+void
+oss_pci_byteswap (oss_device_t * osdev, int mode)
+{
+ // NOP
+}
+
+void
+oss_pcie_init (oss_device_t * osdev, int flags)
+{
+ /* TODO: Should we do something? */
+}
+
+int
+pci_read_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char *val)
+{
+ *val = 0;
+ if (cm_read_devconfig (osdev->key, where, val, sizeof (*val)) ==
+ sizeof (*val))
+ return PCIBIOS_SUCCESSFUL;
+
+ return PCIBIOS_FAILED;
+}
+
+int
+pci_read_config_irq (oss_device_t * osdev, offset_t where, unsigned char *val)
+{
+ *val = 0;
+ if (cm_read_devconfig (osdev->key, where, val, sizeof (*val)) ==
+ sizeof (*val))
+ return PCIBIOS_SUCCESSFUL;
+
+ return PCIBIOS_FAILED;
+}
+
+
+int
+pci_read_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short *val)
+{
+ *val = 0;
+#if 1
+ if (cm_read_devconfig (osdev->key, where, val, sizeof (*val)) ==
+ sizeof (*val))
+ return PCIBIOS_SUCCESSFUL;
+#else
+ switch (where)
+ {
+ case PCI_VENDOR_ID:
+ *val = osdev->vendor;
+ return PCIBIOS_SUCCESSFUL;
+ break;
+
+ case PCI_DEVICE_ID:
+ *val = osdev->product;
+ return PCIBIOS_SUCCESSFUL;
+ break;
+
+ }
+
+#endif
+ return PCIBIOS_FAILED;
+}
+
+int
+pci_read_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int *val)
+{
+ *val = 0;
+ if (cm_read_devconfig (osdev->key, where, val, sizeof (*val)) ==
+ sizeof (*val))
+ return PCIBIOS_SUCCESSFUL;
+
+ return PCIBIOS_FAILED;
+}
+
+int
+pci_write_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char val)
+{
+ if (cm_write_devconfig (osdev->key, where, &val, sizeof (val)) ==
+ sizeof (val))
+ return PCIBIOS_SUCCESSFUL;
+
+ return PCIBIOS_FAILED;
+}
+
+int
+pci_write_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short val)
+{
+ if (cm_write_devconfig (osdev->key, where, &val, sizeof (val)) ==
+ sizeof (val))
+ return PCIBIOS_SUCCESSFUL;
+
+ return PCIBIOS_FAILED;
+}
+
+int
+pci_write_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int val)
+{
+ if (cm_write_devconfig (osdev->key, where, &val, sizeof (val)) ==
+ sizeof (val))
+ return PCIBIOS_SUCCESSFUL;
+
+ return PCIBIOS_FAILED;
+}
+
+/*
+ * Entry point routines
+ */
+static int
+oss_config (cfg_func_t func, void *idata, rm_key_t key)
+{
+ return EOPNOTSUPP;
+}
+
+int
+oss_devinfo (void *idata, channel_t channel, di_parm_t parm, void *valp)
+{
+ switch (parm)
+ {
+ case DI_MEDIA:
+ break;
+
+ case DI_SIZE:
+ break;
+
+ case DI_RBCBP:
+ *(bcb_t **) valp = oss_bcb;
+ return 0;
+ break;
+
+ case DI_WBCBP:
+ *(bcb_t **) valp = oss_bcb;
+ return 0;
+ break;
+
+ case DI_PHYS_HINT:
+ break;
+
+ }
+ return EOPNOTSUPP;
+}
+
+void
+oss_biostart (void *idata, channel_t channel, buf_t * bp)
+{
+ int dev = channel;
+ oss_cdev_t *cdev;
+ int count = bp->b_un.b_uio->uio_resid;
+ int retval;
+
+ if ((cdev = oss_cdevs[dev]) == NULL)
+ {
+ bioerror (bp, ENXIO);
+ biodone (bp);
+ return;
+ }
+
+ cdev->file.acc_flags = 0;
+
+ if (bp->b_flags & B_READ)
+ {
+ /* Read operation */
+ if (cdev->d->read == NULL)
+ {
+ bioerror (bp, ENXIO);
+ biodone (bp);
+ return;
+ }
+ retval =
+ cdev->d->read (cdev->instance, &cdev->file, bp->b_un.b_uio, count);
+ if (retval < 0)
+ bioerror (bp, -retval);
+ else if (retval < count)
+ bp->b_resid = count - retval;
+
+ biodone (bp);
+ return;
+ }
+
+ /* Write operation */
+ if (cdev->d->write == NULL)
+ {
+ bioerror (bp, ENXIO);
+ biodone (bp);
+ return;
+ }
+ retval =
+ cdev->d->write (cdev->instance, &cdev->file, bp->b_un.b_uio, count);
+ if (retval < 0)
+ bioerror (bp, -retval);
+ else if (retval < count)
+ bp->b_resid = count - retval;
+
+ biodone (bp);
+}
+
+int
+oss_open (void *idata, channel_t * channelp,
+ int open_flags, cred_t * crp, queue_t * q)
+{
+ oss_device_t *osdev;
+ int dev = *channelp, tmpdev;
+ oss_cdev_t *cdev;
+ int retval;
+
+ osdev = idata;
+
+ if (dev >= OSS_MAX_CDEVS)
+ return ENXIO;
+
+ if (dev >= oss_num_cdevs)
+ {
+ return ENODEV;
+ }
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return ENODEV;
+
+ if (cdev->d->open == NULL)
+ {
+ return ENODEV;
+ }
+
+ memset (&cdev->file, 0, sizeof (cdev->file));
+ cdev->file.mode = 0;
+ cdev->file.acc_flags = open_flags;
+
+ if (open_flags & FREAD && open_flags & FWRITE)
+ cdev->file.mode = OPEN_READWRITE;
+ else if (open_flags & FREAD)
+ cdev->file.mode = OPEN_READ;
+ else if (open_flags & FWRITE)
+ cdev->file.mode = OPEN_WRITE;
+
+ tmpdev = dev;
+ retval =
+ cdev->d->open (cdev->instance, cdev->dev_class, &cdev->file, 0, 0, &tmpdev);
+ *channelp = tmpdev;
+ dev = tmpdev;
+
+ if (retval < 0)
+ {
+ return -retval;
+ }
+
+ oss_open_devices++;
+ cdev->open_count++;
+
+ return 0;
+}
+
+int
+oss_close (void *idata, channel_t channel,
+ int oflags, cred_t * crp, queue_t * q)
+{
+ oss_cdev_t *cdev;
+ int dev;
+
+ dev = channel;
+
+ if (dev >= OSS_MAX_CDEVS)
+ return ENXIO;
+
+ if ((cdev = oss_cdevs[dev]) == NULL)
+ return ENXIO;
+
+ if (cdev->open_count == 0) /* Not opened */
+ return 0;
+
+ cdev->d->close (cdev->instance, &cdev->file);
+
+ oss_open_devices--;
+ cdev->open_count--;
+ return 0;
+}
+
+int
+oss_ioctl (void *idata, channel_t channel, int cmd, void *arg,
+ int oflags, cred_t * crp, int *rvalp)
+{
+ int dev = channel;
+ int retval;
+ int len = 0;
+ char localbuf[256]; /* All frequently used ioctl calls fit in 256 bytes */
+ char *buf = localbuf, *auxbuf = NULL;
+ oss_cdev_t *cdev;
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->ioctl == NULL)
+ return *rvalp = ENXIO;
+
+ if (oss_expired)
+ return *rvalp = ENODEV;
+
+ if (cmd & (SIOC_OUT | SIOC_IN))
+ {
+
+ len = __SIOC_SIZE (cmd);
+ if (len < 0)
+ len = 0;
+ if (len > sizeof (localbuf))
+ {
+ /*
+ * For the few largest ioctl calls we need to allocate an off-stack
+ * buffer because otherwise the kernel stack will overflow.
+ * This approach is slower but fortunately "sane" applications don't
+ * use these ioctl calls too frequently.
+ */
+ if ((auxbuf = KERNEL_MALLOC (len)) == NULL)
+ {
+ cmn_err (CE_WARN,
+ "Failed to allocate an ioctl buffer of %d bytes\n",
+ len);
+ return *rvalp = ENOMEM;
+ }
+ buf = auxbuf;
+ }
+
+ if ((cmd & SIOC_IN) && len > 0)
+ {
+ if (copyin ((char *) arg, buf, len) == -1)
+ {
+ if (auxbuf != NULL)
+ KERNEL_FREE (auxbuf);
+ return *rvalp = EFAULT;
+ }
+ }
+
+ }
+
+ retval = cdev->d->ioctl (cdev->instance, &cdev->file, cmd, (ioctl_arg) buf);
+
+ if ((cmd & SIOC_OUT) && len > 0)
+ {
+ if (copyout (buf, (char *) arg, len) == -1)
+ {
+ if (auxbuf != NULL)
+ KERNEL_FREE (auxbuf);
+ return *rvalp = EFAULT;
+ }
+ }
+
+ *rvalp = (((retval) < 0) ? -(retval) : 0);
+
+ if (auxbuf != NULL)
+ KERNEL_FREE (auxbuf);
+
+ return *rvalp;
+}
+
+#ifdef MUTEX_CHECKS
+
+typedef struct
+{
+ int active;
+ void *mutex;
+ const char *filename;
+ int line;
+ int context;
+} mutex_debug_t;
+
+static mutex_debug_t mutex_tab[1024];
+static int n_mutexes = 0;
+
+void
+push_mutex (void *mutex, const char *file, int line)
+{
+ int i, n = -1;
+//cmn_err(CE_CONT, "Push mutex %08x, %s:%d, context=%d\n", mutex, file, line, oss_context);
+
+ for (i = 0; n == -1 && i < n_mutexes; i++)
+ if (!mutex_tab[i].active)
+ n = i;
+ else
+ {
+ if (mutex_tab[i].mutex == mutex
+ && mutex_tab[i].context == oss_context)
+ {
+ cmn_err (CE_NOTE, "Mutex %08x already held\n", mutex);
+ cmn_err (CE_CONT, " Locked by %s:%d\n", mutex_tab[i].filename,
+ mutex_tab[i].line);
+ cmn_err (CE_CONT, " Acquire by %s:%d\n", file, line);
+ }
+ }
+
+ if (n == -1)
+ {
+ if (n_mutexes >= 1024)
+ {
+ cmn_err (CE_NOTE, "Mutex debug table full\n");
+ return;
+ }
+ n = n_mutexes++;
+ }
+
+ mutex_tab[n].active = 1;
+ mutex_tab[n].mutex = mutex;
+ mutex_tab[n].filename = file;
+ mutex_tab[n].line = line;
+ mutex_tab[n].context = oss_context;
+}
+
+void
+pop_mutex (void *mutex, const char *file, int line)
+{
+ int i;
+
+//cmn_err(CE_CONT, "Pop mutex %08x, %s:%d, context=%d\n", mutex, file, line, oss_context);
+ for (i = 0; i < n_mutexes; i++)
+ if (mutex_tab[i].active && mutex_tab[i].mutex == mutex
+ && mutex_tab[i].context == oss_context)
+ {
+ mutex_tab[i].active = 0;
+ mutex_tab[i].filename = file;
+ mutex_tab[i].line = line;
+ return;
+ }
+
+ cmn_err (CE_NOTE, "Mutex %08x not locked (%s:%d), context=%d\n",
+ mutex, file, line, oss_context);
+ for (i = 0; i < n_mutexes; i++)
+ if (mutex_tab[i].active == 0 && mutex_tab[i].mutex == mutex)
+ {
+ cmn_err (CE_CONT, " Previous unlock at %s:%d, context=%d\n",
+ mutex_tab[i].filename, mutex_tab[i].line,
+ mutex_tab[i].context);
+ }
+}
+
+void
+print_mutexes (void)
+{
+ int i, n = 0;
+
+ for (i = 0; i < n_mutexes; i++)
+ if (mutex_tab[i].active)
+ n++;
+
+ cmn_err (CE_CONT, "%d mutexes held\n", n);
+
+ for (i = 0; i < n_mutexes; i++)
+ if (mutex_tab[i].active)
+ cmn_err (CE_CONT, " %08x %s:%d\n", mutex_tab[i].mutex,
+ mutex_tab[i].filename, mutex_tab[i].line);
+}
+#endif
+
+int
+oss_get_procinfo(int what)
+{
+ // TODO
+
+ return OSS_EINVAL;
+}
diff --git a/kernel/OS/SCO_SV/os_sco.h b/kernel/OS/SCO_SV/os_sco.h
new file mode 100644
index 0000000..0d5d345
--- /dev/null
+++ b/kernel/OS/SCO_SV/os_sco.h
@@ -0,0 +1,408 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+/*
+ * Purpose: OS specific definitions for SCO OpenServer and SCO UnixWare (DDI8)
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define OS_VERSION "6"
+#define OpenServer
+
+#if (!defined(i386) && !defined(x86_64)) || defined(CONFIG_OSS_FIXDEPOINT)
+// Floating point is not supported or it's disabled
+#undef CONFIG_OSS_VMIX_FLOAT
+#endif
+
+#if 0
+// Enable kernel level debugging
+#define DEBUG
+/*
+ * NOTE! Virtual devices (such as vmix, imux and midiloop) cannot be used
+ * when OSS is compiled with _LOCKTEST. Such drivers will not pass
+ * deadlock detection because virtual drivers make calls to the audio
+ * core and other drivers that use lower hierarchy levels. For the
+ * reason the system will crash as soon as the virtual devices get used.
+ */
+#define _LOCKTEST
+#define MUTEX_CHECKS
+#undef MEMDEBUG
+#endif
+
+// Timing/tracing analysis stuff. This info can be read with the readtimings utility.
+
+#ifdef DEBUG
+#include <sys/debug.h>
+#endif
+
+#define VDEV_SUPPORT
+#define USE_DEVICE_SUBDIRS
+
+#define __inline__ inline
+#define __inline inline
+#define EXTERN_C extern "C"
+
+/*
+ * Do not export global parameters in oss_core_options.c since they will be
+ * handled in Space.c for osscore
+ */
+#define NO_GLOBAL_OPTIONS
+
+/*
+ * Disable support for per-application features such as /dev/dsp device
+ * selection based on command name. Requires working GET_PROCESS_NAME
+ * macro implementation.
+ */
+#undef APPLIST_SUPPORT
+
+/*
+ * Some integer types
+ */
+#if defined(amd64) || defined(sparc)
+typedef unsigned long long oss_native_word; /* Same as the address and status register size */
+#else
+typedef unsigned long oss_native_word; /* Same as the address and status register size */
+#endif
+
+typedef long long oss_int64_t; /* Signed 64 bit integer */
+typedef unsigned long long oss_uint64_t; /* Unsigned 64 bit integer */
+typedef unsigned long offset_t;
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/signal.h>
+#include <oss_errno.h>
+#include <sys/file.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/map.h>
+#include <sys/debug.h>
+#include <sys/kmem.h>
+#include <sys/cmn_err.h>
+#include <sys/open.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/ksynch.h>
+#include <sys/confmgr.h>
+#include <sys/cm_i386at.h>
+#include <sys/poll.h>
+
+/*
+ * ddi.h must be the last include
+ */
+#include <sys/ddi.h>
+
+#ifndef HZ
+extern int hz;
+#define HZ hz
+#endif
+#define OSS_HZ HZ
+
+/*
+ * Mutexes
+ */
+
+#ifdef _KERNEL
+typedef lock_t *oss_mutex_t;
+#else
+typedef int oss_mutex_t;
+#endif
+
+/* The soundcard.h could be in a nonstandard place so include it here. */
+#include "soundcard.h"
+
+typedef struct udi_usb_devc udi_usb_devc;
+typedef rm_key_t dev_info_t;
+
+struct _oss_device_t
+{
+#ifdef _KERNEL
+ int cardnum;
+ int dev_type;
+ int available;
+ int instance;
+ rm_key_t key;
+ drvinfo_t *drvinfo;
+ void *osid;
+ void *devc;
+ char *name;
+ char nick[16];
+ char modname[16];
+ char handle[32];
+ char *hw_info;
+ int num_audio_engines;
+ int num_audioplay, num_audiorec, num_audioduplex;
+ int num_mididevs;
+ int num_mixerdevs;
+ int num_loopdevs;
+ int first_mixer; /* This must be set to -1 by osdev_create() */
+
+ volatile int refcount; /* Nonzero means that the device is needed by some other (virtual) driver. */
+
+/* Interrupts */
+
+ void *intr_cookie; /* Returned by cm_intr_attach */
+ oss_tophalf_handler_t tophalf_handler;
+ oss_bottomhalf_handler_t bottomhalf_handler;
+ oss_mutex_t mutex;
+
+/* PCI configuration */
+ int vendor, product;
+#else
+ int dummy;
+#endif
+};
+
+/*
+ * Support for select()
+ */
+
+struct _oss_poll_event_t
+{
+ short events, revents;
+ struct pollhead *php;
+ int anyyet;
+};
+typedef struct _oss_poll_event_t oss_poll_event_t;
+
+#define ALLOW_SELECT
+#define SEL_IN 0
+#define SEL_OUT 1
+#define SEL_EX 0xffffffff
+
+/*
+ * Sleep/wakeup
+ */
+
+#ifdef _KERNEL
+struct oss_wait_queue
+{
+ sv_t *sv;
+ short pollevents;
+ volatile unsigned int flags;
+};
+#endif
+
+#define FP_SUPPORT
+
+#ifdef FP_SUPPORT
+typedef short fp_env_t[512];
+typedef unsigned int fp_flags_t[4];
+extern int oss_fp_check (void);
+extern void oss_fp_save (short *envbuf, fp_flags_t flags);
+extern void oss_fp_restore (short *envbuf, fp_flags_t flags);
+# define FP_SAVE(envbuf, flags) oss_fp_save(envbuf, flags)
+# define FP_RESTORE(envbuf, flags) oss_fp_restore(envbuf, flags)
+#endif
+
+/* Busy wait routine */
+#define oss_udelay drv_usecwait
+/* System wall timer access */
+#define GET_JIFFIES() TICKS()
+
+#ifdef MUTEX_CHECKS
+extern void push_mutex (void *mutex, const char *file, int line);
+extern void pop_mutex (void *mutex, const char *file, int line);
+extern void print_mutexes (void);
+#else
+#define push_mutex(a, b, c)
+#define pop_mutex(a, b, c)
+#endif
+
+#ifdef _LOCKTEST
+# define MUTEX_INIT(osdev, mutex, hier) \
+ {\
+ static LKINFO_DECL(mtx_name, __FILE__ ":" #mutex, 0);\
+ mutex=LOCK_ALLOC((uchar_t)(hier), pldisk, &mtx_name, KM_SLEEP);\
+ }
+#else
+# define MUTEX_INIT(osdev, mutex, hier) \
+ {\
+ mutex=LOCK_ALLOC((uchar_t)(hier), pldisk, NULL, KM_SLEEP);\
+ }
+#endif
+
+#define MUTEX_CLEANUP(mutex) LOCK_DEALLOC(mutex)
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) {push_mutex(mutex, __FILE__, __LINE__);flags=LOCK(mutex, pldisk);}
+#define MUTEX_ENTER(mutex, flags) {push_mutex(mutex, __FILE__, __LINE__);flags=LOCK(mutex, pldisk);}
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) {pop_mutex(mutex, __FILE__, __LINE__);UNLOCK(mutex, flags);}
+#define MUTEX_EXIT(mutex, flags) {pop_mutex(mutex, __FILE__, __LINE__);UNLOCK(mutex, flags);}
+
+/*
+ * Move bytes from the buffer which the application given in a
+ * write() call.
+ * offs is position relative to the beginning of the buffer in
+ * user space. The count is number of bytes to be moved.
+ */
+#define COPY_FROM_USER(target, source, offs, count) \
+ if (uiomove((target), count, UIO_WRITE, source)) { \
+ cmn_err(CE_WARN, "Bad copyin()!\n"); \
+ }
+/* Like COPY_FOM_USER but for writes. */
+#define COPY_TO_USER(target, offs, source, count) \
+ if (uiomove((source), count, UIO_READ, target)) { \
+ cmn_err(CE_WARN, "Bad copyout()!\n"); \
+ }
+
+/*
+ * INB() and OUTB() should be obvious. NOTE! The order of
+ * paratemeters of OUTB() is different than on some other
+ * operating systems.
+ */
+
+/* I/O Mapped devices */
+#define INB(o, p) inb(p)
+#define INW(o, p) inw(p)
+#define INL(o, p) inl(p)
+
+#define OUTB(o, v, p) outb(p,v)
+#define OUTW(o, v, p) outw(p,v)
+#define OUTL(o, v, p) outl(p,v)
+
+/* Memory Mapped devices */
+#define PCI_READB(osdev, addr) *(volatile unsigned char *)(addr)
+#define PCI_READW(osdev, addr) *(volatile unsigned short *)(addr)
+#define PCI_READL(osdev, addr) *(volatile unsigned int *)(addr)
+
+#define PCI_WRITEB(osdev, addr, data) *(volatile unsigned char *)(addr)=data
+#define PCI_WRITEW(osdev, addr, data) *(volatile unsigned short *)(addr)=data
+#define PCI_WRITEL(osdev, addr, data) *(volatile unsigned int *)(addr)=data
+
+#ifndef TRUE
+#define TRUE (1)
+#define FALSE (0)
+#endif
+
+/*
+ KERNEL_MALLOC() allocates requested number of memory and
+ KERNEL_FREE is used to free it.
+ These macros are never called from interrupt, in addition the
+ nbytes will never be more than 4096 bytes. Generally the driver
+ will allocate memory in blocks of 4k. If the kernel has just a
+ page level memory allocation, 4K can be safely used as the size
+ (the nbytes parameter can be ignored).
+*/
+#ifdef MEMDEBUG
+extern void *oss_kmem_alloc (size_t size, int flags, char *file, int line);
+extern void oss_kmem_free (void *addr, char *file, int line);
+# define KERNEL_MALLOC(nbytes) oss_kmem_alloc(nbytes, KM_SLEEP, __FILE__, __LINE__)
+# define KERNEL_FREE(addr) oss_kmem_free(addr, __FILE__, __LINE__)
+#else
+extern void *oss_kmem_alloc (size_t size, int flags);
+extern void oss_kmem_free (void *addr);
+# define KERNEL_MALLOC(nbytes) oss_kmem_alloc(nbytes, KM_SLEEP)
+# define KERNEL_FREE(addr) oss_kmem_free(addr)
+#endif
+
+typedef void *oss_dma_handle_t;
+
+extern void *oss_contig_malloc (oss_device_t * osdev, int sz,
+ oss_uint64_t memlimit,
+ oss_native_word * phaddr);
+extern void oss_contig_free (oss_device_t * osdev, void *p, int sz);
+extern oss_native_word oss_virt_to_bus (void *addr);
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(osdev, sz, memlimit, phaddr)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(osdev, p, sz)
+
+/*
+ * Timer macros
+ *
+ * These macros are obsolete and should not be used in any new code.
+ * Use the timeout mechanism (see the timeout(9F) Solaris man page).
+ */
+#define timeout(fn, arg, ticks) itimeout(fn, arg, ticks, pltimeout)
+typedef int timeout_id_t;
+#define DEFINE_TIMER(name, proc) static timeout_id_t name = 0
+#define REMOVE_TIMER(name, proc) {if (name != 0) untimeout(name);}
+#define INIT_TIMER(name,proc)
+typedef void (*timeout_func_t) (void *);
+#define ACTIVATE_TIMER(name, proc, time) \
+ name=timeout((timeout_func_t)proc, (void*)&name, time)
+
+#ifdef _KERNEL
+struct os_dma_params
+{
+ int state; /* 0=unavail, 1=avail, 2=busy */
+ oss_device_t *osdev;
+ void *orig_buf;
+
+ volatile int enabled, ignore;
+};
+#define OS_DMA_PARMS \
+ struct os_dma_params dma_parms;
+#endif
+#endif
+struct fileinfo
+{
+ int mode; /* Open mode */
+ int acc_flags;
+};
+#define ISSET_FILE_FLAG(fileinfo, flag) (fileinfo->acc_flags & (flag) ? 1:0)
+
+#define OSS_OS "SCO"
+#define OSS_OS_LONGNAME "SCO OpenServer/UnixWare"
+
+#undef DMA_TRY_PSEUDOINIT
+
+int get_dma_residue (int chn);
+void disable_dma (int chn);
+void enable_dma (int chn);
+
+typedef void (*softintr_func_t) (int);
+
+struct oss_softintr
+{
+ int id;
+ softintr_func_t func;
+ volatile int armed, running;
+};
+
+#undef ALLOW_BUFFER_MAPPING
+
+#undef SMALL_DMABUF_SIZE
+#define SMALL_DMABUF_SIZE (16*1024)
+
+extern int detect_trace;
+#define DDB(x) if (detect_trace) x
+
+#define MAP_PCI_IOADDR(osdev, nr, io) io
+#define MAP_PCI_MEM(osdev, ix, phaddr, size) devmem_mapin(osdev->key, ix, 0, size)
+#define UNMAP_PCI_MEM(osdev, ix, ph, virt, size) devmem_mapout(virt, size)
+#define UNMAP_PCI_IOADDR(osdev, ix) {}
+#define GET_PROCESS_PID(x) -1
+#define GET_PROCESS_NAME(x) NULL
+
+#define abs(x) ((x) >= 0 ? (x) : -(x))
+
+#ifdef _KERNEL
+extern void *oss_memset (void *s, int c, size_t n);
+#define memset oss_memset
+
+extern void *oss_memcpy (void *s1, const void *s2, size_t n);
+#define memcpy oss_memcpy
+int oss_sprintf (char *buf, char *cfmt, ...);
+#define sprintf oss_sprintf
+
+extern int oss_open (void *idata, channel_t * channelp,
+ int oflags, cred_t * crp, queue_t * q);
+extern int oss_close (void *idata, channel_t channel,
+ int oflags, cred_t * crp, queue_t * q);
+extern int oss_ioctl (void *idata, channel_t channel, int cmd, void *arg,
+ int oflags, cred_t * crp, int *rvalp);
+extern int oss_devinfo (void *idata, channel_t channel, di_parm_t parm,
+ void *valp);
+extern void oss_biostart (void *idata, channel_t channel, buf_t * bp);
+
+#endif
diff --git a/kernel/OS/SunOS/.config b/kernel/OS/SunOS/.config
new file mode 100644
index 0000000..816ac62
--- /dev/null
+++ b/kernel/OS/SunOS/.config
@@ -0,0 +1 @@
+mode=kernel
diff --git a/kernel/OS/SunOS/module.inc b/kernel/OS/SunOS/module.inc
new file mode 100644
index 0000000..a522492
--- /dev/null
+++ b/kernel/OS/SunOS/module.inc
@@ -0,0 +1,389 @@
+/*
+ * Purpose: OSS module wrapper for Solaris
+ *
+ * This file will be included from the auto-generated drv_cfg.c files. Under
+ * Solaris this file will be compiled in the development system.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 <sys/types.h>
+#include <sys/modctl.h>
+#include <sys/kmem.h>
+#include <sys/conf.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+
+static int ossdrv_getinfo (dev_info_t *, ddi_info_cmd_t, void *, void **);
+static int ossdrv_attach (dev_info_t *, ddi_attach_cmd_t);
+static int ossdrv_detach (dev_info_t *, ddi_detach_cmd_t);
+
+#ifdef OSS_POWER_MANAGE
+static int ossdrv_power (dev_info_t *, int component, int level);
+#endif
+
+/* Entry points structure */
+#if DRIVER_TYPE!=DRV_STREAMS
+
+static struct cb_ops ossdrv_cb_ops = {
+ oss_open,
+ oss_close,
+ nodev, /* not a block driver */
+ nodev, /* no print routine */
+ nodev, /* no dump routine */
+ oss_read,
+ oss_write,
+ oss_ioctl,
+#ifdef ALLOW_BUFFER_MAPPING
+ oss_devmap,
+#else
+ nodev, /* no devmap routine */
+#endif
+ nodev,
+ nodev, /* no segmap routine */
+ oss_chpoll, /* no chpoll routine */
+ ddi_prop_op,
+ 0, /* not a STREAMS driver */
+ D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
+ CB_REV
+};
+#else
+extern struct streamtab DRIVER_STR_INFO;
+
+struct cb_ops ossdrv_streams_cb_ops = {
+ nulldev,
+ nulldev,
+ nodev, /* not a block driver */
+ nodev, /* no print routine */
+ nodev, /* no dump routine */
+ nodev,
+ nodev,
+ nodev,
+ nodev, /* no devmap routine */
+ nodev,
+ nodev, /* no segmap routine */
+ nochpoll, /* no chpoll routine */
+ ddi_prop_op,
+ &DRIVER_STR_INFO, /* cb_str */
+ D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
+ CB_REV,
+ nodev, /* cb_aread */
+ nodev, /* cb_awrite */
+};
+#endif
+
+static struct dev_ops ossdrv_dev_ops = {
+ DEVO_REV, /* devo_rev */
+ 0, /* devo_refcnt */
+ ossdrv_getinfo, /* devo_getinfo */
+ nulldev, /* devo_identify - obsolete */
+#if DRIVER_TYPE==DRV_ISA
+ ossdrv_probe,
+#else
+ nulldev, /* devo_probe */
+#endif
+ ossdrv_attach, /* devo_attach */
+ ossdrv_detach, /* devo_detach */
+ nodev, /* devo_reset */
+#if DRIVER_TYPE==DRV_STREAMS
+ &ossdrv_streams_cb_ops, /* devi_cb_ops */
+#else
+ &ossdrv_cb_ops, /* devi_cb_ops */
+#endif
+ NULL, /* devo_bus_ops */
+#ifdef OSS_POWER_MANAGE
+ ossdrv_power
+#else
+ NULL /* devo_power */
+#endif
+};
+
+static struct modldrv ossdrv_modldrv = {
+ &mod_driverops, /* drv_modops */
+ "OSS " OSS_VERSION_STRING,
+ &ossdrv_dev_ops, /* drv_dev_ops */
+};
+
+static struct modlinkage ossdrv_modlinkage = {
+ MODREV_1, /* ml_rev */
+ (void *) &ossdrv_modldrv, /* ml_linkage */
+ NULL /* NULL terminates the list */
+};
+
+/*
+ * _init, _info, and _fini support loading and unloading the driver.
+ */
+int
+_init (void)
+{
+ int error;
+
+ error = mod_install (&ossdrv_modlinkage);
+
+ return error;
+}
+
+int
+_fini (void)
+{
+ int error;
+
+ error = mod_remove (&ossdrv_modlinkage);
+ return error;
+}
+
+int
+_info (struct modinfo *modinfop)
+{
+ int error;
+
+ error = mod_info (&ossdrv_modlinkage, modinfop);
+
+ return error;
+}
+
+/*ARGSUSED*/
+static int
+ossdrv_getinfo (dev_info_t * dontcare_dip, ddi_info_cmd_t cmd, void *arg,
+ void **result)
+{
+ dev_t dev;
+ register int error;
+ int instance;
+ dev_info_t *dip;
+#ifndef SOL9
+ oss_cdev_t *cdev;
+ int minor;
+
+ dev = (dev_t) arg;
+
+ minor = getminor (dev);
+
+ if (minor >= oss_num_cdevs)
+ {
+ *result = NULL;
+ return DDI_FAILURE;
+ }
+
+ if ((cdev = oss_cdevs[minor]) == NULL || cdev->osdev == NULL)
+ {
+ *result = NULL;
+ return DDI_FAILURE;
+ }
+
+ dip = cdev->osdev->dip;
+#else
+ dip = dontcare_dip;
+#endif
+
+ if (dip == NULL)
+ {
+ /* cmn_err (CE_WARN, "ossdrv_getinfo: dip==NULL\n"); */
+ return DDI_FAILURE;
+ }
+
+ instance = ddi_get_instance (dip);
+
+ switch (cmd)
+ {
+ case DDI_INFO_DEVT2DEVINFO:
+ *result = dip;
+ error = DDI_SUCCESS;
+ break;
+ case DDI_INFO_DEVT2INSTANCE:
+ *result = (void *) (long)instance;
+ error = DDI_SUCCESS;
+ break;
+ default:
+ *result = NULL;
+ error = DDI_FAILURE;
+ }
+
+ DDB (cmn_err (CE_CONT,
+ "oss_getinfo: returns %d, result=%lx instance=%d dev=%x\n",
+ error, (unsigned long)*result, instance, (unsigned int)dev));
+ return error;
+}
+
+static int
+ossdrv_attach (dev_info_t * dip, ddi_attach_cmd_t cmd)
+{
+ int instance;
+ oss_device_t *osdev;
+
+#ifdef OSS_SUSPEND_RESUME
+ if (cmd != DDI_RESUME) /* Allow resume */
+#endif
+ if (cmd != DDI_ATTACH)
+ {
+ cmn_err (CE_WARN, "bad attach cmd %d\n", cmd);
+ return 0;
+ }
+
+ if (dip == NULL)
+ {
+ cmn_err (CE_WARN, "ossdrv_attach: dip==NULL\n");
+ return DDI_FAILURE;
+ }
+
+#ifdef OSS_SUSPEND_RESUME
+ if (cmd == DDI_RESUME)
+ {
+ if ((osdev = (oss_device_t *) ddi_get_driver_private (dip)) == NULL)
+ {
+ cmn_err (CE_WARN, "ddi_get_driver_private() failed\n");
+ return DDI_SUCCESS;
+ }
+ if (!DRIVER_RESUME(osdev))
+ return DDI_FAILURE;
+
+ return DDI_SUCCESS;
+ }
+#endif
+
+ instance = ddi_get_instance (dip);
+ DDB (cmn_err
+ (CE_CONT, "Attach started " DRIVER_NICK "%d (%s)\n", instance,
+ ddi_get_name (dip)));
+
+ if ((osdev =
+ osdev_create (dip, DRIVER_TYPE, instance, DRIVER_NICK, NULL)) == NULL)
+ {
+ return DDI_FAILURE;
+ }
+
+ oss_load_options (osdev, oss_global_options);
+ oss_load_options (osdev, local_driver_options);
+
+#if DRIVER_TYPE==DRV_PCI || DRIVER_TYPE == DRV_ISA
+ {
+ int err;
+ if ((err =
+ ddi_get_iblock_cookie (dip, 0, &osdev->iblock_cookie)) != DDI_SUCCESS)
+ {
+ cmn_err (CE_WARN, "Cannot get iblock cookie (%d)\n", err);
+ return DDI_FAILURE;
+ }
+ }
+#else
+/* NOTE! The USB driver (actually udi.c) will call usb_get_data() to obtain */
+/* the iblock_cookie. There is no need to do that here. */
+ osdev->iblock_cookie = 0;
+#endif
+
+ if (!DRIVER_ATTACH (osdev))
+ {
+ cmn_err (CE_WARN, "Attach failed\n");
+ osdev_delete (osdev);
+ return DDI_FAILURE;
+ }
+
+ ddi_set_driver_private (dip, (caddr_t) osdev);
+ ddi_report_dev (dip);
+#if DRIVER_TYPE != DRV_USB
+ oss_audio_delayed_attach ();
+#endif
+
+ DDB (cmn_err (CE_CONT, "Attach done " DRIVER_NICK "%d\n", instance));
+
+ return DDI_SUCCESS;
+}
+
+static int
+ossdrv_detach (dev_info_t * dip, ddi_detach_cmd_t cmd)
+{
+ oss_device_t *osdev;
+
+#ifdef OSS_SUSPEND_RESUME
+ if (cmd != DDI_SUSPEND) /* Allow suspend */
+#endif
+ if (cmd != DDI_DETACH)
+ {
+ cmn_err (CE_WARN, "bad detach cmd %d\n", cmd);
+ return 0;
+ }
+
+ if (dip == NULL)
+ {
+ cmn_err (CE_WARN, "ossdrv_detach: dip==NULL\n");
+ return DDI_FAILURE;
+ }
+//cmn_err(CE_CONT, "Detach started " DRIVER_NICK "\n");
+
+ DDB (cmn_err
+ (CE_CONT, "Detach started " DRIVER_NICK "(%s)\n", ddi_get_name (dip)));
+ if ((osdev = (oss_device_t *) ddi_get_driver_private (dip)) == NULL)
+ {
+ cmn_err (CE_WARN, "ddi_get_driver_private() failed\n");
+ return DDI_SUCCESS;
+ }
+
+ if (osdev==NULL)
+ {
+ cmn_err (CE_WARN, "Driver osdev==NULL - cannot detach\n");
+ return DDI_FAILURE;
+ }
+
+#ifdef OSS_SUSPEND_RESUME
+ if (cmd == DDI_SUSPEND)
+ {
+ if (!DRIVER_SUSPEND(osdev))
+ return DDI_FAILURE;
+ return DDI_SUCCESS;
+ }
+#endif
+
+ if (DRIVER_DETACH (osdev) <= 0)
+ {
+ cmn_err (CE_WARN, "Driver busy - cannot detach\n");
+ return DDI_FAILURE;
+ }
+
+#if DRIVER_TYPE!=DRV_VMIX
+ osdev_delete (osdev);
+#endif
+
+ DDB (cmn_err (CE_CONT, "Detach done " DRIVER_NICK "\n"));
+ return DDI_SUCCESS;
+}
+
+#ifdef OSS_POWER_MANAGE
+static int
+ossdrv_power (dev_info_t *dip, int component, int level)
+{
+ oss_device_t *osdev;
+
+ if (dip == NULL)
+ {
+ cmn_err (CE_WARN, "ossdrv_detach: dip==NULL\n");
+ return DDI_FAILURE;
+ }
+
+ DDB (cmn_err
+ (CE_CONT, "ossdrv_power " DRIVER_NICK "(%s, %d, %d)\n", ddi_get_name (dip), component, level));
+ if ((osdev = (oss_device_t *) ddi_get_driver_private (dip)) == NULL)
+ {
+ cmn_err (CE_WARN, "ddi_get_driver_private() failed\n");
+ return DDI_SUCCESS;
+ }
+
+ if (osdev==NULL)
+ {
+ cmn_err (CE_WARN, "Driver osdev==NULL - cannot detach\n");
+ return DDI_FAILURE;
+ }
+
+ if (!DRIVER_POWER(osdev, component, level))
+ return DDI_FAILURE;
+
+ return DDI_SUCCESS;
+}
+#endif
diff --git a/kernel/OS/SunOS/os_solaris.c b/kernel/OS/SunOS/os_solaris.c
new file mode 100644
index 0000000..b4ceac3
--- /dev/null
+++ b/kernel/OS/SunOS/os_solaris.c
@@ -0,0 +1,2401 @@
+/*
+ * Purpose: Operating system abstraction functions for Solaris
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+#include <oss_pci.h>
+#if !defined(SOL9) && !defined(SOL8)
+#include <sys/sunldi.h>
+#endif
+#include <sys/mman.h>
+
+#if 1
+/*
+ * Some older DDI routines are used by OSS instead of the latest ones.
+ * In this way the same OSS binary can be run both under Sol10 and Sol11.
+ */
+uint16_t ddi_mem_get16 (ddi_acc_handle_t handle, uint16_t * host_addr);
+uint32_t ddi_mem_get32 (ddi_acc_handle_t handle, uint32_t * host_addr);
+void ddi_mem_put16 (ddi_acc_handle_t handle, uint16_t * dev_addr,
+ uint16_t value);
+void ddi_mem_put32 (ddi_acc_handle_t handle, uint32_t * dev_addr,
+ uint32_t value);
+int ddi_mem_alloc (dev_info_t * dip, ddi_dma_lim_t * limits, uint_t length,
+ uint_t flags, caddr_t * kaddrp, uint_t * real_length);
+void ddi_mem_free (caddr_t kaddr);
+#endif
+
+#if 0
+/* TODO: Disable this debugging stuff */
+unsigned char tmp_status = 0;
+# define UP_STATUS(v) OUTB(NULL, (tmp_status=tmp_status|(v)), 0x378)
+# define DOWN_STATUS(v) OUTB(NULL, (tmp_status=tmp_status&~(v)), 0x378)
+#else
+# define UP_STATUS(v)
+# define DOWN_STATUS(v)
+#endif
+
+static int oss_expired = 0;
+
+static oss_mutex_t osscore_mutex;
+
+#define TRC(x)
+#define TRC2(x)
+
+#define FIX_RET_VALUE(ret) (((ret)<0) ? -(ret) : 0)
+
+static volatile int open_devices = 0;
+static volatile int do_forceload = 0;
+static volatile int forceload_in_progress = 0;
+
+/*
+ * MAX_CARDS must be larger than life. The system will panic if there are
+ * more sound devices (cards os sound chips) than MAX_CARDS.
+ */
+#define MAX_CARDS 32
+
+static oss_device_t *cards[MAX_CARDS];
+int oss_num_cards = 0;
+
+int oss_detach_enabled = 0;
+
+#ifdef MUTEX_CHECKS
+static volatile int inside_intr = 0; /* For mutex debugging only */
+#endif
+
+/*
+ * These are the entry points into our driver that are called when the
+ * driver is loaded, during a system call, or in response to an interrupt.
+ */
+static int oss_getinfo (dev_info_t * dip, ddi_info_cmd_t infocmd, void *arg,
+ void **result);
+static int oss_attach (dev_info_t * dip, ddi_attach_cmd_t cmd);
+static int oss_detach (dev_info_t * dip, ddi_detach_cmd_t cmd);
+static void free_all_contig_memory (void);
+
+/*
+ * DMA memory management
+ */
+
+typedef struct contig_desc
+{
+ int is_special;
+ struct contig_desc *next;
+ unsigned char *first_addr, *last_addr;
+ unsigned long physaddr;
+ void *orig_buf;
+
+ oss_device_t *osdev;
+ ddi_dma_handle_t handle;
+ ddi_dma_handle_t dhandle;
+ ddi_acc_handle_t dma_acc_handle;
+ ddi_dma_cookie_t cookie;
+ ddi_dma_win_t win;
+ ddi_dma_seg_t seg;
+ size_t size;
+}
+contig_desc;
+
+static contig_desc *contig_list = NULL;
+
+#ifdef MEMDEBUG
+typedef struct
+{
+ void *addr;
+ int size;
+ char file[40];
+ int line;
+} mem_block_t;
+
+#define MAX_MEMBLOCKS 1024
+
+static mem_block_t memblocks[MAX_MEMBLOCKS];
+static int num_memblocks = 0;
+#endif
+
+#define CDEV_NUMHASH 79 // Prime number
+static oss_cdev_t *cdev_hash[CDEV_NUMHASH] = {NULL};
+#define compute_cdev_hash(dev_class, instance) (dev_class*13+instance) % CDEV_NUMHASH
+
+static void
+unlink_cdev_hash(oss_cdev_t *this_cdev)
+{
+ oss_cdev_t *cdev = cdev_hash[compute_cdev_hash(this_cdev->dev_class, this_cdev->instance)];
+
+ if (cdev == this_cdev) // First in the hash chain
+ {
+ cdev_hash[compute_cdev_hash(this_cdev->dev_class, this_cdev->instance)] = cdev->hl;
+ return;
+ }
+
+ while (cdev != NULL)
+ {
+ if (cdev->hl == this_cdev)
+ {
+ cdev->hl = this_cdev->hl;
+ return;
+ }
+
+ cdev = cdev->hl;
+ }
+
+ cmn_err(CE_WARN, "unlink_cdev_hash: Cannot find cdev %p\n", this_cdev);
+}
+
+#if 1
+/*
+ * Unfortunately this handy function is not safe (incompatibilities
+ * between kenel versions/builds). So let's hope it gets moved to
+ * the kernel.
+ */
+char *
+oss_get_procname (void) /* Return the command name of the current thread */
+{
+ return ttoproc (curthread)->p_user.u_comm;
+}
+#endif
+
+#ifdef MEMDEBUG
+void *
+oss_kmem_alloc (size_t size, int flags, char *file, int line)
+#else
+void *
+oss_kmem_alloc (size_t size, int flags)
+#endif
+{
+/*
+ * This routine allocates a memory block and stores length of it in
+ * the beginning. This length information can be used when later unallocating
+ * the memory.
+ */
+
+ char *ptr;
+ uint64_t *len;
+
+ ptr = kmem_zalloc (size + sizeof (uint64_t), flags);
+
+ if (ptr == NULL)
+ return NULL;
+
+ len = (uint64_t *) ptr;
+
+ ptr += sizeof (uint64_t);
+ *len = size + sizeof (uint64_t);
+
+#ifdef MEMDEBUG
+#if 1
+ {
+ int i;
+ for (i = 0; i < num_memblocks; i++)
+ if (memblocks[i].addr == NULL)
+ {
+ memblocks[i].addr = ptr;
+ memblocks[i].size = size;
+ strncpy (memblocks[i].file, file, 39);
+ memblocks[i].line = line;
+ return ptr;
+ }
+ }
+#endif
+
+ if (num_memblocks < MAX_MEMBLOCKS)
+ {
+ memblocks[num_memblocks].addr = ptr;
+ memblocks[num_memblocks].size = size;
+ strncpy (memblocks[num_memblocks].file, file, 39);
+ memblocks[num_memblocks].line = line;
+ num_memblocks++;
+ }
+#endif
+
+ return ptr;
+}
+
+void
+oss_kmem_free (void *addr)
+{
+ uint64_t *len;
+
+ char *ptr = addr;
+
+ if (addr == NULL)
+ return;
+
+ ptr -= sizeof (uint64_t);
+
+ len = (uint64_t *) ptr;
+
+ kmem_free (ptr, *len);
+#ifdef MEMDEBUG
+ {
+ int i;
+
+ for (i = 0; i < num_memblocks; i++)
+ if (addr == memblocks[i].addr)
+ {
+ memblocks[i].addr = NULL;
+ break;
+ }
+ }
+#endif
+}
+
+static const ddi_dma_attr_t dma_attr_pci = {
+ DMA_ATTR_V0, // Version
+ 0x00000000ULL, // Address low
+ 0xfffffff0ULL, // Address high
+ 0xffffffffULL, // Counter max
+ 1ULL, // Default byte align
+ 0x7f, // Burst size
+ 0x1, // Minimum xfer size
+ 0xffffffffULL, // Maximum xfer size
+ 0xffffffffULL, // Max segment size
+ 1, // S/G list length
+ 1, // Granularity
+ 0 // Flag
+};
+
+#if !defined(SOL9) && !defined(SOL8)
+static void
+forceload_drivers (dev_t dev, cred_t * credp)
+{
+/*
+ * This routine will be called whenever the first application tries
+ * to access OSS devices. It's purpose is to load all the drivers
+ * just in case they have not been loaded yet. In this way it's possible to
+ * guarantee that the audio device numbering doesn't change between
+ * reboots.
+ */
+ char path[20];
+
+ int i, err;
+ ldi_handle_t lh;
+ ldi_ident_t li;
+ DDB (cmn_err (CE_NOTE, "Forceloading OSS devices\n"));
+
+ if (ldi_ident_from_dev (dev, &li) != 0)
+ {
+ cmn_err (CE_NOTE, "ldi_ident_from_dev failed\n");
+ return;
+ }
+
+ if ((err = ldi_open_by_name ("/dev/sndstat", FWRITE, credp, &lh, li)) != 0)
+ {
+ if (err != ENODEV)
+ cmn_err (CE_NOTE, "Forceload error %d (/dev/sndstat)\n", err);
+ }
+ else
+ err = ldi_close (lh, FWRITE, credp);
+
+ for (i = 0; i < MAX_MIXER_DEV; i++)
+ {
+ sprintf (path, "/dev/mixer%d", i);
+
+ if ((err = ldi_open_by_name (path, FWRITE, credp, &lh, li)) != 0)
+ {
+ if (err != ENODEV)
+ cmn_err (CE_NOTE, "Forceload error %d\n", err);
+ }
+ else
+ err = ldi_close (lh, FWRITE, credp);
+ }
+
+ for (i = 0; i < MAX_AUDIO_DEVFILES; i++)
+ {
+ sprintf (path, "/dev/dsp%d", i);
+
+ if ((err = ldi_open_by_name (path, FWRITE, credp, &lh, li)) != 0)
+ {
+ if (err != ENODEV)
+ cmn_err (CE_NOTE, "Forceload error %d\n", err);
+ }
+ else
+ err = ldi_close (lh, FWRITE, credp);
+ }
+
+ ldi_ident_release (li);
+ DDB (cmn_err (CE_NOTE, "Forceloading OSS devices done\n"));
+}
+
+void
+oss_forceload_drivers (int dev, cred_t * cred_p)
+{
+
+ if (do_forceload)
+ {
+ do_forceload = 0;
+ forceload_in_progress = 1;
+ forceload_drivers (dev, cred_p);
+ forceload_in_progress = 0;
+ }
+}
+#endif
+
+/*ARGSUSED*/
+int
+oss_open (dev_t * dev_p, int open_flags, int otyp, cred_t * cred_p)
+{
+ int retval;
+ dev_t dev = *dev_p;
+ oss_cdev_t *cdev;
+ int tmpdev, maj;
+ oss_native_word flags;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("**** oss_open(%x) ****", getminor (dev));
+#endif
+//cmn_err(CE_CONT, "**** oss_open(%x) ****\n", getminor (dev));
+//cmn_err(CE_CONT, " PID %d, cmd %s\n", GET_PROCESS_PID(x), GET_PROCESS_NAME(x));
+ maj = getmajor (dev);
+ dev = getminor (dev);
+
+#if !defined(SOL9) && !defined(SOL8)
+/*
+ * Handle driver forceload
+ */
+
+ if (forceload_in_progress)
+ return ENODEV;
+
+ oss_forceload_drivers (dev, cred_p);
+#endif
+
+ if (dev >= OSS_MAX_CDEVS)
+ return ENXIO;
+
+ if (dev >= oss_num_cdevs)
+ {
+ return ENODEV;
+ }
+
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ return ENODEV;
+
+ if (cdev->d->open == NULL)
+ {
+ return ENODEV;
+ }
+
+ memset (&cdev->file, 0, sizeof (cdev->file));
+ cdev->file.mode = 0;
+ cdev->file.acc_flags = open_flags;
+
+ if (open_flags & FREAD && open_flags & FWRITE)
+ cdev->file.mode = OPEN_READWRITE;
+ else if (open_flags & FREAD)
+ cdev->file.mode = OPEN_READ;
+ else if (open_flags & FWRITE)
+ cdev->file.mode = OPEN_WRITE;
+
+ tmpdev = dev;
+ retval =
+ cdev->d->open (cdev->instance, cdev->dev_class, &cdev->file, 0, 0, &tmpdev);
+ *dev_p = makedevice (maj, tmpdev);
+ dev = tmpdev;
+
+ if (retval < 0)
+ {
+ return -retval;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (osscore_mutex, flags);
+ open_devices++;
+ cdev = oss_cdevs[dev]; /* Switch to the cdev that was actually opened */
+
+ cdev->open_count++;
+ if (open_flags & FREAD && open_flags & FWRITE)
+ cdev->file.mode = OPEN_READWRITE;
+ else if (open_flags & FREAD)
+ cdev->file.mode = OPEN_READ;
+ else if (open_flags & FWRITE)
+ cdev->file.mode = OPEN_WRITE;
+
+ oss_reserve_device (cdev->osdev);
+//cmn_err(CE_CONT, "Increment open_devices=%d, refcount=%d\n", open_devices, cdev->osdev->refcount);
+ MUTEX_EXIT_IRQRESTORE (osscore_mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+int
+oss_close (dev_t dev, int flag, int otyp, cred_t * cred_p)
+{
+ oss_cdev_t *cdev;
+ oss_native_word flags;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("***** oss_close(%x) ****", getminor (dev));
+#endif
+//cmn_err(CE_CONT, "***** oss_close(%x) ****\n", getminor (dev));
+//cmn_err(CE_CONT, " PID %d, cmd %s\n", GET_PROCESS_PID(x), GET_PROCESS_NAME(x));
+
+ if (getminor (dev) >= OSS_MAX_CDEVS)
+ {
+ cmn_err (CE_NOTE, "Closing bad minor %d\n", getminor (dev));
+ return ENXIO;
+ }
+
+ dev = getminor (dev);
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ {
+ cmn_err (CE_NOTE, "Closing undefined minor %d\n", getminor (dev));
+ return ENXIO;
+ }
+
+
+ if (cdev->open_count == 0) /* Not opened */
+ {
+ cmn_err (CE_NOTE, "Closing minor %d that is not open\n", dev);
+ return 0;
+ }
+
+ cdev->d->close (cdev->instance, &cdev->file);
+
+ MUTEX_ENTER_IRQDISABLE (osscore_mutex, flags);
+ open_devices -= cdev->open_count;
+//cmn_err(CE_CONT, "Decrement open_devices=%d\n", open_devices);
+ oss_unreserve_device (cdev->osdev, cdev->open_count);
+ cdev->open_count = 0;
+ MUTEX_EXIT_IRQRESTORE (osscore_mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+int
+oss_ioctl (dev_t dev, int cmd, intptr_t arg, int mode, cred_t * cred_p,
+ int *rval_p)
+{
+ int retval;
+ int len = 0;
+ char b[4096], *buf = b;
+ oss_cdev_t *cdev;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("OSS ioctl(%x, %x, %x)", getminor (dev), cmd, arg);
+#endif
+
+ *rval_p = 0;
+
+ dev = getminor (dev);
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->ioctl == NULL)
+ return ENXIO;
+
+ if (cdev->open_count == 0) /* Not opened */
+ {
+ cmn_err (CE_NOTE, "Call to ioctl on minor %d that is not open\n", dev);
+ return ENXIO;
+ }
+
+ if (oss_expired)
+ return ENODEV;
+
+ if (mode & FKIOCTL) /* Called from kernel space */
+ buf = (char *) arg;
+ else if (cmd & (SIOC_OUT | SIOC_IN))
+ {
+
+ len = (cmd >> 16) & SIOCPARM_MASK;
+ if (len < 0)
+ len = 0;
+ if (len > sizeof (b))
+ {
+ cmn_err (CE_WARN, "Bad ioctl buffer size %d\n", len);
+ return EFAULT;
+ }
+
+ if ((cmd & SIOC_IN) && len > 0)
+ {
+ if (copyin ((char *) arg, buf, len) == -1)
+ return EFAULT;
+ }
+
+ }
+
+ retval = cdev->d->ioctl (cdev->instance, &cdev->file, cmd, (ioctl_arg) buf);
+
+ if (!(mode & FKIOCTL)) /* Not called from kernel space */
+ if ((cmd & SIOC_OUT) && len > 0)
+ {
+ if (copyout (buf, (char *) arg, len) == -1)
+ return EFAULT;
+ }
+
+ return FIX_RET_VALUE (retval);
+}
+
+/*ARGSUSED*/
+int
+oss_read (dev_t dev, struct uio *uiop, cred_t * credp)
+{
+ int count = uiop->uio_resid;
+ int retval;
+ oss_cdev_t *cdev;
+
+ dev = getminor (dev);
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->read == NULL)
+ return ENXIO;
+
+ if (cdev->open_count == 0) /* Not opened */
+ {
+ cmn_err (CE_NOTE, "Call to read on minor %d that is not open\n", dev);
+ return ENXIO;
+ }
+
+ cdev->file.acc_flags = uiop->uio_fmode;
+
+ retval = cdev->d->read (cdev->instance, &cdev->file, uiop, count);
+
+ return FIX_RET_VALUE (retval);
+}
+
+/*ARGSUSED*/
+int
+oss_write (dev_t dev, struct uio *uiop, cred_t * cred_p)
+{
+ int count = uiop->uio_resid;
+ int retval;
+ oss_cdev_t *cdev;
+
+ dev = getminor (dev);
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->write == NULL)
+ return ENXIO;
+
+ if (cdev->open_count == 0) /* Not opened */
+ {
+ cmn_err (CE_NOTE, "Call to write on minor %d that is not open\n", dev);
+ return ENXIO;
+ }
+ cdev->file.acc_flags = uiop->uio_fmode;
+
+ retval = cdev->d->write (cdev->instance, &cdev->file, uiop, count);
+ return FIX_RET_VALUE (retval);
+}
+
+int
+oss_chpoll (dev_t dev, short events, int anyyet, short *reventsp,
+ struct pollhead **phpp)
+{
+ oss_cdev_t *cdev;
+ oss_poll_event_t ev;
+ int ret;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("***** oss_chpoll(%x) ****", getminor (dev));
+#endif
+
+ if (getminor (dev) >= OSS_MAX_CDEVS)
+ return ENXIO;
+
+ dev = getminor (dev);
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->chpoll == NULL)
+ return ENXIO;
+
+ if (cdev->open_count == 0) /* Not opened */
+ {
+ cmn_err (CE_NOTE, "Call to chpoll on minor %d that is not open\n", dev);
+ return ENXIO;
+ }
+
+ *reventsp = 0;
+ ev.events = events;
+ ev.anyyet = anyyet;
+ ev.revents = 0;
+ ev.php = NULL;
+
+ ret = cdev->d->chpoll (cdev->instance, &cdev->file, &ev);
+ if (ret < 0)
+ {
+ return -ret;
+ }
+
+ *reventsp |= ev.revents;
+ if (ev.php != NULL)
+ *phpp = ev.php;
+
+ return 0;
+}
+
+#ifdef ALLOW_BUFFER_MAPPING
+int
+oss_devmap (dev_t dev, devmap_cookie_t handle, offset_t off, size_t len,
+ size_t * maplen, uint_t model)
+{
+ oss_cdev_t *cdev;
+ oss_poll_event_t ev;
+ int ret;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("***** oss_devmap(%x) ****", getminor (dev));
+#endif
+
+ if (getminor (dev) >= OSS_MAX_CDEVS)
+ {
+ return ENXIO;
+ }
+
+ dev = getminor (dev);
+ if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
+ {
+ return ENXIO;
+ }
+
+ if (cdev->open_count == 0) /* Not opened */
+ {
+ cmn_err (CE_NOTE, "Call to devmap on minor %d that is not open\n", dev);
+ return EPERM;
+ }
+
+ if (cdev->dev_class != OSS_DEV_DSP && cdev->dev_class != OSS_DEV_DSP_ENGINE) /* Only audio devices can be mapped */
+ {
+ return ENXIO;
+ }
+
+ dev = cdev->instance;
+ if (dev < 0 || dev >= num_audio_engines)
+ return ENXIO;
+
+ return ENOTSUP;
+}
+#endif
+
+#if 0
+// Not used in misc modules.
+static struct cb_ops oss_cb_ops = {
+ oss_open,
+ oss_close,
+ nodev, /* not a block driver */
+ nodev, /* no print routine */
+ nodev, /* no dump routine */
+ oss_read,
+ oss_write,
+ oss_ioctl,
+#ifdef ALLOW_BUFFER_MAPPING
+ oss_devmap,
+#else
+ nodev, /* no devmap routine */
+#endif
+ nodev,
+ nodev, /* no segmap routine */
+ oss_chpoll, /* no chpoll routine */
+ ddi_prop_op,
+ 0, /* not a STREAMS driver */
+ D_NEW | D_MP | D_64BIT, /* safe for multi-thread/multi-processor */
+ CB_REV
+};
+
+static struct dev_ops oss_ops = {
+ DEVO_REV, /* DEVO_REV indicated by manual */
+ 0, /* device reference count */
+ oss_getinfo,
+ nulldev,
+ nulldev,
+ oss_attach,
+ oss_detach,
+ nodev, /* device reset routine */
+ &oss_cb_ops,
+ NULL, /* bus operations */
+ NULL /* TODO: Power management */
+};
+#endif
+
+extern struct mod_ops mod_miscops;
+static struct modldrv modldrv = {
+ &mod_miscops,
+ "Open Sound System " OSS_VERSION_STRING " framework"
+ // &oss_ops,
+};
+
+static struct modlinkage modlinkage = {
+ MODREV_1, /* MODREV_1 indicated by manual */
+ {(void *) &modldrv,
+ NULL} /* termination of list of linkage structures */
+};
+
+static ddi_device_acc_attr_t acc_attr_neverswap = {
+ DDI_DEVICE_ATTR_V0,
+ DDI_NEVERSWAP_ACC,
+ DDI_STRICTORDER_ACC
+};
+
+#ifdef OSS_BIG_ENDIAN
+static ddi_device_acc_attr_t acc_attr_le_swap = {
+ DDI_DEVICE_ATTR_V0,
+ DDI_STRUCTURE_LE_ACC,
+ DDI_STRICTORDER_ACC
+};
+#endif
+
+
+/*ARGSUSED*/
+static ddi_device_acc_attr_t *
+get_acc_attr (oss_device_t * osdev)
+{
+#ifdef OSS_BIG_ENDIAN
+ if (osdev->swap_mode == 1)
+ {
+ return &acc_attr_le_swap;
+ }
+ else
+#endif
+ {
+ return &acc_attr_neverswap;
+ }
+}
+
+void
+oss_load_options (oss_device_t * osdev, oss_option_map_t map[])
+{
+ int i, val;
+
+ for (i = 0; map[i].name != NULL; i++)
+ {
+ if ((val =
+ ddi_prop_get_int (DDI_DEV_T_ANY, osdev->dip,
+ DDI_PROP_NOTPROM,
+ map[i].name, -12345)) != -12345)
+ {
+ *map[i].ptr = val;
+ }
+ }
+}
+
+static int
+oss_attach (dev_info_t * dip, ddi_attach_cmd_t cmd)
+{
+ oss_device_t *osdev;
+
+ if (cmd != DDI_ATTACH)
+ {
+ cmn_err (CE_WARN, "oss_attach: Command %x\n", cmd);
+ return (DDI_FAILURE);
+ }
+
+ if ((osdev = osdev_create (dip, DRV_VIRTUAL, 0, "osscore", NULL)) == NULL)
+ {
+ cmn_err (CE_WARN, "Creating osdev failed\n");
+ return DDI_FAILURE;
+ }
+
+ MUTEX_INIT (osdev, osscore_mutex, 0);
+
+ oss_load_options (osdev, oss_global_options);
+
+ oss_common_init (osdev);
+
+ ddi_report_dev (dip);
+ oss_register_device (osdev, "OSS core services");
+
+ return (DDI_SUCCESS);
+}
+
+/*
+ * This is a pretty generic getinfo routine as describe in the manual.
+ */
+
+/*ARGSUSED*/
+static int
+oss_getinfo (dev_info_t * dip, ddi_info_cmd_t infocmd, void *arg,
+ void **result)
+{
+ dev_t dev;
+ register int error;
+ int instance;
+
+ dev = (dev_t) arg;
+ instance = getminor (dev) >> 4;
+
+ switch (infocmd)
+ {
+ case DDI_INFO_DEVT2DEVINFO:
+ *result = dip;
+ error = DDI_SUCCESS;
+ break;
+ case DDI_INFO_DEVT2INSTANCE:
+ *result = (void *) (uintptr_t) instance;
+ error = DDI_SUCCESS;
+ break;
+ default:
+ *result = NULL;
+ error = DDI_FAILURE;
+ }
+
+#if 0
+ DDB (cmn_err (CE_CONT,
+ "oss_getinfo: returns %d, result=%x minor=%d instance=%d dev=%x\n",
+ error, *result, minor_num, instance, dev));
+#endif
+ return (error);
+}
+
+/*
+ * _init, _info, and _fini support loading and unloading the driver.
+ */
+int
+_init (void)
+{
+ register int error = 0;
+ error = mod_install (&modlinkage);
+ return error;
+}
+
+int
+_info (struct modinfo *modinfop)
+{
+ return (mod_info (&modlinkage, modinfop));
+}
+
+int
+_fini (void)
+{
+ int status;
+
+#ifdef MEMDEBUG
+ int i;
+#endif
+
+ if ((status = mod_remove (&modlinkage)) != 0)
+ return (status);
+
+ free_all_contig_memory ();
+
+#ifdef MEMDEBUG
+ if (num_memblocks >= MAX_MEMBLOCKS)
+ cmn_err (CE_NOTE, "All memory allocations were not checked\n");
+
+ for (i = 0; i < num_memblocks; i++)
+ {
+ if (memblocks[i].addr != NULL)
+ {
+ cmn_err (CE_NOTE, "Memory leak in %s:%d\n",
+ memblocks[i].file, memblocks[i].line);
+ }
+ }
+#endif
+
+ return status;
+}
+
+/*
+ * When the osscore module is unloaded, oss_detach cleans up and frees the
+ * resources we allocated in oss_attach.
+ */
+static int
+oss_detach (dev_info_t * dip, ddi_detach_cmd_t cmd)
+{
+ static int already_unloaded = 0;
+
+ if (cmd != DDI_DETACH)
+ return DDI_FAILURE;
+
+ if (already_unloaded)
+ return DDI_SUCCESS;
+ already_unloaded = 1;
+//cmn_err(CE_CONT, "Oss detach\n");
+
+ /* instance = ddi_get_instance (dip); */
+
+ /*
+ * Remove the minor nodes created in attach
+ */
+ ddi_remove_minor_node (dip, NULL);
+
+ oss_unload_drivers ();
+
+ MUTEX_CLEANUP (osscore_mutex);
+
+ return (DDI_SUCCESS);
+}
+
+/*
+ * Some support routines
+ */
+void *
+memset (void *t, int c, size_t l)
+{
+ int i;
+
+ for (i = 0; i < l; i++)
+ ((char *) t)[i] = c;
+
+ return t;
+}
+
+#ifdef sparc
+/*
+ * I/O functions that do byte swapping (for Sparc)
+ */
+void
+oss_put16 (ddi_acc_handle_t handle, unsigned short *addr, unsigned short val)
+{
+ val = ((val >> 8) & 0xff) | ((val & 0xff) << 8);
+ ddi_put16 (handle, addr, val);
+}
+
+void
+oss_put32 (ddi_acc_handle_t handle, unsigned int *addr, unsigned int val)
+{
+#ifdef OSS_BIG_ENDIAN
+ val = ((val & 0x000000ff) << 24) |
+ ((val & 0x0000ff00) << 8) |
+ ((val & 0x00ff0000) >> 8) | ((val & 0xff000000) >> 24);
+#endif
+ ddi_put32 (handle, addr, val);
+}
+
+unsigned short
+oss_get16 (ddi_acc_handle_t handle, unsigned short *addr)
+{
+ unsigned short val;
+
+ val = ddi_get16 (handle, addr);
+#ifdef OSS_BIG_ENDIAN
+ val = ((val >> 8) & 0xff) | ((val & 0xff) << 8);
+#endif
+ return val;
+}
+
+unsigned int
+oss_get32 (ddi_acc_handle_t handle, unsigned int *addr)
+{
+ unsigned int val;
+
+ val = ddi_get32 (handle, addr);
+#ifdef OSS_BIG_ENDIAN
+ val = ((val & 0x000000ff) << 24) |
+ ((val & 0x0000ff00) << 8) |
+ ((val & 0x00ff0000) >> 8) | ((val & 0xff000000) >> 24);
+#endif
+ return val;
+}
+
+uint16_t
+oss_mem_get16 (ddi_acc_handle_t handle, uint16_t * addr)
+{
+ uint16_t val;
+
+ val = ddi_mem_get16 (handle, addr);
+#ifdef OSS_BIG_ENDIAN
+ val = ((val >> 8) & 0xff) | ((val & 0xff) << 8);
+#endif
+ return val;
+}
+
+uint32_t
+oss_mem_get32 (ddi_acc_handle_t handle, uint32_t * addr)
+{
+
+ uint32_t val;
+
+ val = ddi_mem_get32 (handle, addr);
+#ifdef OSS_BIG_ENDIAN
+ val = ((val & 0x000000ff) << 24) |
+ ((val & 0x0000ff00) << 8) |
+ ((val & 0x00ff0000) >> 8) | ((val & 0xff000000) >> 24);
+#endif
+ return val;
+}
+
+void
+oss_mem_put16 (ddi_acc_handle_t handle, uint16_t * addr, uint16_t val)
+{
+#ifdef OSS_BIG_ENDIAN
+ val = ((val >> 8) & 0xff) | ((val & 0xff) << 8);
+#endif
+
+ ddi_mem_put16 (handle, addr, val);
+}
+
+void
+oss_mem_put32 (ddi_acc_handle_t handle, uint32_t * addr, uint32_t val)
+{
+#ifdef OSS_BIG_ENDIAN
+ val = ((val & 0x000000ff) << 24) |
+ ((val & 0x0000ff00) << 8) |
+ ((val & 0x00ff0000) >> 8) | ((val & 0xff000000) >> 24);
+#endif
+ ddi_mem_put32 (handle, addr, val);
+}
+#endif
+
+void
+oss_pci_byteswap (oss_device_t * osdev, int mode)
+{
+ osdev->swap_mode = mode;
+}
+
+void
+oss_pcie_init (oss_device_t * osdev, int flags)
+{
+ /* TODO: Should we do something? */
+}
+
+/*ARGSUSED*/
+caddr_t
+oss_map_pci_ioaddr (oss_device_t * osdev, int nr, int io)
+{
+ caddr_t addr;
+ off_t region_size;
+ int err;
+ ddi_device_acc_attr_t *acc_attr;
+
+ if (nr >= OSS_MAX_ACC_HANDLE)
+ {
+ cmn_err(CE_WARN, "Too large I/O region number %d\n", nr);
+
+ return 0;
+ }
+
+ acc_attr = get_acc_attr (osdev);
+
+ if ((err =
+ ddi_dev_regsize (osdev->dip, nr + 1, &region_size)) != DDI_SUCCESS)
+ {
+ cmn_err (CE_WARN, "Getting device regsize failed (%d)\n", err);
+ return 0;
+ }
+
+ if ((err = ddi_regs_map_setup
+ (osdev->dip, nr + 1, &addr, 0, region_size, acc_attr,
+ &osdev->acc_handle[nr])) != DDI_SUCCESS)
+ {
+ cmn_err (CE_WARN, "Register setup failed (%d)\n", err);
+ return 0;
+ }
+
+ return addr;
+}
+
+void
+oss_unmap_pci_ioaddr(oss_device_t * osdev, int nr)
+{
+ if (nr >= OSS_MAX_ACC_HANDLE)
+ {
+ cmn_err(CE_WARN, "Too large I/O region number %d\n", nr);
+ return;
+ }
+
+ ddi_regs_map_free(&osdev->acc_handle[nr]);
+}
+
+int
+pci_read_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char *val)
+{
+ if (osdev->dev_type != DRV_PCI)
+ return PCIBIOS_FAILED;
+#if defined (sparc)
+ if (where == PCI_INTERRUPT_LINE)
+ *val = 7; /* PC emulation hack */
+ else
+#endif
+ *val = pci_config_get8 (osdev->pci_config_handle, where);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_read_config_irq (oss_device_t * osdev, offset_t where, unsigned char *val)
+{
+ int ret;
+
+ if (osdev->dev_type != DRV_PCI)
+ return PCIBIOS_FAILED;
+ ret = pci_read_config_byte (osdev, where, val);
+ return ret;
+}
+
+
+int
+pci_read_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short *val)
+{
+ if (osdev->dev_type != DRV_PCI)
+ return PCIBIOS_FAILED;
+ *val = pci_config_get16 (osdev->pci_config_handle, where);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_read_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int *val)
+{
+ if (osdev->dev_type != DRV_PCI)
+ return PCIBIOS_FAILED;
+ *val = pci_config_get32 (osdev->pci_config_handle, where);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_write_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char val)
+{
+ if (osdev->dev_type != DRV_PCI)
+ return PCIBIOS_FAILED;
+ pci_config_put8 (osdev->pci_config_handle, where, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_write_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short val)
+{
+ if (osdev->dev_type != DRV_PCI)
+ return PCIBIOS_FAILED;
+ pci_config_put16 (osdev->pci_config_handle, where, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pci_write_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int val)
+{
+ if (osdev->dev_type != DRV_PCI)
+ return PCIBIOS_FAILED;
+ pci_config_put32 (osdev->pci_config_handle, where, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+void *
+memcpy (void *t, const void *s, size_t l)
+{
+ bcopy (s, t, l);
+ return t;
+}
+
+#ifdef MEMDEBUG
+void *
+oss_contig_malloc (oss_device_t * osdev, int size, oss_uint64_t memlimit,
+ oss_native_word * phaddr, oss_dma_handle_t *dma_handle, char *file, int line)
+#else
+void *
+oss_contig_malloc (oss_device_t * osdev, int size, oss_uint64_t memlimit,
+ oss_native_word * phaddr, oss_dma_handle_t *dma_handle)
+#endif
+{
+/*
+ * Allocate physically contiguous memory (suitable for DMA).
+ *
+ * The memlimit parameter is equal to oss_alloc_dmabuf().
+ */
+ int err;
+#if defined(sparc)
+ uint_t len;
+#else
+ size_t len;
+#endif
+ uint_t count;
+ contig_desc *desc;
+ ddi_dma_attr_t dma_attr;
+ ddi_device_acc_attr_t *acc_attr;
+
+ int flags =
+ DDI_DMA_REDZONE | DDI_DMA_CONSISTENT | DDI_DMA_READ | DDI_DMA_WRITE;
+
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "oss_contig_malloc: osdev==NULL\n");
+ return NULL;
+ }
+
+ acc_attr = get_acc_attr (osdev);
+
+ memcpy (&dma_attr, &dma_attr_pci, sizeof (ddi_dma_attr_t));
+ dma_attr.dma_attr_addr_hi = memlimit;
+
+ desc = KERNEL_MALLOC (sizeof (contig_desc));
+ if (desc == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate contig buffer descriptor\n");
+ return NULL;
+ }
+
+ desc->osdev = osdev;
+ desc->next = NULL;
+ desc->is_special = 0;
+
+ if ((err = ddi_dma_alloc_handle (osdev->dip,
+ &dma_attr,
+ DDI_DMA_SLEEP,
+ NULL, &desc->dhandle)) != DDI_SUCCESS)
+ {
+ cmn_err (CE_WARN, "Failed to allocate pci DMA handle (%d)\n", err);
+ return NULL;
+ }
+
+ if (dma_handle != NULL)
+ *dma_handle = desc->dhandle;
+
+#ifndef IOMEM_DATA_UNCACHED
+#define IOMEM_DATA_UNCACHED 0 // Fix for Solaris 10
+#endif
+
+#if defined(sparc)
+ if ((err = ddi_mem_alloc (osdev->dip,
+ NULL,
+ size + 4096,
+ 0,
+ (caddr_t *) & desc->first_addr,
+ (uint_t *) & len)) != DDI_SUCCESS)
+
+
+#else
+ if ((err = ddi_dma_mem_alloc (desc->dhandle,
+ size + 4096,
+ acc_attr,
+ flags,
+ DDI_DMA_SLEEP,
+ NULL,
+ (caddr_t *) & desc->first_addr,
+ (size_t *) & len,
+ &desc->dma_acc_handle)) != DDI_SUCCESS)
+#endif
+ {
+ cmn_err (CE_WARN, "Failed to allocate %d bytes of contig memory (%d)\n",
+ size, err);
+ return NULL;
+
+ }
+
+ desc->size = len;
+ desc->orig_buf = desc->first_addr;
+
+ if (desc->first_addr == NULL)
+ {
+ cmn_err (CE_WARN, "Can't allocate a contig buffer\n");
+ return NULL;
+ }
+
+ DDB (cmn_err
+ (CE_CONT, "Allocated contig memory, addr=%x, len=%d\n",
+ (unsigned int) desc->first_addr, desc->size));
+
+ if ((err = ddi_dma_addr_bind_handle (desc->dhandle,
+ NULL,
+ (char *) desc->first_addr,
+ desc->size,
+ flags | DDI_DMA_STREAMING,
+ DDI_DMA_DONTWAIT,
+ NULL,
+ &desc->cookie, &count)) != DDI_SUCCESS)
+ {
+ cmn_err (CE_WARN, "Contig address setup failed (%d)\n", err);
+ return NULL;
+ }
+
+ desc->physaddr = desc->cookie.dmac_address;
+
+ desc->last_addr = desc->first_addr + desc->size - 1;
+ desc->first_addr =
+ (void *) (((unsigned long) desc->first_addr + 4095) & ~4095);
+ desc->physaddr = (desc->physaddr + 4095) & ~4095;
+ *phaddr = desc->physaddr;
+
+ desc->next = contig_list;
+ contig_list = desc;
+/* HW_PRINTF(("Alloc contig: %x-%x, ph=%x\n", desc->first_addr, desc->last_addr, desc->physaddr)); */
+
+ return desc->first_addr;
+}
+
+/*ARGSUSED*/
+void
+oss_contig_free (oss_device_t * osdev, void *p, int sz)
+{
+ int err;
+ contig_desc *d, *desc = NULL, *prev = NULL;
+
+ if (p == NULL)
+ return;
+
+ d = contig_list;
+
+ while (d && desc == NULL)
+ {
+ if (d->is_special)
+ {
+ prev = d;
+ d = d->next;
+ continue;
+ }
+
+ if (d->first_addr == p)
+ {
+ desc = d;
+ break;
+ }
+
+ prev = d;
+ d = d->next;
+ }
+
+ if (desc == NULL)
+ {
+ cmn_err (CE_WARN, "OSS: Can't free memory\n");
+ return;
+ }
+
+ if ((err = ddi_dma_unbind_handle (desc->dhandle)) != DDI_SUCCESS)
+ cmn_err (CE_WARN, "Failed to free DMA handle (%d)\n", err);
+
+#if defined(sparc)
+ ddi_mem_free (desc->orig_buf);
+#else
+ if (desc->dma_acc_handle == NULL)
+ cmn_err (CE_WARN, "desc->dma_acc_handle==NULL\n");
+ else
+ ddi_dma_mem_free (&desc->dma_acc_handle);
+#endif
+ ddi_dma_free_handle (&desc->dhandle);
+
+
+ if (desc == contig_list)
+ contig_list = desc->next;
+ else
+ {
+ prev->next = desc->next;
+ }
+ KERNEL_FREE (desc);
+
+}
+
+static void
+free_all_contig_memory (void)
+{
+ contig_desc *p, *desc = contig_list;
+
+ while (desc != NULL)
+ {
+ p = desc;
+ desc = desc->next;
+
+ if (p->is_special)
+ continue;
+
+ oss_contig_free (p->osdev, p->orig_buf, 0);
+ }
+
+ contig_list = NULL;
+}
+
+#if !defined(SOL9) && !defined(DISABLE_FMA)
+/*ARGSUSED*/
+static int
+oss_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *osdev_)
+{
+ pci_ereport_post(dip, err, NULL);
+ return err->fme_status;
+}
+#endif
+
+oss_device_t *
+osdev_create (dev_info_t * dip, int dev_type, int instance, const char *nick,
+ const char *handle)
+{
+ oss_device_t *osdev = NULL;
+ int i;
+ ddi_iblock_cookie_t iblk;
+ static int license_checked=0;
+
+#ifdef LICENSED_VERSION
+ if (!license_checked)
+ {
+ timestruc_t ts;
+
+ license_checked = 1;
+ gethrestime (&ts);
+ if (!oss_license_handle_time (ts.tv_sec))
+ {
+ cmn_err (CE_WARN, "This version of Open Sound System has expired\n");
+ cmn_err (CE_CONT,
+ "Please download the latest version from www.opensound.com\n");
+ oss_expired = 1;
+ }
+ }
+#endif
+
+ if (handle == NULL)
+ handle = nick;
+
+ /*
+ * Don't accept any more drivers if expired
+ */
+ if (oss_expired && oss_num_cards > 0)
+ return NULL;
+
+ /*
+ * Check if the same device is being reinserted.
+ */
+ for (i = 0; i < oss_num_cards; i++)
+ {
+ if (cards[i]->available) /* Not deleted */
+ continue;
+
+ if (cards[i]->dip == dip)
+ {
+ osdev = cards[i];
+ break;
+ }
+ }
+
+#if 1
+ if (osdev == NULL)
+ {
+ /*
+ * Check if there are some deleted devices.
+ */
+ for (i = 0; i < oss_num_cards; i++)
+ {
+ if (cards[i]->available) /* Not deleted */
+ continue;
+
+ osdev = cards[i];
+ break;
+ }
+ }
+#endif
+
+ if (osdev == NULL)
+ {
+ for (i=0;i<oss_num_cards;i++)
+ if (!cards[i]->available)
+ {
+ osdev = cards[i];
+ break;
+ }
+ }
+
+ if (osdev == NULL)
+ {
+ if (oss_num_cards >= MAX_CARDS)
+ {
+ cmn_err (CE_WARN, "Too many OSS devices. At most %d permitted.\n",
+ MAX_CARDS);
+ return NULL;
+ }
+
+ if ((osdev = PMALLOC (NULL, sizeof (*osdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+ memset (osdev, 0, sizeof (*osdev));
+
+ osdev->cardnum = oss_num_cards;
+ cards[oss_num_cards++] = osdev;
+ }
+
+ osdev->dip = dip;
+ osdev->osid = dip;
+ osdev->available = 1;
+ osdev->instance = instance;
+ osdev->dev_type = dev_type;
+ osdev->devc = NULL;
+ sprintf (osdev->nick, "%s%d", nick, instance);
+ strcpy (osdev->modname, nick);
+ osdev->num_audio_engines = 0;
+ osdev->num_audioplay = 0;
+ osdev->num_audiorec = 0;
+ osdev->num_audioduplex = 0;
+ osdev->num_mididevs = 0;
+ osdev->num_mixerdevs = 0;
+ osdev->first_mixer = -1;
+
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ if (pci_config_setup (dip, &osdev->pci_config_handle) != DDI_SUCCESS)
+ cmn_err (CE_NOTE, "pci_config_setup() failed\n");
+#if !defined(SOL9) && !defined(DISABLE_FMA)
+ osdev->fm_capabilities = DDI_FM_EREPORT_CAPABLE | DDI_FM_DMACHK_CAPABLE |
+ DDI_FM_ERRCB_CAPABLE;
+ ddi_fm_init(dip, &osdev->fm_capabilities, &iblk);
+ ddi_fm_handler_register(dip, oss_fm_error_cb, (void*)osdev);
+ pci_ereport_setup(dip);
+#endif
+ break;
+
+ case DRV_VIRTUAL:
+ case DRV_VMIX:
+ case DRV_STREAMS:
+#if !defined(SOL9) && !defined(DISABLE_FMA)
+ osdev->fm_capabilities=DDI_FM_EREPORT_CAPABLE;
+ ddi_fm_init(dip, &osdev->fm_capabilities, &iblk);
+#endif
+ break;
+
+ case DRV_USB:
+ /* NOP */
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Bad device type\n");
+ return NULL;
+ }
+
+/*
+ * Create the device handle
+ */
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ {
+ unsigned int subvendor;
+ pci_read_config_dword (osdev, 0x2c, &subvendor);
+
+ sprintf (osdev->handle, "PCI%08x-%d", subvendor, instance);
+ }
+ break;
+
+ case DRV_USB:
+ /* TODO: Get the vendor information */
+ sprintf (osdev->handle, "USB-%s%d", handle, instance);
+ break;
+
+ default:
+ sprintf (osdev->handle, "%s%d", handle, instance);
+ }
+
+ return osdev;
+}
+
+oss_device_t *
+osdev_clone (oss_device_t * orig_osdev, int new_instance)
+{
+ oss_device_t *osdev;
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+ memcpy (osdev, orig_osdev, sizeof (*osdev));
+ osdev->dev_type = DRV_CLONE;
+ osdev->instance = new_instance;
+ sprintf (osdev->nick, "%s%d", orig_osdev->modname, new_instance);
+ sprintf (osdev->handle, "%s%d", orig_osdev->modname, new_instance);
+
+ return osdev;
+}
+
+void
+osdev_delete (oss_device_t * osdev)
+{
+ int i;
+
+ if (osdev == NULL)
+ return;
+
+ if (!osdev->available) /* Already deleted */
+ return;
+
+ osdev->available = 0;
+
+ switch (osdev->dev_type)
+ {
+ case DRV_PCI:
+#if !defined(SOL9) && !defined(DISABLE_FMA)
+ ddi_fm_handler_unregister(osdev->dip);
+ pci_ereport_teardown(osdev->dip);
+#endif
+ pci_config_teardown (&osdev->pci_config_handle);
+#if !defined(SOL9) && !defined(DISABLE_FMA)
+ ddi_fm_fini(osdev->dip);
+#endif
+ osdev->pci_config_handle = NULL;
+ break;
+
+ case DRV_VIRTUAL:
+ case DRV_VMIX:
+ case DRV_STREAMS:
+#if !defined(SOL9) && !defined(DISABLE_FMA)
+ ddi_fm_fini(osdev->dip);
+#endif
+ break;
+ }
+
+ ddi_remove_minor_node (osdev->dip, NULL);
+
+/*
+ * Mark all minor nodes for this module as invalid.
+ */
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i] != NULL)
+ if (oss_cdevs[i]->osdev == osdev)
+ {
+ unlink_cdev_hash(oss_cdevs[i]);
+ oss_cdevs[i]->d = NULL;
+ oss_cdevs[i]->osdev = NULL;
+ oss_cdevs[i]->active = 0; /* Device removed */
+ }
+}
+
+int
+oss_get_cardinfo (int cardnum, oss_card_info * ci)
+{
+/*
+ * Print information about a 'card' in a format suitable for /dev/sndstat
+ */
+
+ if (cardnum < 0 || cardnum >= oss_num_cards)
+ return OSS_ENXIO;
+
+ if (cards[cardnum]->name != NULL)
+ strncpy (ci->longname, cards[cardnum]->name, 128);
+ ci->shortname[127] = 0;
+
+ if (cards[cardnum]->nick != NULL)
+ strncpy (ci->shortname, cards[cardnum]->nick, 16);
+ ci->shortname[15] = 0;
+
+ if (cards[cardnum]->hw_info != NULL)
+ strncpy (ci->hw_info, cards[cardnum]->hw_info, sizeof (ci->hw_info) - 1);
+ ci->hw_info[sizeof (ci->hw_info) - 1] = 0;
+ ci->intr_count = cards[cardnum]->intrcount;
+ ci->ack_count = cards[cardnum]->ackcount;
+
+ return 0;
+}
+
+static int
+grow_array(oss_device_t *osdev, oss_cdev_t ***arr, int *size, int element_size, int increment)
+{
+ oss_cdev_t **old=*arr, **new = *arr;
+ int old_size = *size;
+ int new_size = *size;
+
+ new_size += increment;
+
+ if ((new=PMALLOC(osdev, new_size * element_size))==NULL)
+ return 0;
+
+ memset(new, 0, new_size * element_size);
+ if (old != NULL)
+ memcpy(new, old, old_size * element_size);
+
+ *size = new_size;
+ *arr = new;
+
+ if (old != NULL)
+ PMFREE(osdev, old);
+
+ return 1;
+}
+
+/*ARGSUSED*/
+void
+oss_install_chrdev (oss_device_t * osdev, char *name, int dev_class,
+ int instance, oss_cdev_drv_t * drv, int flags)
+{
+/*
+ * oss_install_chrdev creates a character device (minor). However if
+ * name==NULL the device will not be exported (made visible to userland
+ * clients).
+ */
+
+ int num;
+ int hash_link;
+ oss_cdev_t *cdev = NULL;
+
+ if (dev_class != OSS_DEV_STATUS)
+ if (oss_expired && instance > 0)
+ return;
+/*
+ * Find if this dev_class&instance already exists (after previous module
+ * detach).
+ */
+
+ if (flags & CHDEV_REPLUG)
+ for (num = 0; num < oss_num_cdevs; num++)
+ if (oss_cdevs[num]->d == NULL) /* Unloaded driver */
+ if (oss_cdevs[num]->dev_class == dev_class
+ && oss_cdevs[num]->instance == instance)
+ {
+ cdev = oss_cdevs[num];
+ break;
+ }
+
+ if (cdev == NULL)
+ {
+ if (oss_num_cdevs >= OSS_MAX_CDEVS)
+ {
+ if (!grow_array(osdev, &oss_cdevs, &oss_max_cdevs, sizeof(oss_cdev_t*), 100))
+ {
+ cmn_err (CE_WARN, "Cannot allocate new minor numbers.\n");
+ return;
+ }
+ }
+
+ if ((cdev = PMALLOC (NULL, sizeof (*cdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate character device desc.\n");
+ return;
+ }
+ num = oss_num_cdevs++;
+ }
+
+ memset (cdev, 0, sizeof (*cdev));
+ cdev->dev_class = dev_class;
+ cdev->instance = instance;
+ cdev->d = drv;
+ cdev->active = 1;
+ cdev->osdev = osdev;
+ if (name != NULL)
+ strncpy (cdev->name, name, sizeof (cdev->name) - 1);
+ else
+ strcpy (cdev->name, "NONE");
+ cdev->name[sizeof (cdev->name) - 1] = 0;
+ oss_cdevs[num] = cdev;
+
+ cdev->minor = num;
+
+ /*
+ * Add to the cdev_hash list.
+ */
+ hash_link = compute_cdev_hash (dev_class, instance);
+ cdev->hl = cdev_hash[hash_link];
+ cdev_hash[hash_link] = cdev;
+
+/*
+ * Export the device only if name != NULL
+ */
+ if (name != NULL)
+ {
+ char tmp[64], *s;
+ char *dev_type = "oss_sysdev";
+
+/*
+ * Convert "oss/device/node" style names to the
+ * "device,node" style naming required by Solaris.
+ */
+ if (name[0] == 'o' && name[3] == '/') /* oss/ prefix */
+ {
+ strcpy (tmp, name + 4);
+ name = tmp;
+
+ s = tmp;
+ while (*s)
+ {
+ if (*s == '/')
+ *s = ',';
+ s++;
+ }
+ dev_type = "oss_audio";
+ }
+
+ if (ddi_create_minor_node (osdev->dip, name, S_IFCHR, num,
+ dev_type, 0) == DDI_FAILURE)
+ {
+ cmn_err (CE_WARN, "ddi_create_minor_node failed\n");
+ }
+ }
+}
+
+int
+oss_find_minor (int dev_class, int instance)
+{
+ oss_cdev_t *cdev;
+
+ cdev = cdev_hash[compute_cdev_hash(dev_class, instance)];
+
+ while (cdev != NULL)
+ {
+ if (cdev->d != NULL && cdev->dev_class == dev_class
+ && cdev->instance == instance)
+ return cdev->minor;
+ cdev = cdev->hl; /* Next in the hash chain */
+ }
+
+ return OSS_EIO;
+}
+
+int
+__oss_alloc_dmabuf (int dev, dmap_p dmap, unsigned int alloc_flags,
+ oss_uint64_t maxaddr, int direction)
+{
+ int err;
+#if defined(sparc)
+ uint_t len;
+#else
+ size_t len;
+#endif
+ uint_t ncookies;
+ contig_desc *desc;
+ oss_device_t *osdev = dmap->osdev;
+ ddi_dma_attr_t dma_attr;
+ int size = 32 * 1024;
+ extern int dma_buffsize;
+ ddi_device_acc_attr_t *acc_attr;
+
+ int flags = DDI_DMA_REDZONE | DDI_DMA_CONSISTENT |
+ (direction == OPEN_READ) ? DDI_DMA_READ : DDI_DMA_WRITE;
+
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "oss_alloc_dmabuf: osdev==NULL\n");
+ return OSS_EIO;
+ }
+
+ acc_attr = get_acc_attr (osdev);
+
+ if (dma_buffsize > 16 && dma_buffsize <= 128)
+ size = dma_buffsize * 1024;
+
+/*
+ * Some applications and virtual drivers need shorter buffer.
+ */
+ if (dmap->flags & DMAP_SMALLBUF)
+ {
+ size = SMALL_DMABUF_SIZE;
+ }
+ else if (dmap->flags & DMAP_MEDIUMBUF)
+ {
+ size = MEDIUM_DMABUF_SIZE;
+ }
+
+ if (alloc_flags & DMABUF_LARGE)
+ size = 256 * 1024;
+
+ if ((alloc_flags & DMABUF_SIZE_16BITS) && size > 32 * 1024)
+ size = 32 * 1024;
+
+ memcpy (&dma_attr, &dma_attr_pci, sizeof (ddi_dma_attr_t));
+ dma_attr.dma_attr_addr_hi = maxaddr;
+
+#ifndef SOL9
+ if (osdev->dev_type == DRV_PCI)
+ dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
+#endif
+
+ if (dmap->dmabuf != NULL)
+ return 0; /* Already done */
+
+ dmap->dma_parms.state = 0;
+ dmap->dma_parms.enabled = 1;
+ dmap->dma_parms.ignore = 0;
+
+ if (osdev->dip == NULL)
+ {
+ cmn_err (CE_WARN, "oss_alloc_dmabuf: osdev->dip==NULL\n");
+ return OSS_EIO;
+ }
+
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "oss_alloc_dmabuf: dmap==NULL\n");
+ return OSS_EIO;
+ }
+
+ if ((err = ddi_dma_alloc_handle (osdev->dip,
+ &dma_attr,
+ DDI_DMA_SLEEP,
+ NULL,
+ &dmap->dmabuf_dma_handle)) != DDI_SUCCESS)
+ {
+ cmn_err (CE_WARN, "Failed to allocate DMA handle (error %d)\n", err);
+ return OSS_ENOMEM;
+ }
+
+
+ dmap->dmabuf = NULL;
+ dmap->buffsize = size;
+
+ err = -1;
+
+ while (err != DDI_SUCCESS && dmap->dmabuf == NULL && dmap->buffsize >= 4096)
+ {
+#if defined(sparc)
+ if ((err = ddi_mem_alloc (osdev->dip,
+ NULL,
+ dmap->buffsize,
+ 0,
+ (caddr_t *) & dmap->dmabuf,
+ (uint_t *) & len)) != DDI_SUCCESS)
+#else
+ if ((err = ddi_dma_mem_alloc (dmap->dmabuf_dma_handle,
+ dmap->buffsize,
+ acc_attr,
+ flags,
+ DDI_DMA_SLEEP,
+ NULL,
+ (caddr_t *) & dmap->dmabuf,
+ (size_t *) & len,
+ &dmap->dma_parms.dma_acc_handle)) !=
+ DDI_SUCCESS)
+#endif
+ {
+ if (!(alloc_flags & DMABUF_QUIET))
+ DDB (cmn_err (CE_WARN,
+ "failed to allocate %d bytes of DMA memory (%d)\n",
+ dmap->buffsize, err));
+ dmap->dmabuf = NULL;
+ dmap->buffsize /= 2;
+ }
+ }
+
+ if (dmap->dmabuf == NULL)
+ {
+ cmn_err (CE_WARN, "Can't allocate a DMA buffer for device %d\n", dev);
+ ddi_dma_free_handle (&dmap->dmabuf_dma_handle);
+ return OSS_ENOMEM;
+ }
+
+ DDB (cmn_err (CE_CONT, "Allocated DMA memory, addr=%x, len=%d\n",
+ (int) dmap->dmabuf, (int) dmap->buffsize));
+
+ dmap->dma_parms.orig_buf = (caddr_t) dmap->dmabuf;
+
+ if ((err = ddi_dma_addr_bind_handle (dmap->dmabuf_dma_handle,
+ NULL,
+ (char *) dmap->dmabuf,
+ dmap->buffsize,
+ flags | DDI_DMA_STREAMING,
+ DDI_DMA_DONTWAIT,
+ NULL,
+ &dmap->dma_parms.cookie,
+ &ncookies)) != DDI_SUCCESS)
+ {
+ cmn_err (CE_WARN, "DMA address setup failed (%d)\n", err);
+
+ return OSS_EIO;
+ }
+
+ dmap->dmabuf =
+ (unsigned char *) ((((unsigned long) dmap->dmabuf) + 4095) & ~4095);
+ dmap->dmabuf_phys = (dmap->dma_parms.cookie.dmac_address + 4095) & ~4095;
+
+ desc = PMALLOC (osdev, sizeof (contig_desc));
+ if (desc == NULL)
+ return OSS_ENOMEM;
+
+ desc->osdev = osdev;
+ desc->next = NULL;
+ desc->is_special = 1;
+ desc->first_addr = dmap->dmabuf;
+ desc->last_addr = dmap->dmabuf + dmap->buffsize - 1;
+ desc->physaddr = dmap->dmabuf_phys;
+ desc->orig_buf = dmap->dma_parms.orig_buf;
+
+ if (contig_list != NULL)
+ desc->next = contig_list;
+/* HW_PRINTF(("Alloc DMA: %x-%x, ph=%x\n", desc->first_addr, desc->last_addr, desc->physaddr)); */
+ contig_list = desc;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+void
+oss_free_dmabuf (int dev, dmap_p dmap)
+{
+ int err;
+
+ if (dmap->dmabuf == NULL)
+ return;
+
+ if ((err = ddi_dma_unbind_handle (dmap->dmabuf_dma_handle)) != DDI_SUCCESS)
+ cmn_err (CE_WARN, "Failed to free DMA handle (%d)\n", err);
+#if defined(sparc)
+ ddi_mem_free (dmap->dma_parms.orig_buf);
+#else
+ ddi_dma_mem_free (&dmap->dma_parms.dma_acc_handle);
+#endif
+ ddi_dma_free_handle (&dmap->dmabuf_dma_handle);
+
+ dmap->dmabuf = NULL;
+ dmap->dmabuf_phys = 0;
+}
+
+/*
+ * Interrupt management
+ */
+static u_int
+oss_intr (caddr_t arg) /* Global interrupt handler */
+{
+ oss_device_t *osdev = (oss_device_t *) arg;
+ int serviced;
+#ifdef MUTEX_CHECKS
+ int x = inside_intr;
+ inside_intr = 1; /* For mutex debugging only */
+#endif
+
+ if (osdev == NULL)
+ {
+#ifdef MUTEX_CHECKS
+ inside_intr = x;
+#endif
+ return DDI_INTR_UNCLAIMED;
+ }
+ osdev->intrcount++;
+
+ UP_STATUS (0x01);
+ serviced = osdev->tophalf_handler (osdev);
+ DOWN_STATUS (0x01);
+
+ if (serviced == 0)
+ return DDI_INTR_UNCLAIMED;
+ osdev->ackcount++;
+
+ if (osdev->bottomhalf_handler == NULL)
+ return DDI_INTR_CLAIMED;
+
+#if 0
+ if (osdev->intr_is_hilevel)
+ {
+/* TODO: Schedule the bottom half handler */
+ }
+ else
+#endif
+ osdev->bottomhalf_handler (osdev);
+
+#ifdef MUTEX_CHECKS
+ inside_intr = x;
+#endif
+ return DDI_INTR_CLAIMED;
+}
+
+int
+oss_register_interrupts (oss_device_t * osdev, int intrnum,
+ oss_tophalf_handler_t top,
+ oss_bottomhalf_handler_t bottom)
+{
+ int err;
+ ddi_idevice_cookie_t ic;
+
+
+ if (intrnum != 0)
+ {
+ cmn_err (CE_WARN, "Bad interrupt index (%d) for %s\n", intrnum,
+ osdev->name);
+ return OSS_EINVAL;
+ }
+
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "oss_register_interrupts: Bad osdev\n");
+ return OSS_EINVAL;
+ }
+
+ if (osdev->tophalf_handler != NULL || osdev->bottomhalf_handler != NULL)
+ {
+ cmn_err (CE_WARN, "Interrupts already registered for %s\n",
+ osdev->name);
+ return OSS_EINVAL;
+ }
+
+ if (top == NULL)
+ {
+ cmn_err (CE_WARN, "Bad interrupt handler for %s\n", osdev->name);
+ return OSS_EINVAL;
+ }
+
+ osdev->tophalf_handler = top;
+ osdev->bottomhalf_handler = bottom;
+ osdev->intr_is_hilevel = ddi_intr_hilevel (osdev->dip, intrnum);
+ if (osdev->intr_is_hilevel)
+ {
+ if (bottom == NULL)
+ {
+ cmn_err (CE_WARN,
+ "The driver for %s doesn't support hilevel interrupts\n",
+ osdev->name);
+ return OSS_EINVAL;
+ }
+
+ DDB (cmn_err (CE_NOTE, "Using hilevel intr for %s\n", osdev->name));
+
+ /* TODO: Fix hilevel intr handling */
+ cmn_err (CE_WARN, "Hilevel interrupts are not supported yet.\n");
+ return OSS_EINVAL;
+ }
+
+ ddi_get_iblock_cookie (osdev->dip, intrnum, &osdev->iblock_cookie);
+
+ if ((err = ddi_add_intr (osdev->dip, intrnum, NULL, &ic,
+ oss_intr, (caddr_t) osdev)) != DDI_SUCCESS)
+ {
+ cmn_err (CE_WARN, "ddi_add_intr() failed, error=%d\n", err);
+ return OSS_EIO;
+ }
+
+ return 0;
+}
+
+void
+oss_unregister_interrupts (oss_device_t * osdev)
+{
+ ddi_remove_intr (osdev->dip, 0, osdev->iblock_cookie);
+ osdev->tophalf_handler = NULL;
+ osdev->bottomhalf_handler = NULL;
+}
+
+/*ARGSUSED*/
+int
+oss_register_device (oss_device_t * osdev, const char *name)
+{
+
+ if ((osdev->name = PMALLOC (NULL, strlen (name) + 1)) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate memory for device name\n");
+ osdev->name = "Unknown device";
+ }
+ strcpy (osdev->name, name);
+ return 0;
+}
+
+int
+oss_disable_device (oss_device_t * osdev)
+{
+ int i;
+/*
+ * This routine should check if the device is ready to be unloaded (no devices are in use).
+ * If the device cannot be unloaded this routine must return OSS_EBUSY.
+ *
+ * If the device can be unloaded then disable any timers or other features that may cause the
+ * device to be called. Also mark the audio/midi/mixer/etc devices of this device to be disabled.
+ * However the interrupt handler should still stay enabled. The low level driver will call
+ * oss_unregister_interrupts() after it has cleared the interrupt enable register.
+ */
+ if (osdev->refcount > 0 || open_devices > 0)
+ {
+ cmn_err (CE_CONT, "Refcount %d (%s) , open_devices %d\n",
+ osdev->refcount, osdev->nick, open_devices);
+ if (open_devices > 0)
+ {
+ int i;
+
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->open_count)
+ {
+ cmn_err (CE_CONT, "%s is opened\n", oss_cdevs[i]->name);
+ }
+ }
+ return OSS_EBUSY;
+ }
+//cmn_err(CE_CONT, "oss_disable_device %s\n", osdev->nick);
+
+/*
+ * Now mark all devices unavailable (for the time being)
+ */
+
+ for (i = 0; i < num_mixers; i++)
+ if (mixer_devs[i]->osdev == osdev)
+ {
+ mixer_devs[i]->unloaded = 1;
+ }
+
+ for (i = 0; i < num_mididevs; i++)
+ {
+ if (midi_devs[i]->osdev == osdev)
+ {
+ midi_devs[i]->unloaded = 1;
+ }
+ }
+
+ for (i = 0; i < num_audio_engines; i++)
+ if (audio_engines[i]->osdev == osdev)
+ {
+ audio_uninit_device (i);
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+void
+oss_unregister_device (oss_device_t * osdev)
+{
+/*
+ * Notice! The driver calling this routine (the owner of the osdev parameter)
+ * has already uninitialized itself. Do not do any actions that may call this
+ * driver directly or indirectly.
+ */
+
+/*
+ * Force reload of all drivers if any application tries to open any
+ * of the devices.
+ */
+ do_forceload = 1;
+}
+
+void
+oss_reserve_device (oss_device_t * osdev)
+{
+ osdev->refcount++;
+}
+
+void
+oss_unreserve_device (oss_device_t * osdev, int decrement)
+{
+ osdev->refcount -= decrement;
+}
+
+/*
+ * Wait queue support
+ */
+ /*ARGSUSED*/
+ oss_wait_queue_t *
+oss_create_wait_queue (oss_device_t * osdev, const char *name)
+{
+ oss_wait_queue_t *wq;
+
+ if ((wq = PMALLOC (NULL, sizeof (*wq))) == NULL)
+ return NULL;
+
+ cv_init (&wq->cv, NULL, CV_DRIVER, NULL);
+
+ return wq;
+}
+
+void *
+oss_get_osid (oss_device_t * osdev)
+{
+ return osdev->osid;
+}
+
+/*ARGSUSED*/
+void
+oss_reset_wait_queue (oss_wait_queue_t * wq)
+{
+ /* NOP */
+}
+
+void
+oss_remove_wait_queue (oss_wait_queue_t * wq)
+{
+ cv_destroy (&wq->cv);
+}
+
+/*ARGSUSED*/
+int
+oss_sleep (oss_wait_queue_t * wq, oss_mutex_t * mutex, int ticks,
+ oss_native_word * flags, unsigned int *status)
+{
+/*
+ * oss_sleep will return 0 if timeout occurred and 1 otherwise. The WK_SIGNAL bit will be reported on
+ * status if a signal was caught.
+ */
+ *status = 0;
+
+ if (ticks > 0)
+ {
+ int res;
+
+ if ((res =
+ cv_timedwait_sig (&wq->cv, mutex, ddi_get_lbolt () + ticks)) == 0)
+ *status |= WK_SIGNAL; /* Got signal */
+ if (res < 0) /* Timeout */
+ return 0;
+ }
+ else
+ {
+ if (cv_wait_sig (&wq->cv, mutex) == 0)
+ *status |= WK_SIGNAL; /* Got signal */
+ }
+ return 1;
+}
+
+/*ARGSUSED*/
+int
+oss_register_poll (oss_wait_queue_t * wq, oss_mutex_t * mutex,
+ oss_native_word * flags, oss_poll_event_t * ev)
+{
+ ev->php = &wq->ph;
+ wq->pollevents |= ev->events;
+ return 0;
+}
+
+/*ARGSUSED*/
+void
+oss_wakeup (oss_wait_queue_t * wq, oss_mutex_t * mutex,
+ oss_native_word * flags, short events)
+{
+ cv_broadcast (&wq->cv);
+
+ if (wq->pollevents & events)
+ {
+ wq->pollevents &= ~events;
+ MUTEX_EXIT_IRQRESTORE (*mutex, *flags);
+ pollwakeup (&wq->ph, events);
+ MUTEX_ENTER_IRQDISABLE (*mutex, *flags);
+ }
+}
+
+#ifdef MUTEX_CHECKS
+void
+debug_mutex_init (oss_mutex_t * mutex, void *dummy, int typ, void *arg,
+ char *file, int line)
+{
+ memset (mutex, 0, sizeof (mutex));
+ mutex_init (&mutex->mu, dummy, typ, arg);
+}
+
+void
+debug_mutex_destroy (oss_mutex_t * mutex, char *file, int line)
+{
+ mutex_destroy (&mutex->mu);
+}
+
+void
+debug_mutex_enter (oss_mutex_t * mutex, char *file, int line)
+{
+ if (mutex_owned (&mutex->mu))
+ {
+ cmn_err (CE_NOTE, "%s:%d: Re-entrant mutex (%s:%d %d)\n", file, line,
+ mutex->file, mutex->line, mutex->busy_flags);
+ return;
+ }
+
+ mutex->file = file;
+ mutex->line = line;
+ mutex_enter (&mutex->mu);
+}
+
+void
+debug_mutex_exit (oss_mutex_t * mutex, char *file, int line)
+{
+ if (!mutex_owned (&mutex->mu))
+ {
+ cmn_err (CE_NOTE, "Mutex not owned %s:%d\n", file, line);
+ }
+ else
+ mutex_exit (&mutex->mu);
+
+ mutex->file = NULL;
+ mutex->line = 0;
+}
+#endif
+
+int
+oss_get_procinfo(int what)
+{
+
+ switch (what)
+ {
+ case OSS_GET_PROCINFO_UID:
+ return ddi_get_cred()->cr_uid;
+ break;
+
+ case OSS_GET_PROCINFO_GID:
+ return ddi_get_cred()->cr_gid;
+ break;
+
+#if 0
+ case OSS_GET_PROCINFO_PGID:
+ return ddi_get_cred()->cr_pgid;
+ break;
+#endif
+
+ }
+ return OSS_EINVAL;
+}
diff --git a/kernel/OS/SunOS/os_solaris.h b/kernel/OS/SunOS/os_solaris.h
new file mode 100644
index 0000000..2b36b86
--- /dev/null
+++ b/kernel/OS/SunOS/os_solaris.h
@@ -0,0 +1,518 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+/*
+ * Purpose: OS specific definitions for Solaris
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define OS_VERSION "10"
+#define SUNDDI
+#define __EXTENDED__
+#define Solaris
+
+#if (!defined(i386) && !defined(x86_64)) || defined(CONFIG_OSS_FIXDEPOINT)
+// Floating point is not supported or it's disabled
+#undef CONFIG_OSS_VMIX_FLOAT
+#endif
+
+#define VDEV_SUPPORT
+#define USE_DEVICE_SUBDIRS
+
+#define __inline__ inline
+#define __inline inline
+#define EXTERN_C extern "C"
+
+/*
+ * Debugging and misc settings
+ */
+#undef MUTEX_CHECKS
+#undef MEMDEBUG
+
+/*
+ * Disable support for per-application features such as /dev/dsp device
+ * selection based on command name. Requires working GET_PROCESS_NAME
+ * macro implementation.
+ */
+#undef APPLIST_SUPPORT
+
+/*
+ * Some integer types
+ */
+#if defined(amd64) || defined(sparc)
+typedef unsigned long long oss_native_word; /* Same as the address and status register size */
+#else
+typedef unsigned long oss_native_word; /* Same as the address and status register size */
+#endif
+
+typedef long long oss_int64_t; /* Signed 64 bit integer */
+typedef unsigned long long oss_uint64_t; /* Unsigned 64 bit integer */
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/types32.h>
+#include <sys/param.h>
+#include <sys/signal.h>
+#include <oss_errno.h>
+#include <sys/file.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/map.h>
+#include <sys/debug.h>
+#include <sys/modctl.h>
+#include <sys/kmem.h>
+#include <sys/cmn_err.h>
+#include <sys/open.h>
+#include <sys/stat.h>
+#ifndef sparc
+#include <sys/dditypes.h>
+#include <sys/ddidmareq.h>
+#include <sys/dma_engine.h>
+#endif
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/fcntl.h>
+#include <sys/ddidmareq.h>
+#include <sys/ksynch.h>
+#include <sys/poll.h>
+#ifdef SOL9
+#include <sys/cred.h>
+#else
+#include <sys/cred_impl.h>
+#endif
+
+#ifndef SOL9
+#include <sys/ddifm.h>
+#include <sys/fm/protocol.h>
+#include <sys/fm/util.h>
+#include <sys/fm/io/ddi.h>
+#endif
+
+#undef HZ
+#define OSS_HZ hz
+
+#ifdef sparc
+/*
+ * It's not possible to use SB Live! under Sparc architecture.
+ */
+#define AUDIGY_ONLY
+#endif
+
+/*
+ * Need to use slightly larger buffer because otherwise the interrupt
+ * rate will become too high for Solaris.
+ */
+#undef SMALL_DMABUF_SIZE
+#define SMALL_DMABUF_SIZE (16*1024)
+
+/* The soundcard.h could be in a nonstandard place so include it here. */
+#include "soundcard.h"
+
+typedef struct udi_usb_devc udi_usb_devc;
+
+struct _oss_device_t
+{
+ int cardnum;
+ int dev_type;
+ int instance;
+ int available;
+ dev_info_t *dip;
+ void *osid;
+ void *devc;
+ char *name;
+ char nick[16];
+ char modname[32];
+ char handle[32];
+ int num_audio_engines;
+ int num_audioplay, num_audiorec, num_audioduplex;
+ int num_mididevs;
+ int num_mixerdevs;
+ int num_loopdevs;
+ int first_mixer; /* This must be set to -1 by osdev_create() */
+ char *hw_info;
+
+ volatile int refcount; /* Nonzero means that the device is needed by some other (virtual) driver. */
+
+/* Interrupts */
+
+ ddi_iblock_cookie_t iblock_cookie;
+ int intr_is_hilevel;
+ oss_tophalf_handler_t tophalf_handler;
+ oss_bottomhalf_handler_t bottomhalf_handler;
+ int intrcount, ackcount;
+
+#ifdef _KERNEL
+/* PCI related fields */
+ ddi_acc_handle_t pci_config_handle;
+#define OSS_MAX_ACC_HANDLE 10
+ ddi_acc_handle_t acc_handle[OSS_MAX_ACC_HANDLE];
+ int swap_mode; /* 0=DDI_STRUCTURE_NEVERSWAP_ACC, 1=DDI_STRUCTURE_LE_ACC */
+
+/* USB fields */
+ udi_usb_devc *usbdev;
+
+#ifndef SOL9
+/* Fault management (FMA) */
+ int fm_capabilities;
+#endif
+#endif
+};
+
+/*
+ * Support for select()
+ */
+
+struct _oss_poll_event_t
+{
+ short events, revents;
+ struct pollhead *php;
+ int anyyet;
+};
+typedef struct _oss_poll_event_t oss_poll_event_t;
+
+#define ALLOW_SELECT
+#define SEL_IN 0
+#define SEL_OUT 1
+#define SEL_EX 0xffffffff
+
+/*
+ * Sleep/wakeup
+ */
+
+#ifdef _KERNEL
+struct oss_wait_queue
+{
+ kcondvar_t cv;
+ short pollevents;
+ struct pollhead ph;
+};
+#endif
+
+/* Busy wait routine */
+#define oss_udelay drv_usecwait
+/* System wall timer access */
+#define GET_JIFFIES() ddi_get_lbolt()
+
+/*
+ * Mutexes
+ */
+
+#ifdef MUTEX_CHECKS
+/* Debugging version */
+struct _oss_mutex_t
+{
+ kmutex_t mu;
+ char *file;
+ int line;
+ int busy_flags;
+#define CNTX_INTR 1
+#define CNTX_USER 2
+};
+
+typedef struct _oss_mutex_t oss_mutex_t;
+extern void debug_mutex_init (oss_mutex_t * mutex, void *dummy, int typ,
+ void *arg, char *file, int line);
+extern void debug_mutex_destroy (oss_mutex_t * mutex, char *file, int line);
+extern void debug_mutex_enter (oss_mutex_t * mutex, char *file, int line);
+extern void debug_mutex_exit (oss_mutex_t * mutex, char *file, int line);
+
+#define MUTEX_INIT(osdev, mutex, hier) debug_mutex_init(&mutex, NULL, MUTEX_DRIVER, osdev->iblock_cookie, __FILE__, __LINE__)
+#define MUTEX_CLEANUP(mutex) debug_mutex_destroy(&mutex, __FILE__, __LINE__)
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) flags=0;debug_mutex_enter(&mutex, __FILE__, __LINE__)
+#define MUTEX_ENTER(mutex, flags) flags=0;debug_mutex_enter(&mutex, __FILE__, __LINE__)
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) debug_mutex_exit(&mutex, __FILE__, __LINE__);(flags)++
+#define MUTEX_EXIT(mutex, flags) debug_mutex_exit(&mutex, __FILE__, __LINE__);(flags)++
+#else
+typedef kmutex_t oss_mutex_t;
+#define MUTEX_INIT(osdev, mutex, hier) mutex_init(&mutex, NULL, MUTEX_DRIVER, osdev->iblock_cookie)
+#define MUTEX_CLEANUP(mutex) mutex_destroy(&mutex)
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) flags=0;mutex_enter(&mutex)
+#define MUTEX_ENTER(mutex, flags) flags=0;mutex_enter(&mutex)
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) mutex_exit(&mutex);(flags)++
+#define MUTEX_EXIT(mutex, flags) mutex_exit(&mutex);(flags)++
+#endif
+
+/*
+ * Move bytes from the buffer which the application given in a
+ * write() call.
+ * offs is position relative to the beginning of the buffer in
+ * user space. The count is number of bytes to be moved.
+ */
+#define COPY_FROM_USER(target, source, offs, count) \
+ if (uiomove((target), count, UIO_WRITE, source)) { \
+ cmn_err(CE_WARN, "Bad copyin()!\n"); \
+ }
+/* Like COPY_FOM_USER but for writes. */
+#define COPY_TO_USER(target, offs, source, count) \
+ if (uiomove((source), count, UIO_READ, target)) { \
+ cmn_err(CE_WARN, "Bad copyout()!\n"); \
+ }
+
+/*
+ * INB() and OUTB() should be obvious. NOTE! The order of
+ * paratemeters of OUTB() is different than on some other
+ * operating systems.
+ */
+
+#ifdef sparc
+#ifdef _KERNEL
+extern void oss_put16 (ddi_acc_handle_t handle, unsigned short *addr,
+ unsigned short value);
+extern void oss_put32 (ddi_acc_handle_t handle, unsigned int *addr,
+ unsigned int value);
+extern unsigned short oss_get16 (ddi_acc_handle_t handle,
+ unsigned short *addr);
+extern unsigned int oss_get32 (ddi_acc_handle_t handle, unsigned int *addr);
+
+#define INB(osdev,port) ddi_get8((osdev)->acc_handle[0], (uint8_t*)(port))
+#define OUTB(osdev, d, port) ddi_put8((osdev)->acc_handle[0], (uint8_t*)(port), (d))
+#define INW(osdev,port) oss_get16((osdev)->acc_handle[0], (uint16_t*)(port))
+#define OUTW(osdev, d, port) oss_put16((osdev)->acc_handle[0], (uint16_t*)(port), (d))
+#define INL(osdev,port) oss_get32((osdev)->acc_handle[0], (uint32_t*)(port))
+#define OUTL(osdev,d, port) oss_put32((osdev)->acc_handle[0], (uint32_t*)(port), (d))
+
+/* Memory Mapped devices */
+extern uint16_t oss_mem_get16 (ddi_acc_handle_t handle, uint16_t * addr);
+extern uint32_t oss_mem_get32 (ddi_acc_handle_t handle, uint32_t * addr);
+extern void oss_mem_put16 (ddi_acc_handle_t handle, uint16_t * add,
+ uint16_t v);
+extern void oss_mem_put32 (ddi_acc_handle_t handle, uint32_t * add,
+ uint32_t v);
+#define PCI_READW(osdev, addr) oss_mem_get16((osdev)->acc_handle[0], (uint16_t*)(addr))
+#define PCI_READL(osdev, addr) oss_mem_get32((osdev)->acc_handle[0], (uint32_t*)(addr))
+#define PCI_WRITEW(osdev, addr, data) oss_mem_put16((osdev)->acc_handle[0], (uint16_t*)(addr), data)
+#define PCI_WRITEL(osdev, addr, data) oss_mem_put32((osdev)->acc_handle[0], (uint32_t*)(addr), data)
+#endif
+#else /* x86/AMD64 */
+/* I/O Mapped devices */
+#define INB(o, p) inb(p)
+#define INW(o, p) inw(p)
+#define INL(o, p) inl(p)
+
+#define OUTB(o, v, p) outb(p,v)
+#define OUTW(o, v, p) outw(p,v)
+#define OUTL(o, v, p) outl(p,v)
+
+/* Memory Mapped devices */
+#define PCI_READW(osdev, addr) ddi_mem_get16((osdev)->acc_handle[0], (uint16_t*)(addr))
+#define PCI_READL(osdev, addr) ddi_mem_get32((osdev)->acc_handle[0], (uint32_t*)(addr))
+#define PCI_WRITEW(osdev, addr, data) ddi_mem_put16((osdev)->acc_handle[0], (uint16_t*)(addr), data)
+#define PCI_WRITEL(osdev, addr, data) ddi_mem_put32((osdev)->acc_handle[0], (uint32_t*)(addr), data)
+#endif
+
+#define PCI_READB(osdev, addr) ddi_mem_get8((osdev)->acc_handle[0], addr)
+#define PCI_WRITEB(osdev, addr, data) ddi_mem_put8((osdev)->acc_handle[0], addr, data)
+
+typedef ddi_dma_handle_t oss_dma_handle_t;
+
+/*
+ KERNEL_MALLOC() allocates requested number of memory and
+ KERNEL_FREE is used to free it.
+ These macros are never called from interrupt, in addition the
+ nbytes will never be more than 4096 bytes. Generally the driver
+ will allocate memory in blocks of 4k. If the kernel has just a
+ page level memory allocation, 4K can be safely used as the size
+ (the nbytes parameter can be ignored).
+*/
+#ifdef MEMDEBUG
+extern void *oss_kmem_alloc (size_t size, int flags, char *file, int line);
+extern void oss_kmem_free (void *addr);
+#define KERNEL_MALLOC(nbytes) oss_kmem_alloc(nbytes, KM_SLEEP, __FILE__, __LINE__)
+#define KERNEL_FREE(addr) oss_kmem_free(addr)
+extern void *oss_contig_malloc (oss_device_t * osdev, int sz,
+ oss_uint64_t memlimit,
+ oss_native_word *phaddr,
+ oss_dma_handle_t *dma_handle,
+ char * file, int line);
+extern void oss_contig_free (oss_device_t * osdev, void *p, int sz);
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(osdev, sz, memlimit, phaddr, &handle, __FILE__, __LINE__)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(osdev, p, sz, handle)
+#else
+extern void *oss_kmem_alloc (size_t size, int flags);
+extern void oss_kmem_free (void *addr);
+#define KERNEL_MALLOC(nbytes) oss_kmem_alloc(nbytes, KM_SLEEP)
+#define KERNEL_FREE(addr) oss_kmem_free(addr)
+extern void *oss_contig_malloc (oss_device_t * osdev, int sz,
+ oss_uint64_t memlimit,
+ oss_native_word * phaddr,
+ oss_dma_handle_t *dma_handle);
+extern void oss_contig_free (oss_device_t * osdev, void *p, int sz);
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(osdev, sz, memlimit, phaddr, &handle)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(osdev, p, sz)
+#endif
+
+/*
+ * Timer macros
+ *
+ * These macros are obsolete and should not be used in any new code.
+ * Use the timeout mechanism (see the timeout(9F) Solaris man page).
+ */
+#define DEFINE_TIMER(name, proc) static timeout_id_t name = 0
+#define REMOVE_TIMER(name, proc) {if (name != 0) untimeout(name);}
+#define INIT_TIMER(name,proc)
+typedef void (*timeout_func_t) (void *);
+#define ACTIVATE_TIMER(name, proc, time) \
+ name=timeout((timeout_func_t)proc, (void*)&name, time)
+
+#define OSS_DMA_SYNC_INBOUND DDI_DMA_SYNC_FORCPU
+#define OSS_DMA_SYNC_OUTBOUND DDI_DMA_SYNC_FORDEV
+#define OSS_DMA_SYNC(handle, offs, len, direc) (ddi_dma_sync(handle, offs, len, direc)==DDI_SUCCESS)
+
+#ifdef _KERNEL
+struct os_dma_params
+{
+ int state; /* 0=unavail, 1=avail, 2=busy */
+ oss_device_t *osdev;
+ ddi_dma_handle_t handle;
+ ddi_acc_handle_t dma_acc_handle;
+ ddi_dma_cookie_t cookie;
+ ddi_dma_win_t win;
+ ddi_dma_seg_t seg;
+ void *orig_buf;
+
+ volatile int enabled, ignore;
+};
+#define OS_DMA_PARMS \
+ struct os_dma_params dma_parms;
+#endif
+#endif
+
+struct fileinfo
+{
+ int mode; /* Open mode */
+ int acc_flags;
+};
+
+#define ISSET_FILE_FLAG(fileinfo, flag) (fileinfo->acc_flags & (flag) ? 1:0)
+
+#ifdef sparc
+#define OSS_OS "Sparc"
+#define OSS_OS_LONGNAME "Solaris (Sparc)"
+#else
+#define OSS_OS "Solaris"
+#define OSS_OS_LONGNAME "Solaris (x86)"
+#endif
+
+#undef DMA_TRY_PSEUDOINIT
+
+int get_dma_residue (int chn);
+void disable_dma (int chn);
+void enable_dma (int chn);
+
+typedef void (*softintr_func_t) (int);
+
+struct oss_softintr
+{
+ int id;
+ softintr_func_t func;
+ volatile int armed, running;
+};
+
+/*
+ * There is apparently no documented way to map DMA buffers allocated
+ * using ddi_dma_mem_alloc() to applications. For this reason we cannot
+ * support mmap() under Solaris.
+ */
+#undef ALLOW_BUFFER_MAPPING
+
+#if 0
+extern int detect_trace;
+#define DDB(x) if (detect_trace) x
+#else
+#define DDB(x) {}
+#endif
+
+/*
+ * PCI I/O and memory address mapping.
+ *
+ * Note that for compatibility with the other operating systems supported by
+ * OSS the region numbering is different. So 0 means BAR0 while under
+ * Solaris (ddi_regs_map_setup) BAR0 is 1. oss_map_pci_ioaddr() will
+ * add 1 to the region number.
+ */
+extern caddr_t oss_map_pci_ioaddr (oss_device_t * osdev, int nr, int io);
+extern void oss_unmap_pci_ioaddr(oss_device_t * osdev, int nr);
+#define MAP_PCI_IOADDR(osdev, nr, io) (oss_native_word)oss_map_pci_ioaddr(osdev, nr, io)
+#define MAP_PCI_MEM(osdev, ix, phaddr, size) oss_map_pci_ioaddr(osdev, ix, phaddr)
+#define UNMAP_PCI_MEM(osdev, ix, ph, virt, size) oss_unmap_pci_ioaddr(osdev, ix)
+#define UNMAP_PCI_IOADDR(osdev, ix) oss_unmap_pci_ioaddr(osdev, ix)
+
+#define GET_PROCESS_PID(x) ddi_get_pid()
+
+/*
+ * Instead of returning UID check if the process has PRIV_SYS_DEVICES privilege.
+ * Report such users as UID=0 (root) and others as UID=1.
+ */
+#define GET_PROCESS_UID() ((drv_priv(ddi_get_cred())==0) ? 0 : 1)
+
+#if 1
+/* TODO: This works OK but may cause crashes with different kernel versions/builds */
+extern char *oss_get_procname (void);
+#define GET_PROCESS_NAME(x) oss_get_procname()
+#endif
+
+#define FP_SUPPORT
+
+#ifdef FP_SUPPORT
+typedef short fp_env_t[512];
+typedef unsigned int fp_flags_t[5];
+extern int oss_fp_check (void);
+extern void oss_fp_save (short *envbuf, fp_flags_t flags);
+extern void oss_fp_restore (short *envbuf, fp_flags_t flags);
+# define FP_SAVE(envbuf, flags) oss_fp_save(envbuf, flags)
+# define FP_RESTORE(envbuf, flags) oss_fp_restore(envbuf, flags)
+#endif
+
+#define abs(x) ((x) >= 0 ? (x) : -(x))
+
+extern int oss_open (dev_t * dev_p, int open_flags, int otyp,
+ cred_t * cred_p);
+extern int oss_close (dev_t dev, int flag, int otyp, cred_t * cred_p);
+extern int oss_ioctl (dev_t dev, int cmd, intptr_t arg, int mode,
+ cred_t * cred_p, int *rval_p);
+extern int oss_read (dev_t dev, struct uio *uiop, cred_t * credp);
+extern int oss_write (dev_t dev, struct uio *uiop, cred_t * cred_p);
+extern int oss_chpoll (dev_t dev, short events, int anyyet, short *reventsp,
+ struct pollhead **phpp);
+#ifdef _KERNEL
+extern int oss_devmap (dev_t dev, devmap_cookie_t handle, offset_t off,
+ size_t len, size_t * maplen, uint_t model);
+
+extern void *oss_memset (void *s, int c, size_t n);
+#define memset oss_memset
+
+extern void *oss_memcpy (void *s1, const void *s2, size_t n);
+#define memcpy oss_memcpy
+#endif
+
+#define DISABLE_FMA
+#if !defined(SOL9) && defined(DDI_FM_DEVICE) && !defined(DISABLE_FMA)
+/*
+ * Fault management (FMA) support.
+ */
+
+#define FMA_EREPORT(osdev, detail, name, type, value) \
+{ \
+ uint64_t ena; \
+ char buf[FM_MAX_CLASS]; \
+ (void) snprintf (buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); \
+ ena = fm_ena_generate(0, FM_ENA_FMT1); \
+ if (osdev->dip != NULL && osdev->fm_capabilities != 0) \
+ ddi_fm_ereport_post(osdev->dip, buf, ena, DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, name, type, value, NULL); \
+}
+
+#define FMA_IMPACT(osdev, impact) \
+ if (osdev->fm_capabilities != 0) \
+ ddi_fm_service_impact(osdev->dip, impact)
+#endif
diff --git a/kernel/OS/SunOS/udi.c b/kernel/OS/SunOS/udi.c
new file mode 100644
index 0000000..ad4d4fa
--- /dev/null
+++ b/kernel/OS/SunOS/udi.c
@@ -0,0 +1,1365 @@
+/*
+ * Purpose: USB device interface (udi.h) routines for Solaris
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+#if !defined(SOL9)
+#include "oss_config.h"
+#include <udi.h>
+
+#define USBDRV_MAJOR_VER 2
+#define USBDRV_MINOR_VER 0
+#include <sys/usb/usba.h>
+#include <sys/strsubr.h>
+
+#undef IO_DEBUG
+int udi_usb_trace = 0;
+
+#define MAX_DEVICE_SLOTS 20
+
+struct udi_usb_devc
+{
+ oss_device_t *osdev;
+ usb_client_dev_data_t *dev_data;
+ char *name;
+
+ const struct usb_device_id *id;
+ const udi_usb_devinfo *udi_usb_dev;
+ char devpath[32];
+
+ int enabled;
+
+ struct usb_interface *iface;
+ udi_usb_driver *drv;
+ void *client_devc;
+ void (*client_disconnect) (void *devc);
+};
+
+#define MAX_DEVC 32
+
+int
+udi_attach_usbdriver (oss_device_t * osdev, const udi_usb_devinfo * devlist,
+ udi_usb_driver * driver)
+{
+ int err, i, nalt, vendor, product, busaddr;
+ udi_usb_devc *usbdev;
+ dev_info_t *dip = osdev->dip;
+ char *name;
+ unsigned long osid;
+ //usb_alt_if_data_t *altif_data;
+ usb_client_dev_data_t *dev_data;
+
+ if (dip==NULL)
+ {
+ cmn_err(CE_WARN, "dip==NULL\n");
+ return 0;
+ }
+
+ name = ddi_get_name (osdev->dip);
+
+ if (strcmp (name, "oss_usb") == 0)
+ {
+ oss_register_device (osdev, "USB audio/MIDI device");
+ return 1;
+ }
+
+ /*
+ * Select the default configuration
+ */
+ if ((err = usb_set_cfg (osdev->dip, USB_DEV_DEFAULT_CONFIG_INDEX,
+ USB_FLAGS_SLEEP, NULL, NULL)) == USB_SUCCESS)
+ {
+ cmn_err (CE_CONT, "usb_set_cfg returned %d\n", err);
+ }
+
+ busaddr = ddi_prop_get_int (DDI_DEV_T_ANY, osdev->dip,
+ DDI_PROP_NOTPROM, "assigned-address", 1234);
+ if ((usbdev = KERNEL_MALLOC (sizeof (*usbdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "udi_attach_usbdriver: Out of memory\n");
+ return 0;
+ }
+
+ memset (usbdev, 0, sizeof (*usbdev));
+ osdev->usbdev = usbdev;
+ usbdev->osdev = osdev;
+
+ if ((err = usb_client_attach (dip, USBDRV_VERSION, 0)) != USB_SUCCESS)
+ {
+ cmn_err (CE_WARN, "usb_client_attach failed, err=%d\n", err);
+ KERNEL_FREE (usbdev);
+ return 0;
+ }
+
+ if ((err =
+ usb_get_dev_data (osdev->dip, &usbdev->dev_data, USB_PARSE_LVL_CFG,
+ 0)) != USB_SUCCESS)
+ {
+ cmn_err (CE_WARN, "usb_get_dev_data failed, err=%d\n", err);
+ KERNEL_FREE (usbdev);
+ return 0;
+ }
+ dev_data = usbdev->dev_data;
+
+ osdev->iblock_cookie = dev_data->dev_iblock_cookie;
+
+ sprintf (usbdev->devpath, "usb%x,%x@port%d", udi_usbdev_get_vendor (usbdev),
+ udi_usbdev_get_product (usbdev), busaddr);
+ oss_register_device (osdev, "USB audio/MIDI device");
+ sprintf (osdev->nick, "usb%x_%x_%d", udi_usbdev_get_vendor (usbdev),
+ udi_usbdev_get_product (usbdev), busaddr);
+
+#if 0
+ if (udi_usb_trace > 5)
+ usb_print_descr_tree (osdev->dip, dev_data);
+#endif
+
+ nalt = 1;
+ if (nalt >= dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt)
+ nalt = 0;
+
+ //altif_data = &dev_data->dev_curr_cfg->
+ // cfg_if[dev_data->dev_curr_if].if_alt[nalt];
+
+ usbdev->name = usbdev->dev_data->dev_product;
+ vendor = udi_usbdev_get_vendor (usbdev);
+ product = udi_usbdev_get_product (usbdev);
+
+ /* inum = usbdev->dev_data->dev_curr_if; */
+ osid = (vendor << 16) | product;
+ osdev->osid = (void *) osid;
+
+ sprintf (osdev->handle, "usb%x,%x.%d:%d", vendor, product,
+ dev_data->dev_curr_if, osdev->instance);
+
+ for (i = 0; devlist[i].vendor != -1; i++)
+ if (devlist[i].vendor == vendor && devlist[i].product == product)
+ {
+ usbdev->name = devlist[i].name;
+ usbdev->udi_usb_dev = &devlist[i];
+ oss_register_device (osdev, usbdev->name);
+ break;
+ }
+
+ if ((usbdev->client_devc = driver->attach (usbdev, osdev)) == NULL)
+ {
+ cmn_err (CE_WARN, "Client attach failed, err=%d\n", err);
+ udi_unload_usbdriver (osdev);
+ return 0;
+ }
+
+ usbdev->client_disconnect = driver->disconnect;
+
+ return 1;
+}
+
+static char *
+usb_errstr (int err)
+{
+
+ static struct errmsg_
+ {
+ int err;
+ char *str;
+ } errs[] =
+ {
+ {
+ USB_FAILURE, "USB_FAILURE"},
+ {
+ USB_NO_RESOURCES, "USB_NO_RESOURCES"},
+ {
+ USB_NO_BANDWIDTH, "USB_NO_BANDWIDTH"},
+ {
+ USB_NOT_SUPPORTED, "USB_NOT_SUPPORTED"},
+ {
+ USB_PIPE_ERROR, "USB_PIPE_ERROR"},
+ {
+ USB_INVALID_PIPE, "USB_INVALID_PIPE"},
+ {
+ USB_NO_FRAME_NUMBER, "USB_NO_FRAME_NUMBER"},
+ {
+ USB_INVALID_START_FRAME, "USB_INVALID_START_FRAME"},
+ {
+ USB_HC_HARDWARE_ERROR, "USB_HC_HARDWARE_ERROR"},
+ {
+ USB_INVALID_REQUEST, "USB_INVALID_REQUEST"},
+ {
+ USB_INVALID_CONTEXT, "USB_INVALID_CONTEXT"},
+ {
+ USB_INVALID_VERSION, "USB_INVALID_VERSION"},
+ {
+ USB_INVALID_ARGS, "USB_INVALID_ARGS"},
+ {
+ USB_INVALID_PERM, "USB_INVALID_PERM"},
+ {
+ USB_BUSY, "USB_BUSY"},
+ {
+ 0, NULL}
+ };
+
+ int i;
+ static char msg[20];
+
+ for (i = 0; errs[i].err != 0; i++)
+ if (errs[i].err == err)
+ {
+ return errs[i].str;
+ }
+
+ sprintf (msg, "Err %d", err);
+ return msg;
+}
+
+static char *
+usb_cb_err (int err)
+{
+
+ static struct errmsg_
+ {
+ int err;
+ char *str;
+ } errs[] =
+ {
+ {
+ USB_CB_STALL_CLEARED, "USB_CB_STALL_CLEARED"},
+ {
+ USB_CB_FUNCTIONAL_STALL, "USB_CB_FUNCTIONAL_STALL"},
+ {
+ USB_CB_PROTOCOL_STALL, "USB_CB_PROTOCOL_STALL"},
+ {
+ USB_CB_RESET_PIPE, "USB_CB_RESET_PIPE"},
+ {
+ USB_CB_ASYNC_REQ_FAILED, "USB_CB_ASYNC_REQ_FAILED"},
+ {
+ USB_CB_NO_RESOURCES, "USB_CB_NO_RESOURCES"},
+ {
+ USB_CB_SUBMIT_FAILED, "USB_CB_SUBMIT_FAILED"},
+ {
+ USB_CB_INTR_CONTEXT, "USB_CB_INTR_CONTEXT"},
+ {
+ USB_FAILURE, "USB_FAILURE"},
+ {
+ USB_NO_RESOURCES, "USB_NO_RESOURCES"},
+ {
+ USB_NO_BANDWIDTH, "USB_NO_BANDWIDTH"},
+ {
+ USB_NOT_SUPPORTED, "USB_NOT_SUPPORTED"},
+ {
+ USB_PIPE_ERROR, "USB_PIPE_ERROR"},
+ {
+ USB_INVALID_PIPE, "USB_INVALID_PIPE"},
+ {
+ USB_NO_FRAME_NUMBER, "USB_NO_FRAME_NUMBER"},
+ {
+ USB_INVALID_START_FRAME, "USB_INVALID_START_FRAME"},
+ {
+ USB_HC_HARDWARE_ERROR, "USB_HC_HARDWARE_ERROR"},
+ {
+ USB_INVALID_REQUEST, "USB_INVALID_REQUEST"},
+ {
+ USB_INVALID_CONTEXT, "USB_INVALID_CONTEXT"},
+ {
+ USB_INVALID_VERSION, "USB_INVALID_VERSION"},
+ {
+ USB_INVALID_ARGS, "USB_INVALID_ARGS"},
+ {
+ USB_INVALID_PERM, "USB_INVALID_PERM"},
+ {
+ USB_BUSY, "USB_BUSY"},
+ {
+ 0, NULL}
+ };
+
+ int i;
+ static char msg[20];
+
+ if (err == 0)
+ return "USB_CB_NO_INFO";
+
+ for (i = 0; errs[i].err != 0; i++)
+ {
+ if (errs[i].err == err)
+ {
+ return errs[i].str;
+ }
+ }
+
+ sprintf (msg, "CB Err %d", err);
+ return msg;
+}
+
+static char *
+usb_cr_err (int err)
+{
+
+ static struct errmsg_
+ {
+ int err;
+ char *str;
+ } errs[] =
+ {
+ {
+ USB_CR_CRC, "USB_CR_CRC"},
+ {
+ USB_CR_BITSTUFFING, "USB_CR_BITSTUFFING"},
+ {
+ USB_CR_DATA_TOGGLE_MM, "USB_CR_DATA_TOGGLE_MM"},
+ {
+ USB_CR_STALL, "USB_CR_STALL"},
+ {
+ USB_CR_DEV_NOT_RESP, "USB_CR_DEV_NOT_RESP"},
+ {
+ USB_CR_PID_CHECKFAILURE, "USB_CR_PID_CHECKFAILURE"},
+ {
+ USB_CR_UNEXP_PID, "USB_CR_UNEXP_PID"},
+ {
+ USB_CR_DATA_OVERRUN, "USB_CR_DATA_OVERRUN"},
+ {
+ USB_CR_DATA_UNDERRUN, "USB_CR_DATA_UNDERRUN"},
+ {
+ USB_CR_BUFFER_OVERRUN, "USB_CR_BUFFER_OVERRUN"},
+ {
+ USB_CR_BUFFER_UNDERRUN, "USB_CR_BUFFER_UNDERRUN"},
+ {
+ USB_CR_TIMEOUT, "USB_CR_TIMEOUT"},
+ {
+ USB_CR_NOT_ACCESSED, "USB_CR_NOT_ACCESSED"},
+ {
+ USB_CR_NO_RESOURCES, "USB_CR_NO_RESOURCES"},
+ {
+ USB_CR_UNSPECIFIED_ERR, "USB_CR_UNSPECIFIED_ERR"},
+ {
+ USB_CR_STOPPED_POLLING, "USB_CR_STOPPED_POLLING"},
+ {
+ USB_CR_PIPE_CLOSING, "USB_CR_PIPE_CLOSING"},
+ {
+ USB_CR_PIPE_RESET, "USB_CR_PIPE_RESET"},
+ {
+ USB_CR_NOT_SUPPORTED, "USB_CR_NOT_SUPPORTED"},
+ {
+ USB_CR_FLUSHED, "USB_CR_FLUSHED"},
+ {
+ USB_CR_HC_HARDWARE_ERR, "USB_CR_HC_HARDWARE_ERR"},
+ {
+ 0, NULL}
+ };
+
+ int i;
+ static char msg[20];
+
+ if (err == 0)
+ return "USB_CR_OK";
+
+ for (i = 0; errs[i].err != 0; i++)
+ {
+ if (errs[i].err == err)
+ {
+ return errs[i].str;
+ }
+ }
+
+ sprintf (msg, "CR Err %d", err);
+ return msg;
+}
+
+void
+udi_unload_usbdriver (oss_device_t * osdev)
+{
+ udi_usb_devc *usbdev = osdev->usbdev;
+
+ if (usbdev == NULL)
+ return;
+
+ if (usbdev->client_disconnect != NULL)
+ usbdev->client_disconnect (usbdev->client_devc);
+ usb_client_detach (osdev->dip, usbdev->dev_data);
+
+ KERNEL_FREE (usbdev);
+ osdev->usbdev = NULL;
+}
+
+/*
+ * Device access routines
+ */
+
+int
+udi_usbdev_get_class (udi_usb_devc * usbdev)
+{
+ udi_usb_devc *devc = (udi_usb_devc *) usbdev;
+
+ return devc->dev_data->dev_curr_cfg->cfg_if[devc->dev_data->dev_curr_if].
+ if_alt[0].altif_descr.bInterfaceClass;
+}
+
+int
+udi_usbdev_get_subclass (udi_usb_devc * usbdev)
+{
+ udi_usb_devc *devc = (udi_usb_devc *) usbdev;
+
+ return devc->dev_data->dev_curr_cfg->cfg_if[devc->dev_data->dev_curr_if].
+ if_alt[0].altif_descr.bInterfaceSubClass;
+}
+
+int
+udi_usbdev_get_vendor (udi_usb_devc * usbdev)
+{
+ udi_usb_devc *devc = (udi_usb_devc *) usbdev;
+
+ return devc->dev_data->dev_descr->idVendor;
+}
+
+int
+udi_usbdev_get_product (udi_usb_devc * usbdev)
+{
+ udi_usb_devc *devc = (udi_usb_devc *) usbdev;
+
+ return devc->dev_data->dev_descr->idProduct;
+}
+
+int
+udi_usbdev_get_inum (udi_usb_devc * usbdev)
+{
+ udi_usb_devc *devc = (udi_usb_devc *) usbdev;
+
+ return devc->dev_data->dev_curr_if;
+}
+
+int
+udi_usbdev_set_interface (udi_usb_devc * usbdev, int inum, int altset)
+{
+ //udi_usb_devc *devc = (udi_usb_devc *) usbdev;
+
+ if (usb_set_alt_if (usbdev->osdev->dip, inum, altset, USB_FLAGS_SLEEP,
+ NULL, 0) != USB_SUCCESS)
+ {
+ return OSS_EIO;
+ }
+
+ return 0;
+}
+
+unsigned char *
+udi_usbdev_get_endpoint (udi_usb_devc * usbdev, int altsetting, int n,
+ int *len)
+{
+ usb_alt_if_data_t *altif_data;
+ usb_client_dev_data_t *dev_data;
+
+ *len = 0;
+
+ if (usbdev->dev_data == NULL)
+ {
+ cmn_err (CE_WARN, "Missing USB devdata\n");
+ return NULL;
+ }
+ dev_data = usbdev->dev_data;
+
+ if (altsetting < 0
+ || altsetting >=
+ dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt)
+ {
+ return NULL;
+ }
+
+ altif_data = &dev_data->dev_curr_cfg->
+ cfg_if[dev_data->dev_curr_if].if_alt[altsetting];
+
+ if (altif_data == NULL)
+ return NULL;
+
+ if (n < 0 || n >= altif_data->altif_n_ep)
+ return NULL;
+
+ *len = altif_data->altif_ep[n].ep_descr.bLength;
+ return (unsigned char *) &altif_data->altif_ep[n].ep_descr;
+}
+
+int
+udi_usbdev_get_num_altsettings (udi_usb_devc * usbdev)
+{
+ //udi_usb_devc *devc = (udi_usb_devc *) usbdev;
+ usb_client_dev_data_t *dev_data;
+
+ dev_data = usbdev->dev_data;
+ return dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt;
+}
+
+unsigned char *
+udi_usbdev_get_altsetting (udi_usb_devc * usbdev, int nalt, int *size)
+{
+ int i, n;
+ usb_cvs_data_t *cvs;
+ usb_alt_if_data_t *altif_data;
+ usb_client_dev_data_t *dev_data;
+ static unsigned char buf[1024];
+
+ dev_data = usbdev->dev_data;
+ if ((unsigned long) dev_data <= 4096)
+ {
+ cmn_err (CE_WARN, "Internal error: dev_data==NULL)\n");
+ return NULL;
+ }
+
+ if (nalt < 0
+ || nalt >=
+ dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if].if_n_alt)
+ {
+ return NULL;
+ }
+
+ altif_data = &dev_data->dev_curr_cfg->
+ cfg_if[dev_data->dev_curr_if].if_alt[nalt];
+
+ if (altif_data == NULL)
+ return NULL;
+
+ n = 0;
+
+ for (i = 0; i < altif_data->altif_n_cvs; i++)
+ {
+ cvs = &altif_data->altif_cvs[i];
+ memcpy (buf + n, cvs->cvs_buf, cvs->cvs_buf_len);
+ n += cvs->cvs_buf_len;
+ }
+
+ cvs = &altif_data->altif_cvs[0];
+ if (cvs == NULL || cvs->cvs_buf == NULL)
+ return NULL;
+
+ *size = n;
+ return buf;
+}
+
+char *
+udi_usbdev_get_name (udi_usb_devc * usbdev)
+{
+ udi_usb_devc *devc = (udi_usb_devc *) usbdev;
+
+ return devc->name;
+}
+
+char *
+udi_usbdev_get_altsetting_labels (udi_usb_devc * usbdev, int if_num,
+ int *default_alt, unsigned int *mask)
+{
+ int i;
+
+ *default_alt = 1;
+ *mask = 0xffffffff;
+
+ if (usbdev->udi_usb_dev == NULL) /* No device definitions available */
+ {
+ return NULL;
+ }
+
+ for (i = 0; usbdev->udi_usb_dev->altsettings[i].altsetting_labels != NULL;
+ i++)
+ if (i == if_num)
+ {
+ *default_alt = usbdev->udi_usb_dev->altsettings[i].default_altsetting;
+ *mask = usbdev->udi_usb_dev->altsettings[i].altsetting_mask;
+ if (*mask == 0)
+ *mask = 0xffffffff;
+ return usbdev->udi_usb_dev->altsettings[i].altsetting_labels;
+ }
+
+ return NULL; /* Not found */
+}
+
+char *
+udi_usbdev_get_string (udi_usb_devc * usbdev, int ix)
+{
+ static char str[256];
+
+ if (usb_get_string_descr
+ (usbdev->osdev->dip, USB_LANG_ID, ix, str,
+ sizeof (str) - 1) != USB_SUCCESS)
+ return NULL;
+ return str;
+}
+
+char *
+udi_usbdev_get_devpath (udi_usb_devc * usbdev)
+{
+ udi_usb_devc *devc = (udi_usb_devc *) usbdev;
+
+ return devc->devpath;
+}
+
+/*ARGSUSED*/
+int
+udi_usb_snd_control_msg (udi_usb_devc * usbdev, unsigned int endpoint,
+ unsigned char rq,
+ unsigned char rqtype,
+ unsigned short value,
+ unsigned short index,
+ void *buf, int len, int timeout)
+{
+
+ int err;
+
+ usb_ctrl_setup_t setup;
+ usb_cr_t completion_reason;
+ usb_cb_flags_t cb_flags;
+ mblk_t *data = NULL;
+
+ if (usbdev == NULL)
+ {
+ cmn_err (CE_CONT, "udi_usb_snd_control_msg: usbdev==NULL\n");
+ return OSS_EFAULT;
+ }
+
+ data = allocb_wait (len + 1, BPRI_HI, STR_NOSIG, NULL);
+
+ memcpy (data->b_wptr, buf, len);
+ data->b_wptr = data->b_rptr + len;
+
+ setup.bmRequestType = rqtype | USB_DEV_REQ_HOST_TO_DEV;
+ setup.bRequest = rq;
+ setup.wValue = value;
+ setup.wIndex = index;
+ setup.wLength = len;
+ setup.attrs = 0;
+
+ if ((err = usb_pipe_ctrl_xfer_wait (usbdev->dev_data->dev_default_ph,
+ &setup,
+ &data,
+ &completion_reason,
+ &cb_flags, 0)) != USB_SUCCESS)
+ {
+ char tmp[128], *s = tmp;
+ unsigned char *p = buf;
+ int i;
+
+ sprintf (s, "Msg (rq=0x%x, val=0x%04x, ix=0x%04x, len=%d): ", rq, value,
+ index, len);
+ for (i = 0; i < len; i++)
+ {
+ s += strlen (s);
+ sprintf (s, "%02x ", p[i]);
+ }
+ cmn_err (CE_CONT, "%s\n", tmp);
+
+ cmn_err (CE_NOTE, "usb_pipe_ctrl_xfer_wait write failed: %s (%s)\n",
+ usb_errstr (err), usb_cb_err (completion_reason));
+ cmn_err (CE_CONT, "bRq %x, wIx %x, wVal %x, wLen %d\n", rq, index,
+ value, len);
+ freemsg (data);
+ return OSS_EIO;
+ }
+
+ freemsg (data);
+ return len;
+}
+
+/*ARGSUSED*/
+int
+udi_usb_rcv_control_msg (udi_usb_devc * usbdev, unsigned int endpoint,
+ unsigned char rq,
+ unsigned char rqtype,
+ unsigned short value,
+ unsigned short index,
+ void *buf, int len, int timeout)
+{
+ int err, l;
+
+ usb_ctrl_setup_t setup;
+ usb_cr_t completion_reason;
+ usb_cb_flags_t cb_flags;
+ mblk_t *data = NULL;
+
+ if (usbdev == NULL)
+ {
+ cmn_err (CE_CONT, "udi_usb_rcv_control_msg: usbdev==NULL\n");
+ return OSS_EFAULT;
+ }
+
+ setup.bmRequestType = rqtype | USB_DEV_REQ_DEV_TO_HOST;
+ setup.bRequest = rq;
+ setup.wValue = value;
+ setup.wIndex = index;
+ setup.wLength = len;
+ setup.attrs = 0;
+
+ if ((err = usb_pipe_ctrl_xfer_wait (usbdev->dev_data->dev_default_ph,
+ &setup,
+ &data,
+ &completion_reason,
+ &cb_flags, 0)) != USB_SUCCESS)
+ {
+ char tmp[128], *s = tmp;
+
+ sprintf (s, "Msg (rq=0x%02x, val=0x%04x, ix=0x%04x, len=%d): ", rq,
+ value, index, len);
+ cmn_err (CE_CONT, "%s\n", tmp);
+ cmn_err (CE_NOTE, "usb_pipe_ctrl_xfer_wait read failed: %s (%s)\n",
+ usb_errstr (err), usb_cb_err (completion_reason));
+ freemsg (data);
+ return OSS_EIO;
+ }
+
+ /*LINTED*/ l = data->b_wptr - data->b_rptr;
+
+ memcpy (buf, data->b_rptr, l);
+ freemsg (data);
+
+ return l;
+}
+
+/* Endpoint/pipe access */
+
+struct _udi_endpoint_handle_t
+{
+ usb_pipe_handle_t pipe_handle;
+ unsigned char *ep_desc;
+ udi_usb_devc *usbdev;
+};
+
+udi_endpoint_handle_t *
+udi_open_endpoint (udi_usb_devc * usbdev, void *ep_desc)
+{
+ udi_endpoint_handle_t *h;
+ int err;
+ usb_pipe_policy_t policy;
+
+ if ((h = KERNEL_MALLOC (sizeof (*h))) == NULL)
+ return NULL;
+
+ policy.pp_max_async_reqs = 2;
+
+ if ((err = usb_pipe_open (usbdev->osdev->dip, ep_desc, &policy,
+ USB_FLAGS_SLEEP, &h->pipe_handle)) != USB_SUCCESS)
+ {
+ cmn_err (CE_WARN, "usb_pipe_open() failed %d (%s)\n", err,
+ usb_cb_err (err));
+ KERNEL_FREE (h);
+ return NULL;
+ }
+
+ h->ep_desc = ep_desc;
+ h->usbdev = usbdev;
+
+ return h;
+}
+
+void
+udi_close_endpoint (udi_endpoint_handle_t * h)
+{
+ usb_pipe_close (h->usbdev->osdev->dip, h->pipe_handle, USB_FLAGS_SLEEP,
+ NULL, 0);
+ KERNEL_FREE (h);
+}
+
+int
+udi_endpoint_get_num (udi_endpoint_handle_t * eph)
+{
+ return eph->ep_desc[2] & 0xff;
+}
+
+/* Request stuff */
+
+struct udi_usb_request
+{
+ dev_info_t *dip;
+ usb_pipe_handle_t pipe_handle;
+ udi_usb_complete_func_t callback;
+ void *callback_arg;
+ int active;
+ int xfer_type;
+ mblk_t *data;
+
+ /*
+ * Recording
+ */
+ int actlen;
+
+ usb_isoc_req_t *isoc_req;
+ usb_bulk_req_t *bulk_req;
+ usb_intr_req_t *intr_req;
+};
+
+ /*ARGSUSED*/
+ udi_usb_request_t
+ * udi_usb_alloc_request (udi_usb_devc * usbdev, udi_endpoint_handle_t * eph,
+ int nframes, int xfer_type)
+{
+ udi_usb_request_t *req;
+
+ if ((req = KERNEL_MALLOC (sizeof (*req))) == NULL)
+ {
+ cmn_err (CE_WARN, "udi_usb_alloc_request: Out of memory\n");
+ return NULL;
+ }
+
+ req->xfer_type = xfer_type;
+ req->dip = usbdev->osdev->dip;
+ req->pipe_handle = eph->pipe_handle;
+
+ switch (xfer_type)
+ {
+ case UDI_USBXFER_ISO_READ:
+ return req;
+ break;
+
+ case UDI_USBXFER_ISO_WRITE:
+ return req;
+ break;
+
+ case UDI_USBXFER_BULK_READ:
+ return req;
+ break;
+
+ case UDI_USBXFER_INTR_READ:
+ return req;
+ break;
+
+ case UDI_USBXFER_BULK_WRITE:
+ return req;
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Internal error - bad transfer type %d\n", xfer_type);
+ KERNEL_FREE (req);
+ return NULL;
+ }
+}
+
+void
+udi_usb_free_request (udi_usb_request_t * req)
+{
+ if (req == NULL)
+ return;
+
+ udi_usb_cancel_request (req);
+
+ if (req->active)
+ {
+ cmn_err (CE_WARN, "Warning: Freeing active request\n");
+ }
+
+ switch (req->xfer_type)
+ {
+ case UDI_USBXFER_ISO_WRITE:
+ req->isoc_req = NULL;
+ break;
+
+ case UDI_USBXFER_ISO_READ:
+ req->isoc_req = NULL;
+ break;
+
+ case UDI_USBXFER_BULK_WRITE:
+ req->bulk_req = NULL;
+ break;
+
+ case UDI_USBXFER_BULK_READ:
+ req->bulk_req = NULL;
+ break;
+
+ case UDI_USBXFER_INTR_READ:
+ req->intr_req = NULL;
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Internal error - bad transfer type %d\n",
+ req->xfer_type);
+ }
+
+ KERNEL_FREE (req);
+}
+
+/*ARGSUSED*/
+static void
+isoc_play_callback (usb_pipe_handle_t ph, usb_isoc_req_t * isoc_req)
+{
+ udi_usb_request_t *req =
+ (udi_usb_request_t *) isoc_req->isoc_client_private;
+
+ usb_free_isoc_req (isoc_req);
+
+ req->isoc_req = NULL;
+ req->active = 0;
+
+ req->callback (req, req->callback_arg);
+}
+
+/*ARGSUSED*/
+static void
+isoc_rec_callback (usb_pipe_handle_t ph, usb_isoc_req_t * isoc_req)
+{
+ int i;
+ udi_usb_request_t *req =
+ (udi_usb_request_t *) isoc_req->isoc_client_private;
+
+ req->data = isoc_req->isoc_data;
+
+ for (i = 0; i < isoc_req->isoc_pkts_count; i++)
+ {
+ int len;
+
+ len = isoc_req->isoc_pkt_descr[i].isoc_pkt_actual_length;
+
+ req->actlen = len;
+
+ req->callback (req, req->callback_arg);
+
+ req->data->b_rptr += len;
+ }
+
+ req->active = 0;
+ usb_free_isoc_req (isoc_req);
+}
+
+/*ARGSUSED*/
+static void
+isoc_exc_callback (usb_pipe_handle_t ph, usb_isoc_req_t * isoc_req)
+{
+ udi_usb_request_t *req =
+ (udi_usb_request_t *) isoc_req->isoc_client_private;
+ usb_cr_t reason;
+
+ reason = isoc_req->isoc_completion_reason;
+
+ usb_free_isoc_req (isoc_req);
+ req->isoc_req = NULL;
+ req->active = 0;
+
+ if (reason && reason != USB_CR_FLUSHED && reason != USB_CR_PIPE_CLOSING)
+ cmn_err (CE_CONT, "USB isoc transfer completion status %s\n",
+ usb_cr_err (reason));
+}
+
+/*ARGSUSED*/
+void
+bulk_play_callback (usb_pipe_handle_t ph, usb_bulk_req_t * bulk_req)
+{
+ udi_usb_request_t *req =
+ (udi_usb_request_t *) bulk_req->bulk_client_private;
+
+ usb_free_bulk_req (bulk_req);
+
+ req->bulk_req = NULL;
+ req->active = 0;
+
+ req->callback (req, req->callback_arg);
+}
+
+/*ARGSUSED*/
+void
+bulk_rec_callback (usb_pipe_handle_t ph, usb_bulk_req_t * bulk_req)
+{
+ udi_usb_request_t *req =
+ (udi_usb_request_t *) bulk_req->bulk_client_private;
+
+ req->data = bulk_req->bulk_data;
+ req->actlen = bulk_req->bulk_len;
+ req->active = 0;
+
+ req->callback (req, req->callback_arg);
+ //usb_free_bulk_req (bulk_req);
+}
+
+/*ARGSUSED*/
+static void
+bulk_exc_callback (usb_pipe_handle_t ph, usb_bulk_req_t * bulk_req)
+{
+ udi_usb_request_t *req =
+ (udi_usb_request_t *) bulk_req->bulk_client_private;
+ usb_cr_t reason;
+
+ reason = bulk_req->bulk_completion_reason;
+
+ usb_free_bulk_req (bulk_req);
+ req->bulk_req = NULL;
+ req->active = 0;
+
+ if (reason && reason != USB_CR_FLUSHED && reason != USB_CR_PIPE_CLOSING)
+ cmn_err (CE_CONT, "USB bulk transfer completion status %s\n",
+ usb_cr_err (reason));
+}
+
+/*ARGSUSED*/
+void
+intr_rec_callback (usb_pipe_handle_t ph, usb_intr_req_t * intr_req)
+{
+ udi_usb_request_t *req =
+ (udi_usb_request_t *) intr_req->intr_client_private;
+
+ req->data = intr_req->intr_data;
+ req->actlen = intr_req->intr_len;
+ req->active = 0;
+
+ req->callback (req, req->callback_arg);
+ //usb_free_intr_req (intr_req);
+}
+
+/*ARGSUSED*/
+static void
+intr_exc_callback (usb_pipe_handle_t ph, usb_intr_req_t * intr_req)
+{
+ udi_usb_request_t *req =
+ (udi_usb_request_t *) intr_req->intr_client_private;
+ usb_cr_t reason;
+
+ reason = intr_req->intr_completion_reason;
+
+ usb_free_intr_req (intr_req);
+ req->intr_req = NULL;
+ req->active = 0;
+
+ if (reason && reason != USB_CR_FLUSHED && reason != USB_CR_PIPE_CLOSING)
+ cmn_err (CE_CONT, "USB intr transfer completion status %s\n",
+ usb_cr_err (reason));
+}
+
+/*ARGSUSED*/
+int
+udi_usb_submit_request (udi_usb_request_t * req,
+ udi_usb_complete_func_t callback, void *callback_arg,
+ udi_endpoint_handle_t * eph, int xfer_type,
+ void *data, int len)
+{
+ int err;
+
+ req->callback = callback;
+ req->callback_arg = callback_arg;
+
+ if (req->active)
+ return 0;
+
+ switch (xfer_type)
+ {
+ case UDI_USBXFER_ISO_WRITE:
+ {
+ usb_isoc_req_t *isoc_req;
+
+ if (req->isoc_req != NULL)
+ isoc_req = req->isoc_req;
+ else
+ {
+ req->data = allocb (len, BPRI_HI);
+ if (req->data == NULL)
+ {
+ cmn_err (CE_WARN, "allocb_wait (isoc) failed\n");
+ KERNEL_FREE (req);
+ return OSS_ENOMEM;
+ }
+
+ if ((isoc_req = usb_alloc_isoc_req (req->dip, 1, 0, 0)) == NULL)
+ {
+ cmn_err (CE_WARN, "usb_alloc_isoc_req failed\n");
+ freemsg (req->data);
+ KERNEL_FREE (req);
+ return OSS_ENOMEM;
+ }
+ req->isoc_req = isoc_req;
+ }
+
+ if (isoc_req == NULL)
+ {
+ cmn_err (CE_WARN, "req->isoc==NULL\n");
+ return OSS_EIO;
+ }
+
+ memcpy (req->data->b_wptr, data, len);
+ req->data->b_wptr += len;
+
+ isoc_req->isoc_data = req->data;
+ isoc_req->isoc_pkt_descr[0].isoc_pkt_length = len;
+ isoc_req->isoc_pkts_count = 1;
+ isoc_req->isoc_pkts_length = len;
+ isoc_req->isoc_attributes =
+ USB_ATTRS_ISOC_XFER_ASAP | USB_ATTRS_AUTOCLEARING;
+ isoc_req->isoc_cb = isoc_play_callback;
+ isoc_req->isoc_exc_cb = isoc_exc_callback;
+ isoc_req->isoc_client_private = (usb_opaque_t) req;
+
+ if ((err =
+ usb_pipe_isoc_xfer (req->pipe_handle, isoc_req,
+ 0)) != USB_SUCCESS)
+ {
+ cmn_err (CE_WARN, "usb_pipe_isoc_xfer failed (%s)\n",
+ usb_errstr (err));
+ return OSS_EIO;
+ }
+ req->active = 1;
+ }
+ break;
+
+ case UDI_USBXFER_ISO_READ:
+ {
+ usb_isoc_req_t *isoc_req;
+
+ if (req->isoc_req != NULL)
+ isoc_req = req->isoc_req;
+ else
+ {
+ if ((isoc_req =
+ usb_alloc_isoc_req (req->dip, 1, len,
+ USB_FLAGS_SLEEP)) == NULL)
+ {
+ cmn_err (CE_WARN, "usb_alloc_isoc_req failed\n");
+ KERNEL_FREE (req);
+ return OSS_ENOMEM;
+ }
+ req->isoc_req = isoc_req;
+ }
+
+ if (isoc_req == NULL)
+ {
+ cmn_err (CE_WARN, "req->isoc==NULL\n");
+ return OSS_EIO;
+ }
+
+ isoc_req->isoc_attributes = USB_ATTRS_ISOC_XFER_ASAP;
+ isoc_req->isoc_cb = isoc_rec_callback;
+ isoc_req->isoc_exc_cb = isoc_exc_callback;
+ isoc_req->isoc_client_private = (usb_opaque_t) req;
+ isoc_req->isoc_pkt_descr[0].isoc_pkt_length = len;
+ isoc_req->isoc_pkts_count = 1;
+ isoc_req->isoc_pkts_length = len;
+ req->active = 1;
+
+ if ((err =
+ usb_pipe_isoc_xfer (req->pipe_handle, isoc_req,
+ USB_FLAGS_NOSLEEP)) != USB_SUCCESS)
+ {
+ cmn_err (CE_WARN, "usb_pipe_isoc_xfer failed (%s)\n",
+ usb_errstr (err));
+ return OSS_EIO;
+ }
+ }
+ break;
+
+ case UDI_USBXFER_BULK_WRITE:
+ {
+ usb_bulk_req_t *bulk_req;
+
+ if (req->bulk_req != NULL)
+ bulk_req = req->bulk_req;
+ else
+ {
+ req->data = allocb (len, BPRI_HI);
+ if (req->data == NULL)
+ {
+ cmn_err (CE_WARN, "allocb_wait (bulk) failed\n");
+ KERNEL_FREE (req);
+ return OSS_ENOMEM;
+ }
+
+ if ((bulk_req = usb_alloc_bulk_req (req->dip, len, 0)) == NULL)
+ {
+ cmn_err (CE_WARN, "usb_alloc_bulk_req failed\n");
+ freemsg (req->data);
+ KERNEL_FREE (req);
+ return OSS_ENOMEM;
+ }
+ req->bulk_req = bulk_req;
+ }
+
+ if (bulk_req == NULL)
+ {
+ cmn_err (CE_WARN, "req->bulk==NULL\n");
+ return OSS_EIO;
+ }
+
+ memcpy (req->data->b_wptr, data, len);
+ req->data->b_wptr += len;
+
+ bulk_req->bulk_data = req->data;
+ bulk_req->bulk_len = len;
+ bulk_req->bulk_timeout = 5; /* 5 seconds */
+ bulk_req->bulk_attributes = USB_ATTRS_AUTOCLEARING;
+ bulk_req->bulk_cb = bulk_play_callback;
+ bulk_req->bulk_exc_cb = bulk_exc_callback;
+ bulk_req->bulk_client_private = (usb_opaque_t) req;
+
+ if ((err =
+ usb_pipe_bulk_xfer (req->pipe_handle, bulk_req,
+ 0)) != USB_SUCCESS)
+ {
+ cmn_err (CE_WARN, "usb_pipe_bulk_xfer failed (%s)\n",
+ usb_errstr (err));
+ return OSS_EIO;
+ }
+ req->active = 1;
+ }
+ break;
+
+ case UDI_USBXFER_BULK_READ:
+ {
+ usb_bulk_req_t *bulk_req;
+
+ if (req->bulk_req != NULL)
+ bulk_req = req->bulk_req;
+ else
+ {
+#if 0
+ req->data = allocb (len, BPRI_HI);
+ if (req->data == NULL)
+ {
+ cmn_err (CE_WARN, "allocb_wait (bulk) failed\n");
+ KERNEL_FREE (req);
+ return OSS_ENOMEM;
+ }
+#endif
+
+ if ((bulk_req =
+ usb_alloc_bulk_req (req->dip, len, USB_FLAGS_SLEEP)) == NULL)
+ {
+ cmn_err (CE_WARN, "usb_alloc_bulk_req failed\n");
+ freemsg (req->data);
+ KERNEL_FREE (req);
+ return OSS_ENOMEM;
+ }
+ req->bulk_req = bulk_req;
+ }
+
+ if (bulk_req == NULL)
+ {
+ cmn_err (CE_WARN, "req->bulk==NULL\n");
+ return OSS_EIO;
+ }
+
+ bulk_req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK;
+ bulk_req->bulk_cb = bulk_rec_callback;
+ bulk_req->bulk_exc_cb = bulk_exc_callback;
+ bulk_req->bulk_client_private = (usb_opaque_t) req;
+ // bulk_req->bulk_data = data;
+ bulk_req->bulk_len = len;
+ bulk_req->bulk_timeout = 0x7fffffff; /* As long as possible */
+ req->active = 1;
+
+ if ((err =
+ usb_pipe_bulk_xfer (req->pipe_handle, bulk_req,
+ USB_FLAGS_NOSLEEP)) != USB_SUCCESS)
+ {
+ cmn_err (CE_WARN, "usb_pipe_bulk_xfer failed (%s)\n",
+ usb_errstr (err));
+ return OSS_EIO;
+ }
+ }
+ break;
+
+ case UDI_USBXFER_INTR_READ:
+ {
+ usb_intr_req_t *intr_req;
+
+ if (req->intr_req != NULL)
+ intr_req = req->intr_req;
+ else
+ {
+#if 0
+ req->data = allocb (len, BPRI_HI);
+ if (req->data == NULL)
+ {
+ cmn_err (CE_WARN, "allocb_wait (intr) failed\n");
+ KERNEL_FREE (req);
+ return OSS_ENOMEM;
+ }
+#endif
+
+ if ((intr_req =
+ usb_alloc_intr_req (req->dip, len, USB_FLAGS_SLEEP)) == NULL)
+ {
+ cmn_err (CE_WARN, "usb_alloc_intr_req failed\n");
+ freemsg (req->data);
+ KERNEL_FREE (req);
+ return OSS_ENOMEM;
+ }
+ req->intr_req = intr_req;
+ }
+
+ if (intr_req == NULL)
+ {
+ cmn_err (CE_WARN, "req->intr==NULL\n");
+ return OSS_EIO;
+ }
+
+ intr_req->intr_attributes =
+ USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_ONE_XFER;
+ intr_req->intr_cb = intr_rec_callback;
+ intr_req->intr_exc_cb = intr_exc_callback;
+ intr_req->intr_client_private = (usb_opaque_t) req;
+ intr_req->intr_data = NULL;
+ intr_req->intr_len = len;
+ intr_req->intr_timeout = 0x7fffffff; /* As long as possible */
+ req->active = 1;
+
+ if ((err =
+ usb_pipe_intr_xfer (req->pipe_handle, intr_req,
+ 0)) != USB_SUCCESS)
+ {
+ cmn_err (CE_WARN, "usb_pipe_intr_xfer failed (%s)\n",
+ usb_errstr (err));
+ return OSS_EIO;
+ }
+ }
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Unimplemented transfer type %d\n", xfer_type);
+ return OSS_EIO;
+ }
+
+ return 0;
+}
+
+int
+udi_usb_request_actlen (udi_usb_request_t * request)
+{
+ return request->actlen;
+}
+
+unsigned char *
+udi_usb_request_actdata (udi_usb_request_t * request)
+{
+ return request->data->b_rptr;
+}
+
+void
+udi_usb_cancel_request (udi_usb_request_t * req)
+{
+ if (req == NULL || !req->active)
+ return;
+
+ req->active = 0;
+ usb_pipe_reset (req->dip, req->pipe_handle, USB_FLAGS_SLEEP, NULL, 0);
+
+ switch (req->xfer_type)
+ {
+ case UDI_USBXFER_ISO_WRITE:
+ break;
+
+ case UDI_USBXFER_ISO_READ:
+ usb_pipe_stop_isoc_polling (req->pipe_handle, USB_FLAGS_SLEEP);
+ //if (req->isoc_req!=NULL)
+ //usb_free_isoc_req(req->isoc_req);
+ req->isoc_req = NULL;
+ break;
+
+ case UDI_USBXFER_BULK_WRITE:
+ break;
+
+ case UDI_USBXFER_BULK_READ:
+ req->bulk_req = NULL;
+ break;
+
+ case UDI_USBXFER_INTR_READ:
+ req->intr_req = NULL;
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Internal error - bad transfer type %d\n",
+ req->xfer_type);
+ }
+}
+#endif
diff --git a/kernel/OS/VxWorks/.config b/kernel/OS/VxWorks/.config
new file mode 100644
index 0000000..816ac62
--- /dev/null
+++ b/kernel/OS/VxWorks/.config
@@ -0,0 +1 @@
+mode=kernel
diff --git a/kernel/OS/VxWorks/linux/ioctl.h b/kernel/OS/VxWorks/linux/ioctl.h
new file mode 100644
index 0000000..937d84c
--- /dev/null
+++ b/kernel/OS/VxWorks/linux/ioctl.h
@@ -0,0 +1,5 @@
+/*
+ * This file is currently required when cross compiling
+ * for VxWorks under Linux.
+ */
+#include <sys/ioctl.h>
diff --git a/kernel/OS/VxWorks/module.inc b/kernel/OS/VxWorks/module.inc
new file mode 100644
index 0000000..31f17f0
--- /dev/null
+++ b/kernel/OS/VxWorks/module.inc
@@ -0,0 +1,127 @@
+#if DRIVER_TYPE == DRV_PCI
+#include <drv/pci/pciConfigLib.h>
+#undef PCI_LATENCY_TIMER
+#include <oss_pci.h>
+
+int
+oss_pci_read_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char *val)
+{
+ oss_pci_device_t *pd = osdev->dip;
+
+ return pciConfigInByte (pd->bus, pd->dev, pd->func, where, val);
+}
+
+int
+oss_pci_read_config_irq (oss_device_t * osdev, offset_t where,
+ unsigned char *val)
+{
+ oss_pci_device_t *pd = osdev->dip;
+
+ return pciConfigInByte (pd->bus, pd->dev, pd->func, where, val);
+}
+
+int
+oss_pci_read_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short *val)
+{
+ oss_pci_device_t *pd = osdev->dip;
+
+ if (osdev == NULL)
+ {
+ cmn_err (CE_CONT, "oss_pci_read_config_word: osdev==NULL\n");
+ return PCIBIOS_FAILED;
+ }
+
+ return pciConfigInWord (pd->bus, pd->dev, pd->func, where, val);
+}
+
+int
+oss_pci_read_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int *val)
+{
+ oss_pci_device_t *pd = osdev->dip;
+
+ return pciConfigInLong (pd->bus, pd->dev, pd->func, where, val);
+}
+
+int
+oss_pci_write_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char val)
+{
+ oss_pci_device_t *pd = osdev->dip;
+
+ return pciConfigOutByte (pd->bus, pd->dev, pd->func, where, val);
+}
+
+int
+oss_pci_write_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short val)
+{
+ oss_pci_device_t *pd = osdev->dip;
+
+ return pciConfigOutWord (pd->bus, pd->dev, pd->func, where, val);
+}
+
+int
+oss_pci_write_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int val)
+{
+ oss_pci_device_t *pd = osdev->dip;
+
+ return pciConfigOutLong (pd->bus, pd->dev, pd->func, where, val);
+}
+#endif
+
+int
+DRIVER_NAME(void)
+{
+#if DRIVER_TYPE == DRV_PCI
+ int i;
+ int bus, dev, func;
+ unsigned int d, vendor_id, dev_id;
+ static int instance = 0;
+
+ if (id_table[0] == 0)
+ {
+ cmn_err (CE_WARN, DRIVER_NICK ": ID table is empty\n");
+ return OSS_EIO;
+ }
+
+ i=0;
+
+ while ((d=id_table[i]) != 0)
+ {
+ int index=0;
+ vendor_id = (d >> 16) & 0xffff;
+ dev_id = d & 0xffff;
+
+ while (pciFindDevice(vendor_id, dev_id, instance,&bus, &dev, &func) == OK)
+ {
+ oss_pci_device_t *pcidev = malloc(sizeof(*pcidev));
+ oss_device_t *osdev;
+
+
+ cmn_err(CE_CONT, "Found pci device %08x / %d : b=%d, d=%d, f=%d\n", d, index, bus, dev, func);
+
+ pcidev->bus = bus;
+ pcidev->dev = dev;
+ pcidev->func = func;
+
+ if ((osdev =
+ osdev_create ((dev_info_t*)pcidev, DRIVER_TYPE, instance++, DRIVER_NICK,
+ NULL)) == NULL)
+ {
+ return OSS_ENOMEM;
+ }
+
+ index++;
+ }
+
+ i++;
+ }
+
+#endif
+
+ return 0;
+}
diff --git a/kernel/OS/VxWorks/os_vxworks.c b/kernel/OS/VxWorks/os_vxworks.c
new file mode 100644
index 0000000..a679e6c
--- /dev/null
+++ b/kernel/OS/VxWorks/os_vxworks.c
@@ -0,0 +1,1133 @@
+/*
+ * oss_vxworks.c: Common entry points for OSS under VxWorks.
+ */
+
+#include <oss_config.h>
+#include <oss_pci.h>
+#include <drv/pci/pciConfigLib.h>
+#include <memLib.h>
+
+#if 0
+// TODO: Obsolete
+typedef struct oss_device_handle
+{
+ DEV_HDR devHdr;
+ int minor;
+ int valid; /* 1=valid, 0=undefined */
+ struct fileinfo finfo;
+}
+oss_device_handle;
+#endif
+/*
+ * Number of cards supported in the same system.
+ */
+#define MAX_CARDS 8
+
+static oss_device_t *cards[MAX_CARDS];
+int oss_num_cards = 0;
+
+static int oss_driver_num = ERROR;
+static int oss_expired = 0;
+static oss_device_t *core_osdev = NULL;
+
+int oss_hz = 100;
+
+void
+oss_cmn_err (int level, const char *s, ...)
+{
+ char tmp[1024], *a[6];
+ va_list ap;
+ int i, n = 0;
+
+ va_start (ap, s);
+
+ for (i = 0; i < strlen (s); i++)
+ if (s[i] == '%')
+ n++;
+
+ for (i = 0; i < n && i < 6; i++)
+ a[i] = ( (sizeof(char *) == 32) ? ( *((char * **)(ap += ((sizeof(char * *)+sizeof(int)-1) & ~(sizeof(int)-1))))[-1] ) : ( ((char * *)(ap += ((sizeof(char *)+sizeof(int)-1) & ~(sizeof(int)-1))))[-1] ));
+ //a[i] = va_arg (ap, char *); // This was supposed to be used instead of above. Unfortunately va_arg() seems to be buggy
+
+ for (i = n; i < 6; i++)
+ a[i] = NULL;
+
+ if (level == CE_CONT)
+ {
+ sprintf (tmp, s, a[0], a[1], a[2], a[3], a[4], a[5], NULL,
+ NULL, NULL, NULL);
+ printf ("%s", tmp);
+ }
+ else
+ {
+ strcpy (tmp, "osscore: ");
+ sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5],
+ NULL, NULL, NULL, NULL);
+
+ printf ("%s", tmp);
+ }
+
+ va_end (ap);
+}
+
+int
+oss_uiomove (void *addr, size_t nbytes, enum uio_rw rwflag, uio_t * uio)
+{
+/*
+ * NOTE! Returns 0 upon success and EFAULT on failure (instead of -EFAULT
+ * (for Solaris/BSD compatibility)).
+ */
+
+ if (rwflag != uio->rw)
+ {
+ oss_cmn_err (CE_WARN, "uiomove: Bad direction\n");
+ return EFAULT;
+ }
+
+ if (uio->resid < nbytes)
+ {
+ oss_cmn_err (CE_WARN, "uiomove: Bad count %d (%d)\n", nbytes,
+ uio->resid);
+ return EFAULT;
+ }
+
+ if (uio->kernel_space)
+ return EFAULT;
+
+ switch (rwflag)
+ {
+ case UIO_READ:
+ memcpy(uio->ptr, addr, nbytes);
+ break;
+
+ case UIO_WRITE:
+ memcpy(addr, uio->ptr, nbytes);
+ break;
+ }
+
+ uio->resid -= nbytes;
+ uio->ptr += nbytes;
+
+ return 0;
+}
+
+int
+oss_create_uio (uio_t * uio, char *buf, size_t count, uio_rw_t rw,
+ int is_kernel)
+{
+ memset (uio, 0, sizeof (*uio));
+
+ if (is_kernel)
+ {
+ oss_cmn_err (CE_CONT,
+ "oss_create_uio: Kernel space buffers not supported\n");
+ return -EIO;
+ }
+
+ uio->ptr = buf;
+ uio->resid = count;
+ uio->kernel_space = is_kernel;
+ uio->rw = rw;
+
+ return 0;
+}
+
+static int
+grow_array(oss_device_t *osdev, oss_cdev_t ***arr, int *size, int increment)
+{
+ oss_cdev_t **old=*arr, **new = *arr;
+ int old_size = *size;
+ int new_size = *size;
+
+ new_size += increment;
+
+ if ((new=PMALLOC(osdev, new_size * sizeof (oss_cdev_t *)))==NULL)
+ return 0;
+
+ memset(new, 0, new_size * sizeof(oss_cdev_t *));
+ if (old != NULL)
+ memcpy(new, old, old_size * sizeof(oss_cdev_t *));
+
+ *size = new_size;
+ *arr = new;
+
+ if (old != NULL)
+ PMFREE(osdev, old);
+
+ return 1;
+}
+
+static void
+register_chrdev(oss_cdev_t *cdev, char *name)
+{
+ if (iosDevAdd ((void *)cdev, name, oss_driver_num) == ERROR)
+ {
+ cmn_err (CE_WARN, "Failed to add device %s\n", name);
+ }
+}
+
+void
+oss_install_chrdev (oss_device_t * osdev, char *name, int dev_class,
+ int instance, oss_cdev_drv_t * drv, int flags)
+{
+/*
+ * oss_install_chrdev creates a character device (minor). However if
+ * name==NULL the device will not be exported (made visible to userland
+ * clients).
+ */
+
+ int num;
+ oss_cdev_t *cdev = NULL;
+
+ if (dev_class != OSS_DEV_STATUS)
+ if (oss_expired && instance > 0)
+ return;
+
+ if (oss_num_cdevs >= OSS_MAX_CDEVS)
+ {
+ if (!grow_array(osdev, &oss_cdevs, &oss_max_cdevs, 100))
+ {
+ cmn_err (CE_WARN, "Out of minor numbers.\n");
+ return;
+ }
+ }
+
+ if ((cdev = PMALLOC (NULL, sizeof (*cdev))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate character device desc.\n");
+ return;
+ }
+
+ num = oss_num_cdevs++;
+
+ memset (cdev, 0, sizeof (*cdev));
+ cdev->dev_class = dev_class;
+ cdev->instance = instance;
+ cdev->d = drv;
+ cdev->osdev = osdev;
+ if (name != NULL)
+ strncpy (cdev->name, name, sizeof (cdev->name));
+ else
+ strcpy (cdev->name, "NONE");
+ cdev->name[sizeof (cdev->name) - 1] = 0;
+ oss_cdevs[num] = cdev;
+
+/*
+ * Export the device only if name != NULL
+ */
+ if (name != NULL)
+ {
+ strcpy (cdev->name, name);
+ register_chrdev (cdev, name);
+ }
+}
+
+int
+oss_find_minor (int dev_class, int instance)
+{
+ int i;
+
+ for (i = 0; i < oss_num_cdevs; i++)
+ {
+ if (oss_cdevs[i]->d != NULL && oss_cdevs[i]->dev_class == dev_class
+ && oss_cdevs[i]->instance == instance)
+ return i;
+ }
+
+ return OSS_ENXIO;
+}
+
+static inline int
+cpy_file (int mode, struct fileinfo *fi)
+{
+ fi->mode = 0;
+ fi->acc_flags = mode;
+
+ if ((fi->acc_flags & O_ACCMODE) == O_RDWR)
+ fi->mode = OPEN_READWRITE;
+ if ((fi->acc_flags & O_ACCMODE) == O_RDONLY)
+ fi->mode = OPEN_READ;
+ if ((fi->acc_flags & O_ACCMODE) == O_WRONLY)
+ fi->mode = OPEN_WRITE;
+
+ return fi->mode;
+}
+
+static void *
+ossOpen (oss_cdev_t *cdev, char *reminder, int mode)
+{
+ int tmpdev, retval;
+ struct fileinfo fi;
+
+ cpy_file (mode, &fi);
+
+ DDB (cmn_err
+ (CE_CONT, "ossOpen(%p): %s, class=%d, instance=%d\n", cdev,
+ cdev->name, cdev->dev_class, cdev->instance));
+
+ if (cdev->d->open == NULL)
+ {
+ errnoSet(ENODEV);
+ return (void*)ERROR;
+ }
+
+ tmpdev = -1;
+ retval =
+ cdev->d->open (cdev->instance, cdev->dev_class, &fi, 0, 0, &tmpdev);
+
+ if (retval < 0)
+ {
+ errnoSet(-retval);
+ return (void*)ERROR;
+ }
+
+ if (tmpdev != -1)
+ {
+ if (tmpdev >= 0 && tmpdev < oss_num_cdevs)
+ {
+ cdev = oss_cdevs[tmpdev];
+ }
+ else
+ {
+ errnoSet(ENODEV);
+ return (void*)ERROR;
+ }
+ }
+
+ errnoSet (0);
+ memcpy(&cdev->file, &fi, sizeof(struct fileinfo));
+
+ return cdev;
+}
+
+static int
+ossClose (oss_cdev_t *cdev)
+{
+ if (cdev->d->close == NULL)
+ {
+ return OK;
+ }
+
+ cdev->d->close (cdev->instance, &cdev->file);
+
+ return OK;
+}
+
+static int
+ossRead (oss_cdev_t *cdev, char *buf, int count)
+{
+ int err, len;
+ uio_t uio;
+
+ if (cdev->d->read == NULL)
+ {
+ errnoSet (ENXIO);
+ return ERROR;
+ }
+
+ if ((err = oss_create_uio (&uio, buf, count, UIO_READ, 0)) < 0)
+ {
+ errnoSet (-err);
+ return ERROR;
+ }
+
+ len = cdev->d->read (cdev->instance, &cdev->file, &uio, count);
+
+ if (len >= 0)
+ return len;
+
+ errnoSet (-len);
+ return ERROR;
+}
+
+static int
+ossWrite (oss_cdev_t *cdev, char *buf, int count)
+{
+ int err, len;
+ uio_t uio;
+
+ if (cdev->d->write == NULL)
+ {
+ errnoSet (ENXIO);
+ return ERROR;
+ }
+
+ if ((err = oss_create_uio (&uio, buf, count, UIO_WRITE, 0)) < 0)
+ {
+ errnoSet (-err);
+ return ERROR;
+ }
+
+ len = cdev->d->write (cdev->instance, &cdev->file, &uio, count);
+
+ if (len >= 0)
+ return len;
+
+ errnoSet (-len);
+ return ERROR;
+}
+
+static int
+ossIoctl (oss_cdev_t *cdev, int cmd, int *arg)
+{
+ int err;
+
+ if (cdev->d->ioctl == NULL)
+ {
+ errnoSet (ENXIO);
+ return ERROR;
+ }
+
+ if ((err = cdev->d->ioctl (cdev->instance, &cdev->file, cmd, (ioctl_arg) arg)) < 0)
+ {
+ errnoSet (-err);
+ return ERROR;
+ }
+ return OK;
+}
+
+oss_device_t *
+osdev_create (dev_info_t * dip, int dev_type,
+ int instance, const char *nick, const char *handle)
+{
+ oss_device_t *osdev;
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+
+ memset (osdev, 0, sizeof (*osdev));
+
+ sprintf (osdev->nick, "%s%d", nick, instance);
+ osdev->instance = instance;
+ osdev->dip = dip;
+ osdev->available = 1;
+ osdev->first_mixer = -1;
+
+ strcpy (osdev->modname, nick);
+
+ if (handle == NULL)
+ handle = nick;
+
+ if (oss_num_cards >= MAX_CARDS)
+ cmn_err (CE_WARN, "Too many OSS devices. At most %d permitted.\n",
+ MAX_CARDS);
+ else
+ {
+ osdev->cardnum = oss_num_cards;
+ cards[oss_num_cards++] = osdev;
+ }
+/*
+ * Create the device handle
+ */
+ switch (dev_type)
+ {
+ case DRV_PCI:
+ {
+#if 0
+ // TODO
+ unsigned int subvendor;
+ char *devpath;
+ devpath = oss_pci_read_devpath (osdev->dip);
+ oss_pci_read_config_dword (osdev, 0x2c, &subvendor);
+
+ sprintf (osdev->handle, "PCI%08x-%s", subvendor, devpath);
+#else
+ strcpy(osdev->handle, "PCICARD");
+#endif
+ }
+ break;
+
+ case DRV_USB:
+ // TODO: Get the vendor information
+ sprintf (osdev->handle, "USB-%s%d", handle, instance);
+ break;
+
+ default:
+ sprintf (osdev->handle, "%s%d", handle, instance);
+ }
+
+ return osdev;
+}
+
+oss_device_t *
+osdev_clone (oss_device_t * orig_osdev, int new_instance)
+{
+ oss_device_t *osdev;
+
+ osdev = PMALLOC (NULL, sizeof (*osdev));
+ if (osdev == NULL)
+ {
+ cmn_err (CE_WARN, "osdev_create: Out of memory\n");
+ return NULL;
+ }
+ memcpy (osdev, orig_osdev, sizeof (*osdev));
+ osdev->dev_type = DRV_CLONE;
+ osdev->instance = new_instance;
+ sprintf (osdev->nick, "%s%d", orig_osdev->modname, new_instance);
+ sprintf (osdev->handle, "%s%d", orig_osdev->modname, new_instance);
+
+ return osdev;
+}
+
+void
+osdev_delete (oss_device_t * osdev)
+{
+ int i;
+
+ if (osdev == NULL)
+ return;
+
+ osdev->available = 0;
+/*
+ * Mark all minor nodes for this module as invalid.
+ */
+ for (i = 0; i < oss_num_cdevs; i++)
+ if (oss_cdevs[i]->osdev == osdev)
+ {
+ oss_cdevs[i]->d = NULL;
+ oss_cdevs[i]->osdev = NULL;
+ strcpy (oss_cdevs[i]->name, "Removed device");
+ }
+}
+
+void *
+oss_get_osid (oss_device_t * osdev)
+{
+ return NULL; // TODO
+}
+
+int
+oss_register_device (oss_device_t * osdev, const char *name)
+{
+ if (name == NULL)
+ {
+ cmn_err (CE_WARN, "oss_register_device: name==NULL\n");
+ osdev->name = "Undefined name";
+ return 0;
+ }
+
+ if ((osdev->name = PMALLOC (NULL, strlen (name) + 1)) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate memory for device name\n");
+ osdev->name = "Unknown device";
+ }
+ strcpy (osdev->name, name);
+ return 0;
+}
+
+void
+oss_unregister_device (oss_device_t * osdev)
+{
+/*
+ * Notice! The driver calling this routine (the owner of the osdev parameter)
+ * has already uninitialized itself. Do not do any actions that may call this
+ * driver directly or indirectly.
+ */
+
+// TODO: Move this to some common OSS module (also under Solaris)
+}
+
+int
+oss_get_cardinfo (int cardnum, oss_card_info * ci)
+{
+/*
+ * Print information about a 'card' in a format suitable for /dev/sndstat
+ */
+
+ if (cardnum < 0 || cardnum >= oss_num_cards)
+ return OSS_ENXIO;
+
+ if (cards[cardnum]->name != NULL)
+ strncpy (ci->longname, cards[cardnum]->name, 128);
+ ci->longname[127] = 0;
+
+ if (cards[cardnum]->nick != NULL)
+ strncpy (ci->shortname, cards[cardnum]->nick, 16);
+ ci->shortname[15] = 0;
+
+ if (cards[cardnum]->hw_info != NULL)
+ strncpy (ci->hw_info, cards[cardnum]->hw_info, sizeof (ci->hw_info));
+ ci->hw_info[sizeof (ci->hw_info) - 1] = 0;
+ ci->intr_count = cards[cardnum]->intrcount;
+ ci->ack_count = cards[cardnum]->ackcount;
+
+ return 0;
+}
+
+int
+ossDrv (void)
+{
+ oss_hz = sysClkRateGet();
+
+ if (oss_driver_num != ERROR)
+ {
+ cmn_err (CE_WARN, "OSS is already running\n");
+ return -1;
+ }
+
+#ifdef LICENSED_VERSION
+ if (!oss_license_handle_time (oss_get_time ()))
+ {
+ cmn_err (CE_WARN, "This version of Open Sound System has expired\n");
+ cmn_err (CE_CONT,
+ "Please download the latest version from www.opensound.com\n");
+ oss_expired = 1;
+ return -1;
+ }
+#endif
+
+ oss_driver_num = iosDrvInstall ((FUNCPTR) NULL, /* create */
+ (FUNCPTR) NULL, /* delete */
+ (FUNCPTR) ossOpen, (FUNCPTR) ossClose, (FUNCPTR) ossRead, (FUNCPTR) ossWrite, (FUNCPTR) ossIoctl /* ioctl */
+ );
+ if (oss_driver_num == ERROR)
+ {
+ cmn_err (CE_WARN, "Module osscore failed to install\n");
+ return -1;
+ }
+
+ if ((core_osdev =
+ osdev_create (NULL, DRV_UNKNOWN, 0, "osscore", NULL)) == NULL)
+ {
+ oss_cmn_err (CE_WARN, "Failed to allocate OSDEV structure\n");
+ return -1;
+ }
+ oss_register_device (core_osdev, "OSS core services");
+
+ oss_common_init (core_osdev);
+
+ return oss_driver_num;
+}
+
+int
+ossDrvRemove (void)
+{
+#if 1
+
+ return ERROR;
+#else
+ int i;
+
+ if (oss_driver_num == ERROR)
+ return 0;
+
+ for (i = 0; i < SND_NDEVS; i++)
+ if (oss_files[i].valid)
+ {
+ iosDevDelete (&oss_files[i].devHdr);
+ oss_files[i].valid = 0;
+ }
+
+ if (iosDrvRemove (oss_driver_num, FALSE) == ERROR)
+ {
+ cmn_err (CE_WARN, "Driver busy - cannot remove.\n");
+ return ERROR;
+ }
+
+ // TODO
+ oss_unload_drivers ();
+
+ oss_driver_num = ERROR; /* Mark it free */
+ return OK;
+#endif
+}
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+
+#undef FP_SAVE
+#undef FP_RESTORE
+#define FP_SAVE(envbuf) asm ("fnsave %0":"=m" (*envbuf));
+#define FP_RESTORE(envbuf) asm ("frstor %0":"=m" (*envbuf));
+
+/* SSE/SSE2 compatible macros */
+#define FX_SAVE(envbuf) asm ("fxsave %0":"=m" (*envbuf));
+#define FX_RESTORE(envbuf) asm ("fxrstor %0":"=m" (*envbuf));
+
+static int old_arch = 0; /* No SSE/SSE2 instructions */
+
+#if defined(__amd64__)
+#define AMD64
+#endif
+
+static inline void
+cpuid (int op, int *eax, int *ebx, int *ecx, int *edx)
+{
+__asm__ ("cpuid": "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx):"0" (op), "c"
+ (0));
+}
+
+#ifdef AMD64
+# define local_save_flags(x) asm volatile("pushfq ; popq %0":"=g" (x):)
+# define local_restore_flags(x) asm volatile("pushq %0 ; popfq"::"g" (x):"memory", "cc")
+#else
+# define local_save_flags(x) asm volatile("pushfl ; popl %0":"=g" (x):)
+# define local_restore_flags(x) asm volatile("pushl %0 ; popfl"::"g" (x):"memory", "cc")
+#endif
+
+static inline unsigned long
+read_cr0 (void)
+{
+ unsigned long cr0;
+#ifdef AMD64
+asm ("movq %%cr0,%0":"=r" (cr0));
+#else
+asm ("movl %%cr0,%0":"=r" (cr0));
+#endif
+ return cr0;
+}
+
+static inline void
+write_cr0 (unsigned long val)
+{
+#ifdef AMD64
+ asm ("movq %0,%%cr0"::"r" (val));
+#else
+ asm ("movl %0,%%cr0"::"r" (val));
+#endif
+}
+
+static inline unsigned long
+read_cr4 (void)
+{
+ unsigned long cr4;
+#ifdef AMD64
+asm ("movq %%cr4,%0":"=r" (cr4));
+#else
+asm ("movl %%cr4,%0":"=r" (cr4));
+#endif
+ return cr4;
+}
+
+static inline void
+write_cr4 (unsigned long val)
+{
+#ifdef AMD64
+ asm ("movq %0,%%cr4"::"r" (val));
+#else
+ asm ("movl %0,%%cr4"::"r" (val));
+#endif
+}
+static inline unsigned long long
+read_mxcsr (void)
+{
+ unsigned long long mxcsr;
+ asm volatile ("stmxcsr %0":"=m" (mxcsr));
+ return mxcsr;
+}
+
+static inline void
+write_mxcsr (unsigned long long val)
+{
+ asm volatile ("ldmxcsr %0"::"m" (val));
+}
+
+int
+oss_fp_check (void)
+{
+ int eax, ebx, ecx, edx;
+#define FLAGS_ID (1<<21)
+
+ oss_native_word flags_reg;
+
+ local_save_flags (flags_reg);
+ flags_reg &= ~FLAGS_ID;
+ local_restore_flags (flags_reg);
+
+ local_save_flags (flags_reg);
+ if (flags_reg & FLAGS_ID)
+ return 0;
+
+ flags_reg |= FLAGS_ID;
+ local_restore_flags (flags_reg);
+
+ local_save_flags (flags_reg);
+ if (!(flags_reg & FLAGS_ID))
+ return 0;
+
+//#define CPUID_FXSR (1<<24)
+//#define CPUID_SSE (1<<25)
+//#define CPUID_SSE2 (1<<26)
+
+ cpuid (1, &eax, &ebx, &ecx, &edx);
+
+ if (!(edx & CPUID_FXSR))
+ return -1;
+
+ /*
+ * Older machines require different FP handling than the latest ones. Use the SSE
+ * instruction set as an indicator.
+ */
+ if (!(edx & CPUID_SSE))
+ old_arch = 1;
+
+ return 1;
+}
+
+void
+oss_fp_save (short *envbuf, unsigned int flags[])
+{
+ flags[0] = read_cr0 ();
+ write_cr0 (flags[0] & ~0x0e); /* Clear CR0.TS/MP/EM */
+
+ if (old_arch)
+ {
+ FP_SAVE (envbuf);
+ }
+ else
+ {
+ flags[1] = read_cr4 ();
+ write_cr4 (flags[1] | 0x600); /* Set OSFXSR & OSXMMEXCEPT */
+ FX_SAVE (envbuf);
+ asm ("fninit");
+ asm ("fwait");
+ write_mxcsr (0x1f80);
+ }
+ flags[2] = read_cr0 ();
+}
+
+void
+oss_fp_restore (short *envbuf, unsigned int flags[])
+{
+ asm ("fwait");
+ if (old_arch)
+ {
+ FP_RESTORE (envbuf);
+ }
+ else
+ {
+ FX_RESTORE (envbuf);
+ write_cr4 (flags[1]); /* Restore cr4 */
+ }
+ write_cr0 (flags[0]); /* Restore cr0 */
+}
+#endif
+
+typedef struct tmout_desc
+{
+ volatile int active;
+ int timestamp;
+ void (*func) (void *);
+ void *arg;
+
+ WDOG_ID id;
+
+} tmout_desc_t;
+
+static volatile int next_id = 0;
+#define MAX_TMOUTS 128
+
+tmout_desc_t tmouts[MAX_TMOUTS] = { {0} };
+
+int timeout_random = 0x12123400;
+
+void
+oss_timer_callback (int id)
+{
+ tmout_desc_t *tmout;
+ int ix;
+ void *arg;
+
+ timeout_random++;
+
+ ix = id & 0xff;
+ if (ix < 0 || ix >= MAX_TMOUTS)
+ return;
+ tmout = &tmouts[ix];
+
+ if (tmout->timestamp != id) /* Expired timer */
+ return;
+
+ if (!tmout->active)
+ return;
+
+ arg = tmout->arg;
+ tmout->active = 0;
+ tmout->timestamp = 0;
+
+ tmout->func (arg);
+ wdDelete(tmout->id);
+}
+
+timeout_id_t
+oss_timeout (void (*func) (void *), void *arg,
+ unsigned long long ticks)
+{
+
+ tmout_desc_t *tmout = NULL;
+ int id, n;
+
+ timeout_random++;
+
+ n = 0;
+ id = -1;
+
+ while (id == -1 && n < MAX_TMOUTS)
+ {
+ if (!tmouts[next_id].active)
+ {
+ tmouts[next_id].active = 1;
+ id = next_id++;
+ tmout = &tmouts[id];
+ break;
+ }
+
+ next_id = (next_id + 1) % MAX_TMOUTS;
+ }
+
+ if (id == -1) /* No timer slots available */
+ {
+ oss_cmn_err (CE_WARN, "Timeout table full\n");
+ return 0;
+ }
+
+ tmout->func = func;
+ tmout->arg = arg;
+ tmout->timestamp = id | (timeout_random & ~0xff);
+
+ if ((tmout->id=wdCreate()) == NULL)
+ return 0;
+
+ wdStart(tmout->id, ticks, (FUNCPTR)oss_timer_callback, (int)tmout->timestamp);
+ return id | (timeout_random & ~0xff);
+}
+
+void
+oss_untimeout (timeout_id_t id)
+{
+ tmout_desc_t *tmout;
+ int ix;
+
+ ix = id & 0xff;
+ if (ix < 0 || ix >= MAX_TMOUTS)
+ return;
+
+ timeout_random++;
+ tmout = &tmouts[ix];
+
+ if (tmout->timestamp != id) /* Expired timer */
+ return;
+ if (tmout->active)
+ {
+ wdCancel(tmout->id);
+ wdDelete(tmout->id);
+ }
+
+ tmout->active = 0;
+ tmout->timestamp = 0;
+}
+
+void
+oss_udelay(unsigned long ticks)
+{
+ // TODO
+}
+
+void *
+oss_contig_malloc (oss_device_t * osdev, int buffsize, oss_uint64_t memlimit,
+ oss_native_word * phaddr)
+{
+ char *start_addr, *end_addr;
+
+ *phaddr = 0;
+
+ start_addr = NULL;
+
+ // TODO: See if there is a previously freed buffer available
+
+ start_addr = (char *) valloc (buffsize);
+
+ if (start_addr == NULL)
+ {
+ cmn_err (CE_NOTE, "Failed to allocate memory buffer of %d bytes\n",
+ buffsize);
+ return NULL;
+ }
+ else
+ {
+ /* make some checks */
+ end_addr = start_addr + buffsize - 1;
+ }
+
+ *phaddr = (oss_native_word)start_addr;
+ return start_addr;
+}
+
+void
+oss_contig_free (oss_device_t * osdev, void *p, int buffsize)
+{
+ if (p == NULL)
+ return;
+
+ // TODO: Put the freed memory block to available list
+ cmn_err (CE_WARN, "Cannot free %d bytes of DMA buffer\n", buffsize);
+}
+
+int
+__oss_alloc_dmabuf (int dev, dmap_p dmap, unsigned int alloc_flags,
+ oss_uint64_t maxaddr, int direction)
+{
+ void *buf;
+ int err;
+ oss_native_word phaddr;
+ int size = 64 * 1024;
+ extern int dma_buffsize;
+
+ if (dma_buffsize > 16 && dma_buffsize <= 128)
+ size = dma_buffsize * 1024;
+
+ if (dmap->dmabuf != NULL)
+ return 0; /* Already done */
+
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "oss_alloc_dmabuf: dmap==NULL\n");
+ return OSS_EIO;
+ }
+
+/*
+ * Some applications and virtual drivers need shorter buffer.
+ */
+ if (dmap->flags & DMAP_SMALLBUF)
+ {
+ size = SMALL_DMABUF_SIZE;
+ }
+ else if (dmap->flags & DMAP_MEDIUMBUF)
+ {
+ size = MEDIUM_DMABUF_SIZE;
+ }
+
+ if ((alloc_flags & DMABUF_SIZE_16BITS) && size > 32 * 1024)
+ size = 32 * 1024;
+
+ dmap->dmabuf = NULL;
+ dmap->buffsize = size;
+
+ err = -1;
+
+ while (err < 0 && dmap->dmabuf == NULL && dmap->buffsize >= 4 * 1024)
+ {
+ if ((buf =
+ oss_contig_malloc (dmap->osdev, dmap->buffsize, maxaddr,
+ &phaddr)) == NULL)
+ {
+ if ((dmap->buffsize = (dmap->buffsize / 2)) < 8 * 1024)
+ return OSS_ENOMEM;
+ cmn_err (CE_CONT, "Dropping DMA buffer size to %d bytes.\n",
+ dmap->buffsize);
+ continue;
+ }
+
+ dmap->dmabuf = buf;
+ dmap->dmabuf_phys = phaddr;
+
+ return 0;
+ }
+
+ return OSS_ENOMEM;
+}
+
+void
+oss_free_dmabuf (int dev, dmap_p dmap)
+{
+ void *buf = dmap->dmabuf;
+
+ if (dmap->dmabuf == NULL)
+ return;
+
+ dmap->dmabuf = NULL;
+ oss_contig_free (NULL, buf, dmap->buffsize);
+ dmap->dmabuf_phys = 0;
+}
+
+/*
+ * Sleep/wakeup
+ */
+
+struct oss_wait_queue
+{
+ volatile int flags;
+ SEM_ID wq;
+};
+
+struct oss_wait_queue *
+oss_create_wait_queue (oss_device_t * osdev, const char *name)
+{
+ struct oss_wait_queue *wq;
+
+ if ((wq = malloc (sizeof (*wq))) == NULL)
+ {
+ oss_cmn_err (CE_WARN, "vmalloc(%d) failed (wq)\n", sizeof (*wq));
+ return NULL;
+ }
+ wq->wq = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
+
+ return wq;
+}
+
+void
+oss_reset_wait_queue (struct oss_wait_queue *wq)
+{
+ // TODO: ?
+}
+
+void
+oss_remove_wait_queue (struct oss_wait_queue *wq)
+{
+ free (wq);
+}
+
+int
+oss_sleep (struct oss_wait_queue *wq, oss_mutex_t * mutex, int ticks,
+ oss_native_word * flags, unsigned int *status)
+{
+ int result;
+
+ *status = 0;
+
+ if (wq == NULL)
+ return 0;
+
+ wq->flags = 0;
+
+ if (ticks <= 0)
+ ticks = WAIT_FOREVER;
+
+ result =
+ semTake(wq->wq, ticks);
+
+ if (result == ERROR) /* Signal received */
+ {
+ *status |= WK_SIGNAL;
+ return 1;
+ }
+
+ if (!(wq->flags & WK_WAKEUP)) /* Timeout */
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+int
+oss_register_poll (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ oss_native_word * flags, oss_poll_event_t * ev)
+{
+ // TODO: ?
+ return 0;
+}
+
+void
+oss_wakeup (struct oss_wait_queue *wq, oss_mutex_t * mutex,
+ oss_native_word * flags, short events)
+{
+ if (wq == NULL)
+ return;
+
+ wq->flags |= WK_WAKEUP;
+ semFlush(wq->wq);
+}
diff --git a/kernel/OS/VxWorks/os_vxworks.h b/kernel/OS/VxWorks/os_vxworks.h
new file mode 100644
index 0000000..275aa34
--- /dev/null
+++ b/kernel/OS/VxWorks/os_vxworks.h
@@ -0,0 +1,297 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+/*
+ * Purpose: OS specific definitions for VxWorks
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define OS_VERSION "5.5"
+
+#if (!defined(i386) && !defined(x86_64)) || defined(CONFIG_OSS_FIXDEPOINT)
+// Floating point is not supported or it's disabled
+#undef CONFIG_OSS_VMIX_FLOAT
+#endif
+
+#define VDEV_SUPPORT
+#undef USE_DEVICE_SUBDIRS
+
+#define __inline__ inline
+#define __inline inline
+#define EXTERN_C extern "C"
+
+/*
+ * Disable support for per-application features such as /dev/dsp device
+ * selection based on command name. Requires working GET_PROCESS_NAME
+ * macro implementation.
+ */
+#undef APPLIST_SUPPORT
+
+#undef ALLOW_BUFFER_MAPPING
+
+/*
+ * Some integer types
+ */
+#if defined(amd64) || defined(sparc)
+typedef unsigned long long oss_native_word; /* Same as the address and status register size */
+#else
+typedef unsigned long oss_native_word; /* Same as the address and status register size */
+#endif
+
+typedef long long oss_int64_t; /* Signed 64 bit integer */
+typedef unsigned long long oss_uint64_t; /* Unsigned 64 bit integer */
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include "vxWorks.h"
+#include "iv.h"
+#include "ioLib.h"
+#include "fioLib.h"
+#include "iosLib.h"
+#include "wdLib.h"
+#include "intLib.h"
+#include "tickLib.h"
+#include "errnoLib.h"
+#include "sysLib.h"
+#include "objLib.h"
+#include "vmLib.h"
+#include "semLib.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <oss_errno.h>
+/*
+ * Mutexes
+ */
+typedef int oss_mutex_t;
+#define MUTEX_INIT(osdev, mutex, hier)
+#define MUTEX_CLEANUP(mutex)
+#define MUTEX_ENTER_IRQDISABLE(mutex, flags) {flags=0;mutex=0;}
+#define MUTEX_ENTER(mutex, flags) {flags=0;mutex=0;}
+#define MUTEX_EXIT_IRQRESTORE(mutex, flags) (flags)++
+#define MUTEX_EXIT(mutex, flags) (flags)++
+
+/*
+ * Fileinfo structure
+ */
+struct fileinfo
+{
+ int mode; /* Open mode */
+ int acc_flags;
+};
+#define ISSET_FILE_FLAG(fileinfo, flag) (fileinfo->acc_flags & (flag) ? 1:0)
+
+/*
+ * Misc types
+ */
+typedef int oss_dma_handle_t;
+typedef int oss_poll_event_t;
+typedef int offset_t;
+
+/*
+ * uio_/uiomove()
+ */
+typedef enum uio_rw uio_rw_t;
+typedef struct oss_uio
+{
+ char *ptr;
+ int resid;
+ int kernel_space; /* Set if this uio points to a kernel space buffer */
+ uio_rw_t rw;
+} uio_t;
+extern int oss_uiomove (void *address, size_t nbytes, enum uio_rw rwflag,
+ uio_t * uio_p);
+extern int oss_create_uio (uio_t * uiop, char *buf, size_t count, uio_rw_t rw,
+ int is_kernel);
+#define uiomove oss_uiomove
+
+/*
+ * Error handling
+ */
+#define cmn_err oss_cmn_err
+extern int detect_trace;
+#define DDB(x) if (detect_trace) x
+extern void oss_cmn_err (int level, const char *format, ...);
+#define CE_CONT 0
+#define CE_NOTE 1
+#define CE_WARN 2
+#define CE_PANIC 3
+
+/* Busy wait routine */
+extern void oss_udelay(unsigned long ticks);
+/* System wall timer access */
+#define GET_JIFFIES() tickGet()
+extern inline unsigned int
+__inb (unsigned short port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("in" "b" " %" "w" "1,%" "b" "0":"=a" (_v):"d" (port),
+ "0" (0));
+ return _v;
+}
+extern inline unsigned int
+__inw (unsigned short port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("in" "w" " %" "w" "1,%" "w" "0":"=a" (_v):"d" (port),
+ "0" (0));
+ return _v;
+}
+extern inline unsigned int
+__inl (unsigned short port)
+{
+ unsigned int _v;
+ __asm__ __volatile__ ("in" "l" " %" "w" "1,%" "" "0":"=a" (_v):"d" (port));
+ return _v;
+}
+
+extern inline void
+__outb (unsigned char value, unsigned short port)
+{
+ __asm__ __volatile__ ("out" "b" " %" "b" "0,%" "w" "1"::"a" (value),
+ "d" (port));
+}
+extern inline void
+__outw (unsigned short value, unsigned short port)
+{
+ __asm__ __volatile__ ("out" "w" " %" "w" "0,%" "w" "1"::"a" (value),
+ "d" (port));
+}
+extern inline void
+__outl (unsigned int value, unsigned short port)
+{
+ __asm__ __volatile__ ("out" "l" " %" "0,%" "w" "1"::"a" (value),
+ "d" (port));
+}
+
+#define INB(osdev,a) __inb(a)
+#define INW(osdev,a) __inw(a)
+#define INL(osdev,a) __inl(a)
+
+#define OUTB(osdev, d, a) __outb(d, a)
+
+#define OUTW(osdev, d, a) __outw(d, a)
+#define OUTL(osdev, d, a) __outl(d, a)
+
+#define PCI_READL(osdev, p) (*(volatile unsigned int *) (p))
+#define PCI_WRITEL(osdev, addr, data) (*(volatile unsigned int *) (addr) = (data))
+#define PCI_READW(osdev, p) (*(volatile unsigned short *) (p))
+#define PCI_WRITEW(osdev, addr, data) (*(volatile unsigned short *) (addr) = (data))
+#define PCI_READB(osdev, p) (*(volatile unsigned char *) (p))
+#define PCI_WRITEB(osdev, addr, data) (*(volatile unsigned char *) (addr) = (data))
+
+#define MAP_PCI_IOADDR(osdev, nr, io) (oss_native_word)io
+#define MAP_PCI_MEM(osdev, ix, phaddr, size) (oss_native_word)phaddr
+#define UNMAP_PCI_MEM(osdev, ix, ph, virt, size) {}
+#define UNMAP_PCI_IOADDR(osdev, ix) {}
+/*
+ * Memory allocation and mapping
+ */
+extern void *oss_contig_malloc (oss_device_t * osdev, int sz,
+ oss_uint64_t memlimit,
+ oss_native_word * phaddr);
+extern void oss_contig_free (oss_device_t * osdev, void *p, int sz);
+extern void oss_reserve_pages (oss_native_word start_addr,
+ oss_native_word end_addr);
+extern void oss_unreserve_pages (oss_native_word start_addr,
+ oss_native_word end_addr);
+
+#define KERNEL_MALLOC(nbytes) malloc(nbytes)
+#define KERNEL_FREE(addr) free(addr)
+#define CONTIG_MALLOC(osdev, sz, memlimit, phaddr, handle) oss_contig_malloc(osdev, sz, memlimit, phaddr)
+#define CONTIG_FREE(osdev, p, sz, handle) oss_contig_free(osdev, p, sz)
+
+typedef void dev_info_t;
+
+struct _oss_device_t
+{
+ int cardnum;
+ int dev_type;
+ int available;
+ int instance;
+ dev_info_t *dip;
+ void *devc;
+ char *name;
+ char nick[16];
+ char handle[32];
+ int num_audio_engines;
+ int num_audioplay, num_audiorec, num_audioduplex;
+ int num_mididevs;
+ int num_mixerdevs;
+ int num_loopdevs;
+ int first_mixer; /* This must be set to -1 by osdev_create() */
+ int major;
+ struct module *owner; /* Pointer to THISMODULE (needed by osscore.c) */
+ char modname[32];
+ char *hw_info;
+
+ volatile int refcount; /* Nonzero means that the device is needed by some other (virtual) driver. */
+
+/* Interrupts */
+
+ int iblock_cookie; /* Dummy field under Linux */
+ void *irqparms;
+ int intrcount, ackcount;
+};
+
+typedef struct
+{
+ int bus, dev, func;
+} oss_pci_device_t;
+
+typedef int timeout_id_t;
+extern timeout_id_t oss_timeout (void (*func) (void *), void *arg,
+ unsigned long long ticks);
+extern void oss_untimeout (timeout_id_t id);
+#define timeout oss_timeout
+#define untimeout oss_untimeout
+
+extern int oss_hz;
+#define HZ oss_hz
+#define OSS_HZ HZ
+
+/*
+ * Dummy defines for poll()
+ */
+#define POLLIN 0
+#define POLLOUT 0
+#define POLLRDNORM 0
+#define POLLWRNORM 0
+
+/*
+ * Process info macros
+ */
+#define GET_PROCESS_PID(x) -1
+#define GET_PROCESS_UID(x) 0
+#define GET_PROCESS_NAME(x) NULL
+
+/*
+ * Floating point save/restore support for vmix
+ */
+#define FP_SUPPORT
+
+#ifdef FP_SUPPORT
+typedef short fp_env_t[512];
+typedef unsigned int fp_flags_t[4];
+extern int oss_fp_check (void);
+extern void oss_fp_save (short *envbuf, fp_flags_t flags);
+extern void oss_fp_restore (short *envbuf, fp_flags_t flags);
+#undef FP_SAVE
+#undef FP_RESTORE
+# define FP_SAVE(envbuf, flags) oss_fp_save(envbuf, flags)
+# define FP_RESTORE(envbuf, flags) oss_fp_restore(envbuf, flags)
+#endif
+
+#endif
diff --git a/kernel/drv/.config b/kernel/drv/.config
new file mode 100644
index 0000000..8969ff4
--- /dev/null
+++ b/kernel/drv/.config
@@ -0,0 +1 @@
+mode=module
diff --git a/kernel/drv/oss_ali5455/.devices b/kernel/drv/oss_ali5455/.devices
new file mode 100644
index 0000000..4eff6e6
--- /dev/null
+++ b/kernel/drv/oss_ali5455/.devices
@@ -0,0 +1 @@
+oss_ali5455 pci10b9,5455 ALI M5455
diff --git a/kernel/drv/oss_ali5455/.name b/kernel/drv/oss_ali5455/.name
new file mode 100644
index 0000000..d3bc019
--- /dev/null
+++ b/kernel/drv/oss_ali5455/.name
@@ -0,0 +1 @@
+ALI M5455 chipset
diff --git a/kernel/drv/oss_ali5455/oss_ali5455.c b/kernel/drv/oss_ali5455/oss_ali5455.c
new file mode 100644
index 0000000..ce96844
--- /dev/null
+++ b/kernel/drv/oss_ali5455/oss_ali5455.c
@@ -0,0 +1,979 @@
+/*
+ * Purpose: Driver for the ALI 5455 (AC97) audio controller
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_ali5455_cfg.h"
+#include <oss_pci.h>
+#include <ac97.h>
+
+#define ALI_VENDOR_ID 0x10b9
+#define ALI_DEVICE_5455 0x5455
+
+#define MAX_ALI5455 1
+#define MAX_PORTC 3
+#define BDL_SIZE 32
+
+#ifdef OSS_BIG_ENDIAN
+static __inline__ unsigned int
+swap32 (unsigned int x)
+{
+ return ((x & 0x000000ff) << 24) |
+ ((x & 0x0000ff00) << 8) |
+ ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
+}
+
+static __inline__ unsigned short
+swap16 (unsigned short x)
+{
+ return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
+}
+
+#define SWAP32(x) swap32(x)
+#define SWAP16(x) swap16(x)
+#else
+#define SWAP32(x) x
+#define SWAP16(x) x
+#endif
+
+typedef struct
+{
+ int open_mode;
+ int speed, bits, channels;
+ int audio_enabled;
+ int trigger_bits;
+ int audiodev;
+ int port_type;
+#define DF_PCM 0
+#define DF_SPDIF 1
+}
+ALI_portc;
+
+typedef struct
+{
+ unsigned int addr;
+ unsigned short size;
+ unsigned short flags;
+}
+bdl_t;
+
+typedef struct ALI_devc
+{
+ oss_device_t *osdev;
+ oss_native_word base;
+ int irq;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ /* Mixer */
+ ac97_devc ac97devc;
+ int mixer_dev;
+
+ /* Audio parameters */
+ int open_mode;
+
+ /* Buffer Descriptor List */
+ char *bdlBuffer;
+ bdl_t *playBDL, *recBDL, *spdifBDL;
+ oss_native_word playBDL_phys, recBDL_phys, spdifBDL_phys;
+ oss_dma_handle_t bdl_dma_handle;
+
+ int play_currbuf, play_currfrag;
+ int spdif_currbuf, spdif_currfrag;
+ int rec_currbuf, rec_currfrag;
+ char *chip_name;
+ ALI_portc portc[MAX_PORTC];
+ int play_frag_index[BDL_SIZE];
+ int rec_frag_index[BDL_SIZE];
+ int spdif_frag_index[BDL_SIZE];
+}
+ALI_devc;
+
+static int
+ac97_read (void *devc_, int reg)
+{
+ ALI_devc *devc = devc_;
+ int i = 100;
+ unsigned int status;
+ unsigned int data = 0;
+ unsigned short read_reg = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ status = INB (devc->osdev, devc->base + 0x34);
+
+ /* wait for the Codec Access Semaphore bit to be set */
+ while (i-- && (INL (devc->osdev, devc->base + 0x3c) & 0x80000000))
+ oss_udelay (1);
+
+ for (i = 0; i < 100; i++)
+ {
+ status = INB (devc->osdev, devc->base + 0x38);
+ if (status & 0x08)
+ break;
+ }
+ if (i == 100)
+ {
+ cmn_err (CE_WARN, "AC97 not ready for read\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+ OUTW (devc->osdev, reg | 0x80, devc->base + 0x22);
+
+ for (i = 0; i < 100; i++)
+ {
+ status = INB (devc->osdev, devc->base + 0x38);
+
+ if (status & 0x02)
+ {
+
+ data = INW (devc->osdev, devc->base + 0x24);
+ read_reg = INW (devc->osdev, devc->base + 0x26);
+ break;
+ }
+ }
+
+ if (i == 100)
+ {
+ cmn_err (CE_WARN, "AC97 read timed out \n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+ if (read_reg != reg)
+ {
+ cmn_err (CE_WARN, "AC97 invalid reg read %x (%x)\n", read_reg, reg);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return data;
+}
+
+static int
+ac97_write (void *devc_, int reg, int data)
+{
+ ALI_devc *devc = devc_;
+ int i = 100, status;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /* wait for the Codec Access Semaphore bit to be set */
+ while (i-- && (INL (devc->osdev, devc->base + 0x3c) & 0x80000000))
+ oss_udelay (1);
+
+ /* wait until command port is ready for write */
+ for (i = 0; i < 100; i++)
+ {
+ status = INB (devc->osdev, devc->base + 0x38);
+ if (status & 0x01)
+ break;
+ }
+
+ if (i == 100)
+ {
+ cmn_err (CE_WARN, "AC97 timed out for write\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+ OUTL (devc->osdev, reg << 16 | data, devc->base + 0x20);
+
+ for (i = 0; i < 100; i++)
+ {
+ status = INB (devc->osdev, devc->base + 0x38);
+ if (status & 0x01)
+ break;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 1;
+}
+
+static int
+ALIintr (oss_device_t * osdev)
+{
+ int status, global_status, p, f, i;
+ int serviced = 0;
+ ALI_devc *devc = (ALI_devc *) osdev->devc;
+ ALI_portc *portc;
+ /* oss_native_word flags; */
+
+ /* Handle playback */
+ /*
+ * TODO: Fix mutexes and move the inputintr/outputintr calls outside the
+ * mutex block.
+ */
+
+ /* MUTEX_ENTER (devc->mutex, flags); */
+ /* Handle Global Interrupts */
+ global_status = INL (devc->osdev, devc->base + 0x18);
+ OUTL (devc->osdev, global_status, devc->base + 0x18);
+
+ if (!(global_status & (0x10000 | 0x20000 | 0x80000 | 0x100000 | 0x200000)))
+ {
+ /* MUTEX_EXIT (devc->mutex, flags); */
+ return serviced;
+ }
+
+ /* Handle Playback Interrupts */
+
+ status = INB (devc->osdev, devc->base + 0x56);
+
+ if ((status & 0x08) && (global_status & 0x20000))
+ for (i = 0; i < MAX_PORTC - 1; i++)
+ {
+ portc = &devc->portc[i];
+ serviced = 1;
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT)) /* IOC interrupt */
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
+ p = INB (devc->osdev, devc->base + 0x54);
+
+ if (p != devc->play_currbuf)
+ {
+ p = devc->play_currbuf;
+ f = devc->play_currfrag;
+ devc->playBDL[p].addr =
+ SWAP32 (dmap->dmabuf_phys + (f * dmap->fragment_size));
+
+ devc->playBDL[p].size = SWAP16 (dmap->fragment_size / 2);
+ devc->playBDL[p].flags = SWAP16 (0xc000); /* IOC interrupts */
+
+ OUTB (devc->osdev, p, devc->base + 0x55); /* Set LVD */
+ devc->play_frag_index[p] = f;
+ devc->play_currbuf = (p + 1) % BDL_SIZE;
+ devc->play_currfrag = (f + 1) % dmap->nfrags;
+ }
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+ }
+ OUTB (devc->osdev, status, devc->base + 0x56); /* Clear interrupts */
+
+/*--------------------------------------------------------------------------*/
+ /* handle SPDIF interrupts */
+
+ status = INB (devc->osdev, devc->base + 0x76);
+ if ((status & 0x08) && (global_status & 0x80000))
+ {
+ portc = &devc->portc[2];
+ serviced = 1;
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT)) /* IOC interrupt */
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
+ p = INB (devc->osdev, devc->base + 0x74);
+
+ if (p != devc->spdif_currbuf)
+ {
+ p = devc->spdif_currbuf;
+ f = devc->spdif_currfrag;
+ devc->spdifBDL[p].addr =
+ SWAP32 (dmap->dmabuf_phys + (f * dmap->fragment_size));
+
+ devc->spdifBDL[p].size = SWAP16 (dmap->fragment_size / 2);
+ devc->spdifBDL[p].flags = SWAP16 (0xc000); /* IOC interrupts */
+
+ OUTB (devc->osdev, p, devc->base + 0x75); /* Set LVD */
+ devc->spdif_frag_index[p] = f;
+ devc->spdif_currbuf = (p + 1) % BDL_SIZE;
+ devc->spdif_currfrag = (f + 1) % dmap->nfrags;
+ }
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+ }
+ OUTB (devc->osdev, status, devc->base + 0x76); /* Clear interrupts */
+/*---------------------------------------------------------------------------*/
+
+ /* Handle Recording Interrupts */
+ status = INB (devc->osdev, devc->base + 0x46);
+
+ if ((status & 0x08) && (global_status & 0x10000))
+ for (i = 0; i < MAX_PORTC - 1; i++)
+ {
+ portc = &devc->portc[i];
+ serviced = 1;
+ if ((portc->trigger_bits & PCM_ENABLE_INPUT)) /* IOC interrupt */
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_in;
+ p = INB (devc->osdev, devc->base + 0x44);
+
+ if (p != devc->rec_currbuf)
+ {
+ p = devc->rec_currbuf;
+ f = devc->rec_currfrag;
+ devc->recBDL[p].addr =
+ SWAP32 (dmap->dmabuf_phys + (f * dmap->fragment_size));
+
+ /* SIS uses bytes, ali5455 uses samples */
+ devc->recBDL[p].size = SWAP16 (dmap->fragment_size / 2);
+
+ devc->recBDL[p].flags = SWAP16 (0xc000); /* IOC interrupts */
+
+ OUTB (devc->osdev, p, devc->base + 0x45); /* Set LVD */
+ devc->rec_frag_index[p] = f;
+ devc->rec_currbuf = (p + 1) % BDL_SIZE;
+ devc->rec_currfrag = (f + 1) % dmap->nfrags;
+ }
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+ OUTB (devc->osdev, status, devc->base + 0x46); /* Clear int */
+
+ /* MUTEX_EXIT (devc->mutex, flags); */
+ return serviced;
+}
+
+/*
+ * Audio routines
+ */
+
+static int
+ALI_audio_set_rate (int dev, int arg)
+{
+ ALI_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
+ arg = 48000;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+ALI_audio_set_channels (int dev, short arg)
+{
+ ALI_portc *portc = audio_engines[dev]->portc;
+
+ if ((arg == 1) || (arg == 2))
+ {
+ audio_engines[dev]->flags |= ADEV_STEREOONLY;
+ arg = 2;
+ }
+ else
+ audio_engines[dev]->flags &= ~ADEV_STEREOONLY;
+
+ if (arg>6)
+ arg=6;
+
+ if ((arg != 1) && (arg != 2) && (arg != 4) && (arg != 6))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+ALI_audio_set_format (int dev, unsigned int arg)
+{
+ ALI_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE | AFMT_AC3)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+ALI_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void ALI_audio_trigger (int dev, int state);
+
+static void
+ALI_audio_reset (int dev)
+{
+ ALI_audio_trigger (dev, 0);
+}
+
+static void
+ALI_audio_reset_input (int dev)
+{
+ ALI_portc *portc = audio_engines[dev]->portc;
+ ALI_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+ALI_audio_reset_output (int dev)
+{
+ ALI_portc *portc = audio_engines[dev]->portc;
+ ALI_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+ALI_audio_open (int dev, int mode, int openflags)
+{
+ ALI_portc *portc = audio_engines[dev]->portc;
+ ALI_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (portc->port_type == DF_SPDIF)
+ {
+ if (mode & OPEN_READ)
+ {
+ cmn_err (CE_WARN,
+ "ICH: The S/PDIF device supports only playback\n");
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EIO;
+ }
+ }
+ else
+ {
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode |= mode;
+ }
+
+
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+ALI_audio_close (int dev, int mode)
+{
+ ALI_portc *portc = audio_engines[dev]->portc;
+ ALI_devc *devc = audio_engines[dev]->devc;
+
+ ALI_audio_reset (dev);
+ portc->open_mode = 0;
+
+ if (portc->port_type != DF_SPDIF)
+ devc->open_mode &= ~mode;
+
+
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+ALI_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ALI_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+ALI_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ALI_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+ALI_audio_trigger (int dev, int state)
+{
+ ALI_devc *devc = audio_engines[dev]->devc;
+ ALI_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ if (portc->port_type == DF_SPDIF)
+ {
+ OUTB (devc->osdev, 0x1d, devc->base + 0x7b); /* Setup intr */
+ OUTW (devc->osdev, INW (devc->osdev, devc->base + 0x08) | 0x08, devc->base + 0x08); /* start DMA */
+ }
+
+ if (portc->port_type == DF_PCM)
+ {
+ OUTB (devc->osdev, 0x1d, devc->base + 0x5b); /* setup intr */
+ OUTW (devc->osdev, INW (devc->osdev, devc->base + 0x08) | 0x02, devc->base + 0x08); /* start DMA */
+ }
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ if (portc->port_type == DF_SPDIF)
+ {
+ OUTB (devc->osdev, 0x00, devc->base + 0x7b); /* reset */
+ OUTW (devc->osdev, INW (devc->osdev, devc->base + 0x08) & ~0x08, devc->base + 0x08); /* stop DMA */
+ }
+
+ if (portc->port_type == DF_PCM)
+ {
+ OUTB (devc->osdev, 0x00, devc->base + 0x5b); /* reset */
+ OUTW (devc->osdev, INW (devc->osdev, devc->base + 0x08) & ~0x02, devc->base + 0x08); /* stop DMA */
+ }
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ OUTB (devc->osdev, 0x1d, devc->base + 0x4b); /* Kickstart */
+ OUTW (devc->osdev, INW (devc->osdev, devc->base + 0x08) | 0x01, devc->base + 0x08); /* stop DMA */
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ OUTB (devc->osdev, 0x00, devc->base + 0x4b); /* reset */
+ OUTW (devc->osdev, INW (devc->osdev, devc->base + 0x08) & ~0x01, devc->base + 0x08); /* stop DMA */
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+ALI_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ ALI_devc *devc = audio_engines[dev]->devc;
+ ALI_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ int i, n;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ OUTB (devc->osdev, 0x02, devc->base + 0x4b); /* Reset */
+ OUTL (devc->osdev, devc->recBDL_phys, devc->base + 0x40); /* BDL base */
+
+ ac97_recrate (&devc->ac97devc, portc->speed);
+
+ n = bcount;
+ if (n > BDL_SIZE)
+ n = BDL_SIZE;
+
+ for (i = 0; i < n; i++)
+ {
+ devc->recBDL[i].addr =
+ SWAP32 (dmap->dmabuf_phys + (i * dmap->fragment_size));
+ devc->recBDL[i].size = SWAP16 (dmap->fragment_size / 2);
+ devc->recBDL[i].flags = SWAP16 (0xc000); /* IOC interrupts */
+ devc->rec_frag_index[i] = i;
+ }
+ OUTB (devc->osdev, n - 1, devc->base + 0x45); /* Set last valid descriptor */
+
+ devc->rec_currbuf = n % BDL_SIZE;
+ devc->rec_currfrag = n;
+ if (devc->rec_currfrag >= dmap->nfrags)
+ devc->rec_currfrag = 0;
+
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+ALI_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ ALI_devc *devc = audio_engines[dev]->devc;
+ ALI_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ int i, n;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_AUDIO, SNDCTL_MIX_WRITE, 0);
+ ac97_spdif_setup (devc->mixer_dev, portc->speed, portc->bits);
+
+ if (portc->bits == AFMT_AC3)
+ {
+ portc->channels = 2;
+ portc->bits = 16;
+ }
+
+ /* do SPDIF out */
+ if (portc->port_type == DF_SPDIF)
+ {
+ ac97_playrate (&devc->ac97devc, portc->speed);
+ OUTB (devc->osdev, 0x02, devc->base + 0x7b); /* Reset */
+ OUTL (devc->osdev, devc->spdifBDL_phys, devc->base + 0x70);
+
+ n = bcount;
+ if (n > BDL_SIZE)
+ n = BDL_SIZE;
+
+ for (i = 0; i < n; i++)
+ {
+ devc->spdifBDL[i].addr =
+ SWAP32 (dmap->dmabuf_phys + (i * dmap->fragment_size));
+ devc->spdifBDL[i].size = SWAP16 (dmap->fragment_size / 2);
+ devc->spdifBDL[i].flags = SWAP16 (0xc000); /* IOC interrupts */
+ devc->spdif_frag_index[i] = i;
+ }
+ OUTB (devc->osdev, n - 1, devc->base + 0x75); /* Set LVI descriptor */
+ devc->spdif_currbuf = n % BDL_SIZE;
+ devc->spdif_currfrag = n;
+ if (devc->spdif_currfrag >= dmap->nfrags)
+ devc->spdif_currfrag = 0;
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+
+ /* else do PCM */
+ OUTB (devc->osdev, 0x02, devc->base + 0x5b); /* Reset */
+ OUTL (devc->osdev, devc->playBDL_phys, devc->base + 0x50);
+
+ ac97_playrate (&devc->ac97devc, portc->speed);
+
+ /* set default to 2 channel mode */
+ if (portc->channels == 2)
+ OUTW (devc->osdev, INW (devc->osdev, devc->base + 0x00) & ~0x300,
+ devc->base + 0x00);
+ if (portc->channels == 4)
+ OUTW (devc->osdev,
+ (INW (devc->osdev, devc->base + 0x00) & ~0x300) | 0x100,
+ devc->base + 0x00);
+ if (portc->channels == 6)
+ OUTW (devc->osdev,
+ (INW (devc->osdev, devc->base + 0x00) & ~0x300) | 0x200,
+ devc->base + 0x00);
+
+
+ n = bcount;
+ if (n > BDL_SIZE)
+ n = BDL_SIZE;
+
+ for (i = 0; i < n; i++)
+ {
+ devc->playBDL[i].addr =
+ SWAP32 (dmap->dmabuf_phys + (i * dmap->fragment_size));
+ devc->playBDL[i].size = SWAP16 (dmap->fragment_size / 2);
+ devc->playBDL[i].flags = SWAP16 (0xc000); /* IOC interrupts */
+ devc->play_frag_index[i] = i;
+ }
+ OUTB (devc->osdev, n - 1, devc->base + 0x55); /* Set last valid descriptor */
+
+ devc->play_currbuf = n % BDL_SIZE;
+ devc->play_currfrag = n;
+ if (devc->play_currfrag >= dmap->nfrags)
+ devc->play_currfrag = 0;
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static const audiodrv_t ALI_audio_driver = {
+ ALI_audio_open,
+ ALI_audio_close,
+ ALI_audio_output_block,
+ ALI_audio_start_input,
+ ALI_audio_ioctl,
+ ALI_audio_prepare_for_input,
+ ALI_audio_prepare_for_output,
+ ALI_audio_reset,
+ NULL,
+ NULL,
+ ALI_audio_reset_input,
+ ALI_audio_reset_output,
+ ALI_audio_trigger,
+ ALI_audio_set_rate,
+ ALI_audio_set_format,
+ ALI_audio_set_channels
+};
+
+static int
+init_ALI (ALI_devc * devc)
+{
+ int my_mixer, my_dev, opts;
+ oss_native_word phaddr;
+ int i;
+
+ /* ACLink on, warm reset */
+ OUTL (devc->osdev, 0x80008003, devc->base + 0x00); /*reset SCR */
+ OUTL (devc->osdev, 0x83838383, devc->base + 0x0c); /*reset pcm in/out FIFO */
+ OUTL (devc->osdev, 0x83838383, devc->base + 0x1c); /*reset SPDIF/LFEr FIFO */
+ OUTL (devc->osdev, 0x0028000a, devc->base + 0x10); /*set spdif/pcm in/out */
+ OUTL (devc->osdev, INL (devc->osdev, devc->base + 0xFC) | 0x3,
+ devc->base + 0xFC);
+
+ /* set up Codec SPDIFOUT slot to 10/11 */
+ OUTL (devc->osdev, INL (devc->osdev, devc->base + 0x00) | 0x300000,
+ devc->base + 0x00);
+ /* disable interrupts */
+ OUTL (devc->osdev, 0x00, devc->base + 0x14);
+ OUTL (devc->osdev, 0x00, devc->base + 0x18);
+
+ devc->bdlBuffer =
+ CONTIG_MALLOC (devc->osdev, 4 * 32 * 32, MEMLIMIT_32BITS, &phaddr, devc->bdl_dma_handle);
+ if (devc->bdlBuffer == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate BDL\n");
+ return 0;
+ }
+
+ devc->playBDL = (bdl_t *) devc->bdlBuffer;
+ devc->playBDL_phys = phaddr;
+ devc->recBDL = (bdl_t *) (devc->bdlBuffer + (1 * 32 * 32));
+ devc->recBDL_phys = phaddr + (1 * 32 * 32);
+ devc->spdifBDL = (bdl_t *) (devc->bdlBuffer + (2 * 32 * 32));
+ devc->spdifBDL_phys = phaddr + (2 * 32 * 32);
+
+/*
+ * Init mixer
+ */
+ my_mixer =
+ ac97_install (&devc->ac97devc, "AC97 Mixer", ac97_read, ac97_write, devc,
+ devc->osdev);
+
+ if (my_mixer == -1)
+ return 0; /* No mixer */
+
+ devc->mixer_dev = my_mixer;
+
+ /* enable S/PDIF */
+ devc->ac97devc.spdif_slot = SPDIF_SLOT1011;
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 1);
+
+#if 0
+ /* enable variable rate mode */
+ ac97_write (devc, 0x2a, ac97_read (devc, 0x2a) | 9);
+ if (!(ac97_read (devc, 0x2a) & 1))
+ DDB (cmn_err (CE_WARN, "VRA not supported...using GRC\n"));
+#endif
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ ALI_portc *portc = &devc->portc[i];
+ char tmp_name[100];
+ int port_fmt = DF_PCM;
+ int formats = AFMT_S16_LE | AFMT_AC3;
+ strcpy (tmp_name, devc->chip_name);
+ opts = ADEV_AUTOMODE | ADEV_16BITONLY | ADEV_STEREOONLY;
+ portc->port_type = DF_PCM;
+
+ if (!ac97_varrate (&devc->ac97devc))
+ {
+ opts |= ADEV_FIXEDRATE;
+ }
+
+ if (i == 0)
+ {
+ opts |= ADEV_DUPLEX;
+ strcpy (tmp_name, devc->chip_name);
+ }
+ if (i == 1)
+ {
+ opts |= ADEV_DUPLEX | ADEV_SHADOW;
+ strcpy (tmp_name, devc->chip_name);
+ }
+
+ if (i == 2)
+ {
+ sprintf (tmp_name, "%s (S/PDIF)", devc->chip_name);
+ opts |= ADEV_NOINPUT | ADEV_SPECIAL | ADEV_FIXEDRATE;
+ port_fmt = DF_SPDIF;
+ }
+
+ if ((my_dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &ALI_audio_driver,
+ sizeof (audiodrv_t), opts,
+ formats, devc, -1)) < 0)
+ {
+ my_dev = -1;
+ return 0;
+ }
+ else
+ {
+ audio_engines[my_dev]->portc = portc;
+ audio_engines[my_dev]->mixer_dev = my_mixer;
+ audio_engines[my_dev]->min_rate =
+ (opts & ADEV_FIXEDRATE) ? 48000 : 5000;
+ audio_engines[my_dev]->max_rate = 48000;
+ audio_engines[my_dev]->caps |= PCM_CAP_FREERATE;
+ /*audio_engines[my_dev]->min_block = 4096; */
+ /*audio_engines[my_dev]->max_block = 4096; */
+ audio_engines[my_dev]->min_channels = 2;
+ audio_engines[my_dev]->max_channels = 6;
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+ portc->audiodev = my_dev;
+ portc->port_type = port_fmt;
+ if (audio_engines[my_dev]->flags & ADEV_FIXEDRATE)
+ audio_engines[my_dev]->fixed_rate = 48000;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, my_dev, -1, 0);
+#endif
+ }
+ }
+ return 1;
+}
+
+
+int
+oss_ali5455_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision /*, pci_latency */ ;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr0;
+ ALI_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered ALI AC97 probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if ((vendor != ALI_VENDOR_ID) || (device != ALI_DEVICE_5455))
+ return 0;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr0);
+
+ if (pci_ioaddr0 == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->open_mode = 0;
+
+ /* Remove I/O space marker in bit 0. */
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr0);
+ devc->base &= ~0xF;
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ devc->chip_name = "ALI M5455";
+ devc->irq = pci_irq_line;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if (oss_register_interrupts (devc->osdev, 0, ALIintr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Unable to install interrupt handler\n");
+ return 0;
+ }
+
+ return init_ALI (devc); /* Detected */
+}
+
+
+int
+oss_ali5455_detach (oss_device_t * osdev)
+{
+ ALI_devc *devc = (ALI_devc *) osdev->devc;
+
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ /* disable S/PDIF */
+ if (devc->mixer_dev)
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 0);
+ /* disable interrupts */
+ OUTL (devc->osdev, 0x00, devc->base + 0x14);
+ OUTL (devc->osdev, 0x00, devc->base + 0x18);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ if (devc->bdlBuffer)
+ {
+ CONTIG_FREE (devc->osdev, devc->bdlBuffer, 4 * 32 * 32, devc->bdl_dma_handle);
+ devc->bdlBuffer = NULL;
+ }
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+
+ oss_unregister_device (osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_ali5455/oss_ali5455.man b/kernel/drv/oss_ali5455/oss_ali5455.man
new file mode 100644
index 0000000..bab3621
--- /dev/null
+++ b/kernel/drv/oss_ali5455/oss_ali5455.man
@@ -0,0 +1,20 @@
+NAME
+oss_ali5455 - ALIM5455 audio driver.
+
+DESCRIPTION
+Open Sound System driver for onboard audio on ALI M5455 motherboards. This
+driver is very similar to the Intel ICH driver.
+
+ALI 5455 device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo/4/5.1 channel playback/recording
+ o 8KHz to 48Khz sample rate.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_ali5455.conf Device configuration file
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_atiaudio/.config b/kernel/drv/oss_atiaudio/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_atiaudio/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_atiaudio/.devices b/kernel/drv/oss_atiaudio/.devices
new file mode 100644
index 0000000..703bd00
--- /dev/null
+++ b/kernel/drv/oss_atiaudio/.devices
@@ -0,0 +1,3 @@
+oss_atiaudio pci1002,4341 ATI IXP200
+oss_atiaudio pci1002,4361 ATI IXP300
+oss_atiaudio pci1002,4370 ATI IXP400
diff --git a/kernel/drv/oss_atiaudio/.name b/kernel/drv/oss_atiaudio/.name
new file mode 100644
index 0000000..7d242bd
--- /dev/null
+++ b/kernel/drv/oss_atiaudio/.name
@@ -0,0 +1 @@
+ATI IXP motherboard audio
diff --git a/kernel/drv/oss_atiaudio/oss_atiaudio.c b/kernel/drv/oss_atiaudio/oss_atiaudio.c
new file mode 100644
index 0000000..6727894
--- /dev/null
+++ b/kernel/drv/oss_atiaudio/oss_atiaudio.c
@@ -0,0 +1,1147 @@
+/*
+ * Purpose: Driver for the ATI IXP (AC97) audio controller
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_atiaudio_cfg.h"
+#include "oss_pci.h"
+#include "ac97.h"
+
+#define ATI_VENDOR_ID 0x1002
+#define ATI_DEVICE_IXP 0x4341
+#define ATI_DEVICE_IXP300 0x4361
+#define ATI_DEVICE_IXP400 0x4370
+
+#define MAX_PORTC 3
+#define BDL_SIZE 64
+
+typedef struct
+{
+ int open_mode;
+ int speed, bits, channels;
+ int audio_enabled;
+ int trigger_bits;
+ int audiodev;
+ int port_type;
+#define DF_ANALOG 0
+#define DF_SPDIF 1
+}
+ATI_portc;
+
+typedef struct
+{
+ unsigned int addr;
+ unsigned short status;
+ unsigned short size;
+ unsigned int next;
+}
+bdl_t;
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_native_word membar_addr;
+ char *membar_virt;
+ int irq;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ /* Mixer */
+ ac97_devc ac97devc;
+ int mixer_dev;
+ int inverted;
+
+ /* Audio parameters */
+ int open_mode;
+
+ /* Buffer Descriptor List */
+ char *bdlBuffer;
+ bdl_t *playBDL, *recBDL, *spdifBDL;
+ oss_native_word playBDL_phys, recBDL_phys, spdifBDL_phys;
+ oss_dma_handle_t bldbuf_dma_handle;
+
+ int play_currbuf, play_currfrag;
+ int rec_currbuf, rec_currfrag;
+ char *chip_name;
+ ATI_portc portc[MAX_PORTC];
+ int play_frag_index[BDL_SIZE];
+ int rec_frag_index[BDL_SIZE];
+}
+ATI_devc;
+
+
+/* Mem mapped I/O registers */
+#define READL(o,a) *(volatile unsigned int*)(devc->membar_virt+(a))
+#define READW(o,a) *(volatile unsigned short*)(devc->membar_virt+(a))
+#define READB(o,a) *(volatile unsigned char*)(devc->membar_virt+(a))
+#define WRITEL(o,d,a) *(volatile unsigned int*)(devc->membar_virt+(a))=d
+#define WRITEW(o,d,a) *(volatile unsigned short*)(devc->membar_virt+(a))=d
+#define WRITEB(o,d,a) *(volatile unsigned char*)(devc->membar_virt+(a))=d
+
+
+static int
+ac97_ready (void *devc_)
+{
+ ATI_devc *devc = devc_;
+ int timeout = 10000;
+
+ while (READL (devc->osdev, 0x0c) & 0x100)
+ {
+ if (!timeout--)
+ {
+ cmn_err (CE_WARN, "codec ready timed out\n");
+ return OSS_EIO;
+ }
+ oss_udelay (10);
+ }
+ return 0;
+}
+
+static int
+ac97_read (void *devc_, int reg)
+{
+ ATI_devc *devc = devc_;
+ unsigned int data = 0;
+ unsigned int addr = 0;
+ int timeout;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+again:
+ if (ac97_ready (devc) < 0)
+ {
+ cmn_err (CE_WARN, "ac97 not ready\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+
+ addr = (unsigned int) (reg << 9) | (1 << 8) | (1 << 2);
+ WRITEL (devc->osdev, addr, 0x0c); /* Set read commmand */
+
+ if (ac97_ready (devc) < 0)
+ {
+ cmn_err (CE_WARN, "ac97 not ready\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+
+ timeout = 1000;
+
+ for (;;)
+ {
+ data = READL (devc->osdev, 0x10); /* ac97 data port */
+ if (data & 0x100)
+ {
+ /* if the register returned isn't the reg sent then resend command */
+ if ((data & 0xFE00) != (reg << 9))
+ goto again;
+ else
+ break;
+ }
+
+ if (!--timeout)
+ {
+ cmn_err (CE_WARN, "AC97 read timed out\n");
+ break;
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (data >> 16);
+}
+
+
+static int
+ac97_write (void *devc_, int reg, int data)
+{
+ ATI_devc *devc = devc_;
+ oss_native_word flags;
+ unsigned int val;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (ac97_ready (devc) < 0)
+ {
+ cmn_err (CE_WARN, "AC97 not ready\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+ val = (data << 16) | (reg << 9) | 0x100;
+ WRITEL (devc->osdev, val, 0x0c);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 1;
+}
+
+static int
+ATIIXPintr (oss_device_t * osdev)
+{
+ int status, i;
+ int serviced = 0;
+ ATI_devc *devc = (ATI_devc *) osdev->devc;
+ ATI_portc *portc;
+ /* oss_native_word flags; */
+
+/*
+ * TODO: Enable the mutexes and move inputintr/outputintr calls outside the
+ * mutex region.
+ */
+
+ /* MUTEX_ENTER (devc->mutex, flags); */
+ /* Handle Global Interrupts */
+ status = READL (devc->osdev, 0x00);
+
+ /* handle PCM output */
+ if (status & 0x08)
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ && (portc->port_type == DF_ANALOG))
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
+ int ptr=0, n = 0;
+ int timeout = 1000;
+ serviced = 1;
+ while (timeout--)
+ {
+ ptr = READL (devc->osdev, 0x44);
+
+ if (ptr < dmap->dmabuf_phys)
+ continue;
+
+ ptr -= dmap->dmabuf_phys;
+
+ if (ptr >= dmap->bytes_in_use)
+ continue;
+
+ break;
+ }
+
+ if (dmap->fragment_size == 0)
+ {
+ cmn_err (CE_WARN, "dmap->fragment_size == 0\n");
+ continue;
+ }
+
+ ptr /= dmap->fragment_size;
+
+ if ((ptr < 0) || (ptr > dmap->nfrags))
+ ptr = 0;
+
+ n = 0;
+ while ((dmap_get_qhead (dmap) != ptr) && (n++ < dmap->nfrags))
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+ }
+
+ /* handle PCM input */
+ if (status & 0x02)
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+ if ((portc->trigger_bits & PCM_ENABLE_INPUT)
+ && (portc->port_type == DF_ANALOG))
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_in;
+ int ptr=0, n = 0;
+ int timeout = 1000;
+ serviced = 1;
+
+ while (timeout--)
+ {
+ ptr = READL (devc->osdev, 0x2c);
+
+ if (ptr < dmap->dmabuf_phys)
+ continue;
+
+ ptr -= dmap->dmabuf_phys;
+
+ if (ptr >= dmap->bytes_in_use)
+ continue;
+
+ break;
+ }
+
+ if (dmap->fragment_size == 0)
+ {
+ cmn_err (CE_WARN, "dmap->fragment_size == 0\n");
+ continue;
+ }
+
+ ptr /= dmap->fragment_size;
+
+ if ((ptr < 0) || (ptr > dmap->nfrags))
+ ptr = 0;
+
+ n = 0;
+ while ((dmap_get_qtail (dmap) != ptr) && (n++ < dmap->nfrags))
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+
+ /* handle SPDIF output */
+ if (status & 0x20)
+ {
+ portc = &devc->portc[2];
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ && (portc->port_type == DF_SPDIF))
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
+ int ptr=0, n = 0;
+ int timeout = 1000;
+ serviced = 1;
+
+ while (timeout--)
+ {
+ ptr = READL (devc->osdev, 0x5c);
+ if (ptr < dmap->dmabuf_phys)
+ continue;
+ ptr -= dmap->dmabuf_phys;
+ if (ptr >= dmap->bytes_in_use)
+ continue;
+ break;
+ }
+
+ if (dmap->fragment_size == 0)
+ cmn_err (CE_WARN, "dmap->fragment_size == 0\n");
+ else
+ {
+ ptr /= dmap->fragment_size;
+
+ if ((ptr < 0) || (ptr > dmap->nfrags))
+ ptr = 0;
+
+ n = 0;
+ while ((dmap_get_qhead (dmap) != ptr) && (n++ < dmap->nfrags))
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+ }
+ }
+
+ /* Acknowledge Interrupts */
+ WRITEL (devc->osdev, status, 0x00);
+ /* MUTEX_EXIT (devc->mutex, flags); */
+ return serviced;
+}
+
+/*
+ * Audio routines
+ */
+
+static int
+ATI_audio_set_rate (int dev, int arg)
+{
+ ATI_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
+ arg = 48000;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+ATI_audio_set_channels (int dev, short arg)
+{
+ ATI_portc *portc = audio_engines[dev]->portc;
+
+ if ((arg == 1) || (arg == 2))
+ {
+ audio_engines[dev]->flags |= ADEV_STEREOONLY;
+ arg = 2;
+ }
+ else
+ audio_engines[dev]->flags &= ~ADEV_STEREOONLY;
+
+ if (arg>6)
+ arg=6;
+
+ if ((arg != 1) && (arg != 2) && (arg != 4) && (arg != 6))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+ATI_audio_set_format (int dev, unsigned int arg)
+{
+ ATI_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE | AFMT_AC3)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+ATI_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void ATI_audio_trigger (int dev, int state);
+
+static void
+ATI_audio_reset (int dev)
+{
+ ATI_audio_trigger (dev, 0);
+}
+
+static void
+ATI_audio_reset_input (int dev)
+{
+ ATI_portc *portc = audio_engines[dev]->portc;
+ ATI_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+ATI_audio_reset_output (int dev)
+{
+ ATI_portc *portc = audio_engines[dev]->portc;
+ ATI_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+ATI_audio_open (int dev, int mode, int openflags)
+{
+ ATI_portc *portc = audio_engines[dev]->portc;
+ ATI_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode || (devc->open_mode & mode))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ devc->open_mode |= mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+ATI_audio_close (int dev, int mode)
+{
+ ATI_portc *portc = audio_engines[dev]->portc;
+ ATI_devc *devc = audio_engines[dev]->devc;
+
+ ATI_audio_reset (dev);
+ portc->open_mode = 0;
+ devc->open_mode &= ~mode;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+ATI_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ATI_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+ATI_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ATI_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+ATI_enable_dma (int dev, int direction, int enable)
+{
+ ATI_devc *devc = audio_engines[dev]->devc;
+ ATI_portc *portc = audio_engines[dev]->portc;
+
+ if (enable)
+ {
+ if (direction)
+ {
+ /* flush fifo and enable analog or spdif DMA */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x88) | 1, 0x88);
+
+ if (portc->port_type == DF_ANALOG)
+ WRITEL (devc->osp, READL (devc->osp, 0x08) | 1 << 9, 0x08);
+ else
+ WRITEL (devc->osp, READL (devc->osp, 0x08) | 1 << 10, 0x08);
+
+ }
+ else
+ {
+ /* flush fifo */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x88) | 2, 0x88);
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) | 1 << 8, 0x08);
+ }
+ }
+ else
+ {
+ if (direction)
+ {
+ if (portc->port_type == DF_ANALOG)
+ WRITEL (devc->osp, READL (devc->osp, 0x08) & ~(1 << 9), 0x08);
+ else
+ WRITEL (devc->osp, READL (devc->osp, 0x08) & ~(1 << 10), 0x08);
+ }
+ else
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) & ~(1 << 8), 0x08);
+ }
+}
+
+static void
+ATI_audio_trigger (int dev, int state)
+{
+ ATI_devc *devc = audio_engines[dev]->devc;
+ ATI_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ ATI_enable_dma (dev, 1, 1);
+
+ /* set BDL & enable analog or SPDIF DMA */
+ if (portc->port_type == DF_ANALOG)
+ {
+ WRITEL (devc->osp, devc->playBDL_phys | 1, 0x38);
+ WRITEL (devc->osp, READL (devc->osp, 0x08) | 0x04, 0x08);
+ }
+ else /* SPDIF */
+ {
+ WRITEL (devc->osp, devc->spdifBDL_phys | 1, 0x50);
+ WRITEL (devc->osp, READL (devc->osp, 0x08) | 0x10, 0x08);
+ }
+
+ /* set bus busy */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x04) | 1 << 14, 0x04);
+
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ ATI_enable_dma (dev, 1, 0);
+
+ /* Stop Anlog or SPDIF DMA */
+ if (portc->port_type == DF_ANALOG)
+ WRITEL (devc->osp, READL (devc->osp, 0x08) & ~0x04, 0x08);
+ else
+ WRITEL (devc->osp, READL (devc->osp, 0x08) & ~0x10, 0x08);
+
+ /* set bus clear */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x04) & ~(1 << 14),
+ 0x04);
+
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ ATI_enable_dma (dev, 0, 1);
+ WRITEL (devc->osdev, devc->recBDL_phys | 1, 0x20);
+
+ /* enable audio intput and enable input DMA */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) | 0x02, 0x08);
+ /* set bus busy */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x04) | (1 << 14),
+ 0x04);
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ ATI_enable_dma (dev, 0, 0);
+ /* stop audio input */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) & ~0x02, 0x08);
+ /* clear bus busy */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x04) & ~(1 << 14),
+ 0x04);
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+ATI_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ ATI_devc *devc = audio_engines[dev]->devc;
+ ATI_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ int i, n;
+ unsigned int data;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ /* set the bits */
+ data = READL (devc->osdev, 0x08) & ~(1 << 21);
+ if (portc->bits == 16)
+ data |= (1 << 21);
+ WRITEL (devc->osdev, data, 0x08); /*set 8/16 bits */
+
+ n = dmap->nfrags;
+ if (n > BDL_SIZE)
+ {
+ cmn_err (CE_WARN, "Internal error - BDL too small\n");
+ return OSS_EIO;
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ int next = i + 1;
+ if (i == n - 1)
+ next = 0;
+
+ devc->recBDL[i].addr = dmap->dmabuf_phys + (i * dmap->fragment_size);
+ devc->recBDL[i].status = 0;
+ devc->recBDL[i].size = dmap->fragment_size >> 2;
+ devc->recBDL[i].next = devc->recBDL_phys + next * sizeof (bdl_t);
+ }
+
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+ATI_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ ATI_devc *devc = audio_engines[dev]->devc;
+ ATI_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ int i, n;
+ unsigned int data;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+
+ if (portc->port_type == DF_SPDIF)
+ {
+ ac97_spdif_setup (devc->mixer_dev, portc->speed, portc->bits);
+
+ if (portc->bits == AFMT_AC3)
+ {
+ portc->channels = 2;
+ portc->bits = 16;
+ }
+
+ n = dmap->nfrags;
+ if (n > BDL_SIZE)
+ n = BDL_SIZE;
+
+ for (i = 0; i < n; i++)
+ {
+ int next = i + 1;
+ if (i == n - 1)
+ next = 0;
+
+ devc->spdifBDL[i].addr =
+ dmap->dmabuf_phys + (i * dmap->fragment_size);
+ devc->spdifBDL[i].status = 0;
+ devc->spdifBDL[i].size = dmap->fragment_size >> 2;
+ devc->spdifBDL[i].next =
+ devc->spdifBDL_phys + next * sizeof (bdl_t);
+ }
+
+ }
+ else
+ {
+ data = READL (devc->osdev, 0x34) & ~0x3ff;
+ switch (portc->channels)
+ {
+ case 6:
+ data |= 0x30; /* slots 7, 8 */
+ break;
+ case 4:
+ data |= 0x48; /* slts 6, 9 */
+ break;
+ default:
+ data |= 0x03; /* slots 3, 4 */
+ break;
+ }
+ data |= 4 << 11;
+ WRITEL (devc->osdev, data, 0x34);
+
+ /* set the bits */
+ data = READL (devc->osdev, 0x08) & ~(1 << 22);
+ if (portc->bits == 16)
+ data |= (1 << 22);
+ WRITEL (devc->osdev, data, 0x08); /*set 8/16 bits */
+#if 0
+ /* set 6 channel reorder */
+ if (portc->channels >= 6)
+ WRITEL (devc->osdev, 0x1, 0x84);
+ else
+ WRITEL (devc->osdev, 0x00, 0x84);
+#endif
+ n = dmap->nfrags;
+ if (n > BDL_SIZE)
+ {
+ cmn_err (CE_WARN, "Internal error - BDL too small\n");
+ return OSS_EIO;
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ int next = i + 1;
+ if (i == n - 1)
+ next = 0;
+
+ devc->playBDL[i].addr =
+ dmap->dmabuf_phys + (i * dmap->fragment_size);
+ devc->playBDL[i].status = 0;
+ devc->playBDL[i].size = dmap->fragment_size >> 2;
+ devc->playBDL[i].next = devc->playBDL_phys + next * sizeof (bdl_t);
+ }
+ }
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+ATI_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ ATI_devc *devc = audio_engines[dev]->devc;
+ ATI_portc *portc = audio_engines[dev]->portc;
+ unsigned int f = 0;
+ oss_native_word flags;
+ int loop = 100;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /* we need to read the regs a couple of times because of possible h/w bugs */
+ while (loop--)
+ {
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ if (portc->port_type == DF_ANALOG)
+ f = READL (devc->osdev, 0x44);
+ else
+ f = READL (devc->osdev, 0x5c);
+ }
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ f = READL (devc->osdev, 0x2c);
+ }
+
+ if (f < dmap->dmabuf_phys)
+ continue;
+
+ f -= dmap->dmabuf_phys;
+
+ if (f >= dmap->bytes_in_use)
+ continue;
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return f;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+static const audiodrv_t ATI_audio_driver = {
+ ATI_audio_open,
+ ATI_audio_close,
+ ATI_audio_output_block,
+ ATI_audio_start_input,
+ ATI_audio_ioctl,
+ ATI_audio_prepare_for_input,
+ ATI_audio_prepare_for_output,
+ ATI_audio_reset,
+ NULL,
+ NULL,
+ ATI_audio_reset_input,
+ ATI_audio_reset_output,
+ ATI_audio_trigger,
+ ATI_audio_set_rate,
+ ATI_audio_set_format,
+ ATI_audio_set_channels,
+ NULL,
+ NULL,
+ NULL, /* ATI_check_input, */
+ NULL, /* ATI_check_output, */
+ NULL, /* ATI_alloc_buffer, */
+ NULL, /* ATI_free_buffer, */
+ NULL,
+ NULL,
+ ATI_get_buffer_pointer
+};
+
+static int
+init_ATI (ATI_devc * devc)
+{
+ int my_mixer, my_dev, opts;
+ int i, timeout;
+ oss_native_word phaddr;
+
+ /* Power up */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) & ~1, 0x08);
+ oss_udelay (20);
+ /* check if the ACLink is Active */
+ timeout = 10;
+ while (!(READL (devc->osdev, 0x08) & (1 << 28)))
+ {
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) | (1 << 30), 0x08); /* assert sync */
+ oss_udelay (10);
+ if (READL (devc->osdev, 0x08) & (1 << 28))
+ break;
+
+ /* set AC97 reset field to 0 */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) & ~(0x80000000), 0x08);
+ oss_udelay (10);
+
+ /* set AC97 reset field to 1 */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) | (0x80000000), 0x08);
+ oss_udelay (10);
+
+ if (READL (devc->osdev, 0x08) & (1 << 28))
+ break;
+ if (!--timeout)
+ {
+ cmn_err (CE_WARN, "Timed out waiting for AC97 Link ready\n");
+ break;
+ }
+ }
+
+ /* set ac97 reset field to 1: deassert */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) | (0x80000000), 0x08);
+
+ /* do a soft reset */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) | (1 << 29), 0x08);
+ oss_udelay (10);
+
+ /* deassert softreset */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) & ~(1 << 29), 0x08);
+ oss_udelay (10);
+
+ /* do a sync */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) | (1 << 30), 0x08);
+ oss_udelay (10);
+
+ /* now continue with initializing the rest of the chip */
+ WRITEL (devc->osdev, READL (devc->osdev, 0x08) | (1 << 25), 0x08); /*enable burst */
+
+ WRITEL (devc->osdev, 0x22, 0x04); /* enable audio+spdif interrupts */
+ devc->bdlBuffer =
+ CONTIG_MALLOC (devc->osdev, MAX_PORTC * BDL_SIZE * sizeof (bdl_t),
+ MEMLIMIT_32BITS, &phaddr, devc->bldbuf_dma_handle);
+ if (devc->bdlBuffer == NULL)
+ {
+ cmn_err (CE_WARN, "OSS Failed to allocate BDL\n");
+ return 0;
+ }
+
+ devc->playBDL = (bdl_t *) devc->bdlBuffer;
+ devc->playBDL_phys = phaddr;
+ devc->recBDL =
+ (bdl_t *) (devc->bdlBuffer + (1 * BDL_SIZE * sizeof (bdl_t)));
+ devc->recBDL_phys = phaddr + (1 * BDL_SIZE * sizeof (bdl_t));
+ devc->spdifBDL =
+ (bdl_t *) (devc->bdlBuffer + (2 * BDL_SIZE * sizeof (bdl_t)));
+ devc->spdifBDL_phys = phaddr + (2 * BDL_SIZE * sizeof (bdl_t));
+
+/*
+ * Init mixer
+ */
+ my_mixer =
+ ac97_install_full (&devc->ac97devc, "AC97 Mixer", ac97_read, ac97_write,
+ devc, devc->osdev, devc->inverted);
+
+ if (my_mixer == -1)
+ return 0; /* No mixer */
+
+ devc->mixer_dev = my_mixer;
+
+
+ /* enable S/PDIF */
+ devc->ac97devc.spdif_slot = SPDIF_SLOT1011;
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 1);
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ ATI_portc *portc = &devc->portc[i];
+ char tmp_name[100];
+ int formats = AFMT_S16_LE | AFMT_AC3;
+ char *devfile_name = "";
+ strcpy (tmp_name, devc->chip_name);
+ opts = ADEV_AUTOMODE | ADEV_STEREOONLY | ADEV_FIXEDRATE;
+ portc->port_type = DF_ANALOG;
+
+ if (i == 0)
+ {
+ opts |= ADEV_DUPLEX;
+ strcpy (tmp_name, devc->chip_name);
+ }
+ if (i == 1)
+ {
+ strcpy (tmp_name, devc->chip_name);
+ opts |= ADEV_DUPLEX | ADEV_SHADOW;
+ }
+ if (i == 2)
+ {
+ sprintf (tmp_name, "%s (SPDIF out)", devc->chip_name);
+ opts |= ADEV_NOINPUT | ADEV_SPECIAL;
+ portc->port_type = DF_SPDIF;
+ devfile_name = "spdout";
+ }
+
+ if ((my_dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &ATI_audio_driver,
+ sizeof (audiodrv_t),
+ opts, formats, devc, -1,
+ devfile_name)) < 0)
+ {
+ my_dev = -1;
+ return 0;
+ }
+ else
+ {
+ audio_engines[my_dev]->portc = portc;
+ audio_engines[my_dev]->mixer_dev = my_mixer;
+ audio_engines[my_dev]->min_rate =
+ (opts & ADEV_FIXEDRATE) ? 48000 : 5000;
+ audio_engines[my_dev]->max_rate = 48000;
+ audio_engines[my_dev]->caps |= PCM_CAP_FREERATE;
+ audio_engines[my_dev]->min_channels = 2;
+ audio_engines[my_dev]->max_channels = 6;
+
+ /*
+ * We can have at most BDL_SIZE fragments and they can
+ * be at most 128k each.
+ */
+ audio_engines[my_dev]->max_block = 128 * 1024;
+ audio_engines[my_dev]->max_fragments = BDL_SIZE;
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+ portc->audiodev = my_dev;
+ if (audio_engines[my_dev]->flags & ADEV_FIXEDRATE)
+ audio_engines[my_dev]->fixed_rate = 48000;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, my_dev, -1, 0);
+#endif
+ }
+ }
+ return 1;
+}
+
+
+int
+oss_atiaudio_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision /*, pci_latency */ ;
+ unsigned short pci_command, vendor, device, sub_vendor, sub_id;
+ unsigned int pci_ioaddr;
+ ATI_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered ATI AC97 probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if ((vendor != ATI_VENDOR_ID) || (device != ATI_DEVICE_IXP &&
+ device != ATI_DEVICE_IXP300
+ && device != ATI_DEVICE_IXP400))
+ return 0;
+
+ oss_pci_byteswap (osdev, 1);
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &pci_ioaddr);
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor);
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_ID, &sub_id);
+ switch ((sub_id << 16) | sub_vendor)
+ {
+ case 0x11831043: /* ASUS A6R */
+ case 0x2043161f: /* Maxselect x710s */
+ case 0x0506107b: /* Gateway 7510GX */
+ devc->inverted = AC97_INVERTED;
+ cmn_err (CE_CONT, "An inverted amplifier has been autodetected\n");
+ break;
+ default:
+ devc->inverted = 0;
+ break;
+ }
+
+ devc->membar_addr = pci_ioaddr;
+ devc->membar_virt =
+ (char *) MAP_PCI_MEM (devc->osdev, 0, devc->membar_addr, 256);
+
+ if (devc->membar_virt == NULL)
+ {
+ cmn_err (CE_WARN, "ATIIXP: Cannot map pci mem\n");
+ return 0;
+ }
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+#if 0
+ latency = pci_read_config_dword (osdev, 0x50, &latency);
+ pci_write_config_dword (osdev, 0x50, latency | 1);
+#endif
+
+ switch (device)
+ {
+ case ATI_DEVICE_IXP:
+ devc->chip_name = "ATI IXP200";
+ break;
+
+ case ATI_DEVICE_IXP300:
+ devc->chip_name = "ATI IXP300";
+ break;
+
+ case ATI_DEVICE_IXP400:
+ devc->chip_name = "ATI IXP400";
+ break;
+
+ default:
+ devc->chip_name = "ATI IXP";
+ break;
+ }
+
+ devc->irq = pci_irq_line;
+ devc->open_mode = 0;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if (oss_register_interrupts (devc->osdev, 0, ATIIXPintr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Unable to register interrupts\n");
+ return 0;
+ }
+
+ return init_ATI (devc); /* Detected */
+}
+
+
+int
+oss_atiaudio_detach (oss_device_t * osdev)
+{
+ ATI_devc *devc = (ATI_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ WRITEL (devc->osdev, 0x3f, 0x00); /* ack all interrupts */
+ WRITEL (devc->osdev, 0, 0x04); /* disable interrupts */
+
+ /* disable S/PDIF */
+ if (devc->mixer_dev)
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 0);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ if (devc->bdlBuffer)
+ CONTIG_FREE (devc->osdev, devc->bdlBuffer,
+ MAX_PORTC * BDL_SIZE * sizeof (bdl_t), devc->bldbuf_dma_handle);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+
+ if (devc->membar_addr != 0)
+ {
+ UNMAP_PCI_MEM (devc->osdev, 0, devc->membar_addr, devc->membar_virt,
+ 256);
+ devc->membar_addr = 0;
+ }
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+
+}
diff --git a/kernel/drv/oss_atiaudio/oss_atiaudio.man b/kernel/drv/oss_atiaudio/oss_atiaudio.man
new file mode 100644
index 0000000..9818517
--- /dev/null
+++ b/kernel/drv/oss_atiaudio/oss_atiaudio.man
@@ -0,0 +1,19 @@
+NAME
+oss_atiaudio - ATI IXP southbridge audio driver.
+
+DESCRIPTION
+Open Sound System driver for ATI IXP 150/200/250 audio controller
+ATI IXP device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo/4ch/5.1ch playback
+ o 8KHz to 48Khz sample rate.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_atiaudio.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_audigyls/.devices b/kernel/drv/oss_audigyls/.devices
new file mode 100644
index 0000000..fee016d
--- /dev/null
+++ b/kernel/drv/oss_audigyls/.devices
@@ -0,0 +1 @@
+oss_audigyls pci1102,7 Sound Blaster Audigy LS / Live7.1
diff --git a/kernel/drv/oss_audigyls/.name b/kernel/drv/oss_audigyls/.name
new file mode 100644
index 0000000..c68179e
--- /dev/null
+++ b/kernel/drv/oss_audigyls/.name
@@ -0,0 +1 @@
+Sound Blaster Audigy LS / Live7.1
diff --git a/kernel/drv/oss_audigyls/.params b/kernel/drv/oss_audigyls/.params
new file mode 100644
index 0000000..7714edd
--- /dev/null
+++ b/kernel/drv/oss_audigyls/.params
@@ -0,0 +1,6 @@
+int audigyls_spdif_enable=0;
+/*
+ * Set the Orange Jack to SPDIF or Analog output
+ * Values 1=SPDIF 0=Analog (side-surround) Default=0
+ */
+
diff --git a/kernel/drv/oss_audigyls/oss_audigyls.c b/kernel/drv/oss_audigyls/oss_audigyls.c
new file mode 100644
index 0000000..1639e6c
--- /dev/null
+++ b/kernel/drv/oss_audigyls/oss_audigyls.c
@@ -0,0 +1,1860 @@
+/*
+ * Purpose: Driver for Creative Audigy LS audio controller
+ *
+ * This sound card has been sold under many different names.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_audigyls_cfg.h"
+#include "oss_pci.h"
+#include "ac97.h"
+#include "midi_core.h"
+#include "remux.h"
+
+#define DEFAULT_RATE 48000
+
+#undef USE_ITIMER
+
+#define PCI_VENDOR_ID_CREATIVE 0x1102
+#define PCI_DEVICE_ID_CREATIVE_AUDIGYLS 0x0007
+
+/*
+ * Indirect registers
+ */
+
+#define PTBA 0x000
+#define PTBS 0x001
+#define PTCA 0x002
+#define PFBA 0x004
+#define PFBS 0x005
+#define CPFA 0x006
+#define PFEA 0x007
+#define CPCAV 0x008
+#define RFBA 0x010
+#define RFBS 0x011
+#define CRFA 0x012
+#define CRCAV 0x013
+#define CDL 0x020
+#define SA 0x040
+#define SCS3 0x041
+#define SCS0 0x042
+#define SCS1 0x043
+#define SCS2 0x044
+#define SPC 0x045
+#define WMARK 0x046
+#define SPSC 0x049
+#define RCD 0x050 /* 0x50-0z5f */
+#define P17RECSEL 0x060
+#define P17RECVOLL 0x061
+#define P17RECVOLH 0x062
+
+#define HMIXMAP_SPDIF 0x63
+#define SMIXMAP_SPDIF 0x64
+#define MIXCTL_SPDIF 0x65
+#define MIXVOL_SPDIF 0x66
+#define HMIXMAP_I2S 0x67
+#define SMIXMAP_I2S 0x68
+#define MIXCTL_I2S 0x69
+#define MIXVOL_I2S 0x6a
+
+/* MIDI UART */
+#define MUDATA 0x06c
+#define MUCMDA 0x06d
+#define MUDATB 0x06e
+#define MUCMDB 0x06f
+
+#define SRT 0x070
+#define SRCTL 0x071
+#define AUDCTL 0x072
+#define CHIP_ID 0x074
+#define AINT_ENABLE 0x075
+#define AINT_STATUS 0x076
+#define Wall192 0x077
+#define Wall441 0x078
+#define IT 0x079
+#define SPI 0x07a
+#define I2C_A 0x07b
+#define I2C_0 0x07c
+#define I2C_1 0x07d
+
+/*
+ * Global Interrupt bits
+ */
+
+#define IE 0x0c
+#define INTR_PCI (1<< 0)
+#define INTR_TXA (1<< 1)
+#define INTR_RXA (1<< 2)
+#define INTR_IT1 (1<< 3)
+#define INTR_IT2 (1<< 4)
+#define INTR_SS_ (1<< 5)
+#define INTR_SRT (1<< 6)
+#define INTR_GP (1<< 7)
+#define INTR_AI (1<< 8)
+#define INTR_I2Cdac (1<< 9)
+#define INTR_I2CEE (1<< 10)
+#define INTR_SPI (1<< 11)
+#define INTR_SPF (1<< 12)
+#define INTR_SUO (1<< 13)
+#define INTR_SUI (1<< 14)
+#define INTR_TXB (1<< 16)
+#define INTR_RXB (1<< 17)
+
+/*
+ * Audio interrupt bits
+ */
+
+#define AI_PFH (1<< 0)
+#define AI_PFF (1<< 4)
+#define AI_TFH (1<< 8)
+#define AI_TFF (1<< 12)
+#define AI_RFH (1<< 16)
+#define AI_RFF (1<< 20)
+#define AI_EAI (1<< 24)
+
+
+#define MAX_PORTC 3
+
+extern int audigyls_spdif_enable;
+
+typedef struct
+{
+ int audio_dev;
+ int play_port;
+ int rec_port;
+ int open_mode;
+ int trigger_bits;
+ int audio_enabled;
+ int channels;
+ int bits;
+ int speed;
+#ifdef USE_ITIMER
+ int frag_192khz;
+#endif
+ int port_type;
+ int play_ptr, rec_ptr;
+}
+audigyls_portc;
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_native_word base;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+ char *card_name;
+ unsigned int subvendor;
+ int rec_src; /* record channel src spdif/i2s/ac97/src */
+#define RECSEL_SPDIFOUT 0
+#define RECSEL_I2SOUT 1
+#define RECSEL_SPDIFIN 2
+#define RECSEL_I2SIN 3
+#define RECSEL_AC97 4
+#define RECSEL_SRC 5
+
+ int mixer_dev;
+ ac97_devc ac97devc;
+ int has_ac97;
+ int spread; /* copy front to surr/center channels */
+ int loopback; /* record channel input from /dev/dspXX */
+ int input_source; /* input from mic/line/aux/etc */
+ int captmon; /* hear what you record*/
+ int fbvol; /* recording monitor volume */
+/*
+ * UART
+ */
+ oss_midi_inputbyte_t midi_input_intr;
+ int midi_opened, midi_disabled;
+ volatile unsigned char input_byte;
+ int midi_dev;
+ int mpu_attached;
+ int playvol[4];
+ int recvol;
+ audigyls_portc portc[MAX_PORTC];
+
+}
+audigyls_devc;
+
+
+static void audigylsuartintr (audigyls_devc * devc);
+
+static unsigned int
+read_reg (audigyls_devc * devc, int reg, int chn)
+{
+ oss_native_word flags;
+ unsigned int val;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTL (devc->osdev, (reg << 16) | (chn & 0xffff), devc->base + 0x00); /* Pointer */
+ val = INL (devc->osdev, devc->base + 0x04); /* Data */
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+/*printk("Read reg %03x (ch %d) = %08x\n", reg, chn, val);*/
+ return val;
+}
+
+static void
+write_reg (audigyls_devc * devc, int reg, int chn, unsigned int value)
+{
+ oss_native_word flags;
+
+ /*printk("Write reg %03x (ch %d) = %08x\n", reg, chn, value); */
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTL (devc->osdev, (reg << 16) | (chn & 0xffff), devc->base + 0x00); /* Pointer */
+ OUTL (devc->osdev, value, devc->base + 0x04); /* Data */
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+#if 0
+ {
+ char tmp[100];
+ int ok = 1;
+ sprintf (tmp, "@w%d %04x/%s %x", chn, reg, emu_regname (reg, &ok), value);
+ if (ok)
+ oss_do_timing (tmp);
+ }
+#endif
+}
+
+
+static int
+audigyls_ac97_read (void *devc_, int wAddr)
+{
+ audigyls_devc *devc = devc_;
+ int dtemp = 0, i;
+
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, wAddr, devc->base + 0x1e);
+ for (i = 0; i < 10000; i++)
+ if (INB (devc->osdev, devc->base + 0x1e) & 0x80)
+ break;
+ if (i == 10000)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+ dtemp = INW (devc->osdev, devc->base + 0x1c);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return dtemp & 0xffff;
+}
+
+static int
+audigyls_ac97_write (void *devc_, int wAddr, int wData)
+{
+ audigyls_devc *devc = devc_;
+ oss_native_word flags;
+ int i;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, wAddr, devc->base + 0x1e);
+ for (i = 0; i < 10000; i++)
+ if (INB (devc->osdev, devc->base + 0x1e) & 0x80)
+ break;
+ if (i == 10000)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+ OUTW (devc->osdev, wData, devc->base + 0x1c);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return 0;
+}
+
+static void
+check_recording_intr (audigyls_devc * devc, audigyls_portc * portc)
+{
+#if 1
+ int pos, n = 0;
+ dmap_p dmap;
+
+ dmap = audio_engines[portc->audio_dev]->dmap_in;
+
+ pos = read_reg (devc, CRFA, portc->rec_port);
+ pos /= dmap->fragment_size;
+ while (dmap_get_qtail (dmap) != pos && n++ < dmap->nfrags)
+#endif
+ oss_audio_inputintr (portc->audio_dev, 0);
+}
+
+static void
+check_playback_intr (audigyls_devc * devc, audigyls_portc * portc)
+{
+#if 1
+ int pos, n = 0;
+ dmap_p dmap;
+
+ dmap = audio_engines[portc->audio_dev]->dmap_out;
+
+ pos = read_reg (devc, CPFA, portc->play_port);
+ pos /= dmap->fragment_size;
+ while (dmap_get_qhead (dmap) != pos && n++ < dmap->nfrags)
+#endif
+ oss_audio_outputintr (portc->audio_dev, 0);
+}
+
+static int
+audigylsintr (oss_device_t * osdev)
+{
+ int serviced = 0;
+ unsigned int status;
+ unsigned int astatus = 0;
+ int i;
+ audigyls_devc *devc = osdev->devc;
+ audigyls_portc *portc;
+ oss_native_word flags;
+
+ flags = 0; /* To fix compiler warnings about unused variable */
+ MUTEX_ENTER (devc->mutex, flags);
+
+ status = INL (devc->osdev, devc->base + 0x08);
+
+ if (status & INTR_RXA) /* MIDI RX interrupt */
+ {
+ audigylsuartintr (devc);
+ }
+
+ if (status & INTR_AI)
+ {
+ astatus = read_reg (devc, AINT_STATUS, 0);
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT) &&
+ (astatus & ((AI_PFF | AI_PFH) << portc->play_port)))
+ {
+ dmap_t *dmap = audio_engines[portc->audio_dev]->dmap_out;
+
+ if (astatus & (AI_PFF << portc->play_port))
+ portc->play_ptr = 0;
+ if (astatus & (AI_PFH << portc->play_port))
+ portc->play_ptr = dmap->bytes_in_use / 2;
+
+ oss_audio_outputintr (portc->audio_dev, 0);
+ }
+ if ((portc->trigger_bits & PCM_ENABLE_INPUT) &&
+ (astatus & ((AI_RFF | AI_RFH) << portc->rec_port)))
+ {
+ dmap_t *dmap = audio_engines[portc->audio_dev]->dmap_in;
+
+ if (astatus & (AI_RFF << portc->rec_port))
+ portc->rec_ptr = 0;
+ if (astatus & (AI_RFH << portc->rec_port))
+ portc->rec_ptr = dmap->bytes_in_use / 2;
+
+ oss_audio_inputintr (portc->audio_dev, 0);
+ }
+ }
+ write_reg (devc, AINT_STATUS, 0, astatus);
+ }
+
+ if (status & INTR_IT1)
+ {
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ check_playback_intr (devc, portc);
+
+ if ((portc->trigger_bits & PCM_ENABLE_INPUT))
+ check_recording_intr (devc, portc);
+ }
+ }
+
+ serviced = 1;
+ OUTL (devc->osdev, status, devc->base + 0x08); /* Acknowledge */
+ MUTEX_EXIT (devc->mutex, flags);
+ return serviced;
+}
+
+static int
+audigyls_set_rate (int dev, int arg)
+{
+ audigyls_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
+ arg = DEFAULT_RATE;
+
+ if (arg != 44100 && arg != 48000 && arg != 96000 && arg != 192000)
+ arg = 48000;
+
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+audigyls_set_channels (int dev, short arg)
+{
+ audigyls_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->channels;
+
+ if ((arg == 1))
+ arg = 2;
+
+ if (portc->open_mode & OPEN_READ)
+ return portc->channels = 2;
+
+ if (arg != 1 && arg != 2)
+ return portc->channels = 2;
+ return portc->channels = arg;
+}
+
+static unsigned int
+audigyls_set_format (int dev, unsigned int arg)
+{
+ audigyls_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (arg != AFMT_AC3 && arg != AFMT_S16_LE)
+ return portc->bits = AFMT_S16_LE;
+
+ return portc->bits = arg;
+}
+
+/*ARGSUSED*/
+static int
+audigyls_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void audigyls_trigger (int dev, int state);
+
+static void
+audigyls_reset (int dev)
+{
+ audigyls_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static int
+audigyls_open (int dev, int mode, int open_flags)
+{
+ audigyls_portc *portc = audio_engines[dev]->portc;
+ audigyls_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ portc->open_mode = mode;
+ portc->audio_enabled = ~mode;
+ portc->play_ptr = portc->rec_ptr = 0;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+audigyls_close (int dev, int mode)
+{
+ audigyls_portc *portc = audio_engines[dev]->portc;
+
+ audigyls_reset (dev);
+ portc->open_mode = 0;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+audigyls_output_block (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+audigyls_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+ audigyls_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+#ifdef USE_ITIMER
+static void
+check_itimer (audigyls_devc * devc)
+{
+ int i;
+ unsigned int t = 0x1fffffff;
+ audigyls_portc *portc;
+ int tmp;
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+ if (portc->frag_192khz != 0 && portc->frag_192khz < t)
+ t = portc->frag_192khz;
+ }
+ if (t == 0x1fffffff) /* No audio devices active */
+ {
+ tmp = INL (devc->osdev, devc->base + IE);
+ tmp &= ~INTR_IT1;
+ OUTL (devc->osdev, tmp, devc->base + IE);
+ }
+ else
+ {
+ t /= 16;
+ if (t < 1)
+ t = 1;
+ write_reg (devc, IT, 0, t);
+ tmp = INL (devc->osdev, devc->base + IE);
+ tmp |= INTR_IT1;
+ OUTL (devc->osdev, tmp, devc->base + IE);
+ }
+}
+
+static void
+adjust_itimer (audigyls_devc * devc, audigyls_portc * portc, dmap_p dmap)
+{
+ unsigned int t;
+
+ /* Compute byte rate */
+
+ t = portc->speed * portc->channels;
+
+ switch (portc->bits)
+ {
+ case AFMT_S16_LE:
+ case AFMT_S16_BE:
+ case AFMT_AC3:
+ t *= 2;
+ break;
+
+ case AFMT_S32_LE:
+ case AFMT_S32_BE:
+ case AFMT_S24_LE:
+ case AFMT_S24_BE:
+ t *= 4;
+ break;
+ }
+
+/* Compute the number of 192kHz ticks per fragment */
+
+ t = (dmap->fragment_size * 192000) / t; /* msecs / fragment */
+ if (t < 1)
+ t = 1;
+
+ portc->frag_192khz = t;
+ check_itimer (devc);
+}
+#endif
+
+static void
+audigyls_trigger (int dev, int state)
+{
+ audigyls_devc *devc = audio_engines[dev]->devc;
+ audigyls_portc *portc = audio_engines[dev]->portc;
+ int tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ tmp = read_reg (devc, SA, 0);
+ tmp |= 1 << portc->play_port;
+ write_reg (devc, SA, 0, tmp);
+#ifdef USE_ITIMER
+ check_itimer (devc);
+#else
+ tmp = read_reg (devc, AINT_ENABLE, 0);
+ tmp |= ((AI_PFH | AI_PFF) << portc->play_port);
+ write_reg (devc, AINT_ENABLE, 0, tmp);
+#endif
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+#ifdef USE_ITIMER
+ portc->frag_192khz = 0;
+ check_itimer (devc);
+#endif
+ /* Disable Play channel */
+ tmp = read_reg (devc, SA, 0);
+ tmp &= ~(1 << portc->play_port);
+ write_reg (devc, SA, 0, tmp);
+#ifndef USE_ITIMER
+ tmp = read_reg (devc, AINT_ENABLE, 0);
+ tmp &= ~((AI_PFH | AI_PFF) << portc->play_port);
+ write_reg (devc, AINT_ENABLE, 0, tmp);
+#endif
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ /* Enable Rec Channel */
+ tmp = read_reg (devc, SA, 0);
+ tmp |= 0x100 << portc->rec_port; /* enable record */
+ write_reg (devc, SA, 0, tmp);
+#ifdef USE_ITIMER
+ check_itimer (devc);
+#else
+ tmp = read_reg (devc, AINT_ENABLE, 0);
+ tmp |= ((AI_RFF | AI_RFH) << portc->rec_port);
+ write_reg (devc, AINT_ENABLE, 0, tmp);
+#endif
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+#ifdef USE_ITIMER
+ portc->frag_192khz = 0;
+ check_itimer (devc);
+#endif
+ /* disable channel */
+ tmp = read_reg (devc, SA, 0);
+ tmp &= ~(0x100 << portc->rec_port);
+ write_reg (devc, SA, 0, tmp);
+#ifndef USE_ITIMER
+ tmp = read_reg (devc, AINT_ENABLE, 0);
+ tmp &= ~((AI_RFF | AI_RFH) << portc->rec_port);
+ write_reg (devc, AINT_ENABLE, 0, tmp);
+#endif
+ }
+ }
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+audigyls_prepare_for_input (int dev, int bsize, int bcount)
+{
+ unsigned int tmp, recmap, reg;
+ /*LINTED*/ unsigned int oversample;
+ audigyls_devc *devc = audio_engines[dev]->devc;
+ audigyls_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_in;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ write_reg (devc, CRFA, portc->rec_port, 0);
+ write_reg (devc, CRCAV, portc->rec_port, 0);
+
+ write_reg (devc, RFBA, portc->rec_port, dmap->dmabuf_phys);
+ write_reg (devc, RFBS, portc->rec_port, (dmap->bytes_in_use) << 16);
+
+ /* set 16/24 bits */
+ tmp = INL (devc->osdev, devc->base + 0x14);
+ if (portc->bits == AFMT_S16_LE)
+ tmp &= ~0x400; /*16 bit */
+ else
+ tmp |= 0x400; /*24 bit */
+ OUTL (devc->osdev, tmp, devc->base + 0x14);
+
+ /* set recording speed */
+ reg = read_reg (devc, SRCTL, 0) & ~0xc000;
+
+ switch (portc->speed)
+ {
+ case 48000:
+ reg |= 0x0;
+ oversample = 0x2;
+ break;
+
+ case 96000:
+ reg |= 0x8000;
+ oversample = 0xa;
+ break;
+
+ case 192000:
+ reg |= 0xc000;
+ oversample = 0xa;
+ break;
+
+ default:
+ reg |= 0;
+ oversample = 0x2;
+ break;
+ }
+
+ write_reg (devc, SRCTL, 0, reg);
+/* audigyls_i2c_write(devc, 0xc, oversample);*/
+
+/* setup record input */
+ if (devc->loopback)
+ {
+ devc->rec_src = RECSEL_I2SOUT;
+ recmap = 0;
+ }
+ else
+ {
+ if (devc->has_ac97)
+ {
+ devc->rec_src = RECSEL_AC97; /* audigy LS */
+ }
+ else
+ {
+ devc->rec_src = RECSEL_I2SIN; /* sb 7.1 value */
+ }
+ recmap = 0x00;
+ }
+ tmp = recmap; /* default record input map */
+ tmp |= devc->rec_src << 28 | devc->rec_src << 24 | devc->rec_src << 20 | devc->rec_src << 16;
+//write_reg (devc, SMIXMAP_SPDIF, 0, 0x76767676);
+ write_reg (devc, P17RECSEL, 0, tmp);
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+#ifdef USE_ITIMER
+ adjust_itimer (devc, portc, dmap);
+#endif
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+audigyls_prepare_for_output (int dev, int bsize, int bcount)
+{
+ audigyls_devc *devc = audio_engines[dev]->devc;
+ audigyls_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_out;
+ unsigned int tmp, reg;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->bits == AFMT_AC3)
+ portc->channels = 2;
+
+ write_reg (devc, PTBA, portc->play_port, 0);
+ write_reg (devc, PTBS, portc->play_port, 0);
+ write_reg (devc, PTCA, portc->play_port, 0);
+
+ write_reg (devc, CPFA, portc->play_port, 0);
+ write_reg (devc, PFEA, portc->play_port, 0);
+ write_reg (devc, CPCAV, portc->play_port, 0);
+
+
+ /* set 16/24 bits */
+ tmp = INL (devc->osdev, devc->base + 0x14);
+ if (portc->bits == AFMT_S16_LE)
+ tmp &= ~0x800; /*16 bit */
+ else
+ tmp |= 0x800; /*24 bit */
+ OUTL (devc->osdev, tmp, devc->base + 0x14);
+
+ /* set playback rate */
+ tmp = read_reg (devc, SA, 0) & ~0xff0000;
+ reg = read_reg (devc, SRCTL, 0) & ~0x0303000f;
+#if 0
+ switch (portc->speed)
+ {
+ case 48000:
+ tmp |= 0;
+ reg |= 0;
+ break;
+
+ case 44100:
+ tmp |= 0x10000;
+ reg |= 0x01010005;
+ break;
+
+ case 96000:
+ tmp |= 0x20000;
+ reg |= 0x0202000a;
+ break;
+
+ case 192000:
+ tmp |= 0x30000;
+ reg |= 0x0303000f;
+ break;
+
+ default:
+ tmp |= 0; /* default is 48000 */
+ reg |= 0;
+ break;
+ }
+#endif
+ write_reg (devc, SA, 0, tmp << (portc->play_port * 2));
+ write_reg (devc, SRCTL, 0, reg);
+
+ /* Single buffering mode */
+ write_reg (devc, PFBA, portc->play_port, dmap->dmabuf_phys);
+ write_reg (devc, PFBS, portc->play_port, (dmap->bytes_in_use) << 16);
+
+ if (audigyls_spdif_enable)
+ {
+ if (portc->bits == AFMT_AC3)
+ {
+ audigyls_ac97_write (devc, 0x1c, 0x8000);
+ write_reg (devc, SCS3, 0, 0x02108006); /* Non Audio */
+#if 0
+ write_reg (devc, SCS0, 0, 0x02108006); /* Non Audio */
+ write_reg (devc, SCS1, 0, 0x02108006); /* Non Audio */
+ write_reg (devc, SCS2, 0, 0x02108006); /* Non Audio */
+#endif
+ }
+ else
+ {
+ write_reg (devc, SCS3, 0, 0x02108004); /* Audio */
+#if 0
+ write_reg (devc, SCS0, 0, 0x02108004); /* Audio */
+ write_reg (devc, SCS1, 0, 0x02108004); /* Audio */
+ write_reg (devc, SCS2, 0, 0x02108004); /* Audio */
+#endif
+ }
+ }
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+#ifdef USE_ITIMER
+ adjust_itimer (devc, portc, dmap);
+#endif
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+audigyls_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ unsigned int p = 0;
+ audigyls_portc *portc = audio_engines[dev]->portc;
+
+#if 1
+ audigyls_devc *devc = audio_engines[dev]->devc;
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ p = read_reg (devc, CPFA, portc->play_port);
+ }
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ p = read_reg (devc, CRFA, portc->rec_port);
+ }
+
+ /*
+ * Round to the nearest fragment boundary.
+ */
+ p = (p + dmap->fragment_size / 2);
+ p = (p / dmap->fragment_size) * dmap->fragment_size;
+#else
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ return portc->play_ptr;
+ }
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ return portc->rec_ptr;
+ }
+#endif
+
+ return p % dmap->bytes_in_use;
+}
+
+static audiodrv_t audigyls_audio_driver = {
+ audigyls_open,
+ audigyls_close,
+ audigyls_output_block,
+ audigyls_start_input,
+ audigyls_ioctl,
+ audigyls_prepare_for_input,
+ audigyls_prepare_for_output,
+ audigyls_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ audigyls_trigger,
+ audigyls_set_rate,
+ audigyls_set_format,
+ audigyls_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* audigyls_alloc_buffer, */
+ NULL, /* audigyls_free_buffer */
+ NULL,
+ NULL,
+ audigyls_get_buffer_pointer
+};
+
+
+static __inline__ int
+audigylsuart_status (audigyls_devc * devc)
+{
+ return read_reg (devc, MUCMDA, 0);
+}
+
+#define input_avail(devc) (!(audigylsuart_status(devc)&INPUT_AVAIL))
+#define output_ready(devc) (!(audigylsuart_status(devc)&OUTPUT_READY))
+static void
+audigylsuart_cmd (audigyls_devc * devc, unsigned char cmd)
+{
+ write_reg (devc, MUCMDA, 0, cmd);
+}
+
+static __inline__ int
+audigylsuart_read (audigyls_devc * devc)
+{
+ return read_reg (devc, MUDATA, 0);
+}
+
+static __inline__ void
+audigylsuart_write (audigyls_devc * devc, unsigned char byte)
+{
+ write_reg (devc, MUDATA, 0, byte);
+}
+
+#define OUTPUT_READY 0x40
+#define INPUT_AVAIL 0x80
+#define MPU_ACK 0xFE
+#define MPU_RESET 0xFF
+#define UART_MODE_ON 0x3F
+
+static int reset_audigylsuart (audigyls_devc * devc);
+static void enter_uart_mode (audigyls_devc * devc);
+
+static void
+audigylsuart_input_loop (audigyls_devc * devc)
+{
+ while (input_avail (devc))
+ {
+ unsigned char c = audigylsuart_read (devc);
+
+ if (c == MPU_ACK)
+ devc->input_byte = c;
+ else if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr (devc->midi_dev, c);
+ }
+}
+
+static void
+audigylsuartintr (audigyls_devc * devc)
+{
+ audigylsuart_input_loop (devc);
+}
+
+/*ARGSUSED*/
+static int
+audigylsuart_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ audigyls_devc *devc = (audigyls_devc *) midi_devs[dev]->devc;
+
+ if (devc->midi_opened)
+ {
+ return OSS_EBUSY;
+ }
+
+ while (input_avail (devc))
+ audigylsuart_read (devc);
+
+ devc->midi_input_intr = inputbyte;
+ devc->midi_opened = mode;
+ enter_uart_mode (devc);
+ devc->midi_disabled = 0;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+audigylsuart_close (int dev, int mode)
+{
+ audigyls_devc *devc = (audigyls_devc *) midi_devs[dev]->devc;
+ reset_audigylsuart (devc);
+ oss_udelay (10);
+ enter_uart_mode (devc);
+ reset_audigylsuart (devc);
+ devc->midi_opened = 0;
+}
+
+
+static int
+audigylsuart_out (int dev, unsigned char midi_byte)
+{
+ int timeout;
+ audigyls_devc *devc = (audigyls_devc *) midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ /*
+ * Test for input since pending input seems to block the output.
+ */
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (input_avail (devc))
+ audigylsuart_input_loop (devc);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ /*
+ * Sometimes it takes about 130000 loops before the output becomes ready
+ * (After reset). Normally it takes just about 10 loops.
+ */
+
+ for (timeout = 130000; timeout > 0 && !output_ready (devc); timeout--);
+
+ if (!output_ready (devc))
+ {
+ cmn_err (CE_WARN, "UART timeout - Device not responding\n");
+ devc->midi_disabled = 1;
+ reset_audigylsuart (devc);
+ enter_uart_mode (devc);
+ return 1;
+ }
+
+ audigylsuart_write (devc, midi_byte);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+audigylsuart_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t audigyls_midi_driver = {
+ audigylsuart_open,
+ audigylsuart_close,
+ audigylsuart_ioctl,
+ audigylsuart_out,
+};
+
+static void
+enter_uart_mode (audigyls_devc * devc)
+{
+ int ok, timeout;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+
+ devc->input_byte = 0;
+ audigylsuart_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 (audigylsuart_read (devc) == MPU_ACK)
+ ok = 1;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+
+void
+attach_audigylsuart (audigyls_devc * devc)
+{
+ enter_uart_mode (devc);
+ devc->midi_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "AUDIGYLS", "AudigyLS UART", &audigyls_midi_driver, sizeof (midi_driver_t),
+ 0, devc, devc->osdev);
+ devc->midi_opened = 0;
+}
+
+static int
+reset_audigylsuart (audigyls_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;
+ audigylsuart_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 (audigylsuart_read (devc) == MPU_ACK)
+ ok = 1;
+
+ }
+
+
+
+ if (ok)
+ audigylsuart_input_loop (devc); /*
+ * Flush input before enabling interrupts
+ */
+
+ return ok;
+}
+
+
+int
+probe_audigylsuart (audigyls_devc * devc)
+{
+ int ok = 0;
+ oss_native_word flags;
+
+ DDB (cmn_err (CE_CONT, "Entered probe_audigylsuart\n"));
+
+ devc->midi_input_intr = NULL;
+ devc->midi_opened = 0;
+ devc->input_byte = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ ok = reset_audigylsuart (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (ok)
+ {
+ DDB (cmn_err (CE_CONT, "Reset UART401 OK\n"));
+ }
+ else
+ {
+ DDB (cmn_err
+ (CE_CONT, "Reset UART401 failed (no hardware present?).\n"));
+ DDB (cmn_err
+ (CE_CONT, "mpu401 status %02x\n", audigylsuart_status (devc)));
+ }
+
+ DDB (cmn_err (CE_CONT, "audigylsuart detected OK\n"));
+ return ok;
+}
+
+void
+unload_audigylsuart (audigyls_devc * devc)
+{
+ reset_audigylsuart (devc);
+}
+
+
+static void
+attach_mpu (audigyls_devc * devc)
+{
+ devc->mpu_attached = 1;
+ attach_audigylsuart (devc);
+}
+
+/* only for SBLive 7.1 */
+int
+audigyls_i2c_write (audigyls_devc * devc, int reg, int data)
+{
+ int i, timeout, tmp;
+
+
+ tmp = (reg << 9 | data) << 16; /* set the upper 16 bits */
+ /* first write the command to the data reg */
+ write_reg (devc, I2C_1, 0, tmp);
+ for (i = 0; i < 20; i++)
+ {
+ tmp = read_reg (devc, I2C_A, 0) & ~0x6fe;
+ /* see audigyls.pdf for bits */
+ tmp |= 0x400 | 0x100 | 0x34;
+ write_reg (devc, I2C_A, 0, tmp);
+ /* now wait till controller sets valid bit (0x100) to 0 */
+ timeout = 0;
+ /*LINTED*/ while (1)
+ {
+ tmp = read_reg (devc, I2C_A, 0);
+ if ((tmp & 0x100) == 0)
+ break;
+
+ if (timeout > 100)
+ break;
+
+ timeout++;
+ }
+
+ /* transaction aborted */
+ if (tmp & 0x200)
+ return 0;
+ }
+ return 1;
+}
+
+int
+audigyls_spi_write (audigyls_devc * devc, int data)
+{
+ unsigned int orig;
+ unsigned int tmp;
+ int i, valid;
+
+ tmp = read_reg (devc, SPI, 0);
+ orig = (tmp & ~0x3ffff) | 0x30000;
+ write_reg (devc, SPI, 0, orig | data);
+ valid = 0;
+ /* Wait for status bit to return to 0 */
+ for (i = 0; i < 1000; i++)
+ {
+ oss_udelay (100);
+ tmp = read_reg (devc, SPI, 0);
+ if (!(tmp & 0x10000))
+ {
+ valid = 1;
+ break;
+ }
+ }
+ if (!valid) /* Timed out */
+ return 0;
+
+ return 1;
+}
+
+static unsigned int
+mix_scale (int left, int right, int bits)
+{
+ left = mix_cvt[left];
+ right = mix_cvt[right];
+
+ return ((left * ((1 << bits) - 1) / 100) << 8) | (right *
+ ((1 << bits) - 1) / 100);
+}
+
+static int
+audigyls_set_volume (audigyls_devc * devc, int codecid, int value)
+{
+ audigyls_portc *portc = NULL;
+ int left, right, i2s_vol;
+
+ portc = &devc->portc[codecid];
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+ devc->playvol[codecid] = left | (right << 8);
+
+ i2s_vol = 65535 - mix_scale (left, right, 8);
+ write_reg (devc, MIXVOL_I2S, portc->play_port, (i2s_vol << 16));
+ return devc->playvol[codecid];
+}
+
+int
+audigyls_mix_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ audigyls_devc *devc = mixer_devs[dev]->hw_devc;
+ int val;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case 1: /* spread */
+ value = devc->spread;
+ break;
+
+ case 2: /* record what you hear */
+ value = devc->loopback;
+ break;
+
+ case 3:
+ {
+ value = devc->recvol;
+ }
+ break;
+
+ case 4:
+ value = devc->input_source;
+ break;
+ case 5:
+ value = devc->captmon;
+ break;
+ case 7:
+ value = devc->fbvol;
+ break;
+ }
+ }
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case 1: /* recording source */
+ devc->spread = value;
+ if (value)
+ write_reg (devc, HMIXMAP_I2S, 0, 0x10101010);
+ else
+ write_reg (devc, HMIXMAP_I2S, 0, 0x76543210);
+ break;
+
+ case 2: /* record what you hear */
+ devc->loopback = value;
+ break;
+
+ case 3:
+ {
+ val = (255 - value) & 0xff;
+ write_reg (devc, P17RECVOLL, 0,
+ val << 24 | val << 16 | val << 8 | val);
+ write_reg (devc, P17RECVOLH, 0,
+ val << 24 | val << 16 | val << 8 | val);
+ /* write_reg (devc, SRCTL, 1,
+ 0xff << 24 | 0xff << 16 | val << 8 | val); */
+ devc->recvol = value & 0xff;
+ }
+ break;
+
+ case 4:
+ {
+ switch (value)
+ {
+ case 0: /* for mic input remove GPIO */
+ {
+ OUTL (devc->osdev, INL (devc->osdev, devc->base + 0x18) | 0x400,
+ devc->base + 0x18);
+ audigyls_i2c_write (devc, 0x15, 0x2); /* Mic */
+ }
+ break;
+ case 1:
+ {
+ OUTL (devc->osdev,
+ INL (devc->osdev, devc->base + 0x18) & ~0x400,
+ devc->base + 0x18);
+ audigyls_i2c_write (devc, 0x15, 0x4); /* Line */
+ }
+ break;
+ case 2:
+ {
+ OUTL (devc->osdev,
+ INL (devc->osdev, devc->base + 0x18) & ~0x400,
+ devc->base + 0x18);
+ audigyls_i2c_write (devc, 0x15, 0x8); /* Aux */
+ }
+ break;
+ }
+ devc->input_source = value;
+ }
+ break;
+ case 5:
+ {
+ devc->captmon = value;
+ /* Send analog capture to front speakers */
+ if (value)
+ write_reg (devc, SMIXMAP_I2S, 0, 0x76767676);
+ else
+ write_reg (devc, SMIXMAP_I2S, 0, 0x10101010);
+ }
+ break;
+ case 7:
+ {
+ /*Set recording monitor volume */
+ val = (255 - value) & 0xff;
+ write_reg (devc, SRCTL, 1, val << 8 | val);
+ devc->fbvol = value & 0xff;
+ }
+ break;
+ }
+ }
+ return value;
+}
+
+static int
+audigyls_mix_init (int dev)
+{
+ int group, err;
+ audigyls_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if ((group = mixer_ext_create_group (dev, 0, "EXT")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group, 1, audigyls_mix_control,
+ MIXT_ONOFF, "Spread", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 2, audigyls_mix_control,
+ MIXT_ONOFF, "LOOPBACK", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+
+ if ((err = mixer_ext_create_control (dev, group, 3, audigyls_mix_control,
+ MIXT_MONOSLIDER, "RECORDVOL", 255,
+ MIXF_READABLE | MIXF_WRITEABLE |
+ MIXF_RECVOL)) < 0)
+ return err;
+
+ if (!devc->has_ac97)
+ {
+ if ((err =
+ mixer_ext_create_control (dev, group, 4, audigyls_mix_control,
+ MIXT_ENUM, "RECORDSRC", 3,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ mixer_ext_set_strings (dev, err, "MIC LINE AUX", 0);
+ }
+ if ((err = mixer_ext_create_control (dev, group, 7, audigyls_mix_control,
+ MIXT_MONOSLIDER, "monitorvol", 255,
+ MIXF_READABLE | MIXF_WRITEABLE |
+ MIXF_RECVOL)) < 0)
+ return err;
+ if ((err = mixer_ext_create_control (dev, group, 5, audigyls_mix_control,
+ MIXT_ONOFF, "RecMon", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ return 0;
+}
+
+static const int bindings[MAX_PORTC] = {
+ DSP_BIND_FRONT,
+ DSP_BIND_CENTER_LFE,
+ DSP_BIND_SURR
+};
+
+static int
+install_audio_devices (audigyls_devc * devc)
+{
+ int i;
+ int frontdev = -1;
+ int adev, flags;
+ int fmts = AFMT_S16_LE | AFMT_AC3;
+ static char *names[] = {
+ "AudigyLS front",
+ "AudigyLS center/lfe",
+ "AudigyLS surround"
+ };
+
+#if 0
+ if (audigyls_spdif_enable == 1)
+ n = 2;
+#endif
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ audigyls_portc *portc = &devc->portc[i];
+
+ flags =
+ ADEV_AUTOMODE | ADEV_16BITONLY | ADEV_STEREOONLY | ADEV_FIXEDRATE;
+
+ switch (i)
+ {
+ case 0:
+ portc->play_port = 0;
+ portc->rec_port = 2;
+ flags |= ADEV_DUPLEX;
+ break;
+ case 1:
+ portc->play_port = 1;
+ portc->rec_port = 2;
+ flags |= ADEV_NOINPUT;
+ break;
+ case 2:
+ portc->play_port = 3;
+ portc->rec_port = 2;
+ flags |= ADEV_NOINPUT;
+ break;
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ names[i],
+ &audigyls_audio_driver,
+ sizeof (audiodrv_t),
+ flags, fmts, devc, -1)) < 0)
+ {
+ return 0;
+ }
+
+ if (i == 0)
+ frontdev = adev;
+
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->max_fragments = 2;
+ audio_engines[adev]->dmabuf_alloc_flags |= DMABUF_SIZE_16BITS;
+ audio_engines[adev]->rate_source = frontdev;
+ audio_engines[adev]->mixer_dev = devc->mixer_dev;
+ audio_engines[adev]->binding = bindings[i];
+ if (audio_engines[adev]->flags & ADEV_FIXEDRATE)
+ {
+ audio_engines[adev]->fixed_rate = DEFAULT_RATE;
+ audio_engines[adev]->min_rate = DEFAULT_RATE;
+ audio_engines[adev]->max_rate = DEFAULT_RATE;
+ }
+ else
+ {
+ audio_engines[adev]->min_rate = 44100;
+ audio_engines[adev]->max_rate = 192000;
+ }
+ portc->audio_dev = adev;
+ portc->open_mode = 0;
+ devc->playvol[i] = 0x3030;
+ devc->recvol = 128;
+ portc->bits = AFMT_S16_LE;
+ }
+
+#ifdef USE_REMUX
+ if (frontdev >= 0)
+ {
+ if (audigyls_spdif_enable && devc->has_ac97)
+ remux_install ("AudigyLS 4.0 output", devc->osdev, frontdev,
+ frontdev + 2, -1, -1);
+ else
+ remux_install ("AudigyLS 5.1 output", devc->osdev, frontdev,
+ frontdev + 2, frontdev + 1, -1);
+ }
+#endif
+
+#ifdef CONFIG_OSS_VMIX
+ if (frontdev >= 0)
+ vmix_attach_audiodev(devc->osdev, frontdev, -1, 0);
+#endif
+ return 1;
+}
+
+static void
+select_out3_mode (audigyls_devc * devc, int mode)
+{
+ /*
+ * Set the out3/spdif combo jack format.
+ * mode0=analog rear/center, 1=spdif
+ */
+
+ if (mode == 0)
+ {
+ write_reg (devc, SPC, 0, 0x00000f00);
+ }
+ else
+ {
+ write_reg (devc, SPC, 0, 0x0000000f);
+ }
+}
+
+/*ARGSUSED*/
+static int
+audigyls_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ audigyls_devc *devc = mixer_devs[dev]->devc;
+
+ if (((cmd >> 8) & 0xff) == 'M')
+ {
+ int val;
+
+ if (IOC_IS_OUTPUT (cmd))
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ return *arg = 0;
+ break;
+
+ case SOUND_MIXER_PCM:
+ val = *arg;
+ return *arg = audigyls_set_volume (devc, 0, val);
+
+ case SOUND_MIXER_CENTERVOL:
+ val = *arg;
+ return *arg = audigyls_set_volume (devc, 1, val);
+
+ case SOUND_MIXER_REARVOL:
+ val = *arg;
+ return *arg = audigyls_set_volume (devc, 2, val);
+ }
+ else
+ switch (cmd & 0xff) /* Return Parameter */
+ {
+ case SOUND_MIXER_RECSRC:
+ case SOUND_MIXER_RECMASK:
+ return *arg = 0;
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ return *arg =
+ SOUND_MASK_PCM | SOUND_MASK_REARVOL | SOUND_MASK_CENTERVOL;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ return *arg =
+ SOUND_MASK_PCM | SOUND_MASK_REARVOL | SOUND_MASK_CENTERVOL;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ return *arg = SOUND_CAP_EXCL_INPUT;
+ break;
+
+ case SOUND_MIXER_PCM:
+ return *arg = devc->playvol[0];
+ break;
+
+ case SOUND_MIXER_CENTERVOL:
+ return *arg = devc->playvol[2];
+ break;
+
+ case SOUND_MIXER_REARVOL:
+ return *arg = devc->playvol[3];
+ break;
+ }
+ }
+ else
+ return *arg = 0;
+
+ return OSS_EINVAL;
+}
+
+static mixer_driver_t audigyls_mixer_driver = {
+ audigyls_mixer_ioctl
+};
+
+int
+oss_audigyls_attach (oss_device_t * osdev)
+{
+ int tmp, err, i;
+ unsigned char pci_irq_line, pci_revision;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ unsigned int subvendor;
+ audigyls_devc *devc;
+
+ static unsigned int spi_dac[] = {
+ 0x00ff, 0x02ff, 0x0400, 0x530, 0x0622, 0x08ff, 0x0aff, 0x0cff,
+ 0x0eff, 0x10ff, 0x1200, 0x1400, 0x1800, 0x1aff, 0x1cff,
+ 0x1e00,
+ };
+
+ DDB (cmn_err (CE_WARN, "Entered AUDIGYLS probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != PCI_VENDOR_ID_CREATIVE ||
+ device != PCI_DEVICE_ID_CREATIVE_AUDIGYLS)
+ return 0;
+
+ pci_read_config_dword (osdev, 0x2c, &subvendor);
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->card_name = "AudigyLS";
+ devc->subvendor = subvendor;
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+ devc->base &= ~0x3;
+
+ MUTEX_INIT (osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->card_name);
+
+ if ((err =
+ oss_register_interrupts (devc->osdev, 0, audigylsintr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+
+
+/*
+ * Init mixer
+ */
+ if (subvendor == 0x10021102) /* original audigyls */
+ {
+ devc->mixer_dev = ac97_install (&devc->ac97devc, devc->card_name,
+ audigyls_ac97_read, audigyls_ac97_write,
+ devc, devc->osdev);
+ devc->has_ac97 = 1;
+ audigyls_ac97_write (devc, 0x1c, 0x8000);
+ }
+ else
+ {
+ devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "AudigyLS Mixer",
+ &audigyls_mixer_driver,
+ sizeof (mixer_driver_t), devc);
+ devc->has_ac97 = 0; /* no ac97 */
+ mixer_devs[devc->mixer_dev]->hw_devc = devc;
+ mixer_devs[devc->mixer_dev]->priority = 1; /* Possible default mixer candidate */
+ }
+
+ mixer_ext_set_init_fn (devc->mixer_dev, audigyls_mix_init, 10);
+
+#if 0
+ write_reg (devc, SCS0, 0, 0x02108504);
+ write_reg (devc, SCS1, 0, 0x02108504);
+ write_reg (devc, SCS2, 0, 0x02108504);
+#endif
+ write_reg (devc, SCS3, 0, 0x02108504);
+
+ write_reg (devc, AUDCTL, 0, 0x0f0f003f); /* enable all outputs */
+
+ select_out3_mode (devc, audigyls_spdif_enable);
+
+/**********************************************************************
+ * In P17, there's 8 GPIO pins.
+ * GPIO register: 0x00XXYYZZ
+ * XX: Configure GPIO to be either GPI (0) or GPO (1).
+ * YY: GPO values, applicable if the pin is configure to be GPO.
+ * ZZ: GPI values, applicable if the pin is configure to be GPI.
+ *
+ * in SB570, pin 0-4 and 6 is used as GPO and pin 5 and 7 is used as GPI.
+ *
+ * GPO0:
+ * 1 ==> Analog output
+ * 0 ==> Digital output
+ * GPO1:
+ * 1 ==> Enable output on card
+ * 0 ==> Diable output on card
+ * GPO2:
+ * 1 ==> Enable Mic Bias and Mic Path
+ * 0 ==> Disable Mic Bias and Mic Path
+ * GPO3:
+ * 1 ==> Disable SPDIF-IO output
+ * 0 ==> Enable SPDIF-IO output
+ * GPO4 and GPO6:
+ * DAC sampling rate selection:
+ * Not applicable to SB570 since DAC is controlled through SPI
+ * GPI5:
+ * 1 ==> Front Panel is not connected
+ * 0 ==> Front Panel is connected
+ * GPI7:
+ * 1 ==> Front Panel Headphone is not connected
+ * 0 ==> Front Panel Headphone is connected
+ ***********************************************************/
+
+ OUTL (devc->osdev, 0, devc->base + 0x18); /* GPIO */
+ if (devc->has_ac97)
+ OUTL (devc->osdev, 0x005f03a3, devc->base + 0x18);
+ else
+ {
+ /* for SBLive 7.1 */
+ OUTL (devc->osdev, 0x005f4301, devc->base + 0x18);
+ audigyls_i2c_write (devc, 0x15, 0x4);
+ for (i = 0; i < (sizeof (spi_dac)/sizeof (spi_dac[0])); i++)
+ {
+ audigyls_spi_write (devc, spi_dac[i]);
+ }
+ }
+
+ OUTL (devc->osdev, INTR_PCI | INTR_RXA | INTR_AI, devc->base + IE);
+ OUTL (devc->osdev, 0x00000009, devc->base + 0x14); /* Enable audio */
+
+ tmp = read_reg (devc, SRCTL, 0);
+ if (devc->has_ac97)
+ tmp |= 0xf0c81000; /* record src0/src1 from ac97 */
+ else
+ tmp |= 0x50c81000; /* record src0/src1 from I2SIN */
+ write_reg (devc, SRCTL, 0, tmp);
+ write_reg (devc, HMIXMAP_I2S, 0, 0x76543210); /* default out route */
+ install_audio_devices (devc);
+
+ if (devc->has_ac97) /* only attach midi for AudigyLS */
+ attach_mpu (devc);
+
+ return 1;
+}
+
+int
+oss_audigyls_detach (oss_device_t * osdev)
+{
+ unsigned int status;
+ audigyls_devc *devc = (audigyls_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+
+ write_reg (devc, SA, 0, 0);
+ OUTL (devc->osdev, 0x00000000, devc->base + IE); /* Interrupt disable */
+ write_reg (devc, AINT_ENABLE, 0, 0); /* Disable audio interrupts */
+ status = INL (devc->osdev, devc->base + 0x08);
+ OUTL (devc->osdev, status, devc->base + 0x08); /* Acknowledge */
+ oss_udelay (1000);
+ if (devc->mpu_attached)
+ unload_audigylsuart (devc);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+
+ oss_unregister_device (osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_audigyls/oss_audigyls.man b/kernel/drv/oss_audigyls/oss_audigyls.man
new file mode 100644
index 0000000..b490a32
--- /dev/null
+++ b/kernel/drv/oss_audigyls/oss_audigyls.man
@@ -0,0 +1,45 @@
+NAME
+oss_audigyls - Creative Labs CA106 (AudigyLS/SBLive 24bit) driver.
+
+DESCRIPTION
+Open Sound System driver for Creative Labs Audigy2-LS and SBLive 24bit 7.1
+soundcards.
+
+Audigy-LS device characteristics:
+ o 8/16/24 bit playback/record
+ o mono/stereo/4/5.1 playback
+ o 8KHz to 192Khz sample rate.
+
+ AUDIGYLS MODELS
+
+There are 2 models of the AudigyLS device: one with an AC97 codec called the
+AudigyLS and the one without called the SBLive 7.1. Essentially they are
+the same chip but behave a bit differently.
+
+When playing AC3 on the AudigyLS (the one with the AC97 mixer) - you
+need to ensure that the igain slider is set to 0.
+
+ AUDIGYLS MIXER
+
+o The AudigyLS has 4 mixer controls for each channel.
+o The "spread" button will simply duplicate the front audio on the other 3
+ channels so that every speaker is playing what the front L/R is playing.
+o LoopBack recording allows you to capture any channel that's playing audio.
+o Record Volume slider just adjusts the input gain.
+o Record Source selector selects the input.
+o The "recmon" button enables a passthrough of the analog input signal.
+o Monitor Volume slider sets the passthrough gain if recmon is enabled.
+
+OPTIONS
+o audigyls_spdif_enable=0|1
+The Audigy LS has a versa-jack (orange) that can be set as SPDIF output
+or the Side-Surround left/right speakers in a 7.1 setup.
+When set as SPDIF, you can get play PCM/AC3 audio to a Dolby(R) capable
+receiver.
+
+FILES
+CONFIGFILEPATH/oss_audigyls.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_audiocs/.config b/kernel/drv/oss_audiocs/.config
new file mode 100644
index 0000000..a08633b
--- /dev/null
+++ b/kernel/drv/oss_audiocs/.config
@@ -0,0 +1 @@
+platform=sparc
diff --git a/kernel/drv/oss_audiocs/.devices b/kernel/drv/oss_audiocs/.devices
new file mode 100644
index 0000000..75dcebb
--- /dev/null
+++ b/kernel/drv/oss_audiocs/.devices
@@ -0,0 +1 @@
+oss_audiocs SUNW,CS4231 Sun UltraSparc workstation audio (CS4231)
diff --git a/kernel/drv/oss_audiocs/.name b/kernel/drv/oss_audiocs/.name
new file mode 100644
index 0000000..561dbe3
--- /dev/null
+++ b/kernel/drv/oss_audiocs/.name
@@ -0,0 +1 @@
+Driver for older Sun UltraSparc workstations based on CS4231 codec
diff --git a/kernel/drv/oss_audiocs/cs4231_mixer.h b/kernel/drv/oss_audiocs/cs4231_mixer.h
new file mode 100644
index 0000000..253ea01
--- /dev/null
+++ b/kernel/drv/oss_audiocs/cs4231_mixer.h
@@ -0,0 +1,101 @@
+/*
+ * Purpose: Definitions for the mixer of cs4231.
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define MODE2_MIXER_DEVICES (SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | \
+ SOUND_MASK_MIC | \
+ SOUND_MASK_LINE | SOUND_MASK_SPEAKER | \
+ SOUND_MASK_IGAIN | \
+ SOUND_MASK_PCM | SOUND_MASK_IMIX)
+
+#define MODE2_REC_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | \
+ SOUND_MASK_LINE1|SOUND_MASK_IMIX)
+
+struct mixer_def
+{
+ unsigned int regno;
+ unsigned int polarity; /* 0=normal, 1=reversed */
+ unsigned int bitpos;
+ unsigned int nbits;
+ unsigned int mutepos;
+};
+
+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 soundcards 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) \
+ {{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r, mute_bit}}
+
+static mixer_ents cs4231_mix_devices[32] = {
+ MIX_ENT (SOUND_MIXER_VOLUME, 27, 1, 0, 4, 29, 1, 0, 4, 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, 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_LINE, 18, 1, 0, 5, 19, 1, 0, 5, 7)
+};
+
+static int default_mixer_levels[32] = {
+ 0x3232, /* Master Volume */
+ 0x3232, /* Bass */
+ 0x3232, /* Treble */
+ 0x4b4b, /* FM */
+ 0x3232, /* PCM */
+ 0x1515, /* PC Speaker */
+ 0x2020, /* Line in */
+ 0x2020, /* Mic */
+ 0x4b4b, /* CD */
+ 0x0000, /* Recording monitor */
+ 0x4b4b, /* Second PCM */
+ 0x4b4b, /* Recording level */
+ 0x0000, /* 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/kernel/drv/oss_audiocs/oss_audiocs.c b/kernel/drv/oss_audiocs/oss_audiocs.c
new file mode 100644
index 0000000..774a410
--- /dev/null
+++ b/kernel/drv/oss_audiocs/oss_audiocs.c
@@ -0,0 +1,1808 @@
+/*
+ * Purpose: Driver for the UltraSparc workstations using CS4231 codec for audio
+ *
+ * This driver is for Solaris/Sparc only. It uses Solaris specific kernel
+ * services which are not portable to other operating systems.
+ *
+ * Originally this driver supported various AD1848 based ISA codecs. For
+ * this reason devc->model is used to find out which features the codec
+ * supports. The latest version of the driver supports only models 2 (CS4231)
+ * and 3 (CS4231A).
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_audiocs_cfg.h"
+#include <oss_pci.h>
+
+#include "cs4231_mixer.h"
+
+struct cs4231_pioregs
+{
+ uint8_t iar; /* index address register */
+ uint8_t pad1[3]; /* pad */
+ uint8_t idr; /* indexed data register */
+ uint8_t pad2[3]; /* pad */
+ uint8_t statr; /* status register */
+ uint8_t pad3[3]; /* pad */
+ uint8_t piodr; /* PIO data regsiter */
+ uint8_t pad4[3];
+};
+
+/*
+ * These are the registers for the EBUS2 DMA channel interface to the
+ * 4231. One struct per channel for playback and record, therefore there
+ * individual handles for the CODEC and the two DMA engines.
+ */
+
+struct cs4231_eb2regs {
+ uint32_t eb2csr; /* Ebus 2 csr */
+ uint32_t eb2acr; /* ebus 2 Addrs */
+ uint32_t eb2bcr; /* ebus 2 counts */
+};
+typedef struct cs4231_eb2regs cs4231_eb2regs_t;
+
+#define PLAY_CSR devc->play_regs->eb2csr
+#define PLAY_ACR devc->play_regs->eb2acr
+#define PLAY_BCR devc->play_regs->eb2bcr
+#define REC_CSR devc->rec_regs->eb2csr
+#define REC_ACR devc->rec_regs->eb2acr
+#define REC_BCR devc->rec_regs->eb2bcr
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+ struct cs4231_pioregs *codec_base;
+ uint_t *auxio_base;
+
+ cs4231_eb2regs_t *play_regs;
+ cs4231_eb2regs_t *rec_regs;
+
+ ddi_acc_handle_t codec_acc_handle;
+ ddi_acc_handle_t auxio_acc_handle;
+ ddi_acc_handle_t play_acc_handle;
+ ddi_acc_handle_t rec_acc_handle;
+#define CODEC_HNDL devc->codec_acc_handle
+#define PLAY_HNDL devc->play_acc_handle
+#define REC_HNDL devc->rec_acc_handle
+#define AUXIO_HNDL devc->auxio_acc_handle
+
+ unsigned char MCE_bit;
+ unsigned char saved_regs[32];
+
+ int audio_flags;
+ int record_dev, playback_dev;
+ int speed;
+ unsigned char speed_bits;
+ int channels;
+ int audio_format;
+ unsigned char format_bits;
+
+ int xfer_count;
+ int audio_mode;
+ int open_mode;
+ char *chip_name;
+ int model;
+#define MD_1848 1
+#define MD_4231 2
+#define MD_4231A 3
+
+ /* Mixer parameters */
+ int is_muted;
+ 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;
+}
+cs4231_devc_t;
+
+typedef struct cs4231_portc_t
+{
+ int open_mode;
+}
+cs4231_portc_t;
+
+static int ad_format_mask[9 /*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_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE,
+ 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_U8 | AFMT_S16_LE | AFMT_S16_BE,
+ AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE,
+ AFMT_U8 | AFMT_S16_LE /* CMI8330 */
+};
+
+#define CODEC_INB(devc, addr) ddi_get8(CODEC_HNDL, addr)
+#define CODEC_OUTB(devc, data, addr) ddi_put8(CODEC_HNDL, addr, data)
+
+/*
+ * CS4231 codec I/O registers
+ */
+#define io_Index_Addr(d) &d->codec_base->iar
+#define io_Indexed_Data(d) &d->codec_base->idr
+#define io_Status(d) &d->codec_base->statr
+#define io_Polled_IO(d) &d->codec_base->piodr
+#define CS4231_IO_RETRIES 10
+
+/*
+ * EB2 audio registers
+ */
+#define EB2_AUXIO_COD_PDWN 0x00000001u /* power down Codec */
+
+static int cs4231_open (int dev, int mode, int open_flags);
+static void cs4231_close (int dev, int mode);
+static int cs4231_ioctl (int dev, unsigned int cmd, ioctl_arg arg);
+static void cs4231_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag);
+static void cs4231_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag);
+static int cs4231_prepare_for_output (int dev, int bsize, int bcount);
+static int cs4231_prepare_for_input (int dev, int bsize, int bcount);
+static void cs4231_halt (int dev);
+static void cs4231_halt_input (int dev);
+static void cs4231_halt_output (int dev);
+static void cs4231_trigger (int dev, int bits);
+
+static void
+eb2_power(cs4231_devc_t * devc, int level)
+{
+ unsigned int tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ tmp = ddi_get32(AUXIO_HNDL, devc->auxio_base);
+
+ tmp &= ~EB2_AUXIO_COD_PDWN;
+
+ if (!level)
+ tmp |= EB2_AUXIO_COD_PDWN;
+ ddi_put32(AUXIO_HNDL, devc->auxio_base, tmp);
+
+ oss_udelay(10000);
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+
+static int
+ad_read (cs4231_devc_t * devc, int reg)
+{
+ oss_native_word flags;
+ int x;
+
+ reg = reg & 0xff;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ for (x=0;x<CS4231_IO_RETRIES;x++)
+ {
+ CODEC_OUTB (devc, (unsigned char) reg | devc->MCE_bit,
+ io_Index_Addr (devc));
+ oss_udelay(1000);
+
+ if (CODEC_INB (devc, io_Index_Addr (devc)) == (reg | devc->MCE_bit))
+ break;
+ }
+
+ if (x==CS4231_IO_RETRIES)
+ {
+ cmn_err(CE_NOTE, "Indirect register selection failed (read %d)\n", reg);
+ cmn_err(CE_CONT, "Reg=%02x (%02x)\n", CODEC_INB (devc, io_Index_Addr (devc)), reg | devc->MCE_bit);
+ }
+
+ x = CODEC_INB (devc, io_Indexed_Data (devc));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return x;
+}
+
+static void
+ad_write (cs4231_devc_t * devc, int reg, int data)
+{
+ oss_native_word flags;
+ int x;
+
+ reg &= 0xff;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ for (x=0;x<CS4231_IO_RETRIES;x++)
+ {
+ CODEC_OUTB (devc, (unsigned char) reg | devc->MCE_bit,
+ io_Index_Addr (devc));
+
+ oss_udelay(1000);
+
+ if (CODEC_INB (devc, io_Index_Addr (devc)) == (reg | devc->MCE_bit))
+ break;
+ }
+
+ if (x==CS4231_IO_RETRIES)
+ {
+ cmn_err(CE_NOTE, "Indirect register selection failed (write %d)\n", reg);
+ cmn_err(CE_CONT, "Reg=%02x (%02x)\n", CODEC_INB (devc, io_Index_Addr (devc)), reg | devc->MCE_bit);
+ }
+
+ CODEC_OUTB (devc, (unsigned char) (data & 0xff), io_Indexed_Data (devc));
+ oss_udelay(1000);
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+
+static void
+ad_mute (cs4231_devc_t * 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);
+
+ devc->is_muted = 1;
+ ad_write (devc, i, prev | 0x80);
+ }
+}
+
+static void
+ad_unmute (cs4231_devc_t * devc)
+{
+ int i, dummy;
+
+ /*
+ * Restore back old volume registers (unmute)
+ */
+ for (i = 6; i < 8; i++)
+ {
+ ad_write (devc, i, devc->saved_regs[i] & ~0x80);
+ }
+ devc->is_muted = 0;
+}
+
+static void
+ad_enter_MCE (cs4231_devc_t * devc)
+{
+ unsigned short prev;
+
+ int timeout = 1000;
+ while (timeout > 0 && CODEC_INB (devc, io_Index_Addr(devc)) == 0x80) /*Are we initializing */
+ timeout--;
+
+ devc->MCE_bit = 0x40;
+ prev = CODEC_INB (devc, io_Index_Addr (devc));
+ if (prev & 0x40)
+ {
+ return;
+ }
+
+ CODEC_OUTB (devc, devc->MCE_bit, io_Index_Addr (devc));
+}
+
+static void
+ad_leave_MCE (cs4231_devc_t * devc)
+{
+ unsigned char prev;
+ int timeout = 1000;
+
+ while (timeout > 0 && CODEC_INB (devc, io_Index_Addr(devc)) == 0x80) /*Are we initializing */
+ timeout--;
+
+ devc->MCE_bit = 0x00;
+ prev = CODEC_INB (devc, io_Index_Addr (devc));
+ CODEC_OUTB (devc, 0x00, io_Index_Addr (devc)); /* Clear the MCE bit */
+
+ if ((prev & 0x40) == 0) /* Not in MCE mode */
+ {
+ return;
+ }
+
+ CODEC_OUTB (devc, 0x00, io_Index_Addr (devc)); /* Clear the MCE bit */
+}
+
+static int
+cs4231_set_recmask (cs4231_devc_t * devc, int mask)
+{
+ unsigned char recdev;
+ int i, n;
+
+ 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++;
+
+ 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:
+ 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);
+
+ /* 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
+change_bits (cs4231_devc_t * devc, unsigned char *regval, int dev, int chn,
+ int newval, int regoffs)
+{
+ unsigned char mask;
+ int shift;
+ int mute;
+ int mutemask;
+ int set_mute_bit;
+
+ set_mute_bit = (newval == 0) || (devc->is_muted && dev == SOUND_MIXER_PCM);
+
+ 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 0
+ newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
+ *regval &= ~(mask << shift); /* Clear bits */
+ *regval |= (newval & mask) << shift; /* Set new value */
+#else
+ if (devc->mix_devices[dev][RIGHT_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][RIGHT_CHN].mutepos);
+ mutemask = ~(1 << devc->mix_devices[dev][RIGHT_CHN].mutepos);
+ }
+
+ newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
+ *regval &= (~(mask << shift)) & (mutemask); /* Clear bits */
+ *regval |= ((newval & mask) << shift) | mute; /* Set new value */
+#endif
+}
+
+static int
+cs4231_mixer_get (cs4231_devc_t * devc, int dev)
+{
+ if (!((1 << dev) & devc->supported_devices))
+ return OSS_EINVAL;
+
+ dev = devc->mixer_reroute[dev];
+
+ return devc->levels[dev];
+}
+
+static int
+cs4231_mixer_set (cs4231_devc_t * devc, int dev, int value)
+{
+ int left = value & 0x000000ff;
+ int right = (value & 0x0000ff00) >> 8;
+ int retvol;
+
+ int regoffs, regoffs1;
+ unsigned char val;
+
+ if (dev > 31)
+ return OSS_EINVAL;
+
+ if (!(devc->supported_devices & (1 << dev)))
+ return OSS_EINVAL;
+
+ dev = devc->mixer_reroute[dev];
+
+ 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);
+
+#if 1
+ /* Scale volumes */
+ left = mix_cvt[left];
+ right = mix_cvt[right];
+
+ /* Scale it again */
+ left = mix_cvt[left];
+ right = mix_cvt[right];
+#endif
+
+ if (devc->mix_devices[dev][LEFT_CHN].nbits == 0)
+ return OSS_EINVAL;
+
+ devc->levels[dev] = retvol;
+
+ /*
+ * Set the left channel
+ */
+
+ regoffs1 = regoffs = devc->mix_devices[dev][LEFT_CHN].regno;
+ val = ad_read (devc, regoffs);
+ change_bits (devc, &val, dev, LEFT_CHN, left, regoffs);
+ devc->saved_regs[regoffs] = val;
+
+ /*
+ * Set the right channel
+ */
+
+ if (devc->mix_devices[dev][RIGHT_CHN].nbits == 0)
+ {
+ ad_write (devc, regoffs, val);
+ return retvol; /* Was just a mono channel */
+ }
+
+ regoffs = devc->mix_devices[dev][RIGHT_CHN].regno;
+ if (regoffs != regoffs1)
+ {
+ ad_write (devc, regoffs1, val);
+ val = ad_read (devc, regoffs);
+ }
+
+ change_bits (devc, &val, dev, RIGHT_CHN, right, regoffs);
+ ad_write (devc, regoffs, val);
+ devc->saved_regs[regoffs] = val;
+
+ return retvol;
+}
+
+static void
+cs4231_mixer_reset (cs4231_devc_t * devc)
+{
+ int i;
+
+ devc->mix_devices = &(cs4231_mix_devices[0]);
+ devc->supported_devices = MODE2_MIXER_DEVICES;
+ devc->supported_rec_devices = MODE2_REC_DEVICES;
+
+ for (i = 0; i < 32; i++)
+ devc->mixer_reroute[i] = i;
+
+ devc->orig_devices = devc->supported_devices;
+ devc->orig_rec_devices = devc->supported_rec_devices;
+
+ devc->levels = default_mixer_levels;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if (devc->supported_devices & (1 << i))
+ cs4231_mixer_set (devc, i, devc->levels[i]);
+ cs4231_set_recmask (devc, SOUND_MASK_MIC);
+}
+
+static int
+cs4231_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ cs4231_devc_t *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SOUND_MIXER_PRIVATE1) /* SADA compatible play target selection */
+ {
+ int val;
+
+ val = *arg;
+
+ if (val == 0xffff)
+ return *arg = devc->mixer_output_port;
+
+ val &= (AUDIO_SPEAKER | AUDIO_HEADPHONE | AUDIO_LINE_OUT);
+
+ devc->mixer_output_port = val;
+
+ 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 */
+
+ return *arg = devc->mixer_output_port;
+ }
+
+ if (((cmd >> 8) & 0xff) == 'M')
+ {
+ int val;
+
+ if (IOC_IS_OUTPUT (cmd))
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ val = *arg;
+ return *arg = cs4231_set_recmask (devc, val);
+ break;
+
+ default:
+ val = *arg;
+ return *arg = cs4231_mixer_set (devc, cmd & 0xff, val);
+ }
+ else
+ switch (cmd & 0xff) /*
+ * Return parameters
+ */
+ {
+
+ case SOUND_MIXER_RECSRC:
+ return *arg = devc->recmask;
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ return *arg = devc->supported_devices;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ return *arg = devc->supported_devices &
+ ~(SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
+ break;
+
+ case SOUND_MIXER_RECMASK:
+ return *arg = devc->supported_rec_devices;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ return *arg = SOUND_CAP_EXCL_INPUT;
+ break;
+
+ default:
+ return *arg = cs4231_mixer_get (devc, cmd & 0xff);
+ }
+ }
+ else
+ return OSS_EINVAL;
+}
+
+static int
+cs4231_set_rate (int dev, int arg)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ /*
+ * 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 devc->speed;
+
+#if 1
+ if (ad_read (devc, 9) & 0x03)
+ return devc->speed;
+#endif
+
+ 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)
+ {
+ cmn_err (CE_WARN, "Can't find supported sample rate?\n");
+ selected = 3;
+ }
+
+ devc->speed = speed_table[selected].speed;
+ devc->speed_bits = speed_table[selected].bits;
+ return devc->speed;
+}
+
+static short
+cs4231_set_channels (int dev, short arg)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ if (arg != 1 && arg != 2)
+ {
+ return devc->channels;
+ }
+
+#if 1
+ if (ad_read (devc, 9) & 0x03)
+ {
+ return devc->channels;
+ }
+#endif
+
+ devc->channels = arg;
+ return arg;
+}
+
+static unsigned int
+cs4231_set_bits (int dev, unsigned int arg)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ static struct format_tbl
+ {
+ int format;
+ unsigned char bits;
+ }
+ format2bits[] =
+ {
+ {0, 0},
+ {AFMT_MU_LAW, 1},
+ {AFMT_A_LAW, 3},
+ {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 devc->audio_format;
+
+#if 1
+ if (ad_read (devc, 9) & 0x03)
+ return devc->audio_format;
+#endif
+
+ if (!(arg & ad_format_mask[devc->model]))
+ arg = AFMT_U8;
+
+ devc->audio_format = arg;
+
+ for (i = 0; i < n; i++)
+ if (format2bits[i].format == arg)
+ {
+ if ((devc->format_bits = format2bits[i].bits) == 0)
+ return devc->audio_format = AFMT_U8; /* Was not supported */
+
+ return arg;
+ }
+
+ /* Still hanging here. Something must be terribly wrong */
+ devc->format_bits = 0;
+ return devc->audio_format = AFMT_U8;
+}
+
+static const audiodrv_t cs4231_audio_driver = {
+ cs4231_open,
+ cs4231_close,
+ cs4231_output_block,
+ cs4231_start_input,
+ cs4231_ioctl,
+ cs4231_prepare_for_input,
+ cs4231_prepare_for_output,
+ cs4231_halt,
+ NULL,
+ NULL,
+ cs4231_halt_input,
+ cs4231_halt_output,
+ cs4231_trigger,
+ cs4231_set_rate,
+ cs4231_set_bits,
+ cs4231_set_channels
+};
+
+static mixer_driver_t cs4231_mixer_driver = {
+ cs4231_mixer_ioctl
+};
+
+static int
+cs4231_open (int dev, int mode, int open_flags)
+{
+ cs4231_devc_t *devc = NULL;
+ cs4231_portc_t *portc;
+ oss_native_word flags;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+ portc = (cs4231_portc_t *) audio_engines[dev]->portc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode || (devc->open_mode & mode))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode |= mode;
+ portc->open_mode = mode;
+ devc->audio_mode &= ~mode;
+
+ 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).
+ */
+ ad_mute (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+cs4231_close (int dev, int mode)
+{
+ oss_native_word flags;
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+ cs4231_portc_t *portc = (cs4231_portc_t *) audio_engines[dev]->portc;
+
+ DDB (cmn_err (CE_CONT, "cs4231_close(void)\n"));
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ cs4231_halt (dev);
+
+ devc->open_mode &= ~portc->open_mode;
+ devc->audio_mode &= ~portc->open_mode;
+ portc->open_mode = 0;
+
+ ad_mute (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static int
+cs4231_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void
+cs4231_output_block (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+ oss_native_word flags;
+ unsigned int cnt;
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ cnt = fragsize;
+ /* cnt = count; */
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (devc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
+ cnt >>= 1;
+ if (devc->channels > 1)
+ cnt >>= 1;
+ cnt--;
+
+ if (devc->audio_mode & PCM_ENABLE_OUTPUT
+ && audio_engines[dev]->flags & ADEV_AUTOMODE && intrflag
+ && cnt == devc->xfer_count)
+ {
+ devc->audio_mode |= PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return;
+ }
+
+ 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;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+cs4231_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+ oss_native_word flags;
+ unsigned int cnt;
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ cnt = fragsize;
+ /* cnt = count; */
+
+ if (devc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
+ cnt >>= 1;
+
+ if (devc->channels > 1)
+ cnt >>= 1;
+ cnt--;
+
+ if (devc->audio_mode & PCM_ENABLE_INPUT
+ && audio_engines[dev]->flags & ADEV_AUTOMODE && intrflag
+ && cnt == devc->xfer_count)
+ {
+ devc->audio_mode |= PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return; /*
+ * Auto DMA mode on. No need to react
+ */
+ }
+
+ 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;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+set_output_format (int dev)
+{
+ int timeout;
+ unsigned char fs, old_fs, tmp = 0;
+ oss_native_word flags;
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ if (ad_read (devc, 9) & 0x03)
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ fs = devc->speed_bits | (devc->format_bits << 5);
+
+ if (devc->channels > 1)
+ fs |= 0x10;
+
+ ad_enter_MCE (devc); /* Enables changes to the format select reg */
+
+ 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 && CODEC_INB (devc, io_Index_Addr(devc)) != 0x80)
+ timeout++;
+ timeout = 0;
+ while (timeout < 10000 && CODEC_INB (devc, io_Index_Addr(devc)) == 0x80)
+ timeout++;
+
+ ad_leave_MCE (devc);
+
+ devc->xfer_count = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+set_input_format (int dev)
+{
+ int timeout;
+ unsigned char fs, old_fs, tmp = 0;
+ oss_native_word flags;
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ fs = devc->speed_bits | (devc->format_bits << 5);
+
+ if (devc->channels > 1)
+ fs |= 0x10;
+
+ ad_enter_MCE (devc); /* Enables changes to the format select reg */
+
+ /*
+ * 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 && CODEC_INB (devc, io_Index_Addr(devc)) != 0x80)
+ timeout++;
+
+ timeout = 0;
+ while (timeout < 10000 && CODEC_INB (devc, io_Index_Addr(devc)) == 0x80)
+ timeout++;
+
+ if (devc->model != MD_1848)
+ {
+ /*
+ * 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 = devc->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 && CODEC_INB (devc, io_Index_Addr(devc)) != 0x80)
+ timeout++;
+
+ timeout = 0;
+ while (timeout < 10000 && CODEC_INB (devc, io_Index_Addr(devc)) == 0x80)
+ timeout++;
+ }
+ }
+ else
+ { /* For CS4231 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 && CODEC_INB (devc, io_Index_Addr(devc)) != 0x80)
+ timeout++;
+ timeout = 0;
+ while (timeout < 10000 && CODEC_INB (devc, io_Index_Addr(devc)) == 0x80)
+ timeout++;
+ }
+
+ ad_leave_MCE (devc);
+ devc->xfer_count = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+}
+
+static void
+set_sample_format (int dev)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ if (ad_read (devc, 9) & 0x03) /* Playback or recording active */
+ return;
+
+ set_input_format (dev);
+ set_output_format (dev);
+}
+
+static int
+cs4231_prepare_for_output (int dev, int bsize, int bcount)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ ad_mute (devc);
+
+ cs4231_halt_output (dev);
+ set_sample_format (dev);
+
+/*
+ * Setup the EB2 DMA engine
+ */
+
+ return 0;
+}
+
+static int
+cs4231_prepare_for_input (int dev, int bsize, int bcount)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+
+ if (devc->audio_mode)
+ return 0;
+
+ cs4231_halt_input (dev);
+ set_sample_format (dev);
+ //TODO: Prepare the DMA engine
+ return 0;
+}
+
+static void
+cs4231_halt (int dev)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+ cs4231_portc_t *portc = (cs4231_portc_t *) audio_engines[dev]->portc;
+
+ unsigned char bits = ad_read (devc, 9);
+
+ if (bits & 0x01 && portc->open_mode & OPEN_WRITE)
+ cs4231_halt_output (dev);
+
+ if (bits & 0x02 && portc->open_mode & OPEN_READ)
+ cs4231_halt_input (dev);
+}
+
+static void
+cs4231_halt_input (int dev)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+ cs4231_portc_t *portc = (cs4231_portc_t *) audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ if (!(portc->open_mode & OPEN_READ))
+ return;
+ if (!(ad_read (devc, 9) & 0x02))
+ return; /* Capture not enabled */
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ ad_write (devc, 9, ad_read (devc, 9) & ~0x02); /* Stop capture */
+ // TODO: Stop DMA
+
+ CODEC_OUTB (devc, 0, io_Status (devc)); /* Clear interrupt status */
+ CODEC_OUTB (devc, 0, io_Status (devc)); /* Clear interrupt status */
+
+ devc->audio_mode &= ~PCM_ENABLE_INPUT;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+cs4231_halt_output (int dev)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+ cs4231_portc_t *portc = (cs4231_portc_t *) audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ if (!(portc->open_mode & OPEN_WRITE))
+ return;
+ if (!(ad_read (devc, 9) & 0x01))
+ return; /* Playback not enabled */
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ ad_mute (devc);
+ oss_udelay (10);
+
+ ad_write (devc, 9, ad_read (devc, 9) & ~0x01); /* Stop playback */
+ //TODO: Disable DMA
+
+ CODEC_OUTB (devc, 0, io_Status (devc)); /* Clear interrupt status */
+ CODEC_OUTB (devc, 0, io_Status (devc)); /* Clear interrupt status */
+
+ devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+cs4231_trigger (int dev, int state)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) audio_engines[dev]->devc;
+ cs4231_portc_t *portc = (cs4231_portc_t *) audio_engines[dev]->portc;
+ oss_native_word flags;
+ unsigned char tmp, old, oldstate;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ oldstate = state;
+ 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);
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ oss_udelay (10);
+ oss_udelay (10);
+ oss_udelay (10);
+ ad_unmute (devc);
+ }
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+cs4231_init_hw (cs4231_devc_t * devc)
+{
+ int i;
+ oss_native_word flags;
+ /*
+ * Initial values for the indirect registers of CS4248/CS4231.
+ */
+ static int init_values[] = {
+ 0xa8, 0xa8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+ 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, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ for (i = 0; i < 16; i++)
+ ad_write (devc, i, init_values[i]);
+
+/*
+ * The XCTL0 (0x40) and XCTL1 (0x80) bits of I10 are used in Sparcs to
+ * control codec's output pins which mute the line out and speaker out
+ * connectors (respectively).
+ *
+ * Set them both to 0 (not muted). Better control is required in future.
+ */
+
+ ad_write (devc, 10, ad_read (devc, 10) & ~0xc0);
+
+ ad_mute (devc); /* Mute PCM until next use and initialize some variables */
+
+ if (devc->model > MD_1848)
+ {
+ ad_write (devc, 12, ad_read (devc, 12) | 0x40); /* Mode2 = enabled */
+
+ for (i = 16; i < 32; i++)
+ ad_write (devc, i, init_values[i]);
+
+ }
+
+ if (devc->model > MD_1848)
+ {
+ if (devc->audio_flags & ADEV_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 */
+
+ }
+ else
+ {
+ devc->audio_flags &= ~ADEV_DUPLEX;
+ ad_write (devc, 9, ad_read (devc, 9) | 0x04); /* Single DMA mode */
+ }
+
+ CODEC_OUTB (devc, 0, io_Status (devc)); /* Clear pending interrupts */
+
+ /*
+ * Toggle the MCE bit. It completes the initialization phase.
+ */
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ ad_enter_MCE (devc); /* In case the bit was off */
+ ad_leave_MCE (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+/*
+ * Perform full calibration
+ */
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ ad_enter_MCE (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ ad_write (devc, 9, ad_read (devc, 9) | 0x18); /* Enable autocalibration */
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ ad_leave_MCE (devc); /* This will trigger autocalibration */
+ ad_enter_MCE (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ ad_write (devc, 9, ad_read (devc, 9) & ~0x18); /* Disable autocalibration */
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ ad_leave_MCE (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+
+int
+cs4231_detect (cs4231_devc_t * devc)
+{
+
+ unsigned char tmp;
+ unsigned char tmp1 = 0xff, tmp2 = 0xff;
+ oss_native_word flags;
+
+ int i;
+
+ devc->MCE_bit = 0x40;
+ devc->chip_name = "CS4231";
+ devc->model = MD_4231; /* CS4231 or CS4248 */
+ devc->levels = NULL;
+
+ /*
+ * 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 (CODEC_INB (devc, io_Index_Addr(devc)) == 0xff)
+ {
+ DDB (cmn_err
+ (CE_CONT,
+ "cs4231_detect: The base I/O address appears to be dead\n"));
+ }
+
+#if 1
+/*
+ * Wait for the device to stop initialization
+ */
+ DDB (cmn_err (CE_CONT, "cs4231_detect() - step 0\n"));
+
+ for (i = 0; i < 10000000; i++)
+ {
+ unsigned char x = CODEC_INB (devc, io_Index_Addr(devc));
+ if (x == 0xff || !(x & 0x80))
+ break;
+ }
+
+#endif
+
+ DDB (cmn_err (CE_CONT, "cs4231_detect() - step A\n"));
+
+ if (CODEC_INB (devc, io_Index_Addr(devc)) == 0x80) /* Not ready. Let's wait */
+ {
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ ad_leave_MCE (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ }
+
+ if ((CODEC_INB (devc, io_Index_Addr(devc)) & 0x80) != 0x00) /* Not a CS4231 */
+ {
+ DDB (cmn_err (CE_WARN, "cs4231 detect error - step A (%02x)\n",
+ (int) CODEC_INB (devc, io_Index_Addr(devc))));
+ 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 (cmn_err (CE_CONT, "cs4231_detect() - step B\n"));
+ ad_write (devc, 0, 0xaa);
+ ad_write (devc, 1, 0x45); /* 0x55 with bit 0x10 clear */
+ oss_udelay (10);
+
+ if ((tmp1 = ad_read (devc, 0)) != 0xaa ||
+ (tmp2 = ad_read (devc, 1)) != 0x45)
+ {
+ DDB (cmn_err
+ (CE_WARN, "cs4231 detect error - step B (%x/%x)\n", tmp1, tmp2));
+#if 1
+ if (tmp1 == 0x8a && tmp2 == 0xff) /* AZT2320 ????? */
+ {
+ DDB (cmn_err (CE_CONT, "Ignoring error\n"));
+ }
+ else
+#endif
+ return 0;
+ }
+
+ DDB (cmn_err (CE_CONT, "cs4231_detect() - step C\n"));
+ ad_write (devc, 0, 0x45);
+ ad_write (devc, 1, 0xaa);
+ oss_udelay (10);
+
+ if ((tmp1 = ad_read (devc, 0)) != 0x45
+ || (tmp2 = ad_read (devc, 1)) != 0xaa)
+ {
+ DDB (cmn_err
+ (CE_WARN, "cs4231 detect error - step C (%x/%x)\n", tmp1, tmp2));
+#if 1
+ if (tmp1 == 0x65 && tmp2 == 0xff) /* AZT2320 ????? */
+ {
+ DDB (cmn_err (CE_CONT, "Ignoring error\n"));
+ }
+ else
+#endif
+ return 0;
+ }
+
+ /*
+ * The indirect register I12 has some read only bits. Lets
+ * try to change them.
+ */
+ DDB (cmn_err (CE_CONT, "cs4231_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 (cmn_err (CE_WARN, "cs4231 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.
+ */
+
+ DDB (cmn_err (CE_CONT, "cs4231_detect() - step G\n"));
+
+ ad_write (devc, 12, 0x40); /* Set mode2, clear 0x80 */
+
+ tmp1 = ad_read (devc, 12);
+ if (tmp1 & 0x80)
+ {
+ devc->chip_name = "CS4248"; /* Our best knowledge just now */
+ }
+
+ if ((tmp1 & 0xc0) == (0x80 | 0x40))
+ {
+ /*
+ * CS4231 detected - is it?
+ *
+ * Verify that setting I0 doesn't change I16.
+ */
+ DDB (cmn_err (CE_CONT, "cs4231_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 (cmn_err
+ (CE_WARN, "cs4231 detect error - step H(%x)\n", tmp1));
+ return 0;
+ }
+
+ /*
+ * Verify that some bits of I25 are read only.
+ */
+
+ DDB (cmn_err (CE_CONT, "cs4231_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, full_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) & 0xe7;
+ full_id = ad_read (devc, 25);
+ if (id == 0x80) /* Device busy??? */
+ id = ad_read (devc, 25) & 0xe7;
+ if (id == 0x80) /* Device still busy??? */
+ id = ad_read (devc, 25) & 0xe7;
+ DDB (cmn_err
+ (CE_CONT, "cs4231_detect() - step J (%02x/%02x)\n", id,
+ ad_read (devc, 25)));
+
+ switch (id)
+ {
+
+ case 0xa0:
+ devc->chip_name = "CS4231A";
+ devc->model = MD_4231A;
+ break;
+
+ default: /* Assume CS4231 or OPTi 82C930 */
+ DDB (cmn_err (CE_CONT, "I25 = %02x/%02x\n",
+ ad_read (devc, 25),
+ ad_read (devc, 25) & 0xe7));
+ devc->model = MD_4231;
+
+ }
+ }
+ ad_write (devc, 25, tmp1); /* Restore bits */
+
+ DDB (cmn_err (CE_CONT, "cs4231_detect() - step K\n"));
+ }
+ }
+
+ DDB (cmn_err (CE_CONT, "cs4231_detect() - Detected OK\n"));
+
+ return 1;
+}
+
+void
+cs4231_init (cs4231_devc_t * devc)
+{
+ int i, my_dev, my_mixer;
+ char dev_name[100];
+
+ cs4231_portc_t *portc = NULL;
+
+ devc->open_mode = 0;
+ devc->timer_ticks = 0;
+ devc->audio_flags = ADEV_AUTOMODE;
+ devc->playback_dev = devc->record_dev = 0;
+
+ sprintf (dev_name, "Sparc builtin audio (%s)", devc->chip_name);
+
+ if ((my_mixer = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ dev_name,
+ &cs4231_mixer_driver,
+ sizeof (mixer_driver_t), devc)) >= 0)
+ {
+ cs4231_mixer_reset (devc);
+ }
+
+ if (devc->model > MD_1848)
+ {
+ devc->audio_flags |= ADEV_DUPLEX;
+ }
+
+ if ((my_dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ dev_name,
+ &cs4231_audio_driver,
+ sizeof (audiodrv_t),
+ devc->audio_flags,
+ ad_format_mask[devc->model],
+ devc, -1)) < 0)
+ {
+ return;
+ }
+
+ portc = PMALLOC (devc->osdev, sizeof (*portc));
+ memset ((char *) portc, 0, sizeof (*portc));
+
+ audio_engines[my_dev]->portc = portc;
+ audio_engines[my_dev]->min_block = 512;
+ audio_engines[my_dev]->mixer_dev = my_mixer;
+
+ cs4231_init_hw (devc);
+
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, my_dev, -1, 0);
+#endif
+#if 0
+ test_it (devc);
+#endif
+}
+
+void
+cs4231_unload (cs4231_devc_t * devc)
+{
+#if 0
+ int i, dev = 0;
+
+ for (i = 0; devc == NULL && i < nr_cs4231_devs; i++)
+ if (adev_info[i].base == io_base)
+ {
+ devc = &adev_info[i];
+ dev = devc->dev_no;
+ }
+
+ if (devc != NULL)
+ {
+
+ if (!share_dma)
+ {
+ if (irq > 0)
+ snd_release_irq (devc->irq, NULL);
+
+ FREE_DMA_CHN (audio_engines[dev]->dmap_out->dma);
+
+ if (audio_engines[dev]->dmap_in->dma !=
+ audio_engines[dev]->dmap_out->dma)
+ FREE_DMA_CHN (audio_engines[dev]->dmap_in->dma);
+ }
+ }
+ else
+ cmn_err (CE_WARN, "Can't find device to be unloaded. Base=%x\n", io_base);
+#endif
+}
+
+int
+cs4231intr (oss_device_t * osdev)
+{
+ unsigned char status;
+ cs4231_devc_t *devc = osdev->devc;
+ int alt_stat = 0xff;
+ unsigned char c930_stat = 0;
+ int cnt = 0;
+ int serviced = 0;
+
+ devc->irq_ok = 1;
+
+interrupt_again: /* Jump back here if int status doesn't reset */
+
+ status = CODEC_INB (devc, io_Status (devc));
+
+ if (status == 0x80)
+ cmn_err (CE_CONT, "cs4231intr: Why?\n");
+ else
+ serviced = 1;
+ if (devc->model == MD_1848)
+ CODEC_OUTB (devc, 0, io_Status (devc)); /* Clear interrupt status */
+
+ if (status & 0x01)
+ {
+ if (devc->model != MD_1848)
+ {
+ alt_stat = ad_read (devc, 24);
+ }
+
+ /* Acknowledge the intr before proceeding */
+ if (devc->model != MD_1848)
+ ad_write (devc, 24, ad_read (devc, 24) & ~alt_stat); /* Selective ack */
+
+ if (devc->open_mode & OPEN_READ && devc->audio_mode & PCM_ENABLE_INPUT
+ && alt_stat & 0x20)
+ {
+ oss_audio_inputintr (devc->record_dev, 0);
+ }
+
+ if (devc->open_mode & OPEN_WRITE && devc->audio_mode & PCM_ENABLE_OUTPUT
+ && alt_stat & 0x10)
+ {
+ oss_audio_outputintr (devc->playback_dev, 1);
+ }
+
+ if (devc->model != MD_1848 && alt_stat & 0x40) /* Timer interrupt */
+ {
+ devc->timer_ticks++;
+ }
+ }
+
+#if 1
+/*
+ * 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 (CODEC_INB (devc, io_Status (devc)) & 0x01 && cnt++ < 4)
+ {
+ goto interrupt_again;
+ }
+#endif
+ return serviced;
+}
+
+int
+oss_audiocs_attach (oss_device_t * osdev)
+{
+ unsigned int dw;
+ int err;
+
+static ddi_device_acc_attr_t acc_attr = {
+ DDI_DEVICE_ATTR_V0,
+ DDI_STRUCTURE_LE_ACC,
+ DDI_STRICTORDER_ACC
+};
+ caddr_t addr;
+
+ cs4231_devc_t *devc = osdev->devc;
+
+ DDB(cmn_err(CE_CONT, "Entered oss_audiocs_attach()\n"));
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->open_mode = 0;
+
+ devc->chip_name = "Generic CS4231";
+
+/*
+ * Map I/O registers. This is done in Solaris specific way so the code
+ * is not portable.
+ */
+
+ // Codec registers
+ if ((err = ddi_regs_map_setup
+ (osdev->dip, 0, &addr, 0, 16, &acc_attr,
+ &CODEC_HNDL)) != DDI_SUCCESS)
+ {
+ cmn_err(CE_WARN, "Cannot map codec registers, error=%d\n", err);
+ return 0;
+ }
+ devc->codec_base = (struct cs4231_pioregs*)addr;
+
+ // Play registers
+ if ((err = ddi_regs_map_setup
+ (osdev->dip, 1, (caddr_t *)&devc->play_regs, 0, sizeof(cs4231_eb2regs_t), &acc_attr,
+ &PLAY_HNDL)) != DDI_SUCCESS)
+ {
+ cmn_err(CE_WARN, "Cannot map codec registers, error=%d\n", err);
+ return 0;
+ }
+
+ // Capture registers
+ if ((err = ddi_regs_map_setup
+ (osdev->dip, 2, (caddr_t *)&devc->rec_regs, 0, sizeof(cs4231_eb2regs_t), &acc_attr,
+ &REC_HNDL)) != DDI_SUCCESS)
+ {
+ cmn_err(CE_WARN, "Cannot map codec registers, error=%d\n", err);
+ return 0;
+ }
+
+ // Auxio register
+ if ((err = ddi_regs_map_setup
+ (osdev->dip, 3, &addr, 0, 4, &acc_attr,
+ &AUXIO_HNDL)) != DDI_SUCCESS)
+ {
+ cmn_err(CE_WARN, "Cannot map aixio register, error=%d\n", err);
+ return 0;
+ }
+ devc->auxio_base = (uint_t *)addr;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ eb2_power(devc, 1);
+
+ if (oss_register_interrupts (devc->osdev, 0, cs4231intr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Unable to install interrupt handler\n");
+ return 0;
+ }
+
+ if (!cs4231_detect(devc))
+ return 0;
+
+ oss_register_device (osdev, devc->chip_name);
+
+ cs4231_init (devc);
+
+ return 1;
+}
+
+int
+oss_audiocs_detach (oss_device_t * osdev)
+{
+ cs4231_devc_t *devc = (cs4231_devc_t *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ oss_unregister_interrupts (devc->osdev);
+
+ eb2_power(devc, 0);
+
+ ddi_regs_map_free(&CODEC_HNDL);
+ ddi_regs_map_free(&PLAY_HNDL);
+ ddi_regs_map_free(&REC_HNDL);
+ ddi_regs_map_free(&AUXIO_HNDL);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+
+ oss_unregister_device (osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_audiocs/oss_audiocs.man b/kernel/drv/oss_audiocs/oss_audiocs.man
new file mode 100644
index 0000000..66f2b21
--- /dev/null
+++ b/kernel/drv/oss_audiocs/oss_audiocs.man
@@ -0,0 +1,21 @@
+NAME
+oss_audiocs - Cirrus Logic CS4231 driver for Sun Sparc Workstations
+
+DESCRIPTION
+Open Sound System driver for Cirrus Logic (Crystal Semicoductor) CS4231 audio
+controller onboard the Sun Sparc workstatiosn
+
+CS4231 device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo playback/recording
+ o 8KHz to 48Khz sample rate.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_audiocs.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_audioloop/.config b/kernel/drv/oss_audioloop/.config
new file mode 100644
index 0000000..828bd4f
--- /dev/null
+++ b/kernel/drv/oss_audioloop/.config
@@ -0,0 +1,2 @@
+bus=VIRTUAL
+targetcpu=any
diff --git a/kernel/drv/oss_audioloop/.devices b/kernel/drv/oss_audioloop/.devices
new file mode 100644
index 0000000..fd543fb
--- /dev/null
+++ b/kernel/drv/oss_audioloop/.devices
@@ -0,0 +1 @@
+oss_audioloop AUDIOLOOP OSS loopback audio driver
diff --git a/kernel/drv/oss_audioloop/.name b/kernel/drv/oss_audioloop/.name
new file mode 100644
index 0000000..4d501dc
--- /dev/null
+++ b/kernel/drv/oss_audioloop/.name
@@ -0,0 +1 @@
+OSS loopback audio driver
diff --git a/kernel/drv/oss_audioloop/.params b/kernel/drv/oss_audioloop/.params
new file mode 100644
index 0000000..b8c8f7b
--- /dev/null
+++ b/kernel/drv/oss_audioloop/.params
@@ -0,0 +1,4 @@
+int audioloop_instances=1;
+/*
+ * audioloop_instances: Number of instances (client/server pairs) to create.
+ */
diff --git a/kernel/drv/oss_audioloop/oss_audioloop.c b/kernel/drv/oss_audioloop/oss_audioloop.c
new file mode 100644
index 0000000..c51cc48
--- /dev/null
+++ b/kernel/drv/oss_audioloop/oss_audioloop.c
@@ -0,0 +1,919 @@
+/*
+ * Purpose: OSS audio loopback (virtual) driver
+ *
+ * Description:
+ * OSS audio loopback driver is a virtual/pseudo driver that can be used
+ * for example to user land based virtual audio devices.
+ *
+ * Each audioloop instance has two sides or endpoints. The server side is
+ * typically used by the application that implements the virtual audio device.
+ * Client side in turn is used by any audio application that wants to record or
+ * play audio. Server side device must be open before the client side can be
+ * opened.
+ *
+ *
+ *
+ * CAUTION! Certain portc fields (mutex, rate/format) are only available
+ * on the server side portc structure. Care must be taken.
+ *
+ *
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_audioloop_cfg.h"
+
+#define MAX_RATE 192000
+#define MAX_CHANNELS 64
+#define SUPPORTED_FORMATS (AFMT_S16_NE|AFMT_S32_NE)
+
+extern int audioloop_instances; /* Config option */
+
+#define MAX_INSTANCES 16
+
+typedef struct _audioloop_devc_t audioloop_devc_t;
+typedef struct _audioloop_portc_t audioloop_portc_t;
+
+struct _audioloop_portc_t
+{
+ audioloop_devc_t *devc;
+ audioloop_portc_t *peer;
+ int audio_dev;
+ int open_mode;
+ int port_type;
+#define PT_CLIENT 1
+#define PT_SERVER 2
+ int instance;
+
+ /* State variables */
+ int input_triggered, output_triggered;
+ oss_wait_queue_t *wq;
+
+ /* Server side (only) fields */
+ int rate;
+ int channels;
+ unsigned int fmt, fmt_bytes;
+ oss_mutex_t mutex;
+ timeout_id_t timeout_id;
+};
+
+struct _audioloop_devc_t
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+
+ int num_instances;
+
+ audioloop_portc_t *client_portc[MAX_INSTANCES];
+ audioloop_portc_t *server_portc[MAX_INSTANCES];
+};
+
+#define MAX_ATTACH_COUNT 1
+static audioloop_devc_t audioloop_devices[MAX_ATTACH_COUNT];
+static int attach_count;
+
+static void
+transfer_audio (audioloop_portc_t * server_portc, dmap_t * dmap_from,
+ dmap_t * dmap_to)
+{
+ int l = dmap_from->fragment_size;
+ unsigned char *fromp, *top;
+
+ if (dmap_to->fragment_size != l)
+ {
+ cmn_err (CE_WARN, "Fragment size mismatch (%d != %d)\n",
+ dmap_to->fragment_size, l);
+
+ /* Perform emergency stop */
+ server_portc->input_triggered = 0;
+ server_portc->output_triggered = 0;
+ server_portc->peer->input_triggered = 0;
+ server_portc->peer->output_triggered = 0;
+ return;
+ }
+
+ fromp =
+ dmap_from->dmabuf + (dmap_from->byte_counter % dmap_from->bytes_in_use);
+ top = dmap_to->dmabuf + (dmap_to->byte_counter % dmap_to->bytes_in_use);
+
+ memcpy (top, fromp, l);
+
+}
+
+static void
+handle_input (audioloop_portc_t * server_portc)
+{
+ audioloop_portc_t *client_portc = server_portc->peer;
+
+ if (client_portc->output_triggered)
+ {
+ transfer_audio (server_portc,
+ audio_engines[client_portc->audio_dev]->dmap_out,
+ audio_engines[server_portc->audio_dev]->dmap_in);
+ oss_audio_outputintr (client_portc->audio_dev, 0);
+ }
+
+ oss_audio_inputintr (server_portc->audio_dev, 0);
+}
+
+static void
+handle_output (audioloop_portc_t * server_portc)
+{
+ audioloop_portc_t *client_portc = server_portc->peer;
+
+ if (client_portc->input_triggered)
+ {
+ transfer_audio (server_portc,
+ audio_engines[server_portc->audio_dev]->dmap_out,
+ audio_engines[client_portc->audio_dev]->dmap_in);
+ oss_audio_inputintr (client_portc->audio_dev, 0);
+ }
+
+ oss_audio_outputintr (server_portc->audio_dev, 0);
+}
+
+static void
+audioloop_cb (void *pc)
+{
+/*
+ * This timer callback routine will get called 100 times/second. It handles
+ * movement of audio data between the client and server sides.
+ */
+ audioloop_portc_t *server_portc = pc;
+ int tmout = OSS_HZ / 100;
+
+ if (tmout < 1)
+ tmout = 1;
+
+ server_portc->timeout_id = 0; /* No longer valid */
+
+ if (server_portc->input_triggered)
+ handle_input (server_portc);
+
+ if (server_portc->output_triggered)
+ handle_output (server_portc);
+
+ /* Retrigger timer callback */
+ if (server_portc->input_triggered || server_portc->output_triggered)
+ server_portc->timeout_id = timeout (audioloop_cb, server_portc, tmout);
+}
+
+static int
+audioloop_check_input (int dev)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+ if (!portc->peer->output_triggered)
+ {
+ return OSS_ECONNRESET;
+ }
+ return 0;
+}
+
+static int
+audioloop_check_output (int dev)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ if (!portc->peer->input_triggered)
+ {
+ return OSS_ECONNRESET;
+ }
+
+ if (portc->peer->open_mode == 0)
+ return OSS_EIO;
+ return 0;
+}
+
+static void
+setup_sample_format (audioloop_portc_t * portc)
+{
+ adev_t *adev;
+ int fragsize, frame_size;
+
+ frame_size = portc->channels * portc->fmt_bytes;
+ if (frame_size == 0)
+ frame_size = 4;
+
+ fragsize = (portc->rate * frame_size) / 100; /* Number of bytes/fragment (100Hz) */
+ portc->rate = fragsize * 100 / frame_size;
+
+/* Setup the server side */
+ adev = audio_engines[portc->audio_dev];
+ adev->min_block = adev->max_block = fragsize;
+
+/* Setup the client side */
+ adev = audio_engines[portc->peer->audio_dev];
+ adev->min_block = adev->max_block = fragsize;
+
+ adev->max_rate = adev->min_rate = portc->rate;
+ adev->iformat_mask = portc->fmt;
+ adev->oformat_mask = portc->fmt;
+ adev->xformat_mask = portc->fmt;
+ adev->min_channels = adev->max_channels = portc->channels;
+}
+
+static int
+audioloop_server_set_rate (int dev, int arg)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->rate;
+
+ if (portc->peer->input_triggered || portc->peer->output_triggered)
+ return portc->rate;
+
+ if (arg < 5000)
+ arg = 5000;
+ if (arg > MAX_RATE)
+ arg = MAX_RATE;
+
+ /* Force the sample rate to be multiple of 100 */
+ arg = (arg / 100) * 100;
+
+ portc->rate = arg;
+
+ setup_sample_format (portc);
+
+ return portc->rate = arg;
+}
+
+/*ARGSUSED*/
+static int
+audioloop_client_set_rate (int dev, int arg)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ return portc->peer->rate;
+}
+
+static short
+audioloop_server_set_channels (int dev, short arg)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->channels;
+
+ if (portc->peer->input_triggered || portc->peer->output_triggered)
+ return portc->channels;
+
+ if (arg < 1)
+ arg = 1;
+ if (arg > MAX_CHANNELS)
+ arg = MAX_CHANNELS;
+
+ portc->channels = arg;
+
+ setup_sample_format (portc);
+
+ return portc->channels;
+}
+
+/*ARGSUSED*/
+static short
+audioloop_client_set_channels (int dev, short arg)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ return portc->peer->channels; /* Server side channels */
+}
+
+static unsigned int
+audioloop_server_set_format (int dev, unsigned int arg)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->fmt;
+
+ if (portc->peer->input_triggered || portc->peer->output_triggered)
+ return portc->fmt;
+
+ switch (arg)
+ {
+ case AFMT_S16_NE:
+ portc->fmt_bytes = 2;
+ break;
+
+ case AFMT_S32_NE:
+ portc->fmt_bytes = 4;
+ break;
+
+ default: /* Unsupported format */
+ arg = AFMT_S16_NE;
+ portc->fmt_bytes = 2;
+
+ }
+
+ portc->fmt = arg;
+
+ setup_sample_format (portc);
+
+ return portc->fmt;
+}
+
+/*ARGSUSED*/
+static unsigned int
+audioloop_client_set_format (int dev, unsigned int arg)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ return portc->peer->fmt; /* Server side sample format */
+}
+
+static void audioloop_trigger (int dev, int state);
+
+static void
+audioloop_reset (int dev)
+{
+ audioloop_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static int
+audioloop_server_open (int dev, int mode, int open_flags)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+ audioloop_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ adev_t *adev;
+
+ if ((mode & OPEN_READ) && (mode & OPEN_WRITE))
+ return OSS_EACCES;
+
+ if (portc == NULL || portc->peer == NULL)
+ return OSS_ENXIO;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+/*
+ * Update client device flags
+ */
+ adev = audio_engines[portc->peer->audio_dev];
+ adev->flags &= ~(ADEV_NOINPUT | ADEV_NOOUTPUT);
+ if (!(mode & OPEN_READ))
+ adev->flags |= ADEV_NOOUTPUT;
+ if (!(mode & OPEN_WRITE))
+ adev->flags |= ADEV_NOINPUT;
+ adev->enabled = 1; /* Enable client side */
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+audioloop_client_open (int dev, int mode, int open_flags)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+ audioloop_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ if (portc == NULL || portc->peer == NULL)
+ return OSS_ENXIO;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+audioloop_server_close (int dev, int mode)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+ audioloop_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ audio_engines[portc->peer->audio_dev]->enabled = 0; /* Disable client side */
+ portc->open_mode = 0;
+
+ /* Stop the client side */
+ portc->peer->input_triggered = 0;
+ portc->peer->output_triggered = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static void
+audioloop_client_close (int dev, int mode)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+ audioloop_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->open_mode = 0;
+
+ /* Stop the server side */
+ portc->peer->input_triggered = 0;
+ portc->peer->output_triggered = 0;
+
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+audioloop_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ switch (cmd)
+ {
+ case SNDCTL_GETLABEL:
+ {
+ /*
+ * Return an empty string so that this feature can be tested.
+ * Complete functionality is to be implemented later.
+ */
+ oss_label_t *s = (oss_label_t *) arg;
+ memset (s, 0, sizeof (oss_label_t));
+ return 0;
+ }
+ break;
+
+ case SNDCTL_GETSONG:
+ {
+ /*
+ * Return an empty string so that this feature can be tested.
+ * Complete functionality is to be implemented later.
+ */
+ oss_longname_t *s = (oss_longname_t *) arg;
+ memset (s, 0, sizeof (oss_longname_t));
+ return 0;
+ }
+ break;
+ }
+
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static void
+audioloop_output_block (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+audioloop_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+static void
+audioloop_trigger (int dev, int state)
+{
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ if (portc->open_mode & OPEN_READ) /* Handle input */
+ {
+ portc->input_triggered = !!(state & OPEN_READ);
+ if (!portc->input_triggered)
+ portc->peer->output_triggered = 0;
+ }
+
+ if (portc->open_mode & OPEN_WRITE) /* Handle output */
+ {
+ portc->output_triggered = !!(state & OPEN_WRITE);
+ if (!portc->output_triggered)
+ portc->peer->input_triggered = 0;
+ }
+
+ if (portc->output_triggered || portc->input_triggered) /* Something is going on */
+ {
+ int tmout = OSS_HZ / 100;
+
+ if (tmout < 1)
+ tmout = 1;
+
+ if (portc->port_type != PT_SERVER)
+ portc = portc->peer; /* Switch to the server side */
+
+ if (portc->output_triggered || portc->input_triggered) /* Something is going on */
+ if (portc->timeout_id == 0)
+ portc->timeout_id = timeout (audioloop_cb, portc, tmout);
+ }
+ else
+ {
+ if (portc->port_type == PT_SERVER)
+ if (portc->timeout_id != 0)
+ {
+ untimeout (portc->timeout_id);
+ portc->timeout_id = 0;
+ }
+ }
+}
+
+/*ARGSUSED*/
+static int
+audioloop_server_prepare_for_input (int dev, int bsize, int bcount)
+{
+ oss_native_word flags;
+ unsigned int status;
+
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ MUTEX_ENTER_IRQDISABLE (portc->mutex, flags);
+ portc->input_triggered = 0;
+
+ /*
+ * Wake the client which may be in waiting in close()
+ */
+ oss_wakeup (portc->peer->wq, &portc->mutex, &flags, POLLOUT | POLLWRNORM);
+
+ if (!(portc->peer->open_mode & OPEN_WRITE))
+ {
+ /* Sleep until the client side becomes ready */
+ oss_sleep (portc->wq, &portc->mutex, 0, &flags, &status);
+ if (status & WK_SIGNAL)
+ {
+ MUTEX_EXIT_IRQRESTORE (portc->mutex, flags);
+ return OSS_EINTR;
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (portc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+audioloop_server_prepare_for_output (int dev, int bsize, int bcount)
+{
+ oss_native_word flags;
+ unsigned int status;
+
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+
+ MUTEX_ENTER_IRQDISABLE (portc->mutex, flags);
+ portc->output_triggered = 0;
+
+ /*
+ * Wake the client which may be in waiting in close()
+ */
+ oss_wakeup (portc->peer->wq, &portc->mutex, &flags, POLLIN | POLLRDNORM);
+
+ if (!(portc->peer->open_mode & OPEN_READ))
+ {
+ /* Sleep until the client side becomes ready */
+ oss_sleep (portc->wq, &portc->mutex, 0, &flags, &status);
+ if (status & WK_SIGNAL)
+ {
+ MUTEX_EXIT_IRQRESTORE (portc->mutex, flags);
+ return OSS_EINTR;
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (portc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+audioloop_client_prepare_for_input (int dev, int bsize, int bcount)
+{
+ oss_native_word flags;
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+ unsigned int status;
+
+ MUTEX_ENTER_IRQDISABLE (portc->peer->mutex, flags);
+ portc->input_triggered = 0;
+ /* Wake the server side */
+ oss_wakeup (portc->peer->wq, &portc->peer->mutex, &flags,
+ POLLIN | POLLRDNORM);
+
+ /*
+ * Delay a moment so that the server side gets chance to reinit itself
+ * for next file/stream.
+ */
+ oss_sleep (portc->wq, &portc->peer->mutex, OSS_HZ, &flags, &status);
+ MUTEX_EXIT_IRQRESTORE (portc->peer->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+audioloop_client_prepare_for_output (int dev, int bsize, int bcount)
+{
+ oss_native_word flags;
+ audioloop_portc_t *portc = audio_engines[dev]->portc;
+ unsigned int status;
+
+ MUTEX_ENTER_IRQDISABLE (portc->peer->mutex, flags);
+ portc->output_triggered = 0;
+ /* Wake the server side */
+ oss_wakeup (portc->peer->wq, &portc->peer->mutex, &flags,
+ POLLIN | POLLRDNORM);
+
+ /*
+ * Delay a moment so that the server side gets chance to reinit itself
+ * for next file/stream.
+ */
+ oss_sleep (portc->wq, &portc->peer->mutex, OSS_HZ, &flags, &status);
+ MUTEX_EXIT_IRQRESTORE (portc->peer->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+audioloop_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+#define MY_BUFFSIZE (64*1024)
+ if (dmap->dmabuf != NULL)
+ return 0;
+ dmap->dmabuf_phys = 0; /* Not mmap() capable */
+ dmap->dmabuf = KERNEL_MALLOC (MY_BUFFSIZE);
+ if (dmap->dmabuf == NULL)
+ return OSS_ENOSPC;
+ dmap->buffsize = MY_BUFFSIZE;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+audioloop_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ if (dmap->dmabuf == NULL)
+ return 0;
+ KERNEL_FREE (dmap->dmabuf);
+
+ dmap->dmabuf = NULL;
+ return 0;
+}
+
+#if 0
+static int
+audioloop_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+}
+#endif
+
+static audiodrv_t audioloop_server_driver = {
+ audioloop_server_open,
+ audioloop_server_close,
+ audioloop_output_block,
+ audioloop_start_input,
+ audioloop_ioctl,
+ audioloop_server_prepare_for_input,
+ audioloop_server_prepare_for_output,
+ audioloop_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ audioloop_trigger,
+ audioloop_server_set_rate,
+ audioloop_server_set_format,
+ audioloop_server_set_channels,
+ NULL,
+ NULL,
+ audioloop_check_input,
+ audioloop_check_output,
+ audioloop_alloc_buffer,
+ audioloop_free_buffer,
+ NULL,
+ NULL,
+ NULL /* audioloop_get_buffer_pointer */
+};
+
+static audiodrv_t audioloop_client_driver = {
+ audioloop_client_open,
+ audioloop_client_close,
+ audioloop_output_block,
+ audioloop_start_input,
+ audioloop_ioctl,
+ audioloop_client_prepare_for_input,
+ audioloop_client_prepare_for_output,
+ audioloop_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ audioloop_trigger,
+ audioloop_client_set_rate,
+ audioloop_client_set_format,
+ audioloop_client_set_channels,
+ NULL,
+ NULL,
+ audioloop_check_input,
+ audioloop_check_output,
+ audioloop_alloc_buffer,
+ audioloop_free_buffer,
+ NULL,
+ NULL,
+ NULL /* audioloop_get_buffer_pointer */
+};
+
+
+static int
+install_server (audioloop_devc_t * devc, int num)
+{
+ audioloop_portc_t *portc;
+ char tmp[64], devname[16];
+ int adev;
+
+ int opts =
+ ADEV_STEREOONLY | ADEV_16BITONLY | ADEV_VIRTUAL |
+ ADEV_FIXEDRATE | ADEV_SPECIAL;
+
+ if ((portc = PMALLOC (devc->osdev, sizeof (*portc))) == NULL)
+ return OSS_ENOMEM;
+ memset (portc, 0, sizeof (*portc));
+
+ portc->devc = devc;
+ MUTEX_INIT (devc->osdev, portc->mutex, MH_DRV + 1);
+ if ((portc->wq = oss_create_wait_queue (devc->osdev, "audioloop")) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot create audioloop wait queue\n");
+ return OSS_EIO;
+ }
+
+ portc->instance = num;
+ portc->port_type = PT_SERVER;
+
+ devc->server_portc[num] = portc;
+
+ sprintf (devname, "server%d", num);
+
+ sprintf (tmp, "Audio loopback %d server side", num);
+
+ if ((adev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp,
+ &audioloop_server_driver,
+ sizeof (audiodrv_t),
+ opts, SUPPORTED_FORMATS, devc, -1,
+ devname)) < 0)
+ {
+ return adev;
+ }
+
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = MAX_RATE;
+ audio_engines[adev]->min_channels = 1;
+ audio_engines[adev]->caps |= PCM_CAP_HIDDEN;
+ audio_engines[adev]->max_channels = MAX_CHANNELS;
+
+ portc->audio_dev = adev;
+ portc->rate = 48000;
+ portc->fmt = AFMT_S16_NE;
+ portc->fmt_bytes = 2;
+ portc->channels = 2;
+
+ return 0;
+}
+
+
+static int
+install_client (audioloop_devc_t * devc, int num)
+{
+ audioloop_portc_t *portc;
+ char tmp[64];
+ int adev;
+
+ int opts =
+ ADEV_STEREOONLY | ADEV_16BITONLY | ADEV_VIRTUAL |
+ ADEV_FIXEDRATE | ADEV_SPECIAL | ADEV_LOOP;
+
+ if ((portc = PMALLOC (devc->osdev, sizeof (*portc))) == NULL)
+ return OSS_ENOMEM;
+ memset (portc, 0, sizeof (*portc));
+
+ portc->devc = devc;
+ if ((portc->wq = oss_create_wait_queue (devc->osdev, "audioloop")) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot create audioloop wait queue\n");
+ return OSS_EIO;
+ }
+
+ portc->instance = num;
+ portc->port_type = PT_CLIENT;
+
+ devc->client_portc[num] = portc;
+
+ sprintf (tmp, "Audio loopback %d", num);
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp,
+ &audioloop_client_driver,
+ sizeof (audiodrv_t),
+ opts, SUPPORTED_FORMATS, devc, -1)) < 0)
+ {
+ return adev;
+ }
+
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = MAX_RATE;
+ audio_engines[adev]->min_channels = 1;
+ audio_engines[adev]->max_channels = MAX_CHANNELS;;
+ audio_engines[adev]->enabled = 0; /* Not enabled until server side is opened */
+
+ portc->audio_dev = adev;
+
+
+ return 0;
+}
+
+int
+oss_audioloop_attach (oss_device_t * osdev)
+{
+ audioloop_devc_t *devc;
+ int i;
+
+ if (attach_count >= MAX_ATTACH_COUNT)
+ {
+ cmn_err (CE_WARN, "Attach limit reached (%d)\n", MAX_ATTACH_COUNT);
+ return 0;
+ }
+
+ if (audioloop_instances < 1)
+ audioloop_instances = 1;
+ if (audioloop_instances > MAX_INSTANCES)
+ audioloop_instances = MAX_INSTANCES;
+
+ DDB (cmn_err
+ (CE_CONT, "Initailzing audioloop %d instances\n",
+ audioloop_instances));
+ devc = &audioloop_devices[0];
+
+ osdev->devc = devc;
+ devc->osdev = osdev;
+ MUTEX_INIT (osdev, devc->mutex, MH_DRV);
+
+ oss_register_device (osdev, "audioloop");
+
+ for (i = 0; i < audioloop_instances; i++)
+ {
+ if (install_server (devc, i) < 0)
+ break;
+
+ if (install_client (devc, i) < 0)
+ break;
+
+ devc->client_portc[i]->peer = devc->server_portc[i];
+ devc->server_portc[i]->peer = devc->client_portc[i];
+ devc->num_instances = i + 1;
+ }
+
+ return 1;
+}
+
+int
+oss_audioloop_detach (oss_device_t * osdev)
+{
+ audioloop_devc_t *devc = osdev->devc;
+ int i;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ MUTEX_CLEANUP (devc->mutex);
+
+ for (i = 0; i < devc->num_instances; i++)
+ {
+ MUTEX_CLEANUP (devc->server_portc[i]->mutex);
+ }
+
+ oss_unregister_device (osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_audioloop/oss_audioloop.man b/kernel/drv/oss_audioloop/oss_audioloop.man
new file mode 100644
index 0000000..46932cb
--- /dev/null
+++ b/kernel/drv/oss_audioloop/oss_audioloop.man
@@ -0,0 +1,80 @@
+NAME
+oss_audioloop - Loopback audio driver.
+
+DESCRIPTION
+The loopback audio driver makes it possible to create special purpose
+virtual audio devices based on user land server processes.
+
+Loopback devices are driven by a timer interrupt and no real audio
+hardware is required.
+
+ INTRODUCTION
+Audio loopback devices are like named pipes or pseudo terminals. They are
+grouped in client and server device pairs. The server side device must be open
+before the client side device can be opened.
+
+Loopback devices are typically used to implement server based special purpose
+audio devices. This kind of server can for example transfer the audio data
+played by the client application to some remote system using some VoIP
+protocol. However the server application doesn't need to be any dedicated
+server. Practically any audio application can be used as the server.
+
+ SERVER SIDE DEVICE
+The server side applications sets up the native sampling rate and sample format
+(number of bits and channels). The server side device can be opened for input
+(O_RDONLY) pr output (O_WRONLY). Opening for simultaneous input and output
+(O_RDWR) is not permitted.
+
+The server application will automatically be paused at the moment it tries to
+read or write audio data for the first time. It will be kept in sleep until the
+client side application starts writing or reading data. This sleep period may
+last forever and in some cases the first write/read call never returns. For
+this reason it's not recommended to use GUI based audio applications as the
+server. Note that this wait will occur even in the non-blocking
+(O_NONBLOCK) mode (this is intentional feature and not a bug).
+
+ CLIENT SIDE DEVICE
+The client side device is typically used by any ordinary audio application.
+There is nothing special in loopback devices.
+
+Since the loop is unidirectional the client side will be forced to be write
+only if the server side device is open for recording and vice versa.
+
+The loop will use the sample rate and sample format (number of bits and
+channels) set by the server side application. If the client uses different
+settings then OSS will perform the required sampling rate and format conversions
+automatically.
+
+COMPATIBILITY ISSUES
+Audio loopback devices differ from "normal" audio devices because an
+application is needed at the both ends of the loop. The loop device
+will return a "Connection reset by peer" error (ECONNRESET) error. Applications
+designed to be used as loopback based server applications can/should use this
+error (returned by read or write) as an end-of-stream indication.
+
+OPTIONS
+
+o audioloop_instances: Specifies how many loopback client/server audio device
+ pairs to be created.
+ Values: 1-16 Default: 1
+
+KNOWN PROBLEMS
+o There is no mixer (volume control) related with loopback audio devices. This
+may prevent poorly designed audio applications (that expect/require a mixer)
+from working. There is no workaround available.
+
+o The server side application will wait until the client side application
+starts using it. This wait may last forever which in turn may cause
+unrecoverable (network) problems with some applications.
+
+o Loopback devices may return "Connection reset by peer" error when the
+reote side of the loop disconnects the device. Some recording applications
+may fail to save the recorded data properly because of this. Use some
+other application (such as ossrecord) if this happens.
+
+FILES
+CONFIGFILEPATH/oss_audioloop.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_audiopci/.devices b/kernel/drv/oss_audiopci/.devices
new file mode 100644
index 0000000..431c66e
--- /dev/null
+++ b/kernel/drv/oss_audiopci/.devices
@@ -0,0 +1 @@
+oss_audiopci pci1274,5000 Creative AudioPCI (ES1370)
diff --git a/kernel/drv/oss_audiopci/.name b/kernel/drv/oss_audiopci/.name
new file mode 100644
index 0000000..6bea261
--- /dev/null
+++ b/kernel/drv/oss_audiopci/.name
@@ -0,0 +1 @@
+Ensoniq/Creative AudioPCI (ES1370)
diff --git a/kernel/drv/oss_audiopci/audiopci.h b/kernel/drv/oss_audiopci/audiopci.h
new file mode 100644
index 0000000..cacf0bb
--- /dev/null
+++ b/kernel/drv/oss_audiopci/audiopci.h
@@ -0,0 +1,299 @@
+/*
+ * Purpose: Definitions for the Creative/Ensoniq AudioPCI driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/* CONCERT PCI-SIG defines */
+#define CONC_PCI_VENDID 0x1274U
+#define CONC_PCI_DEVID 0x5000U
+
+/* used for the development board only!!*/
+#define CONC_DEV_PCI_VENDID 0x1274U
+#define CONC_DEV_PCI_DEVID 0x5000U
+
+
+/*
+** CONCERT Registers
+**
+**
+*/
+
+#define DAC_CLOCK_DIVIDE 22579200UL /* DAC2 (CODEC) clock divide */
+/* Concert direct register offset defines */
+
+#define CONC_bDEVCTL_OFF 0x00 /* Device control/enable */
+/* Device Control defines */
+#define CONC_DEVCTL_SERR_DISABLE 0x01 /* internal PCI serr bus enable */
+#define CONC_DEVCTL_CODEC_EN 0x02 /* CoDec Enable */
+#define CONC_DEVCTL_JSTICK_EN 0x04 /* Joystick Enable */
+#define CONC_DEVCTL_UART_EN 0x08 /* UART Enable */
+#define CONC_DEVCTL_ADC_EN 0x10 /* ADC Enable (record) */
+#define CONC_DEVCTL_DAC2_EN 0x20 /* DAC2 Enable (playback) */
+#define CONC_DEVCTL_DAC1_EN 0x40 /* DAC1 Enabale (synth) */
+#define CONC_DEVCTL_MICBIAS 0x4000L /* mic bias switch */
+
+#define CONC_bMISCCTL_OFF 0x01 /* Miscellaneous control */
+/* Misc Control defines */
+#define CONC_MISCTL_MUTE 0x01 /* XTL0 wired to mute */
+#define CONC_MISCTL_CCB_INTRM 0x04 /* CCB interrupt mask */
+#define CONC_MISCTL_DAC1FREQ_2205 0x20 /* synth frequency */
+
+#define CONC_wDACRATE_OFF 0x02 /* CODEC clock divider for PLL */
+#define CONC_dSTATUS_OFF 0x04 /* long status register */
+
+#define CONC_bINTSTAT_OFF 0x04 /* Device interrupt status */
+/* Interrupt Status defines */
+#define CONC_INTSTAT_ADCINT 0x01 /* A/D interrupt pending bit */
+#define CONC_INTSTAT_DAC2INT 0x02 /* DAC2 interrupt pending bit */
+#define CONC_INTSTAT_DAC1INT 0x04 /* DAC1 interrupt pending bit */
+#define CONC_INTSTAT_UARTINT 0x08 /* UART interrupt pending bit */
+
+#define CONC_bCODECSTAT_OFF 0x05 /* CODEC interface status */
+#define CONC_bINTSUMM_OFF 0x07 /* Interrupt summary status */
+#define CONC_bUARTDATA_OFF 0x08 /* UART data R/W - read clears RX int */
+#define CONC_bUARTCSTAT_OFF 0x09 /* UART control and status */
+#define CONC_bMEMPAGE_OFF 0x0c /* Memory page select */
+#define CONC_wCODECCTL_OFF 0x10 /* CODEC control - word-write-only */
+#define CONC_wNMISTAT_OFF 0x18 /* Legacy NMI status */
+#define CONC_bNMIENA_OFF 0x1a /* Legacy NMI enable */
+#define CONC_bNMICTL_OFF 0x1b /* Legacy control */
+
+#define CONC_bSERFMT_OFF 0x20 /* Serial device control */
+/* SERFMT PCM format defines */
+#define CONC_PCM_DAC1_STEREO 0x01
+#define CONC_PCM_DAC1_16BIT 0x02
+#define CONC_PCM_DAC1_MASK 0xfc
+#define CONC_PCM_DAC2_STEREO 0x04
+#define CONC_PCM_DAC2_16BIT 0x08
+#define CONC_PCM_DAC2_MASK 0xf3
+#define CONC_PCM_ADC_STEREO 0x10
+#define CONC_PCM_ADC_16BIT 0x20
+#define CONC_PCM_ADC_MASK 0xcf
+
+#define CONC_bSERCTL_OFF 0x21 /* Serial device format */
+/* Serial Control defines */
+#define CONC_SERCTL_SYNIE 0x01 /* synth (DAC1) int enable */
+#define CONC_SERCTL_SYNIE_MASK 0x0e /* synth interrupt mask */
+#define CONC_SERCTL_DACIE 0x02 /* playback interrupt enable */
+#define CONC_SERCTL_DACIE_MASK 0x0d /* playback interrupt mask */
+#define CONC_SERCTL_ADCIE 0x04 /* record interrupt enable */
+#define CONC_SERCTL_ADCIE_MASK 0x0b /* record interrupt mask */
+#define CONC_SERCTL_DACPAUSE 0x10 /* playback pause */
+
+#define CONC_bSKIPC_OFF 0x22 /* Start/end skip counts for DAC2 (wave) */
+#define CONC_wSYNIC_OFF 0x24 /* Synth int count in sample frames */
+#define CONC_wSYNCIC_OFF 0x26 /* Synth current int count */
+#define CONC_wDACIC_OFF 0x28 /* DAC int count in sample frames */
+#define CONC_wDACCIC_OFF 0x2a /* DAC current int count */
+#define CONC_wADCIC_OFF 0x2c /* ADC int count in sample frames */
+#define CONC_wADCCIC_OFF 0x2e /* ADC current int count */
+#define CONC_MEMBASE_OFF 0x30 /* Memory window base - 16 bytes */
+
+/* Concert memory page-banked register offset defines */
+#define CONC_dSYNPADDR_OFF 0x30 /* Synth host frame PCI phys addr */
+#define CONC_wSYNFC_OFF 0x34 /* Synth host frame count in DWORDS */
+#define CONC_wSYNCFC_OFF 0x36 /* Synth host current frame count */
+#define CONC_dDACPADDR_OFF 0x38 /* DAC host frame PCI phys addr */
+#define CONC_wDACFC_OFF 0x3c /* DAC host frame count in DWORDS */
+#define CONC_wDACCFC_OFF 0x3e /* DAC host current frame count */
+#define CONC_dADCPADDR_OFF 0x30 /* ADC host frame PCI phys addr */
+#define CONC_wADCFC_OFF 0x34 /* ADC host frame count in DWORDS */
+#define CONC_wADCCFC_OFF 0x36 /* ADC host current frame count */
+
+/* Concert memory page number defines */
+#define CONC_SYNRAM_PAGE 0x00 /* Synth host/serial I/F RAM */
+#define CONC_DACRAM_PAGE 0x04 /* DAC host/serial I/F RAM */
+#define CONC_ADCRAM_PAGE 0x08 /* ADC host/serial I/F RAM */
+#define CONC_SYNCTL_PAGE 0x0c /* Page bank for synth host control */
+#define CONC_DACCTL_PAGE 0x0c /* Page bank for DAC host control */
+#define CONC_ADCCTL_PAGE 0x0d /* Page bank for ADC host control */
+#define CONC_FIFO0_PAGE 0x0e /* page 0 of UART "FIFO" (rx stash) */
+#define CONC_FIFO1_PAGE 0x0f /* page 1 of UART "FIFO" (rx stash) */
+
+/* UARTCSTAT register masks */
+#define CONC_UART_RXRDY 0x01
+#define CONC_UART_TXRDY 0x02
+#define CONC_UART_TXINT 0x04
+#define CONC_UART_RXINT 0x80
+
+#define CONC_UART_CTL 0x03
+#define CONC_UART_TXINTEN 0x20
+#define CONC_UART_RXINTEN 0x80
+
+/*
+** CODEC register map
+**
+*/
+#define NUMREGS 32 /* total number of registers */
+#define NUMVOLS 16 /* number of vol regs */
+
+/* Source and output volume control defines */
+#define CODEC_VOL_MASTER_L 0x00U /* Master out, left */
+#define CODEC_VOL_MASTER_R 0x01U /* Master out, right */
+#define CODEC_VOL_WAVE_L 0x02U /* Wave DAC, left */
+#define CODEC_VOL_WAVE_R 0x03U /* Wave DAC, right */
+#define CODEC_VOL_SYNTH_L 0x04U /* Synth DAC, left */
+#define CODEC_VOL_SYNTH_R 0x05U /* Synth DAC, right */
+#define CODEC_VOL_CD_L 0x06U /* CD audio, left */
+#define CODEC_VOL_CD_R 0x07U /* CD audio, right */
+#define CODEC_VOL_AUX_L 0x08U /* Aux line source, left */
+#define CODEC_VOL_AUX_R 0x09U /* Aux line source, right */
+#define CODEC_VOL_TV_L 0x0aU /* TV Tuner, left */
+#define CODEC_VOL_TV_R 0x0bU /* TV Tuner, right */
+#define CODEC_VOL_TAD 0x0cU /* TAD monitor, mono */
+#define CODEC_VOL_MONO2 0x0dU /* Unused MONO2 */
+#define CODEC_VOL_MIC 0x0eU /* Mic, mono */
+#define CODEC_VOL_MONO 0x0fU /* Mono out volume */
+
+/* Input bus enable defines -SW1 */
+#define CODEC_IN_ENABLE_MIC 0x01U /* Mic enable, mono */
+#define CODEC_IN_ENABLE_CD_R 0x02U /* CD audio enable, right */
+#define CODEC_IN_ENABLE_CD_L 0x04U /* CD audio enable, left */
+#define CODEC_IN_ENABLE_AUX_R 0x08U /* Aux line source enable, right */
+#define CODEC_IN_ENABLE_AUX_L 0x10U /* Aux line source enable, left */
+#define CODEC_IN_ENABLE_SYNTH_R 0x20U /* Synth DAC enable, right */
+#define CODEC_IN_ENABLE_SYNTH_L 0x40U /* Synth DAC enable, left */
+
+/* Input bus enable defines - SW2 */
+#define CODEC_IN_ENABLE_TAD 0x01U /* TAD monitor enable, mono */
+#define CODEC_IN_ENABLE_MONO2 0x02U /* Unused MONO2 enable, mono */
+#define CODEC_IN_ENABLE_WAVE 0x04U /* Wave DAC enable */
+#define CODEC_IN_ENABLE_TV_R 0x08U /* TV Tuner enable, right */
+#define CODEC_IN_ENABLE_TV_L 0x10U /* TV Tuner enable, left */
+#define CODEC_IN_ENABLE_TMONO2 0x20U /* unboosted MONO2 */
+#define CODEC_IN_ENABLE_TMONO1 0x40U /* unboosted MONO1 */
+#define CODEC_IN_ENABLE_TMIC 0x80U /* unboosted MONO3 (mic) */
+
+/* Output bus enable defines */
+#define CODEC_OUT_ENABLE_MIC 0x0001U /* Mic enable, mono */
+#define CODEC_OUT_ENABLE_CD 0x0006U /* CD audio enable, stereo */
+#define CODEC_OUT_ENABLE_AUX 0x0018U /* Aux line source enable, stereo */
+#define CODEC_OUT_ENABLE_SYNTH 0x0060U /* Synth DAC enable, stereo */
+#define CODEC_OUT_ENABLE_TAD 0x0100U /* TAD monitor enable, mono */
+#define CODEC_OUT_ENABLE_MONO2 0x0200U /* Unused MONO2 enable, mono */
+#define CODEC_OUT_ENABLE_WAVE 0x0c00U /* Wave DAC enable, stereo */
+#define CODEC_OUT_ENABLE_TV 0x3000U /* TV Tuner enable, stereo */
+
+/* Volume setting constants */
+#define CODEC_VOL_MUTE 0x80U
+#define CODEC_VOL_MAX 0x00U
+#define CODEC_VOL_MIN 0x1fU
+
+/* Control function defines */
+#define CODEC_CTL_4SPKR 0x00U /* 4-spkr output mode enable */
+#define CODEC_CTL_MICBOOST 0x01U /* Mic boost (+30 dB) enable */
+
+/* Miscellaneous CODEC defines for internal use */
+#define CODEC_OUT_SW1 0x10U
+#define CODEC_OUT_SW2 0x11U
+#define CODEC_LIN_SW1 0x12U
+#define CODEC_RIN_SW1 0x13U
+#define CODEC_LIN_SW2 0x14U
+#define CODEC_RIN_SW2 0x15U
+#define CODEC_RESET_PWRD 0x16U
+#define CODEC_CLKSELECT 0x17U
+#define CODEC_ADSELECT 0x18U
+#define CODEC_MICBOOST 0x19U
+
+/* PCM format defines */
+#define CONC_PCM_DAC_STEREO 0x04
+#define CONC_PCM_DAC_16BIT 0x08
+#define CONC_PCM_DAC_MASK 0xf3
+#define CONC_PCM_ADC_STEREO 0x10
+#define CONC_PCM_ADC_16BIT 0x20
+#define CONC_PCM_ADC_MASK 0xcf
+
+/* Logical index for each DMA controller on chip - used for */
+/* generic routines that access all DMA controllers */
+#define CONC_SYNTH_DAC 0
+#define CONC_WAVE_DAC 1
+#define CONC_WAVE_ADC 2
+
+/************************
+ * Mixer definitions
+ */
+
+struct mixer_def
+{
+ unsigned int regno;
+ unsigned int polarity; /* 0=normal, 1=reversed */
+ unsigned int bitpos;
+ unsigned int nbits;
+ unsigned int mutepos;
+};
+
+typedef struct mixer_def mixer_ent;
+typedef mixer_ent mixer_ents[2];
+
+#define MIXER_DEVS (SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | \
+ SOUND_MASK_MIC | SOUND_MASK_VOLUME | \
+ SOUND_MASK_LINE3 | SOUND_MASK_SPEAKER | \
+ SOUND_MASK_CD | SOUND_MASK_LINE | \
+ SOUND_MASK_PCM | SOUND_MASK_ALTPCM)
+
+#define REC_DEVS (SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | \
+ SOUND_MASK_MIC | \
+ SOUND_MASK_LINE3 | \
+ SOUND_MASK_CD | SOUND_MASK_LINE)
+
+#define STEREO_DEVS (SOUND_MASK_LINE1 | \
+ SOUND_MASK_VOLUME | \
+ SOUND_MASK_CD | SOUND_MASK_LINE | \
+ SOUND_MASK_PCM | SOUND_MASK_ALTPCM)
+
+#define LEFT_CHN 0
+#define RIGHT_CHN 1
+
+#define MIX_ENT(name, reg_l, pola_l, pos_l, len_l, reg_r, pola_r, pos_r, len_r, mute_bit) \
+ {{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r, mute_bit}}
+
+static mixer_ents ak_mix_devices[32] = {
+/* Name Reg p b l Reg p b l M */
+ MIX_ENT (SOUND_MIXER_VOLUME, 0x00, 1, 0, 5, 0x01, 1, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_BASS, 0xff, 0, 0, 5, 0xff, 0, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_TREBLE, 0xff, 0, 0, 5, 0xff, 0, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_SYNTH, 0xff, 0, 0, 5, 0xff, 0, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_PCM, 0x02, 1, 0, 5, 0x03, 1, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_SPEAKER, 0x0f, 1, 0, 3, 0xff, 0, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_LINE, 0x08, 1, 0, 5, 0x09, 1, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_MIC, 0x0e, 1, 0, 5, 0xff, 1, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_CD, 0x06, 1, 0, 5, 0x07, 1, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_IMIX, 0xff, 0, 0, 5, 0xff, 0, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_ALTPCM, 0x04, 1, 0, 5, 0x05, 1, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_RECLEV, 0xff, 0, 0, 5, 0xff, 0, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_IGAIN, 0xff, 0, 0, 5, 0xff, 0, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_OGAIN, 0xff, 0, 0, 5, 0xff, 0, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_LINE1, 0x0a, 1, 0, 5, 0x0b, 1, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_LINE2, 0x0c, 1, 0, 5, 0xff, 0, 0, 5, 7),
+ MIX_ENT (SOUND_MIXER_LINE3, 0x0d, 1, 0, 5, 0xff, 0, 0, 5, 7)
+};
+
+static int default_mixer_levels[32] = {
+ 0x3232, /* Master Volume */
+ 0x3232, /* Bass */
+ 0x3232, /* Treble */
+ 0x4b4b, /* FM */
+ 0x3232, /* PCM */
+ 0x1515, /* PC Speaker */
+ 0x2020, /* Ext Line */
+ 0x2020, /* 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) */
+};
diff --git a/kernel/drv/oss_audiopci/oss_audiopci.c b/kernel/drv/oss_audiopci/oss_audiopci.c
new file mode 100644
index 0000000..f608cf8
--- /dev/null
+++ b/kernel/drv/oss_audiopci/oss_audiopci.c
@@ -0,0 +1,1536 @@
+/*
+ * Purpose: Creative/Ensoniq AudioPCI driver (ES1370 "CONCERT" ASIC and AKM4531 codec/mixer)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_audiopci_cfg.h"
+#include "audiopci.h"
+#include "midi_core.h"
+#include "oss_pci.h"
+
+#define ENSONIQ_VENDOR_ID 0x1274
+#define ENSONIQ_VENDOR_ID2 0x1275
+#define ENSONIQ_AUDIOPCI 0x5000
+
+#define MAX_PORTC 2
+
+typedef struct apci_portc
+{
+
+ /* Audio parameters */
+ int audiodev;
+ int open_mode;
+ int trigger_bits;
+ int audio_enabled;
+ int speed, bits, channels;
+ int atype; /* 0=DAC/ADC, 1=Synth */
+ int speedsel;
+} apci_portc;
+
+typedef struct apci_devc
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex, low_mutex;
+ oss_native_word base;
+ int irq;
+ char *chip_name;
+
+ /* Mixer parameters */
+ int *levels;
+ unsigned char ak_regs[0x20]; /* Current mixer register values */
+ int recdevs;
+ int micbias, micboost;
+ unsigned char outsw1, outsw2;
+
+ /* Audio parameters */
+ int irq_allocated;
+ apci_portc portc[MAX_PORTC];
+
+/*
+ * MIDI
+ */
+ int midi_opened;
+ int midi_dev;
+ oss_midi_inputbyte_t midi_input_intr;
+} apci_devc;
+
+
+/*
+ * Initial values to be written into the mixer registers of AK4531 codec.
+ */
+static const unsigned char ak_reg_init[0x20] = {
+ /* Mute all inputs/outputs initially */
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 00 to 07 */
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 08 to 0f */
+ 0x7f, 0x3d, 0x55, 0x26, 0xf7, 0xef, 0x03, 0x00, /* 10 to 17 */
+ 0x00, 0x01 /* 18 to 19 */
+};
+
+static void
+ak_write (apci_devc * devc, int reg, int value)
+{
+ int i;
+
+ if (reg < 0 || reg > 0x19)
+ return;
+
+ value &= 0xff;
+ devc->ak_regs[reg] = (unsigned char) value;
+
+ /* Wait until the codec is ready */
+ for (i = 0; i < 0x40000; i++)
+ if (!(INB (devc->osdev, devc->base + CONC_bCODECSTAT_OFF) & 0x01))
+ break;
+ oss_udelay (10);
+ OUTW (devc->osdev, (reg << 8) | value, devc->base + CONC_wCODECCTL_OFF);
+ oss_udelay (10);
+}
+
+static void
+apci_writemem (apci_devc * devc, int page, int offs, int data)
+{
+ int tmp;
+
+ tmp = INL (devc->osdev, devc->base + 0xc);
+ OUTL (devc->osdev, page, devc->base + 0xc); /* Select memory page */
+ OUTL (devc->osdev, data, devc->base + offs);
+ OUTL (devc->osdev, tmp, devc->base + 0xc); /* Select the original memory page */
+}
+
+static unsigned int
+apci_readmem (apci_devc * devc, int page, int offs)
+{
+ unsigned int val;
+
+ OUTL (devc->osdev, page, devc->base + 0xc); /* Select memory page */
+ val = INL (devc->osdev, devc->base + offs);
+ return val;
+}
+
+#define bmast_off(x)
+#define bmast_on(x)
+
+static int
+apci_set_recmask (apci_devc * devc, int mask)
+{
+ unsigned char tmp;
+
+ mask &= REC_DEVS;
+
+/*
+ * Set lch input mixer SW 1 register
+ */
+ tmp = 0;
+ if (mask & SOUND_MASK_ALTPCM)
+ tmp |= 0x40;
+ if (mask & SOUND_MASK_LINE)
+ tmp |= 0x10;
+ if (mask & SOUND_MASK_CD)
+ tmp |= 0x04;
+ if (mask & SOUND_MASK_MIC)
+ tmp |= 0x01;
+ ak_write (devc, 0x12, tmp);
+
+/*
+ * Set rch input mixer SW 1 register
+ */
+ tmp = 0;
+ if (mask & SOUND_MASK_ALTPCM)
+ tmp |= 0x20;
+ if (mask & SOUND_MASK_LINE)
+ tmp |= 0x08;
+ if (mask & SOUND_MASK_CD)
+ tmp |= 0x02;
+ if (mask & SOUND_MASK_MIC)
+ tmp |= 0x01;
+ ak_write (devc, 0x13, tmp);
+
+/*
+ * Set lch input mixer SW 2 register
+ */
+ tmp = 0;
+ if (mask & SOUND_MASK_LINE2)
+ tmp |= 0x40;
+ if (mask & SOUND_MASK_LINE3)
+ tmp |= 0x20;
+ if (mask & SOUND_MASK_LINE1)
+ tmp |= 0x10;
+ if (mask & SOUND_MASK_MIC)
+ tmp |= 0x80;
+ ak_write (devc, 0x14, tmp);
+
+/*
+ * Set rch input mixer SW 2 register
+ */
+ tmp = 0;
+ if (mask & SOUND_MASK_LINE2)
+ tmp |= 0x40;
+ if (mask & SOUND_MASK_LINE3)
+ tmp |= 0x20;
+ if (mask & SOUND_MASK_LINE1)
+ tmp |= 0x08;
+ if (mask & SOUND_MASK_MIC)
+ tmp |= 0x80;
+ ak_write (devc, 0x15, tmp);
+
+ return devc->recdevs = mask;
+}
+
+/*ARGSUSED*/
+static void
+change_bits (apci_devc * devc, unsigned char *regval, int dev, int chn,
+ int newval)
+{
+ unsigned char mask;
+ int shift;
+ int mute;
+ int mutemask;
+ int set_mute_bit;
+
+ set_mute_bit = (newval == 0);
+
+ if (ak_mix_devices[dev][chn].polarity == 1) /* Reverse */
+ newval = 100 - newval;
+
+ mask = (1 << ak_mix_devices[dev][chn].nbits) - 1;
+ shift = ak_mix_devices[dev][chn].bitpos;
+
+#if 0
+ newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
+ *regval &= ~(mask << shift); /* Clear bits */
+ *regval |= (newval & mask) << shift; /* Set new value */
+#else
+ if (ak_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 << ak_mix_devices[dev][chn].mutepos);
+ mutemask = ~(1 << ak_mix_devices[dev][chn].mutepos);
+ }
+
+ newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
+ *regval &= (~(mask << shift)) & (mutemask); /* Clear bits */
+ *regval |= ((newval & mask) << shift) | mute; /* Set new value */
+#endif
+}
+
+static int
+apci_mixer_get (apci_devc * devc, int dev)
+{
+ if (!((1 << dev) & MIXER_DEVS))
+ return OSS_EINVAL;
+
+ return devc->levels[dev];
+}
+
+static int
+apci_mixer_set (apci_devc * devc, int dev, int value)
+{
+ int left = value & 0x000000ff;
+ int right = (value & 0x0000ff00) >> 8;
+ int retvol;
+
+ int regoffs;
+ unsigned char val;
+
+ if (dev > 31)
+ return OSS_EINVAL;
+
+ if (!(MIXER_DEVS & (1 << dev)))
+ return OSS_EINVAL;
+
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+
+ if (ak_mix_devices[dev][RIGHT_CHN].regno == 0xff) /* Mono control */
+ right = left;
+
+ retvol = left | (right << 8);
+
+#if 1
+ /* Scale volumes */
+ left = mix_cvt[left];
+ right = mix_cvt[right];
+
+ /* Scale it again */
+ left = mix_cvt[left];
+ right = mix_cvt[right];
+#endif
+
+ if (ak_mix_devices[dev][LEFT_CHN].regno == 0xff)
+ return OSS_EINVAL;
+
+ devc->levels[dev] = retvol;
+
+ /*
+ * Set the left channel
+ */
+
+ regoffs = ak_mix_devices[dev][LEFT_CHN].regno;
+ val = 0;
+ change_bits (devc, &val, dev, LEFT_CHN, left);
+ ak_write (devc, regoffs, val);
+
+ /*
+ * Set the right channel
+ */
+
+ if (ak_mix_devices[dev][RIGHT_CHN].regno == 0xff)
+ return retvol; /* Was just a mono channel */
+
+ regoffs = ak_mix_devices[dev][RIGHT_CHN].regno;
+ val = 0;
+ change_bits (devc, &val, dev, RIGHT_CHN, right);
+ ak_write (devc, regoffs, val);
+
+ return retvol;
+}
+
+static void
+apci_mixer_reset (apci_devc * devc)
+{
+ int i;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if (MIXER_DEVS & (1 << i))
+ apci_mixer_set (devc, i, devc->levels[i]);
+ apci_set_recmask (devc, SOUND_MASK_MIC);
+ devc->outsw1 = ak_reg_init[0x10];
+ devc->outsw2 = ak_reg_init[0x11];
+}
+
+/*ARGSUSED*/
+static int
+apci_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ apci_devc *devc = mixer_devs[dev]->devc;
+
+ if (((cmd >> 8) & 0xff) == 'M')
+ {
+ int val;
+
+ if (IOC_IS_OUTPUT (cmd))
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ val = *arg;
+ return *arg = apci_set_recmask (devc, val);
+ break;
+
+ default:
+ val = *arg;
+ return *arg = apci_mixer_set (devc, cmd & 0xff, val);
+ }
+ else
+ switch (cmd & 0xff) /*
+ * Return parameters
+ */
+ {
+
+ case SOUND_MIXER_RECSRC:
+ return *arg = devc->recdevs;
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ return *arg = MIXER_DEVS;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ return *arg = STEREO_DEVS;
+ break;
+
+ case SOUND_MIXER_RECMASK:
+ return *arg = REC_DEVS;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ return *arg = SOUND_CAP_EXCL_INPUT;
+ break;
+
+ default:
+ return *arg = apci_mixer_get (devc, cmd & 0xff);
+ }
+ }
+ else
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static int
+getmute (apci_devc * devc, int offs, unsigned char bits, int value)
+{
+ unsigned char tmp;
+
+ tmp = (offs == 0x10) ? devc->outsw1 : devc->outsw2;
+
+ tmp &= bits;
+ return (tmp == 0); /* Note! inverted polarity */
+}
+
+static int
+setmute (apci_devc * devc, int offs, unsigned char bits, int value)
+{
+ unsigned char tmp;
+
+ value = !value; /* Inverted polarity (now 0=mute) */
+
+ tmp = (offs == 0x10) ? devc->outsw1 : devc->outsw2;
+
+ tmp &= ~bits; /* Mask old bits */
+ if (value)
+ tmp |= bits;
+
+ ak_write (devc, offs, tmp);
+ if (offs == 0x10)
+ devc->outsw1 = tmp;
+ else
+ devc->outsw2 = tmp;
+
+ return !value;
+}
+
+static int
+apci_outsw (int dev, int ctrl, unsigned int cmd, int value)
+{
+/*
+ * Access function for AudioPCI mixer extension bits
+ */
+ apci_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case 1: /* 20 dB microphone boost */
+ value = devc->micboost;
+ break;
+
+ case 2: /* Microphone phantom power */
+ value = devc->micbias;
+ break;
+
+ case 10: /* Pcm mute */
+ value = getmute (devc, 0x11, 0x0c, value);
+ break;
+
+ case 11: /* Pcm2 mute */
+ value = getmute (devc, 0x10, 0x60, value);
+ break;
+
+ case 12: /* Mic mute */
+ value = getmute (devc, 0x10, 0x01, value);
+ break;
+
+ case 13: /* CD mute */
+ value = getmute (devc, 0x10, 0x06, value);
+ break;
+
+ case 14: /* Line mute */
+ value = getmute (devc, 0x10, 0x18, value);
+ break;
+
+ case 15: /* Line1 mute */
+ value = getmute (devc, 0x11, 0x30, value);
+ break;
+
+ case 16: /* Line2 mute */
+ value = getmute (devc, 0x11, 0x01, value);
+ break;
+
+ case 17: /* Line3 mute */
+ value = getmute (devc, 0x11, 0x02, value);
+ break;
+
+ case 18: /*Separate output enable for the synth device (XCTL0) */
+ value =
+ ((INB (devc->osdev, devc->base + CONC_bMISCCTL_OFF) & 0x01) != 0);
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ return value;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ int tmp;
+
+ if (value)
+ value = 1;
+
+ switch (ctrl)
+ {
+ case 1: /* 20 dB microphone boost */
+ devc->micboost = value;
+ ak_write (devc, 0x19, value);
+ break;
+
+ case 2: /* Microphone phantom power */
+ devc->micbias = value;
+ /* Delay the actual change until next recording */
+ break;
+
+ case 10: /* Pcm mute */
+ value = setmute (devc, 0x11, 0x0c, value);
+ break;
+
+ case 11: /* Pcm2 mute */
+ value = setmute (devc, 0x10, 0x60, value);
+ break;
+
+ case 12: /* Mic mute */
+ value = setmute (devc, 0x10, 0x01, value);
+ break;
+
+ case 13: /* CD mute */
+ value = setmute (devc, 0x10, 0x06, value);
+ break;
+
+ case 14: /* Line mute */
+ value = setmute (devc, 0x10, 0x18, value);
+ break;
+
+ case 15: /* Line1 mute */
+ value = setmute (devc, 0x11, 0x30, value);
+ break;
+
+ case 16: /* Line2 mute */
+ value = setmute (devc, 0x11, 0x01, value);
+ break;
+
+ case 17: /* Line3 mute */
+ value = setmute (devc, 0x11, 0x02, value);
+ break;
+
+ case 18: /*Separate output enable for the synth device (XCTL0) */
+ tmp = INB (devc->osdev, devc->base + CONC_bMISCCTL_OFF);
+ if (value)
+ {
+ OUTB (devc->osdev, tmp | 0x01, devc->base + CONC_bMISCCTL_OFF);
+ }
+ else
+ {
+ OUTB (devc->osdev, tmp & ~0x01, devc->base + CONC_bMISCCTL_OFF);
+ }
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ return value;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+apci_mix_init (int dev)
+{
+ int group, err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "APCI_EXTMIC")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group, 1, apci_outsw, MIXT_ONOFF,
+ "APCI_MICBOOST", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 2, apci_outsw, MIXT_ONOFF,
+ "APCI_MICBIAS", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "APCI_MUTE")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group, 10, apci_outsw,
+ MIXT_ONOFF,
+ "APCI_PCMMUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 11, apci_outsw,
+ MIXT_ONOFF,
+ "APCI_PCM2MUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 12, apci_outsw,
+ MIXT_ONOFF,
+ "APCI_MICMUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 13, apci_outsw,
+ MIXT_ONOFF,
+ "APCI_CDMUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 14, apci_outsw,
+ MIXT_ONOFF,
+ "APCI_LINEMUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 15, apci_outsw,
+ MIXT_ONOFF,
+ "APCI_LINE1MUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 16, apci_outsw,
+ MIXT_ONOFF,
+ "APCI_LINE2MUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 17, apci_outsw,
+ MIXT_ONOFF,
+ "APCI_LINE3MUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "APCI_4CHAN")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group, 18, apci_outsw,
+ MIXT_ONOFF,
+ "APCI4CH_ENABLE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+static mixer_driver_t apci_mixer_driver = {
+ apci_mixer_ioctl
+};
+
+static int
+apciintr (oss_device_t * osdev)
+{
+ int stats, i;
+ unsigned char ackbits = 0, tmp;
+ unsigned char uart_stat;
+ apci_devc *devc = (apci_devc *) osdev->devc;
+ apci_portc *portc;
+ int serviced = 0;
+
+ stats = INL (devc->osdev, devc->base + 0x04);
+
+ if (!(stats & 0x80000000)) /* No interrupt pending */
+ return 0;
+
+ serviced = 1;
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+
+ if (stats & 0x00000010) /* CCB interrupt */
+ {
+ cmn_err (CE_WARN, "CCB interrupt\n");
+ }
+
+ if ((stats & 0x00000004) && (portc->atype)) /* DAC1 (synth) interrupt */
+ {
+ ackbits |= CONC_SERCTL_SYNIE;
+ if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ oss_audio_outputintr (portc->audiodev, 0);
+
+ }
+
+ if ((stats & 0x00000002) && (!portc->atype)) /* DAC2 interrupt */
+ {
+ ackbits |= CONC_SERCTL_DACIE;
+ if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ oss_audio_outputintr (portc->audiodev, 0);
+ }
+
+ if ((stats & 0x00000001) && (!portc->atype)) /* ADC interrupt */
+ {
+ ackbits |= CONC_SERCTL_ADCIE;
+ if (portc->trigger_bits & PCM_ENABLE_INPUT)
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+
+ if (stats & 0x00000008) /* UART interrupt */
+ {
+ uart_stat = INB (devc->osdev, devc->base + CONC_bUARTCSTAT_OFF);
+
+ while (uart_stat & CONC_UART_RXRDY)
+ {
+ unsigned char d;
+
+ d = INB (devc->osdev, devc->base + CONC_bUARTDATA_OFF);
+
+ if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr (devc->midi_dev, d);
+ uart_stat = INB (devc->osdev, devc->base + CONC_bUARTCSTAT_OFF);
+ }
+ }
+
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF);
+ OUTB (devc->osdev, (tmp & ~ackbits), devc->base + CONC_bSERCTL_OFF); /* Clear bits */
+ OUTB (devc->osdev, tmp | ackbits, devc->base + CONC_bSERCTL_OFF); /* Return them back on */
+
+ }
+ return serviced;
+}
+
+/*
+ * Audio routines
+ */
+
+static unsigned short
+compute_dac2_rate (int samPerSec)
+{
+
+ unsigned short usTemp;
+
+ /* samPerSec /= 2; */
+
+ usTemp = (unsigned short) ((DAC_CLOCK_DIVIDE / 8) / samPerSec);
+
+ if (usTemp & 0x00000001)
+ {
+ usTemp >>= 1;
+ usTemp -= 1;
+ }
+ else
+ {
+ usTemp >>= 1;
+ usTemp -= 2;
+ }
+
+ return usTemp;
+
+}
+
+static int
+apci_audio_set_rate (int dev, int arg)
+{
+ apci_portc *portc = audio_engines[dev]->portc;
+
+ int speeds[] = { 5512, 11025, 22050, 44100 };
+ int i, n = 0, best = 1000000;
+
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (portc->atype)
+ {
+ if (arg > 44100)
+ arg = 44100;
+ if (arg < 5512)
+ arg = 5512;
+
+ for (i = 0; i < 4; i++)
+ {
+ int diff = arg - speeds[i];
+
+ if (diff < 0)
+ diff *= -1;
+
+ if (diff < best)
+ {
+ n = i;
+ best = diff;
+ }
+ }
+ portc->speed = speeds[n];
+ portc->speedsel = n;
+ }
+ else
+ {
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ }
+ return portc->speed;
+}
+
+static short
+apci_audio_set_channels (int dev, short arg)
+{
+ apci_portc *portc = audio_engines[dev]->portc;
+
+ if ((arg != 1) && (arg != 2))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+apci_audio_set_format (int dev, unsigned int arg)
+{
+ apci_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+apci_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void apci_audio_trigger (int dev, int state);
+
+static void
+apci_audio_reset (int dev)
+{
+ apci_audio_trigger (dev, 0);
+}
+
+static void
+apci_audio_reset_input (int dev)
+{
+ apci_portc *portc = audio_engines[dev]->portc;
+ apci_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+apci_audio_reset_output (int dev)
+{
+ apci_portc *portc = audio_engines[dev]->portc;
+ apci_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+apci_audio_open (int dev, int mode, int open_flags)
+{
+ apci_portc *portc = audio_engines[dev]->portc;
+ apci_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ portc->audio_enabled = ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+apci_audio_close (int dev, int mode)
+{
+ apci_portc *portc = audio_engines[dev]->portc;
+
+ apci_audio_reset (dev);
+ portc->open_mode = 0;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+apci_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ apci_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+}
+
+/*ARGSUSED*/
+static void
+apci_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ apci_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+}
+
+static void
+apci_audio_trigger (int dev, int state)
+{
+ apci_devc *devc = audio_engines[dev]->devc;
+ apci_portc *portc = audio_engines[dev]->portc;
+ int tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ if (portc->atype)
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp |= CONC_DEVCTL_DAC1_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ }
+ else
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp |= CONC_DEVCTL_DAC2_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ }
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ oss_udelay (50);
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ if (portc->atype)
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp &= ~CONC_DEVCTL_DAC1_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF);
+ tmp &= ~CONC_SERCTL_SYNIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ }
+ else
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp &= ~CONC_DEVCTL_DAC2_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF);
+ tmp &= ~CONC_SERCTL_DACIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ }
+ }
+ }
+ }
+
+ if ((portc->open_mode & OPEN_READ)
+ && !(audio_engines[dev]->flags & ADEV_NOINPUT))
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp |= CONC_DEVCTL_ADC_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ oss_udelay (50);
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp &= ~CONC_DEVCTL_ADC_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF);
+ tmp &= ~CONC_SERCTL_ADCIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ }
+ }
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+apci_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ apci_devc *devc = audio_engines[dev]->devc;
+ apci_portc *portc = audio_engines[dev]->portc;
+ unsigned short tmp = 0x00;
+ oss_native_word flags;
+
+ /* Set physical address of the DMA buffer */
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ apci_writemem (devc, CONC_ADCCTL_PAGE, CONC_dADCPADDR_OFF,
+ dmap->dmabuf_phys);
+
+ /* Set DAC (ADC) rate */
+ OUTW (devc->osdev, compute_dac2_rate (portc->speed),
+ devc->base + CONC_wDACRATE_OFF);
+
+ /* Set format */
+ tmp = INB (devc->osdev, devc->base + CONC_bSERFMT_OFF);
+ tmp &= ~(CONC_PCM_ADC_STEREO | CONC_PCM_ADC_16BIT);
+ if (portc->channels == 2)
+ tmp |= CONC_PCM_ADC_STEREO;
+ if (portc->bits == 16)
+ {
+ tmp |= CONC_PCM_ADC_16BIT;
+ OUTB (devc->osdev, 0x10, devc->base + CONC_bSKIPC_OFF); /* Skip count register */
+ }
+ else
+ {
+ OUTB (devc->osdev, 0x08, devc->base + CONC_bSKIPC_OFF); /* Skip count register */
+ }
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERFMT_OFF);
+
+ /* Set the frame count */
+ apci_writemem (devc, CONC_ADCCTL_PAGE, CONC_wADCFC_OFF,
+ (dmap->bytes_in_use / 4) - 1);
+
+ /* Set # of samples between interrupts */
+ OUTW (devc->osdev,
+ (dmap->fragment_size / ((portc->channels * portc->bits) / 8)) - 1,
+ devc->base + CONC_wADCIC_OFF);
+
+ /* Enable the wave interrupt */
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF) & ~CONC_SERCTL_ADCIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ tmp |= CONC_SERCTL_ADCIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+
+ /* Enable microphone phantom power */
+ tmp = INW (devc->osdev, devc->base + 2) & ~CONC_DEVCTL_MICBIAS;
+ if (devc->micbias)
+ tmp |= CONC_DEVCTL_MICBIAS;
+ OUTW (devc->osdev, tmp, devc->base + 2);
+
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+apci_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ unsigned char tmp = 0x00;
+ apci_devc *devc = audio_engines[dev]->devc;
+ apci_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->atype)
+ {
+ /* Set physical address of the DMA buffer */
+ apci_writemem (devc, CONC_SYNCTL_PAGE, CONC_dSYNPADDR_OFF,
+ dmap->dmabuf_phys);
+
+ /* Set DAC1 rate */
+ tmp = INB (devc->osdev, devc->base + CONC_bMISCCTL_OFF) & ~0x30;
+ tmp |= portc->speedsel << 4;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bMISCCTL_OFF);
+
+ /* Set format */
+ tmp = INB (devc->osdev, devc->base + CONC_bSERFMT_OFF);
+ tmp &= ~(CONC_PCM_DAC1_STEREO | CONC_PCM_DAC1_16BIT);
+ if (portc->channels == 2)
+ tmp |= CONC_PCM_DAC1_STEREO;
+ if (portc->bits == 16)
+ {
+ tmp |= CONC_PCM_DAC1_16BIT;
+ }
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERFMT_OFF);
+
+ /* Set the frame count */
+ apci_writemem (devc, CONC_SYNCTL_PAGE, CONC_wSYNFC_OFF,
+ (dmap->bytes_in_use / 4) - 1);
+
+ /* Set # of samples between interrupts */
+ OUTW (devc->osdev,
+ (dmap->fragment_size / ((portc->channels * portc->bits) / 8)) - 1,
+ devc->base + CONC_wSYNIC_OFF);
+
+ /* Enable the wave interrupt */
+ tmp =
+ INB (devc->osdev, devc->base + CONC_bSERCTL_OFF) & ~CONC_SERCTL_SYNIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ tmp |= CONC_SERCTL_SYNIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ }
+ else
+ {
+ /* Set physical address of the DMA buffer */
+ apci_writemem (devc, CONC_DACCTL_PAGE, CONC_dDACPADDR_OFF,
+ dmap->dmabuf_phys);
+
+ /* Set DAC rate */
+ OUTW (devc->osdev, compute_dac2_rate (portc->speed),
+ devc->base + CONC_wDACRATE_OFF);
+
+ /* Set format */
+ tmp = INB (devc->osdev, devc->base + CONC_bSERFMT_OFF);
+ tmp &= ~(CONC_PCM_DAC2_STEREO | CONC_PCM_DAC2_16BIT);
+ if (portc->channels == 2)
+ tmp |= CONC_PCM_DAC2_STEREO;
+ if (portc->bits == 16)
+ {
+ tmp |= CONC_PCM_DAC2_16BIT;
+ OUTB (devc->osdev, 0x10, devc->base + CONC_bSKIPC_OFF); /* Skip count register */
+ }
+ else
+ {
+ OUTB (devc->osdev, 0x08, devc->base + CONC_bSKIPC_OFF); /* Skip count register */
+ }
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERFMT_OFF);
+
+ /* Set the frame count */
+ apci_writemem (devc, CONC_DACCTL_PAGE, CONC_wDACFC_OFF,
+ (dmap->bytes_in_use / 4) - 1);
+ apci_writemem (devc, CONC_DACCTL_PAGE, CONC_wDACFC_OFF,
+ (dmap->bytes_in_use / 4) - 1);
+
+ /* Set # of samples between interrupts */
+ OUTW (devc->osdev,
+ (dmap->fragment_size / ((portc->channels * portc->bits) / 8)) - 1,
+ devc->base + CONC_wDACIC_OFF);
+
+ /* Enable the wave interrupt */
+ tmp =
+ INB (devc->osdev, devc->base + CONC_bSERCTL_OFF) & ~CONC_SERCTL_DACIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ tmp |= CONC_SERCTL_DACIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ }
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+apci_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ apci_devc *devc = audio_engines[dev]->devc;
+ apci_portc *portc = audio_engines[dev]->portc;
+ int ptr = 0, port = 0, page = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ if (portc->atype)
+ {
+ port = CONC_wSYNFC_OFF;
+ page = CONC_SYNCTL_PAGE;
+ }
+ else
+ {
+ port = CONC_wDACFC_OFF;
+ page = CONC_DACCTL_PAGE;
+ }
+ }
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ port = CONC_wADCFC_OFF;
+ page = CONC_ADCCTL_PAGE;
+ }
+
+ ptr = apci_readmem (devc, page, port);
+ ptr >>= 16;
+ ptr <<= 2; /* count is in dwords */
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ptr;
+}
+
+
+static const audiodrv_t apci_audio_driver = {
+ apci_audio_open,
+ apci_audio_close,
+ apci_audio_output_block,
+ apci_audio_start_input,
+ apci_audio_ioctl,
+ apci_audio_prepare_for_input,
+ apci_audio_prepare_for_output,
+ apci_audio_reset,
+ NULL,
+ NULL,
+ apci_audio_reset_input,
+ apci_audio_reset_output,
+ apci_audio_trigger,
+ apci_audio_set_rate,
+ apci_audio_set_format,
+ apci_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* apci_alloc_buffer */
+ NULL, /* apci_free_buffer */
+ NULL,
+ NULL,
+ apci_get_buffer_pointer
+};
+
+/*ARGSUSED*/
+static int
+apci_midi_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ apci_devc *devc = (apci_devc *) midi_devs[dev]->devc;
+
+ if (devc->midi_opened)
+ {
+ return OSS_EBUSY;
+ }
+
+ devc->midi_input_intr = inputbyte;
+ devc->midi_opened = mode;
+
+ if (mode & OPEN_READ)
+ {
+ OUTB (devc->osdev, CONC_UART_RXINTEN, devc->base + CONC_bUARTCSTAT_OFF);
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+apci_midi_close (int dev, int mode)
+{
+ apci_devc *devc = (apci_devc *) midi_devs[dev]->devc;
+
+ OUTB (devc->osdev, 0x00, devc->base + CONC_bUARTCSTAT_OFF);
+ devc->midi_opened = 0;
+}
+
+static int
+apci_midi_out (int dev, unsigned char midi_byte)
+{
+ apci_devc *devc = (apci_devc *) midi_devs[dev]->devc;
+ int i;
+
+ unsigned char uart_stat =
+ INB (devc->osdev, devc->base + CONC_bUARTCSTAT_OFF);
+
+ bmast_off (devc);
+ for (i = 0; i < 30000; i++)
+ {
+ uart_stat = INB (devc->osdev, devc->base + CONC_bUARTCSTAT_OFF);
+ if (uart_stat & CONC_UART_TXRDY)
+ break;
+ }
+
+ if (!(uart_stat & CONC_UART_TXRDY))
+ {
+ bmast_on (devc);
+ return 0;
+ }
+
+
+ OUTB (devc->osdev, midi_byte, devc->base + CONC_bUARTDATA_OFF);
+ bmast_on (devc);
+
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+apci_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t apci_midi_driver = {
+ apci_midi_open,
+ apci_midi_close,
+ apci_midi_ioctl,
+ apci_midi_out,
+};
+
+static int
+init_apci (apci_devc * devc)
+{
+ int i, my_mixer, tmp;
+
+ devc->micbias = 1;
+ devc->micboost = 1;
+
+ OUTW (devc->osdev, compute_dac2_rate (8000),
+ devc->base + CONC_wDACRATE_OFF);
+
+ tmp =
+ INB (devc->osdev,
+ devc->base + CONC_bMISCCTL_OFF) & ~CONC_MISCTL_CCB_INTRM;
+ tmp |= CONC_MISCTL_MUTE | CONC_MISCTL_DAC1FREQ_2205;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bMISCCTL_OFF);
+
+ /* Turn on UART, CODEC and joystick. Disable SERR. */
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF) & ~CONC_DEVCTL_SERR_DISABLE; /* Yes */
+ tmp |= CONC_DEVCTL_UART_EN | CONC_DEVCTL_CODEC_EN | CONC_DEVCTL_JSTICK_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+
+ /* Disable NMI */
+ OUTB (devc->osdev, 0x00, devc->base + CONC_bNMIENA_OFF);
+ OUTW (devc->osdev, 0x0000, devc->base + CONC_wNMISTAT_OFF);
+
+ /* Init serial interface */
+ OUTB (devc->osdev, 0x00, devc->base + CONC_bSERCTL_OFF);
+ OUTB (devc->osdev, CONC_PCM_DAC1_STEREO | CONC_PCM_DAC1_16BIT,
+ devc->base + CONC_bSERFMT_OFF);
+
+ /* Unmute the codec */
+ tmp = INB (devc->osdev, devc->base + CONC_bMISCCTL_OFF) & ~CONC_MISCTL_MUTE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bMISCCTL_OFF);
+
+ /* Reset the UART */
+ OUTB (devc->osdev, 0x03, devc->base + CONC_bUARTCSTAT_OFF);
+ OUTB (devc->osdev, 0x00, devc->base + CONC_bUARTCSTAT_OFF);
+
+ /*
+ ******** Mixer initialization *********
+ */
+ oss_udelay (30);
+ ak_write (devc, 0x16, 0x03); /* Release reset */
+ oss_udelay (50);
+ ak_write (devc, 0x18, 0x00); /* Select ADC from input mixer */
+
+ for (i = 0; i <= 0x19; i++)
+ ak_write (devc, i, ak_reg_init[i]);
+
+ /* Enable microphone phantom power */
+ tmp = INW (devc->osdev, devc->base + 2) & ~CONC_DEVCTL_MICBIAS;
+ if (devc->micbias)
+ tmp |= CONC_DEVCTL_MICBIAS;
+ OUTW (devc->osdev, tmp, devc->base + 2);
+
+ if ((my_mixer = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "Creative AudioPCI",
+ &apci_mixer_driver,
+ sizeof (mixer_driver_t), devc)) >= 0)
+ {
+ char mxname[20];
+
+ sprintf (mxname, "AudioPCI");
+ devc->recdevs = 0;
+ apci_set_recmask (devc, SOUND_MASK_MIC);
+ devc->levels = load_mixer_volumes (mxname, default_mixer_levels, 1);
+ mixer_ext_set_init_fn (my_mixer, apci_mix_init, 30);
+ apci_mixer_reset (devc);
+ }
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+
+ int adev;
+ char tmp_name[100];
+ apci_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE;
+
+ if (i == 0)
+ {
+ strcpy (tmp_name, devc->chip_name);
+ caps |= ADEV_DUPLEX;
+ }
+ else
+ {
+ sprintf (tmp_name, "%s (playback only)", devc->chip_name);
+ caps |= ADEV_NOINPUT;
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &apci_audio_driver,
+ sizeof (audiodrv_t),
+ caps,
+ AFMT_U8 | AFMT_S16_LE, devc, -1)) < 0)
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ audio_engines[adev]->portc = portc;
+ if (i == 0)
+ {
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ }
+ else
+ {
+ audio_engines[adev]->min_rate = 5012;
+ audio_engines[adev]->max_rate = 44100;
+ }
+/* audio_engines[adev]->min_block = 1024; */
+ portc->open_mode = 0;
+ portc->audiodev = adev;
+ portc->atype = i;
+ audio_engines[adev]->mixer_dev = my_mixer;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+ }
+
+ if ((devc->midi_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "AUDIOPCI", "AudioPCI UART", &apci_midi_driver, sizeof (midi_driver_t),
+ 0, devc, devc->osdev)) < 0)
+ {
+ cmn_err (CE_WARN, "Couldn't install MIDI device\n");
+ return 0;
+ }
+
+ devc->midi_opened = 0;
+ return 1;
+}
+
+int
+oss_audiopci_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ int err;
+ apci_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered AudioPCI probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if ((vendor != ENSONIQ_VENDOR_ID && vendor != ENSONIQ_VENDOR_ID2) ||
+ device != ENSONIQ_AUDIOPCI)
+
+ return 0;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d). Can't continue\n",
+ pci_irq_line);
+ return 0;
+ }
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+ /* Remove I/O space marker in bit 0. */
+ devc->base &= ~3;
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ devc->chip_name = "Creative AudioPCI (ES1370)";
+
+ oss_register_device (osdev, devc->chip_name);
+
+
+ if ((err = oss_register_interrupts (osdev, 0, apciintr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't allocate IRQ%d, err=%d\n", pci_irq_line, err);
+ return 0;
+ }
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ return init_apci (devc); /* Detected */
+}
+
+
+int
+oss_audiopci_detach (oss_device_t * osdev)
+{
+ apci_devc *devc = (apci_devc *) osdev->devc;
+ int tmp;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF) &
+ ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_audiopci/oss_audiopci.man b/kernel/drv/oss_audiopci/oss_audiopci.man
new file mode 100644
index 0000000..d173821
--- /dev/null
+++ b/kernel/drv/oss_audiopci/oss_audiopci.man
@@ -0,0 +1,20 @@
+NAME
+oss_audiopci - Creative/Ensoniq Audiopci - ES1370 audio driver.
+
+DESCRIPTION
+Open Sound System driver for Creative AudioPCI ES1370 (also sold as SBPCI128)
+audio controllers
+
+ES1370 device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo playback/recording
+ o 8KHz to 48Khz sample rate.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_audiopci.conf Device configuration file
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_cmi878x/.devices b/kernel/drv/oss_cmi878x/.devices
new file mode 100644
index 0000000..c53ff1f
--- /dev/null
+++ b/kernel/drv/oss_cmi878x/.devices
@@ -0,0 +1,8 @@
+oss_cmi878x pci13f6,8788 CMedia CMI8788
+oss_cmi878x pci1043,8269 Asus Xonar D2
+oss_cmi878x pci1043,834f Asus Xonar D1
+oss_cmi878x pci1043,8275 Asus Xonar DX
+oss_cmi878x pci1043,82b7 Asus Xonar D2X
+oss_cmi878x pci1043,838e Asus Xonar DS
+oss_cmi878x pci1043,835c Asus Xonar Essence STX
+
diff --git a/kernel/drv/oss_cmi878x/.name b/kernel/drv/oss_cmi878x/.name
new file mode 100644
index 0000000..162dfb0
--- /dev/null
+++ b/kernel/drv/oss_cmi878x/.name
@@ -0,0 +1 @@
+CMedia CMI8788
diff --git a/kernel/drv/oss_cmi878x/oss_cmi878x.c b/kernel/drv/oss_cmi878x/oss_cmi878x.c
new file mode 100644
index 0000000..e19229c
--- /dev/null
+++ b/kernel/drv/oss_cmi878x/oss_cmi878x.c
@@ -0,0 +1,3104 @@
+/*
+ * Purpose: Driver for C-Media CMI8788 PCI audio controller.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_cmi878x_cfg.h"
+#include <oss_pci.h>
+#include <uart401.h>
+#include <ac97.h>
+
+#define CMEDIA_VENDOR_ID 0x13F6
+#define CMEDIA_CMI8788 0x8788
+
+/*
+ * CM8338 registers definition
+ */
+
+#define RECA_ADDR (devc->base+0x00)
+#define RECA_SIZE (devc->base+0x04)
+#define RECA_FRAG (devc->base+0x06)
+#define RECB_ADDR (devc->base+0x08)
+#define RECB_SIZE (devc->base+0x0C)
+#define RECB_FRAG (devc->base+0x0E)
+#define RECC_ADDR (devc->base+0x10)
+#define RECC_SIZE (devc->base+0x14)
+#define RECC_FRAG (devc->base+0x16)
+#define SPDIF_ADDR (devc->base+0x18)
+#define SPDIF_SIZE (devc->base+0x1C)
+#define SPDIF_FRAG (devc->base+0x1E)
+#define MULTICH_ADDR (devc->base+0x20)
+#define MULTICH_SIZE (devc->base+0x24)
+#define MULTICH_FRAG (devc->base+0x28)
+#define FPOUT_ADDR (devc->base+0x30)
+#define FPOUT_SIZE (devc->base+0x34)
+#define FPOUT_FRAG (devc->base+0x36)
+
+#define DMA_START (devc->base+0x40)
+#define CHAN_RESET (devc->base+0x42)
+#define MULTICH_MODE (devc->base+0x43)
+#define IRQ_MASK (devc->base+0x44)
+#define IRQ_STAT (devc->base+0x46)
+#define MISC_REG (devc->base+0x48)
+#define REC_FORMAT (devc->base+0x4A)
+#define PLAY_FORMAT (devc->base+0x4B)
+#define REC_MODE (devc->base+0x4C)
+#define FUNCTION (devc->base+0x50)
+
+#define I2S_MULTICH_FORMAT (devc->base+0x60)
+#define I2S_ADC1_FORMAT (devc->base+0x62)
+#define I2S_ADC2_FORMAT (devc->base+0x64)
+#define I2S_ADC3_FORMAT (devc->base+0x66)
+
+#define SPDIF_FUNC (devc->base+0x70)
+#define SPDIFOUT_CHAN_STAT (devc->base+0x74)
+#define SPDIFIN_CHAN_STAT (devc->base+0x78)
+
+#define I2C_ADDR (devc->base+0x90)
+#define I2C_MAP (devc->base+0x91)
+#define I2C_DATA (devc->base+0x92)
+#define I2C_CTRL (devc->base+0x94)
+
+#define SPI_CONTROL (devc->base+0x98)
+#define SPI_DATA (devc->base+0x99)
+
+#define MPU401_DATA (devc->base+0xA0)
+#define MPU401_COMMAND (devc->base+0xA1)
+#define MPU401_CONTROL (devc->base+0xA2)
+
+#define GPI_DATA (devc->base+0xA4)
+#define GPI_IRQ_MASK (devc->base+0xA5)
+#define GPIO_DATA (devc->base+0xA6)
+#define GPIO_CONTROL (devc->base+0xA8)
+#define GPIO_IRQ_MASK (devc->base+0xAA)
+#define DEVICE_SENSE (devc->base+0xAC)
+
+#define PLAY_ROUTING (devc->base+0xC0)
+#define REC_ROUTING (devc->base+0xC2)
+#define REC_MONITOR (devc->base+0xC3)
+#define MONITOR_ROUTING (devc->base+0xC4)
+
+#define AC97_CTRL (devc->base+0xD0)
+#define AC97_INTR_MASK (devc->base+0xD2)
+#define AC97_INTR_STAT (devc->base+0xD3)
+#define AC97_OUT_CHAN_CONFIG (devc->base+0xD4)
+#define AC97_IN_CHAN_CONFIG (devc->base+0xD8)
+#define AC97_CMD_DATA (devc->base+0xDC)
+
+#define CODEC_VERSION (devc->base+0xE4)
+#define CTRL_VERSION (devc->base+0xE6)
+
+/* Device IDs */
+#define ASUS_VENDOR_ID 0x1043
+#define SUBID_XONAR_D2 0x8269
+#define SUBID_XONAR_D2X 0x82b7
+#define SUBID_XONAR_D1 0x834f
+#define SUBID_XONAR_DX 0x8275
+#define SUBID_XONAR_STX 0x835c
+#define SUBID_XONAR_DS 0x838e
+#define SUBID_XONAR_ST 0x835d
+
+#define SUBID_GENERIC 0x0000
+
+/* Xonar specific */
+#define XONAR_DX_FRONTDAC 0x9e
+#define XONAR_DX_SURRDAC 0x30
+#define XONAR_STX_FRONTDAC 0x98
+#define XONAR_ST_FRONTDAC 0x98
+#define XONAR_ST_CLOCK 0x9c
+#define XONAR_DS_FRONTDAC 0x1
+#define XONAR_DS_SURRDAC 0x0
+#define XONAR_MCLOCK_256 0x10
+#define XONAR_MCLOCK_512 0x20
+
+/* defs for AKM 4396 DAC */
+#define AK4396_CTL1 0x00
+#define AK4396_CTL2 0x01
+#define AK4396_CTL3 0x02
+#define AK4396_LchATTCtl 0x03
+#define AK4396_RchATTCtl 0x04
+
+/* defs for CS4398 DAC */
+#define CS4398_CHIP_ID 0x01
+#define CS4398_MODE_CTRL 0x02
+#define CS4398_MIXING 0x03
+#define CS4398_MUTE_CTRL 0x04
+#define CS4398_VOLA 0x05
+#define CS4398_VOLB 0x06
+#define CS4398_RAMP_CTRL 0x07
+#define CS4398_MISC_CTRL 0x08
+#define CS4398_MISC2_CTRL 0x09
+
+#define CS4398_POWER_DOWN (1<<7) /* Obvious */
+#define CS4398_CPEN (1<<6) /* Control Port Enable */
+#define CS4398_FREEZE (1<<5) /* Freezes registers, unfreeze to
+ * accept changed registers */
+#define CS4398_MCLKDIV2 (1<<4) /* Divide MCLK by 2 */
+#define CS4398_MCLKDIV3 (1<<3) /* Divive MCLK by 3 */
+#define CS4398_I2S (1<<4) /* Set I2S mode */
+
+/* defs for CS4362A DAC */
+#define CS4362A_MODE1_CTRL 0x01
+#define CS4362A_MODE2_CTRL 0x02
+#define CS4362A_MODE3_CTRL 0x03
+#define CS4362A_FILTER_CTRL 0x04
+#define CS4362A_INVERT_CTRL 0x05
+#define CS4362A_MIX1_CTRL 0x06
+#define CS4362A_VOLA_1 0x07
+#define CS4362A_VOLB_1 0x08
+#define CS4362A_MIX2_CTRL 0x09
+#define CS4362A_VOLA_2 0x0A
+#define CS4362A_VOLB_2 0x0B
+#define CS4362A_MIX3_CTRL 0x0C
+#define CS4362A_VOLA_3 0x0D
+#define CS4362A_VOLB_3 0x0E
+#define CS4362A_CHIP_REV 0x12
+
+/* CS4362A Reg 01h */
+#define CS4362A_CPEN (1<<7)
+#define CS4362A_FREEZE (1<<6)
+#define CS4362A_MCLKDIV (1<<5)
+#define CS4362A_DAC3_ENABLE (1<<3)
+#define CS4362A_DAC2_ENABLE (1<<2)
+#define CS4362A_DAC1_ENABLE (1<<1)
+#define CS4362A_POWER_DOWN (1)
+
+/* CS4362A Reg 02h */
+#define CS4362A_DIF_LJUST 0x00
+#define CS4362A_DIF_I2S 0x10
+#define CS4362A_DIF_RJUST16 0x20
+#define CS4362A_DIF_RJUST24 0x30
+#define CS4362A_DIF_RJUST20 0x40
+#define CS4362A_DIF_RJUST18 0x50
+
+/* CS4362A Reg 03h */
+#define CS4362A_RAMP_IMMEDIATE 0x00
+#define CS4362A_RAMP_ZEROCROSS 0x40
+#define CS4362A_RAMP_SOFT 0x80
+#define CS4362A_RAMP_SOFTZERO 0xC0
+#define CS4362A_SINGLE_VOL 0x20
+#define CS4362A_RAMP_ERROR 0x10
+#define CS4362A_MUTEC_POL 0x08
+#define CS4362A_AUTOMUTE 0x04
+#define CS4362A_SIX_MUTE 0x00
+#define CS4362A_ONE_MUTE 0x01
+#define CS4362A_THREE_MUTE 0x03
+
+/* CS4362A Reg 04h */
+#define CS4362A_FILT_SEL 0x10
+#define CS4362A_DEM_NONE 0x00
+#define CS4362A_DEM_44KHZ 0x02
+#define CS4362A_DEM_48KHZ 0x04
+#define CS4362A_DEM_32KHZ 0x06
+#define CS4362A_RAMPDOWN 0x01
+
+/* CS4362A Reg 05h */
+#define CS4362A_INV_A3 (1<<4)
+#define CS4362A_INV_B3 (1<<5)
+#define CS4362A_INV_A2 (1<<2)
+#define CS4362A_INV_B2 (1<<3)
+#define CS4362A_INV_A1 (1)
+#define CS4362A_INV_B1 (1<<1)
+
+/* CS4362A Reg 06h, 09h, 0Ch */
+/* ATAPI crap, does anyone still use analog CD playback? */
+
+/* CS4362A Reg 07h, 08h, 0Ah, 0Bh, 0Dh, 0Eh */
+/* Volume registers */
+#define CS4362A_VOL_MUTE 0x80
+
+
+/* 0-100. Start at -96dB. */
+#define CS4398_VOL(x) \
+ ((x) == 0 ? 0xFF : (0xC0 - ((x)*192/100)))
+/* 0-100. Start at -96dB. Bit 7 is mute. */
+#define CS4362A_VOL(x) \
+ (char)((x) == 0 ? 0xFF : (0x60 - ((x)*96/100)))
+
+#define UNUSED_CMI9780_CONTROLS ( \
+ SOUND_MASK_VOLUME | \
+ SOUND_MASK_PCM | \
+ SOUND_MASK_REARVOL | \
+ SOUND_MASK_CENTERVOL | \
+ SOUND_MASK_SIDEVOL | \
+ SOUND_MASK_SPEAKER | \
+ SOUND_MASK_ALTPCM | \
+ SOUND_MASK_VIDEO | \
+ SOUND_MASK_DEPTH | \
+ SOUND_MASK_MONO | \
+ SOUND_MASK_PHONE \
+ )
+
+typedef struct cmi8788_portc
+{
+ int speed, bits, channels;
+ int open_mode;
+ int trigger_bits;
+ int audio_enabled;
+ int audiodev;
+ int dac_type;
+#define ADEV_MULTICH 0
+#define ADEV_FRONTPANEL 2
+#define ADEV_SPDIF 3
+ int adc_type;
+#define ADEV_I2SADC1 0
+#define ADEV_I2SADC2 1
+#define ADEV_I2SADC3 2
+ int play_dma_start, rec_dma_start;
+ int play_irq_mask, rec_irq_mask;
+ int play_chan_reset, rec_chan_reset;
+ int min_rate, max_rate, min_chan, max_chan;
+}
+cmi8788_portc;
+
+#define MAX_PORTC 4
+
+typedef struct cmi8788_devc
+{
+ oss_device_t *osdev;
+ oss_native_word base;
+ int fm_attached;
+ int irq;
+ int dma_len;
+ volatile unsigned char intr_mask;
+ int model;
+#define MDL_CMI8788 1
+ char *chip_name;
+
+ /* Audio parameters */
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+ oss_mutex_t dac_mutex;
+ int open_mode;
+ cmi8788_portc portc[MAX_PORTC];
+
+ /* Mixer */
+ ac97_devc ac97devc, fp_ac97devc;
+ int ac97_mixer_dev, fp_mixer_dev, cmi_mixer_dev;
+ int playvol[4];
+ int recvol;
+ int mute;
+
+ /* uart401 */
+ oss_midi_inputbyte_t midi_input_intr;
+ int midi_opened, midi_disabled;
+ volatile unsigned char input_byte;
+ int midi_dev;
+ int mpu_attached;
+}
+cmi8788_devc;
+
+static const char xd2_codec_map[4] = {
+ 0, 1, 2, 4
+ };
+
+static void cmi8788uartintr (cmi8788_devc * devc);
+static int reset_cmi8788uart (cmi8788_devc * devc);
+static void enter_uart_mode (cmi8788_devc * devc);
+
+static int
+ac97_read (void *devc_, int reg)
+{
+ cmi8788_devc *devc = devc_;
+ oss_native_word flags;
+ int val, data;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ val = 0L;
+ val |= reg << 16;
+ val |= 1 << 23; /*ac97 read the reg address */
+ val |= 0 << 24; /*codec 0 */
+ OUTL (devc->osdev, val, AC97_CMD_DATA);
+ oss_udelay (200);
+ data = INL (devc->osdev, AC97_CMD_DATA) & 0xFFFF;
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return data;
+}
+
+static int
+ac97_write (void *devc_, int reg, int data)
+{
+ cmi8788_devc *devc = devc_;
+ oss_native_word flags;
+ int val;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ val = 0L;
+ val |= data & 0xFFFF;
+ val |= reg << 16;
+ val |= 0 << 23; /*ac97 write operation */
+ val |= 0 << 24; /*on board codec */
+ OUTL (devc->osdev, val, AC97_CMD_DATA);
+ oss_udelay (200);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 1;
+}
+
+static int
+fp_ac97_read (void *devc_, int reg)
+{
+ cmi8788_devc *devc = devc_;
+ oss_native_word flags;
+ int data, val;
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ val = 0L;
+ val |= reg << 16;
+ val |= 1 << 23; /*ac97 read the reg address */
+ val |= 1 << 24; /*fp codec1 */
+ OUTL (devc->osdev, val, AC97_CMD_DATA);
+ oss_udelay (200);
+ data = INL (devc->osdev, AC97_CMD_DATA) & 0xFFFF;
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return data;
+}
+
+static int
+fp_ac97_write (void *devc_, int reg, int data)
+{
+ cmi8788_devc *devc = devc_;
+ oss_native_word flags;
+ int val;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ val = 0L;
+ val |= data & 0xFFFF;
+ val |= reg << 16;
+ val |= 0 << 23; /*ac97 write operation */
+ val |= 1 << 24; /*fp codec1 */
+ OUTL (devc->osdev, val, AC97_CMD_DATA);
+ oss_udelay (200);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 1;
+}
+
+static int
+spi_write (cmi8788_devc *devc, int codec_num, unsigned char reg, int val)
+{
+ oss_native_word flags;
+ unsigned int tmp;
+ int latch, shift, count;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ /* check if SPI is busy */
+ count = 10;
+ while ((INB(devc->osdev, SPI_CONTROL) & 0x1) && count-- > 0) {
+ oss_udelay(10);
+ }
+
+ if (devc->model == SUBID_XONAR_DS) {
+ shift = 9;
+ latch = 0;
+ }
+ else {
+ shift = 8;
+ latch = 0x80;
+ }
+
+ /* 2 byte data/reg info to be written */
+ tmp = val;
+ tmp |= (reg << shift);
+
+ /* write 2-byte data values */
+ OUTB (devc->osdev, tmp & 0xff, SPI_DATA + 0);
+ OUTB (devc->osdev, (tmp >> 8) & 0xff, SPI_DATA + 1);
+
+ /* Latch high, clock=160, Len=2byte, mode=write */
+ tmp = (INB (devc->osdev, SPI_CONTROL) & ~0x7E) | latch | 0x1;
+
+ /* now address which codec you want to send the data to */
+ tmp |= (codec_num << 4);
+
+ /* send the command to write the data */
+ OUTB (devc->osdev, tmp, SPI_CONTROL);
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 1;
+}
+
+static int
+i2c_write (cmi8788_devc *devc, unsigned char codec_num, unsigned char reg,
+ unsigned char data)
+{
+ oss_native_word flags;
+ int count = 50;
+
+ /* Wait for it to stop being busy */
+ MUTEX_ENTER(devc->dac_mutex, flags);
+ while((INW(devc->osdev, I2C_CTRL) & 0x1) && (count > 0))
+ {
+ oss_udelay(10);
+ count--;
+ }
+ if(count == 0)
+ {
+ cmn_err(CE_WARN, "Time out on Two-Wire interface (busy).");
+ MUTEX_EXIT(devc->dac_mutex, flags);
+ return OSS_EIO;
+ }
+ MUTEX_EXIT(devc->dac_mutex, flags);
+
+ MUTEX_ENTER_IRQDISABLE(devc->low_mutex, flags);
+ /* first write the Register Address into the MAP register */
+ OUTB (devc->osdev, reg, I2C_MAP);
+
+ /* now write the data */
+ OUTB (devc->osdev, data, I2C_DATA);
+
+ /* select the codec number to address */
+ OUTB (devc->osdev, codec_num, I2C_ADDR);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ oss_udelay(100);
+
+ return 1;
+
+}
+
+static void
+cs4398_init (cmi8788_devc *devc, int codec_addr)
+{
+
+ /* Fast Two-Wire. Reduces the wire ready time. */
+ OUTW(devc->osdev, 0x0100, I2C_CTRL);
+
+ /* Power down, enable control mode.
+ * i2c_write(devc, codec_addr, CS4398_MISC_CTRL,
+ * CS4398_CPEN | CS4398_POWER_DOWN);
+ * Left justified PCM (DAC and 8788 support I2S, but doesn't work.
+ * Setting it introduces clipping like hell).
+ */
+ i2c_write(devc, codec_addr, CS4398_MODE_CTRL, 0);
+ /* That's the DAC default, set anyway. */
+ i2c_write(devc, codec_addr, 3, 0x09);
+ /* PCM auto-mute. */
+ i2c_write(devc, codec_addr, 4, 0x82);
+ /* Vol A+B to -64dB. */
+ i2c_write(devc, codec_addr, 5, 0x80);
+ i2c_write(devc, codec_addr, 6, 0x80);
+ /* Soft-ramping. */
+ i2c_write(devc, codec_addr, 7, 0xF0);
+ /* Remove power down flag. */
+ i2c_write(devc, codec_addr, CS4398_MISC_CTRL, CS4398_CPEN);
+}
+
+static void
+cs4362a_init(cmi8788_devc *devc, int codec_addr)
+{
+
+ /* Fast Two-Wire. Reduces the wire ready time. */
+ OUTW(devc->osdev, 0x0100, I2C_CTRL);
+
+ /* Power down and enable control port. */
+ i2c_write(devc, codec_addr, CS4362A_MODE1_CTRL, CS4362A_CPEN | CS4362A_POWER_DOWN);
+ /* Left-justified PCM */
+ i2c_write(devc, codec_addr, CS4362A_MODE2_CTRL, CS4362A_DIF_LJUST);
+ /* Ramp & Automute, re-set DAC defaults. */
+ i2c_write(devc, codec_addr, CS4362A_MODE3_CTRL, 0x84);
+ /* Filter control, DAC defs. */
+ i2c_write(devc, codec_addr, CS4362A_FILTER_CTRL, 0);
+ /* Invert control, DAC defs. */
+ i2c_write(devc, codec_addr, CS4362A_INVERT_CTRL, 0);
+ /* Mixing control, DAC defs. */
+ i2c_write(devc, codec_addr, CS4362A_MIX1_CTRL, 0x24);
+ i2c_write(devc, codec_addr, CS4362A_MIX2_CTRL, 0x24);
+ i2c_write(devc, codec_addr, CS4362A_MIX3_CTRL, 0x24);
+ /* Volume to -64dB. */
+ i2c_write(devc, codec_addr, CS4362A_VOLA_1, 0x40);
+ i2c_write(devc, codec_addr, CS4362A_VOLB_1, 0x40);
+ i2c_write(devc, codec_addr, CS4362A_VOLA_2, 0x40);
+ i2c_write(devc, codec_addr, CS4362A_VOLB_2, 0x40);
+ i2c_write(devc, codec_addr, CS4362A_VOLA_3, 0x40);
+ i2c_write(devc, codec_addr, CS4362A_VOLB_3, 0x40);
+ /* Power up. */
+ i2c_write(devc, codec_addr, CS4362A_MODE1_CTRL, CS4362A_CPEN);
+}
+
+
+static void
+cs2000_init(cmi8788_devc *devc, int addr)
+{
+
+ /* Fast Two-Wire. Reduces the wire ready time. */
+ OUTW(devc->osdev, 0x0100, I2C_CTRL);
+
+ /* first set global config reg to freeze */
+ i2c_write (devc, addr, 0x5, 0x08);
+
+ /* set dev ctrl reg to output enabled (0) */
+ i2c_write (devc, addr, 0x2, 0);
+
+ /* set dev cfg1 reg to defaults and enable */
+ i2c_write (devc, addr, 0x3, 0x0 | (0 << 3) | 0x0 | 0x1);
+
+ /* set dev cfg2 reg to defaults and enable */
+ i2c_write (devc, addr, 0x4, (0 << 1) | 0x0);
+
+ /* set ratio0 MSB to 0 */
+ i2c_write (devc, addr, 0x06, 0x00);
+ /* set ratio0 MSB+8 to 0x10 */
+ i2c_write (devc, addr, 0x07, 0x10);
+ /* set ratio0 LSB+15 to 0 */
+ i2c_write (devc, addr, 0x08, 0x00);
+ /* set ratio0 LSB+7 to 0 */
+ i2c_write (devc, addr, 0x09, 0x00);
+
+ /* Func reg1 to ref clock div 1 */
+ i2c_write (devc, addr, 0x16, 0x10);
+
+ /* set func reg2 to 0 */
+ i2c_write (devc, addr, 0x17, 0);
+
+ /* set global cfg to run */
+ i2c_write (devc, addr, 0x05, 0x1);
+}
+
+
+static unsigned int
+mix_scale (int vol, int bits)
+{
+ vol = mix_cvt[vol];
+ return (vol * ((1 << bits) - 1) / 100);
+}
+
+
+static void
+cmi8788_generic_set_play_volume (cmi8788_devc *devc, int codec_id, int left, int right)
+
+{
+ spi_write (devc, codec_id, AK4396_LchATTCtl | 0x20, mix_scale(left, 8));
+ spi_write (devc, codec_id, AK4396_RchATTCtl | 0x20, mix_scale(right, 8));
+}
+
+static void
+xonar_d1_set_play_volume(cmi8788_devc * devc, int codec_id, int left, int right)
+{
+ switch(codec_id)
+ {
+ case 0:
+ i2c_write(devc, XONAR_DX_FRONTDAC, CS4398_VOLA, CS4398_VOL(left));
+ i2c_write(devc, XONAR_DX_FRONTDAC, CS4398_VOLB, CS4398_VOL(right));
+ break;
+ case 1:
+ i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_1, CS4362A_VOL(left));
+ i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_1, CS4362A_VOL(right));
+ break;
+ case 2:
+ i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_2, CS4362A_VOL(left));
+ i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_2, CS4362A_VOL(right));
+ break;
+ case 3:
+ i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLA_3, CS4362A_VOL(left));
+ i2c_write(devc, XONAR_DX_SURRDAC, CS4362A_VOLB_3, CS4362A_VOL(right));
+ break;
+ }
+}
+
+static void
+xonar_d2_set_play_volume(cmi8788_devc *devc, int codec_id, int left, int right)
+{
+ spi_write (devc, xd2_codec_map[codec_id], 16, mix_scale(left,8));
+ spi_write (devc, xd2_codec_map[codec_id], 17, mix_scale(right,8));
+}
+
+static void
+xonar_stx_set_play_volume(cmi8788_devc * devc, int codec_id, int left, int right)
+{
+ if (codec_id == 0)
+ {
+ i2c_write(devc, XONAR_STX_FRONTDAC, 16, mix_scale(left,8));
+ i2c_write(devc, XONAR_STX_FRONTDAC, 17, mix_scale(right,8));
+ }
+}
+
+static void
+xonar_st_set_play_volume(cmi8788_devc * devc, int codec_id, int left, int right)
+{
+ if (codec_id == 0)
+ {
+ i2c_write(devc, XONAR_ST_FRONTDAC, 16, mix_scale(left,8));
+ i2c_write(devc, XONAR_ST_FRONTDAC, 17, mix_scale(right,8));
+ }
+}
+
+static void
+xonar_ds_set_play_volume(cmi8788_devc * devc, int codec_id, int left, int right)
+{
+ switch (codec_id)
+ {
+ case 0: /* front */
+ spi_write (devc, XONAR_DS_FRONTDAC, 0, mix_scale(left,7)|0x80);
+ spi_write (devc, XONAR_DS_FRONTDAC, 1, mix_scale(right,7)|0x180);
+ spi_write (devc, XONAR_DS_FRONTDAC, 3, mix_scale(left,7)|0x80);
+ spi_write (devc, XONAR_DS_FRONTDAC, 4, mix_scale(right,7)|0x180);
+ break;
+
+ case 1: /* side */
+ spi_write (devc, XONAR_DS_SURRDAC, 0, mix_scale(left,7)|0x80);
+ spi_write (devc, XONAR_DS_SURRDAC, 1, mix_scale(right,7)|0x180);
+ break;
+ case 2: /* rear */
+ spi_write (devc, XONAR_DS_SURRDAC, 4, mix_scale(left,7)|0x80);
+ spi_write (devc, XONAR_DS_SURRDAC, 5, mix_scale(right,7)|0x180);
+ break;
+ case 3: /* center */
+ spi_write (devc, XONAR_DS_SURRDAC, 6, mix_scale(left,7)|0x80);
+ spi_write (devc, XONAR_DS_SURRDAC, 7, mix_scale(right,7)|0x180);
+ break;
+ }
+}
+
+static int
+cmi8788_set_rec_volume (cmi8788_devc * devc, int value)
+{
+ unsigned char left, right;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+
+ devc->recvol = left | (right << 8);
+
+ spi_write (devc, XONAR_DS_FRONTDAC, 0xe, mix_scale(left,8));
+ spi_write (devc, XONAR_DS_FRONTDAC, 0xf, mix_scale(right,8));
+
+ return devc->recvol;
+}
+
+
+
+static int
+cmi8788_set_play_volume (cmi8788_devc * devc, int codec_id, int value)
+{
+ int left, right;
+
+ left = (value & 0x00FF);
+ right = (value & 0xFF00) >> 8;
+
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+
+ devc->playvol[codec_id] = left | (right<<8);
+
+ switch(devc->model)
+ {
+ case SUBID_XONAR_D1:
+ case SUBID_XONAR_DX:
+ xonar_d1_set_play_volume(devc, codec_id, left, right);
+ break;
+ case SUBID_XONAR_D2:
+ case SUBID_XONAR_D2X:
+ xonar_d2_set_play_volume(devc, codec_id, left, right);
+ break;
+ case SUBID_XONAR_STX:
+ xonar_stx_set_play_volume(devc, codec_id, left, right);
+ break;
+ case SUBID_XONAR_ST:
+ xonar_st_set_play_volume(devc, codec_id, left, right);
+ break;
+ case SUBID_XONAR_DS:
+ xonar_ds_set_play_volume(devc, codec_id, left, right);
+ break;
+ default:
+ cmi8788_generic_set_play_volume (devc, codec_id, left, right);
+ break;
+ }
+ return devc->playvol[codec_id];
+}
+
+static int
+cmi8788intr (oss_device_t * osdev)
+{
+ cmi8788_devc *devc = (cmi8788_devc *) osdev->devc;
+ unsigned int intstat;
+ int i;
+ int serviced = 0;
+
+
+ intstat = INW (devc->osdev, IRQ_STAT);
+ if (intstat != 0)
+ serviced = 1;
+ else
+ return 0;
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ cmi8788_portc *portc = &devc->portc[i];
+
+ /* Handle Playback Ints */
+ if ((intstat & portc->play_irq_mask)
+ && (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+
+ /* Acknowledge the interrupt by disabling and enabling the irq */
+ OUTW (devc->osdev,
+ INW (devc->osdev, IRQ_MASK) & ~portc->play_irq_mask,
+ IRQ_MASK);
+ OUTW (devc->osdev,
+ INW (devc->osdev, IRQ_MASK) | portc->play_irq_mask, IRQ_MASK);
+
+ /* process buffer */
+ oss_audio_outputintr (portc->audiodev, 0);
+ }
+
+ /* Handle Record Ints */
+ if ((intstat & portc->rec_irq_mask)
+ && (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ /* disable the interrupt first */
+ OUTW (devc->osdev,
+ INW (devc->osdev, IRQ_MASK) & ~portc->rec_irq_mask, IRQ_MASK);
+ /* enable the interrupt mask */
+ OUTW (devc->osdev,
+ INW (devc->osdev, IRQ_MASK) | portc->rec_irq_mask, IRQ_MASK);
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+
+ }
+
+ /* MPU interrupt */
+ if (intstat & 0x1000)
+ {
+ cmi8788uartintr (devc);
+ }
+
+ return serviced;
+}
+
+static int
+cmi8788_audio_set_rate (int dev, int arg)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (arg > portc->max_rate)
+ arg = portc->max_rate;
+ if (arg < portc->min_rate)
+ arg = portc->min_rate;
+
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+cmi8788_audio_set_channels (int dev, short arg)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+
+ if (audio_engines[dev]->flags & ADEV_STEREOONLY)
+ arg = 2;
+
+ if (arg == 1)
+ arg = 2;
+
+ if (arg>8)
+ arg=8;
+ if ((arg != 2) && (arg != 4) && (arg != 6) && (arg != 8))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+cmi8788_audio_set_format (int dev, unsigned int arg)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (audio_engines[dev]->flags & ADEV_16BITONLY)
+ arg = AFMT_S16_LE;
+
+ if (!(arg & (AFMT_S16_LE | AFMT_AC3 | AFMT_S32_LE)))
+ return portc->bits;
+ portc->bits = arg;
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+cmi8788_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void cmi8788_audio_trigger (int dev, int state);
+
+static void
+cmi8788_audio_reset (int dev)
+{
+ cmi8788_audio_trigger (dev, 0);
+}
+
+static void
+cmi8788_audio_reset_input (int dev)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+ cmi8788_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+cmi8788_audio_reset_output (int dev)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+ cmi8788_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+cmi8788_audio_open (int dev, int mode, int open_flags)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+ cmi8788_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode |= mode;
+
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+cmi8788_audio_close (int dev, int mode)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+ cmi8788_devc *devc = audio_engines[dev]->devc;
+
+ cmi8788_audio_reset (dev);
+ portc->open_mode = 0;
+ devc->open_mode &= ~mode;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+cmi8788_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+cmi8788_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+cmi8788_audio_trigger (int dev, int state)
+{
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+ cmi8788_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ /* Enable Interrupt */
+ OUTW (devc->osdev,
+ INW (devc->osdev, IRQ_MASK) | portc->play_irq_mask,
+ IRQ_MASK);
+ /* enable the dma */
+ OUTW (devc->osdev,
+ INW (devc->osdev, DMA_START) | portc->play_dma_start,
+ DMA_START);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ /* disable dma */
+ OUTW (devc->osdev,
+ INW (devc->osdev, DMA_START) & ~portc->play_dma_start,
+ DMA_START);
+ /* Disable Interrupt */
+ OUTW (devc->osdev,
+ INW (devc->osdev, IRQ_MASK) & ~portc->play_irq_mask,
+ IRQ_MASK);
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ /* Enable Interrupt */
+ OUTW (devc->osdev,
+ INW (devc->osdev, IRQ_MASK) | portc->rec_irq_mask,
+ IRQ_MASK);
+
+ /* enable the channel */
+ OUTW (devc->osdev,
+ INW (devc->osdev, DMA_START) | portc->rec_dma_start,
+ DMA_START);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ /* disable channel */
+ OUTW (devc->osdev,
+ INW (devc->osdev, DMA_START) & ~portc->rec_dma_start,
+ DMA_START);
+
+ /* Disable Interrupt */
+ OUTW (devc->osdev,
+ INW (devc->osdev, IRQ_MASK) & ~portc->rec_irq_mask,
+ IRQ_MASK);
+
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+cmi8788_reset_channel (cmi8788_devc * devc, cmi8788_portc * portc,
+ int direction)
+{
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ /* reset the channel */
+ OUTB (devc->osdev,
+ INB (devc->osdev, CHAN_RESET) | portc->play_chan_reset,
+ CHAN_RESET);
+ oss_udelay (10);
+ OUTB (devc->osdev,
+ INB (devc->osdev, CHAN_RESET) & ~portc->play_chan_reset,
+ CHAN_RESET);
+ }
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ /* reset the channel */
+ OUTB (devc->osdev,
+ INB (devc->osdev, CHAN_RESET) | portc->rec_chan_reset,
+ CHAN_RESET);
+ oss_udelay (10);
+ OUTB (devc->osdev,
+ INB (devc->osdev, CHAN_RESET) & ~portc->rec_chan_reset,
+ CHAN_RESET);
+ }
+
+}
+
+static int
+i2s_calc_rate (int rate)
+{
+ int i2s_rate;
+
+ switch (rate)
+ {
+ case 32000:
+ i2s_rate = 0;
+ break;
+ case 44100:
+ i2s_rate = 1;
+ break;
+ case 48000:
+ i2s_rate = 2;
+ break;
+ case 64000:
+ i2s_rate = 3;
+ break;
+ case 88200:
+ i2s_rate = 4;
+ break;
+ case 96000:
+ i2s_rate = 5;
+ break;
+ case 176400:
+ i2s_rate = 6;
+ break;
+ case 192000:
+ i2s_rate = 7;
+ break;
+ default:
+ i2s_rate = 2;
+ break;
+ }
+
+ return i2s_rate;
+}
+
+int
+i2s_calc_bits (int bits)
+{
+ int i2s_bits;
+
+ switch (bits)
+ {
+#if 0
+ case AFMT_S24_LE:
+ i2s_bits = 0x80;
+ break;
+#endif
+ case AFMT_S32_LE:
+ i2s_bits = 0xC0;
+ break;
+ default: /* AFMT_S16_LE */
+ i2s_bits = 0x00;
+ break;
+ }
+
+ return i2s_bits;
+}
+
+/*ARGSUSED*/
+static int
+cmi8788_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ cmi8788_devc *devc = audio_engines[dev]->devc;
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_in;
+ oss_native_word flags;
+ int channels, bits, i2s_bits, i2s_rate;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ switch (portc->adc_type)
+ {
+ case ADEV_I2SADC1:
+ {
+ portc->rec_dma_start = 0x1;
+ portc->rec_irq_mask = 0x1;
+ portc->rec_chan_reset = 0x1;
+ cmi8788_reset_channel (devc, portc, PCM_ENABLE_INPUT);
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, RECA_ADDR);
+ OUTW (devc->osdev, dmap->bytes_in_use / 4 - 1, RECA_SIZE);
+ OUTW (devc->osdev, dmap->fragment_size / 4 - 1, RECA_FRAG);
+
+ switch (portc->channels)
+ {
+ case 4:
+ channels = 0x1;
+ break;
+ case 6:
+ channels = 0x2;
+ break;
+ case 8:
+ channels = 0x4;
+ break;
+ default:
+ channels = 0x0; /* Stereo */
+ break;
+ }
+
+ OUTB (devc->osdev, (INB (devc->osdev, REC_MODE) & ~0x3) | channels,
+ REC_MODE);
+
+ switch (portc->bits)
+ {
+#if 0
+ /* The 24 bit format supported by cmi8788 is not AFMT_S24_LE */
+ case AFMT_S24_LE:
+ bits = 0x1;
+ break;
+#endif
+ case AFMT_S32_LE:
+ bits = 0x2;
+ break;
+ default: /* AFMT_S16_LE */
+ bits = 0x0;
+ break;
+ }
+ OUTB (devc->osdev, (INB (devc->osdev, REC_FORMAT) & ~0x3) | bits,
+ REC_FORMAT);
+
+ /* set up the i2s bits as well */
+ i2s_bits = i2s_calc_bits (portc->bits);
+ OUTB (devc->osdev,
+ (INB (devc->osdev, I2S_ADC1_FORMAT) & ~0xC0) | i2s_bits,
+ I2S_ADC1_FORMAT);
+
+ /* setup the i2s speed */
+ i2s_rate = i2s_calc_rate (portc->speed);
+ OUTB (devc->osdev,
+ (INB (devc->osdev, I2S_ADC1_FORMAT) & ~0x7) | i2s_rate,
+ I2S_ADC1_FORMAT);
+
+ break;
+ }
+
+ case ADEV_I2SADC2:
+ {
+ portc->rec_dma_start = 0x2;
+ portc->rec_irq_mask = 0x2;
+ portc->rec_chan_reset = 0x2;
+ cmi8788_reset_channel (devc, portc, PCM_ENABLE_INPUT);
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, RECB_ADDR);
+ OUTW (devc->osdev, dmap->bytes_in_use / 4 - 1, RECB_SIZE);
+ OUTW (devc->osdev, dmap->fragment_size / 4 - 1, RECB_FRAG);
+
+ switch (portc->bits)
+ {
+#if 0
+ case AFMT_S24_LE:
+ bits = 0x04;
+ break;
+#endif
+ case AFMT_S32_LE:
+ bits = 0x08;
+ break;
+ default: /* AFMT_S16_LE */
+ bits = 0x0;
+ break;
+ }
+
+ OUTB (devc->osdev, (INB (devc->osdev, REC_FORMAT) & ~0x0C) | bits,
+ REC_FORMAT);
+
+ /* setup i2s bits */
+ i2s_bits = i2s_calc_bits (portc->bits);
+ OUTB (devc->osdev,
+ (INB (devc->osdev, I2S_ADC2_FORMAT) & ~0xC0) | i2s_bits,
+ I2S_ADC2_FORMAT);
+
+ /* setup speed */
+ i2s_rate = i2s_calc_rate (portc->speed);
+ OUTB (devc->osdev,
+ (INB (devc->osdev, I2S_ADC2_FORMAT) & ~0x7) | i2s_rate,
+ I2S_ADC2_FORMAT);
+
+ break;
+ }
+
+ case ADEV_I2SADC3:
+ {
+ portc->rec_dma_start = 0x4;
+ portc->rec_irq_mask = 0x4;
+ portc->rec_chan_reset = 0x4;
+ cmi8788_reset_channel (devc, portc, PCM_ENABLE_INPUT);
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, RECC_ADDR);
+ OUTW (devc->osdev, dmap->bytes_in_use / 4 - 1, RECC_SIZE);
+ OUTW (devc->osdev, dmap->fragment_size / 4 - 1, RECC_FRAG);
+
+ switch (portc->bits)
+ {
+#if 0
+ case AFMT_S24_LE:
+ bits = 0x10;
+ break;
+#endif
+ case AFMT_S32_LE:
+ bits = 0x20;
+ break;
+ default: /* AFMT_S16_LE */
+ bits = 0x0;
+ break;
+ }
+
+ OUTB (devc->osdev, (INB (devc->osdev, REC_FORMAT) & ~0x30) | bits,
+ REC_FORMAT);
+
+ /* setup i2s bits */
+ i2s_bits = i2s_calc_bits (portc->bits);
+ OUTB (devc->osdev,
+ (INB (devc->osdev, I2S_ADC3_FORMAT) & ~0xC0) | i2s_bits,
+ I2S_ADC3_FORMAT);
+
+ /* setup speed */
+ i2s_rate = i2s_calc_rate (portc->speed);
+ OUTB (devc->osdev,
+ (INB (devc->osdev, I2S_ADC3_FORMAT) & ~0x7) | i2s_rate,
+ I2S_ADC3_FORMAT);
+ break;
+ }
+ }
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+cmi8788_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ cmi8788_devc *devc = audio_engines[dev]->devc;
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_out;
+ oss_native_word flags;
+ int i2s_rate, rate, spdif_rate, bits = 0, i2s_bits, channels = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ switch (portc->dac_type)
+ {
+ case ADEV_MULTICH:
+ {
+ portc->play_dma_start = 0x10;
+ portc->play_irq_mask = 0x10;
+ portc->play_chan_reset = 0x10;
+ cmi8788_reset_channel (devc, portc, PCM_ENABLE_OUTPUT);
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, MULTICH_ADDR);
+ OUTL (devc->osdev, dmap->bytes_in_use / 4 - 1, MULTICH_SIZE);
+ OUTL (devc->osdev, dmap->fragment_size / 4 - 1, MULTICH_FRAG);
+
+ switch (portc->channels)
+ {
+ case 2:
+ channels = 0;
+ break;
+ case 4:
+ channels = 1;
+ break;
+ case 6:
+ channels = 2;
+ break;
+ case 8:
+ channels = 3;
+ break;
+ }
+
+ OUTB (devc->osdev,
+ (INB (devc->osdev, MULTICH_MODE) & ~0x3) | channels,
+ MULTICH_MODE);
+
+ /* setup bits per sample */
+ switch (portc->bits)
+ {
+#if 0
+ case AFMT_S24_LE:
+ bits = 4;
+ break;
+#endif
+ case AFMT_S32_LE:
+ bits = 8;
+ break;
+
+ default: /* AFMT_S16_LE */
+ bits = 0;
+ break;
+ }
+
+ /* set the format bits in play format register */
+ OUTB (devc->osdev, (INB (devc->osdev, PLAY_FORMAT) & ~0xC) | bits,
+ PLAY_FORMAT);
+
+ /* setup the i2s bits in the i2s register */
+ i2s_bits = i2s_calc_bits (portc->bits);
+ OUTB (devc->osdev,
+ (INB (devc->osdev, I2S_MULTICH_FORMAT) & ~0xC0) | i2s_bits,
+ I2S_MULTICH_FORMAT);
+
+ /* setup speed */
+ i2s_rate = i2s_calc_rate (portc->speed);
+ OUTB (devc->osdev,
+ (INB (devc->osdev, I2S_MULTICH_FORMAT) & ~0x7) | i2s_rate,
+ I2S_MULTICH_FORMAT);
+
+ break;
+ }
+
+ case ADEV_FRONTPANEL:
+ {
+ portc->play_dma_start = 0x20;
+ portc->play_irq_mask = 0x20;
+ portc->play_chan_reset = 0x20;
+ cmi8788_reset_channel (devc, portc, PCM_ENABLE_OUTPUT);
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, FPOUT_ADDR);
+ OUTW (devc->osdev, dmap->bytes_in_use / 4 - 1, FPOUT_SIZE);
+ OUTW (devc->osdev, dmap->fragment_size / 4 - 1, FPOUT_FRAG);
+ ac97_playrate (&devc->fp_ac97devc, portc->speed);
+ ac97_spdif_setup (devc->fp_mixer_dev, portc->speed, portc->bits);
+
+ break;
+ }
+
+ case ADEV_SPDIF:
+ {
+ portc->play_dma_start = 0x08;
+ portc->play_irq_mask = 0x08;
+ portc->play_chan_reset = 0x08;
+ cmi8788_reset_channel (devc, portc, PCM_ENABLE_OUTPUT);
+
+ /* STOP SPDIF Out */
+ OUTL (devc->osdev, (INL (devc->osdev, SPDIF_FUNC) & ~0x00000002),
+ SPDIF_FUNC);
+
+ /* setup AC3 for 16bit 48Khz, Non-Audio */
+ if (portc->bits == AFMT_AC3)
+ {
+ portc->bits = 16;
+ portc->channels = 2;
+ portc->speed = 48000;
+
+ /* set the PCM/Data bit to Non-Audio */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0x0002) | 0x0002,
+ SPDIFOUT_CHAN_STAT);
+ }
+ else
+ OUTL (devc->osdev,
+ INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0x0002,
+ SPDIFOUT_CHAN_STAT);
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, SPDIF_ADDR);
+ OUTW (devc->osdev, dmap->bytes_in_use / 4 - 1, SPDIF_SIZE);
+ OUTW (devc->osdev, dmap->fragment_size / 4 - 1, SPDIF_FRAG);
+
+ /* setup number of bits/sample */
+ switch (portc->bits)
+ {
+ case 16:
+ bits = 0;
+ break;
+ case 24:
+ bits = 1;
+ break;
+ case 32:
+ bits = 2;
+ break;
+ }
+
+ OUTB (devc->osdev, (INB (devc->osdev, PLAY_FORMAT) & ~0x3) | bits,
+ PLAY_FORMAT);
+
+ /* setup sampling rate */
+ switch (portc->speed)
+ {
+ case 32000:
+ rate = 0;
+ spdif_rate = 0x3;
+ break;
+ case 44100:
+ rate = 1;
+ spdif_rate = 0x0;
+ break;
+ case 48000:
+ rate = 2;
+ spdif_rate = 0x2;
+ break;
+ case 64000:
+ rate = 3;
+ spdif_rate = 0xb;
+ break;
+ case 88200:
+ rate = 4;
+ spdif_rate = 0x8;
+ break;
+ case 96000:
+ rate = 5;
+ spdif_rate = 0xa;
+ break;
+ case 176400:
+ rate = 6;
+ spdif_rate = 0xc;
+ break;
+ case 192000:
+ rate = 7;
+ spdif_rate = 0xe;
+ break;
+ default:
+ rate = 2; /* 48000 */
+ spdif_rate = 0x2;
+ break;
+ }
+
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIF_FUNC) & ~0x0f000000) | rate << 24,
+ SPDIF_FUNC);
+
+ /* also program the Channel status */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0xF000) | spdif_rate
+ << 12, SPDIFOUT_CHAN_STAT);
+
+ /* Enable SPDIF Out */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIF_FUNC) & ~0x00000002) | 0x2,
+ SPDIF_FUNC);
+
+ break;
+ }
+ }
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+cmi8788_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ cmi8788_devc *devc = audio_engines[dev]->devc;
+ cmi8788_portc *portc = audio_engines[dev]->portc;
+ unsigned int ptr = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ switch (portc->adc_type)
+ {
+ case ADEV_I2SADC1:
+ ptr = INL (devc->osdev, RECA_ADDR);
+ break;
+ case ADEV_I2SADC2:
+ ptr = INL (devc->osdev, RECB_ADDR);
+ break;
+ case ADEV_I2SADC3:
+ ptr = INL (devc->osdev, RECC_ADDR);
+ break;
+ }
+ }
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ switch (portc->dac_type)
+ {
+ case ADEV_MULTICH:
+ ptr = INL (devc->osdev, MULTICH_ADDR);
+ break;
+ case ADEV_FRONTPANEL:
+ ptr = INL (devc->osdev, FPOUT_ADDR);
+ break;
+ case ADEV_SPDIF:
+ ptr = INL (devc->osdev, SPDIF_ADDR);
+ break;
+ }
+ }
+
+ ptr -= dmap->dmabuf_phys;
+ ptr %= dmap->bytes_in_use;
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ptr;
+}
+
+
+static audiodrv_t cmi8788_audio_driver = {
+ cmi8788_audio_open,
+ cmi8788_audio_close,
+ cmi8788_audio_output_block,
+ cmi8788_audio_start_input,
+ cmi8788_audio_ioctl,
+ cmi8788_audio_prepare_for_input,
+ cmi8788_audio_prepare_for_output,
+ cmi8788_audio_reset,
+ NULL,
+ NULL,
+ cmi8788_audio_reset_input,
+ cmi8788_audio_reset_output,
+ cmi8788_audio_trigger,
+ cmi8788_audio_set_rate,
+ cmi8788_audio_set_format,
+ cmi8788_audio_set_channels,
+ NULL,
+ NULL,
+ NULL, /* cmi8788_check_input, */
+ NULL, /* cmi8788_check_output, */
+ NULL, /* cmi8788_alloc_buffer */
+ NULL, /* cmi8788_free_buffer */
+ NULL,
+ NULL,
+ cmi8788_get_buffer_pointer
+};
+
+#define input_avail(devc) (!(cmi8788uart_status(devc)&INPUT_AVAIL))
+#define output_ready(devc) (!(cmi8788uart_status(devc)&OUTPUT_READY))
+
+static __inline__ int
+cmi8788uart_status (cmi8788_devc * devc)
+{
+ return INB (devc->osdev, MPU401_COMMAND);
+}
+
+static void
+cmi8788uart_cmd (cmi8788_devc * devc, unsigned char cmd)
+{
+ OUTB (devc->osdev, cmd, MPU401_COMMAND);
+}
+
+static __inline__ int
+cmi8788uart_read (cmi8788_devc * devc)
+{
+ return INB (devc->osdev, MPU401_DATA);
+}
+
+static __inline__ void
+cmi8788uart_write (cmi8788_devc * devc, unsigned char byte)
+{
+ OUTB (devc->osdev, byte, MPU401_DATA);
+}
+
+#define OUTPUT_READY 0x40
+#define INPUT_AVAIL 0x80
+#define MPU_ACK 0xFE
+#define MPU_RESET 0xFF
+#define UART_MODE_ON 0x3F
+
+
+static void
+cmi8788uart_input_loop (cmi8788_devc * devc)
+{
+ while (input_avail (devc))
+ {
+ unsigned char c = cmi8788uart_read (devc);
+
+ if (c == MPU_ACK)
+ devc->input_byte = c;
+ else if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr (devc->midi_dev, c);
+ }
+}
+
+static void
+cmi8788uartintr (cmi8788_devc * devc)
+{
+ cmi8788uart_input_loop (devc);
+}
+
+/*ARGSUSED*/
+static int
+cmi8788uart_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ cmi8788_devc *devc = (cmi8788_devc *) midi_devs[dev]->devc;
+
+ if (devc->midi_opened)
+ {
+ return OSS_EBUSY;
+ }
+
+ while (input_avail (devc))
+ cmi8788uart_read (devc);
+
+ devc->midi_input_intr = inputbyte;
+ devc->midi_opened = mode;
+ enter_uart_mode (devc);
+ devc->midi_disabled = 0;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+cmi8788uart_close (int dev, int mode)
+{
+ cmi8788_devc *devc = (cmi8788_devc *) midi_devs[dev]->devc;
+ reset_cmi8788uart (devc);
+ oss_udelay (10);
+ enter_uart_mode (devc);
+ reset_cmi8788uart (devc);
+ devc->midi_opened = 0;
+}
+
+
+static int
+cmi8788uart_out (int dev, unsigned char midi_byte)
+{
+ int timeout;
+ cmi8788_devc *devc = (cmi8788_devc *) midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ /*
+ * Test for input since pending input seems to block the output.
+ */
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (input_avail (devc))
+ cmi8788uart_input_loop (devc);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ /*
+ * Sometimes it takes about 130000 loops before the output becomes ready
+ * (After reset). Normally it takes just about 10 loops.
+ */
+
+ for (timeout = 130000; timeout > 0 && !output_ready (devc); timeout--);
+
+ if (!output_ready (devc))
+ {
+ cmn_err (CE_WARN, "UART timeout - Device not responding\n");
+ devc->midi_disabled = 1;
+ reset_cmi8788uart (devc);
+ enter_uart_mode (devc);
+ return 1;
+ }
+
+ cmi8788uart_write (devc, midi_byte);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+cmi8788uart_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t cmi8788_midi_driver = {
+ cmi8788uart_open,
+ cmi8788uart_close,
+ cmi8788uart_ioctl,
+ cmi8788uart_out,
+};
+
+static void
+enter_uart_mode (cmi8788_devc * devc)
+{
+ int ok, timeout;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+
+ devc->input_byte = 0;
+ cmi8788uart_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 (cmi8788uart_read (devc) == MPU_ACK)
+ ok = 1;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+
+void
+attach_cmi8788uart (cmi8788_devc * devc)
+{
+ enter_uart_mode (devc);
+ devc->midi_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "CMI8788", "CMI8788 UART", &cmi8788_midi_driver, sizeof (midi_driver_t),
+ 0, devc, devc->osdev);
+ devc->midi_opened = 0;
+}
+
+static int
+reset_cmi8788uart (cmi8788_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;
+ cmi8788uart_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 (cmi8788uart_read (devc) == MPU_ACK)
+ ok = 1;
+
+ }
+
+
+
+ if (ok)
+ cmi8788uart_input_loop (devc); /*
+ * Flush input before enabling interrupts
+ */
+
+ return ok;
+}
+
+
+int
+probe_cmi8788uart (cmi8788_devc * devc)
+{
+ int ok = 0;
+ oss_native_word flags;
+
+ DDB (cmn_err (CE_CONT, "Entered probe_cmi8788uart\n"));
+
+ devc->midi_input_intr = NULL;
+ devc->midi_opened = 0;
+ devc->input_byte = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ ok = reset_cmi8788uart (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (ok)
+ {
+ DDB (cmn_err (CE_CONT, "Reset UART401 OK\n"));
+ }
+ else
+ {
+ DDB (cmn_err
+ (CE_CONT, "Reset UART401 failed (no hardware present?).\n"));
+ DDB (cmn_err
+ (CE_CONT, "mpu401 status %02x\n", cmi8788uart_status (devc)));
+ }
+
+ DDB (cmn_err (CE_CONT, "cmi8788uart detected OK\n"));
+ return ok;
+}
+
+void
+unload_cmi8788uart (cmi8788_devc * devc)
+{
+ reset_cmi8788uart (devc);
+}
+
+
+static void
+attach_mpu (cmi8788_devc * devc)
+{
+ devc->mpu_attached = 1;
+ attach_cmi8788uart (devc);
+}
+
+/*ARGSUSED*/
+static int
+cmi8788_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ cmi8788_devc *devc = mixer_devs[dev]->devc;
+
+ if (((cmd >> 8) & 0xff) == 'M')
+ {
+ int val;
+
+ if (IOC_IS_OUTPUT (cmd))
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ return *arg = 0;
+ break;
+
+ case SOUND_MIXER_PCM:
+ val = *arg;
+ return *arg = cmi8788_set_play_volume (devc, 0, val);
+ break;
+
+ case SOUND_MIXER_REARVOL:
+ val = *arg;
+ return *arg = cmi8788_set_play_volume (devc, 1, val);
+ break;
+
+ case SOUND_MIXER_CENTERVOL:
+ val = *arg;
+ return *arg = cmi8788_set_play_volume (devc, 2, val);
+ break;
+
+ case SOUND_MIXER_SIDEVOL:
+ val = *arg;
+ return *arg = cmi8788_set_play_volume (devc, 3, val);
+ break;
+
+ case SOUND_MIXER_RECLEV:
+ val = *arg;
+ return *arg = cmi8788_set_rec_volume (devc, val);
+ break;
+
+ default:
+ val = *arg;
+ return *arg = 0;
+ break;
+ }
+ else
+ switch (cmd & 0xff) /* Return Parameter */
+ {
+ case SOUND_MIXER_RECSRC:
+ return *arg = 0;
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ if ((devc->model == SUBID_XONAR_STX) || (devc->model == SUBID_XONAR_ST))
+ *arg = SOUND_MASK_PCM;
+ else
+ *arg = SOUND_MASK_PCM | SOUND_MASK_REARVOL |
+ SOUND_MASK_CENTERVOL | SOUND_MASK_SIDEVOL;
+
+ if (devc->model == SUBID_XONAR_DS)
+ *arg |= SOUND_MASK_RECLEV;
+
+ return *arg;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ if ((devc->model == SUBID_XONAR_STX) || (devc->model == SUBID_XONAR_ST))
+ *arg = SOUND_MASK_PCM;
+ else
+ *arg = SOUND_MASK_PCM | SOUND_MASK_REARVOL |
+ SOUND_MASK_CENTERVOL | SOUND_MASK_SIDEVOL;
+
+ if (devc->model == SUBID_XONAR_DS)
+ *arg |= SOUND_MASK_RECLEV;
+
+ return *arg;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ return *arg = SOUND_CAP_EXCL_INPUT;
+ break;
+
+ case SOUND_MIXER_PCM:
+ return *arg = devc->playvol[0];
+ break;
+
+ case SOUND_MIXER_REARVOL:
+ return *arg = devc->playvol[1];
+ break;
+
+ case SOUND_MIXER_CENTERVOL:
+ return *arg = devc->playvol[2];
+ break;
+
+ case SOUND_MIXER_SIDEVOL:
+ return *arg = devc->playvol[3];
+ break;
+
+ case SOUND_MIXER_RECLEV:
+ return *arg = devc->recvol;
+ break;
+
+ default:
+ return *arg = 0;
+ break;
+ }
+ }
+ else
+ return *arg = 0;
+
+}
+
+static mixer_driver_t cmi8788_mixer_driver = {
+ cmi8788_mixer_ioctl
+};
+
+/********************Record/Play ROUTING Control *************************/
+
+static int
+cmi8788_ext (int dev, int ctrl, unsigned int cmd, int value)
+{
+/*
+ * Access function for CMPCI mixer extension bits
+ */
+ cmi8788_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case 0: /* Record Monitor */
+ value = (INB (devc->osdev, REC_MONITOR) & 0x1) ? 1 : 0;
+ break;
+ case 1: /* SPDIFIN Monitor */
+ value = (INB (devc->osdev, REC_MONITOR) & 0x10) ? 1 : 0;
+ break;
+ case 2: /* Record source select */
+ switch (devc->model)
+ {
+ case SUBID_XONAR_DS:
+ value = (INW (devc->osdev, GPIO_DATA) & 0x40) ? 1 : 0;
+ break;
+ case SUBID_XONAR_D1:
+ case SUBID_XONAR_DX:
+ case SUBID_XONAR_STX:
+ case SUBID_XONAR_ST:
+ value = (INW (devc->osdev, GPIO_DATA) & 0x100) ? 1 : 0;
+ break;
+ default:
+ value = (ac97_read (devc, 0x72) & 0x1) ? 1 : 0;
+ break;
+ }
+ break;
+ case 3: /* Speaker Spread - check bit15 to see if it's set */
+ value = (INW (devc->osdev, PLAY_ROUTING) & 0x8000) ? 0 : 1;
+ break;
+ case 4: /* SPDIF IN->OUT Loopback */
+ value = (INW (devc->osdev, SPDIF_FUNC) & 0x4) ? 1 : 0;
+ break;
+ case 5:
+ value = (INW (devc->osdev, GPIO_DATA) & 0x80) ? 1 : 0;
+ break;
+ case 6:
+ if (!(INW (devc->osdev, GPIO_DATA) & 0x80))
+ value = 0;
+ else if (INW (devc->osdev, GPIO_DATA) & 0x02)
+ value = 1;
+ else
+ value = 2;
+ break;
+ case 7:
+ value = devc->mute;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ break;
+ }
+
+ return value;
+ }
+
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case 0: /* Record Monitor */
+ if (value)
+ OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0xF,
+ REC_MONITOR);
+ else
+ OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0xF,
+ REC_MONITOR);
+ break;
+
+ case 1: /* SPDIFIN Monitor */
+ if (value)
+ OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0x10,
+ REC_MONITOR);
+ else
+ OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0x10,
+ REC_MONITOR);
+ break;
+
+ case 2:
+ if (value)
+ {
+ switch (devc->model)
+ {
+ case SUBID_XONAR_DS:
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x40, GPIO_DATA);
+ break;
+ case SUBID_XONAR_D1:
+ case SUBID_XONAR_DX:
+ case SUBID_XONAR_STX:
+ case SUBID_XONAR_ST:
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x100, GPIO_DATA);
+ break;
+ }
+ ac97_write(devc, 0x72, ac97_read(devc, 0x72) | 0x1);
+ }
+ else
+ {
+ switch (devc->model)
+ {
+ case SUBID_XONAR_DS:
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) & ~0x40, GPIO_DATA);
+ break;
+ case SUBID_XONAR_D1:
+ case SUBID_XONAR_DX:
+ case SUBID_XONAR_STX:
+ case SUBID_XONAR_ST:
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) & ~0x100, GPIO_DATA);
+ break;
+ }
+
+ ac97_write(devc, 0x72, ac97_read(devc, 0x72) & ~0x1);
+ }
+ break;
+
+ case 3: /* Speaker Spread (clone front to all channels) */
+ if (value)
+ OUTW (devc->osdev, INW (devc->osdev, PLAY_ROUTING) & 0x00FF,
+ PLAY_ROUTING);
+ else
+ OUTW (devc->osdev,
+ (INW (devc->osdev, PLAY_ROUTING) & 0x00FF) | 0xE400,
+ PLAY_ROUTING);
+ break;
+
+ case 4: /* SPDIF IN->OUT Loopback */
+ if (value)
+ OUTW (devc->osdev, INW (devc->osdev, SPDIF_FUNC) | 0x4,
+ SPDIF_FUNC);
+ else
+ OUTW (devc->osdev, INW (devc->osdev, SPDIF_FUNC) & ~0x4,
+ SPDIF_FUNC);
+ break;
+
+ case 5:
+ if (value)
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x80, GPIO_DATA) ;
+ else
+ OUTW(devc->osdev, (INW(devc->osdev, GPIO_DATA) & ~0x80), GPIO_DATA);
+ break;
+
+ case 6:
+ switch (value)
+ {
+ /* speaker (line) output */
+ case 0: OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) & ~(0x80|0x02), GPIO_DATA);
+ break;
+ /* rear headphone output */
+ case 1: OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | (0x80|0x02), GPIO_DATA);
+ break;
+ case 2: OUTW (devc->osdev, (INW(devc->osdev, GPIO_DATA) | 0x80) & ~0x02, GPIO_DATA);
+ break;
+
+ }
+ break;
+
+ case 7:
+ /* muting for Xonar ST/STX on PCM1796 */
+ if (value)
+ {
+ i2c_write (devc, XONAR_ST_FRONTDAC, 18, 0x01|0x30|0x80);
+ devc->mute=1;
+ }
+ else
+ {
+ i2c_write (devc, XONAR_ST_FRONTDAC, 18, 0x00|0x30|0x80);
+ devc->mute=0;
+ }
+ break;
+
+ default:
+ return OSS_EINVAL;
+ break;
+ }
+ return (value);
+ }
+ return OSS_EINVAL;
+}
+
+
+/********************SPDIFOUT Control *************************/
+int
+spdifout_ctl (int dev, int ctrl, unsigned int cmd, int value)
+{
+ int tmp = 0;
+ cmi8788_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case SPDIFOUT_ENABLE: /* SPDIF OUT */
+ value = (INL (devc->osdev, SPDIF_FUNC) & 0x2) ? 1 : 0;
+ break;
+
+ case SPDIFOUT_PRO: /* Consumer/PRO */
+ value = (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & 0x1) ? 1 : 0;
+ break;
+
+ case SPDIFOUT_AUDIO: /* PCM/AC3 */
+ value = (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & 0x2) ? 1 : 0;
+ break;
+
+ case SPDIFOUT_COPY: /* Copy Prot */
+ value = (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & 0x4) ? 1 : 0;
+ break;
+
+ case SPDIFOUT_PREEMPH: /* Pre emphasis */
+ value = (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & 0x8) ? 1 : 0;
+ break;
+
+ case SPDIFOUT_RATE: /* Sampling Rate */
+ tmp = (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & 0xf000);
+ switch (tmp)
+ {
+ case 0x0000: /* 44100 */
+ value = 0;
+ break;
+ case 0x2000: /* 48000 */
+ value = 1;
+ break;
+ case 0x3000: /* 32000 */
+ value = 2;
+ break;
+ case 0x8000: /* 88200 */
+ value = 3;
+ break;
+ case 0xA000: /* 96000 */
+ value = 4;
+ break;
+ case 0xB000: /* 64000 */
+ value = 5;
+ break;
+ case 0xC000: /* 176400 */
+ value = 6;
+ break;
+ case 0xE000: /* 192000 */
+ value = 7;
+ break;
+ default:
+ cmn_err (CE_WARN, "unsupported SPDIF F/S rate\n");
+ break;
+ }
+ break;
+
+ case SPDIFOUT_VBIT: /* V Bit */
+ value = (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & 0x10000) ? 1 : 0;
+ break;
+
+ case SPDIFOUT_ADC: /* Analog In to SPDIF Out */
+ value = (INW (devc->osdev, PLAY_ROUTING) & 0x80) ? 1 : 0;
+ break;
+
+ default:
+ break;
+ }
+
+ return value;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case SPDIFOUT_ENABLE: /* Enable SPDIF OUT */
+ if (value)
+ OUTL (devc->osdev, INL (devc->osdev, SPDIF_FUNC) | 0x2,
+ SPDIF_FUNC);
+ else
+ OUTL (devc->osdev, INL (devc->osdev, SPDIF_FUNC) & ~0x2,
+ SPDIF_FUNC);
+ break;
+
+ case SPDIFOUT_PRO: /* consumer/pro audio */
+ if (value)
+ OUTL (devc->osdev, INL (devc->osdev, SPDIFOUT_CHAN_STAT) | 0x1,
+ SPDIFOUT_CHAN_STAT);
+ else
+ OUTL (devc->osdev, INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0x1,
+ SPDIFOUT_CHAN_STAT);
+ break;
+
+ case SPDIFOUT_AUDIO: /* PCM/AC3 */
+ if (value)
+ OUTL (devc->osdev, INL (devc->osdev, SPDIFOUT_CHAN_STAT) | 0x2,
+ SPDIFOUT_CHAN_STAT);
+ else
+ OUTL (devc->osdev, INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0x2,
+ SPDIFOUT_CHAN_STAT);
+ break;
+
+ case SPDIFOUT_COPY: /* copy prot */
+ if (value)
+ OUTL (devc->osdev, INL (devc->osdev, SPDIFOUT_CHAN_STAT) | 0x4,
+ SPDIFOUT_CHAN_STAT);
+ else
+ OUTL (devc->osdev, INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0x4,
+ SPDIFOUT_CHAN_STAT);
+ break;
+
+ case SPDIFOUT_PREEMPH: /* preemphasis */
+ if (value)
+ OUTL (devc->osdev, INL (devc->osdev, SPDIFOUT_CHAN_STAT) | 0x8,
+ SPDIFOUT_CHAN_STAT);
+ else
+ OUTL (devc->osdev, INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0x8,
+ SPDIFOUT_CHAN_STAT);
+ break;
+
+ case SPDIFOUT_RATE: /* Frequency */
+ switch (value)
+ {
+ case 0: /* 44100 */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0xF0000) | 0x0,
+ SPDIFOUT_CHAN_STAT);
+ break;
+ case 1: /* 48000 */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0xF0000) |
+ 0x2000, SPDIFOUT_CHAN_STAT);
+ break;
+ case 2: /* 32000 */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0xF0000) |
+ 0x3000, SPDIFOUT_CHAN_STAT);
+ break;
+ case 3: /* 88000 */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0xF0000) |
+ 0x8000, SPDIFOUT_CHAN_STAT);
+ break;
+ case 4: /* 96000 */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0xF0000) |
+ 0xA000, SPDIFOUT_CHAN_STAT);
+ break;
+ case 5: /* 64000 */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0xF0000) |
+ 0xB000, SPDIFOUT_CHAN_STAT);
+ break;
+ case 6: /* 176400 */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0xF0000) |
+ 0xC000, SPDIFOUT_CHAN_STAT);
+ break;
+ case 7: /* 192000 */
+ OUTL (devc->osdev,
+ (INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0xF0000) |
+ 0xE000, SPDIFOUT_CHAN_STAT);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SPDIFOUT_VBIT: /* V Bit */
+ if (value)
+ OUTL (devc->osdev,
+ INL (devc->osdev, SPDIFOUT_CHAN_STAT) | 0x10000,
+ SPDIFOUT_CHAN_STAT);
+ else
+ OUTL (devc->osdev,
+ INL (devc->osdev, SPDIFOUT_CHAN_STAT) & ~0x10000,
+ SPDIFOUT_CHAN_STAT);
+ break;
+
+ case SPDIFOUT_ADC: /* Analog In to SPDIF Out */
+ if (value)
+ OUTW (devc->osdev, INW (devc->osdev, PLAY_ROUTING) | 0xA0,
+ PLAY_ROUTING);
+ else
+ OUTW (devc->osdev, INW (devc->osdev, PLAY_ROUTING) & ~0xE0,
+ PLAY_ROUTING);
+ break;
+
+ default:
+ break;
+ }
+
+ return (value);
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+cmi8788_mix_init (int dev)
+{
+ int group, parent, ctl;
+ cmi8788_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if ((parent = mixer_ext_create_group (dev, 0, "EXT")) < 0)
+ return parent;
+
+/* CREATE MONITOR */
+ if ((group = mixer_ext_create_group (dev, parent, "MONITOR")) < 0)
+ return group;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, 0, cmi8788_ext,
+ MIXT_ONOFF, "ANALOG", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, 1, cmi8788_ext,
+ MIXT_ONOFF, "SPDIF", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, 2, cmi8788_ext, MIXT_ENUM,
+ "INPUTSRC", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "Line Mic", 0);
+
+/* Create PLAYBACK ROUTING */
+ if ((group = mixer_ext_create_group (dev, parent, "ROUTING")) < 0)
+ return group;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, 3, cmi8788_ext,
+ MIXT_ONOFF, "SPREAD", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, 4, cmi8788_ext,
+ MIXT_ONOFF, "SPDIF-LOOPBACK", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if (devc->model == SUBID_XONAR_D2 || devc->model == SUBID_XONAR_D2X)
+ if ((ctl = mixer_ext_create_control (dev, group, 5, cmi8788_ext,
+ MIXT_ONOFF, "PCM-LOOPBACK", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if (devc->model == SUBID_XONAR_STX || devc->model == SUBID_XONAR_ST)
+
+ {
+ if ((ctl =
+ mixer_ext_create_control (dev, group, 6, cmi8788_ext, MIXT_ENUM,
+ "OUTPUTSRC", 3,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "Speaker Headphone FrontHeadphone", 0);
+
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, 7, cmi8788_ext,
+ MIXT_ONOFF, "MUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ }
+
+/* Create SPDIF OUTPUT */
+ if ((group = mixer_ext_create_group (dev, 0, "SPDIF-OUT")) < 0)
+ return group;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, SPDIFOUT_ENABLE,
+ spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_ENABLE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, SPDIFOUT_ADC,
+ spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_ADC/DAC", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, SPDIFOUT_PRO,
+ spdifout_ctl, MIXT_ENUM,
+ "SPDOUT_Pro", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "Consumer Professional", 0);
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, SPDIFOUT_AUDIO,
+ spdifout_ctl, MIXT_ENUM,
+ "SPDOUT_Audio", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "Audio Data", 0);
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, SPDIFOUT_COPY,
+ spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_Copy", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, SPDIFOUT_PREEMPH,
+ spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_Pre-emph", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, SPDIFOUT_RATE,
+ spdifout_ctl, MIXT_ENUM,
+ "SPDOUT_Rate", 8,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ mixer_ext_set_strings (dev, ctl,
+ "44.1KHz 48KHz 32KHz 88.2KHz 96KHz 64KHz 176.4KHz 192KHz",
+ 0);
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, SPDIFOUT_VBIT,
+ spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_VBit", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ return 0;
+}
+
+
+static void
+ac97_hwinit(cmi8788_devc *devc)
+{
+
+ /* Gpio #0 programmed as output, set CMI9780 Reg0x70 */
+ ac97_write(devc, 0x70, 0x100);
+
+ /* LI2LI,MIC2MIC; let them always on, FOE on, ROE/BKOE/CBOE off */
+ ac97_write(devc, 0x62, 0x180F);
+
+ /* change PCBeep path, set Mix2FR on, option for quality issue */
+ ac97_write(devc, 0x64, 0x8043);
+#if 0
+ /* unmute Master Volume */
+ ac97_write(devc, 0x02, 0x0);
+
+
+ /* mute PCBeep, option for quality issues */
+ ac97_write(devc, 0x0A, 0x8000);
+
+ /* Record Select Control Register (Index 1Ah) */
+ ac97_write(devc, 0x1A, 0x0000);
+
+ /* set Mic Volume Register 0x0Eh umute and enable micboost */
+ ac97_write(devc, 0x0E, 0x0848);
+
+ /* set Line in Volume Register 0x10h mute */
+ ac97_write(devc, 0x10, 0x8808);
+
+ /* set CD Volume Register 0x12h mute */
+ ac97_write(devc, 0x12, 0x8808);
+
+ /* set AUX Volume Register 0x16h max */
+ ac97_write(devc, 0x16, 0x0808);
+
+ /* set record gain Register 0x1Ch to max */
+ ac97_write(devc, 0x1C, 0x0F0F);
+#endif
+ ac97_write(devc, 0x71, 0x0001);
+}
+
+static int
+init_cmi8788 (cmi8788_devc * devc)
+{
+ unsigned short sVal;
+ unsigned short sDac;
+ unsigned char bVal;
+ int i, first_dev = -1, count;
+ int default_vol;
+/*
+ * Init CMI Controller
+ */
+ sVal = INW (devc->osdev, CTRL_VERSION);
+ if (!(sVal & 0x0008))
+ {
+ bVal = INB (devc->osdev, MISC_REG);
+ bVal |= 0x20;
+ OUTB (devc->osdev, bVal, MISC_REG);
+ }
+
+ bVal = INB (devc->osdev, FUNCTION);
+ bVal |= 0x02; /* Reset codec*/
+ OUTB(devc->osdev, bVal, FUNCTION);
+
+
+ /* I2S to 16bit, see below. */
+ sDac = 0x010A;
+
+ /* Non-generic DAC initialization */
+ switch(devc->model)
+ {
+ case SUBID_XONAR_D1:
+ case SUBID_XONAR_DX:
+ case SUBID_XONAR_D2:
+ case SUBID_XONAR_D2X:
+ case SUBID_XONAR_STX:
+ case SUBID_XONAR_DS:
+ /* Must set master clock. */
+ sDac |= XONAR_MCLOCK_256;
+ break;
+ case SUBID_XONAR_ST:
+ sDac |= XONAR_MCLOCK_512;
+ }
+
+ /* Setup I2S to use 16bit instead of 24Bit */
+ OUTW (devc->osdev, sDac, I2S_MULTICH_FORMAT);
+ OUTW (devc->osdev, sDac, I2S_ADC1_FORMAT);
+ OUTW (devc->osdev, sDac, I2S_ADC2_FORMAT);
+ OUTW (devc->osdev, sDac, I2S_ADC3_FORMAT);
+
+ /* setup Routing regs (default vals) */
+ OUTW (devc->osdev, 0xE400, PLAY_ROUTING);
+ OUTB (devc->osdev, 0x00, REC_ROUTING);
+ OUTB (devc->osdev, 0x00, REC_MONITOR);
+ OUTB (devc->osdev, 0xE4, MONITOR_ROUTING);
+
+
+ /* install the CMI8788 mixer */
+ if ((devc->cmi_mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "CMedia CMI8788",
+ &cmi8788_mixer_driver,
+ sizeof (mixer_driver_t),
+ devc)) < 0)
+ {
+ return 0;
+ }
+
+ mixer_devs[devc->cmi_mixer_dev]->hw_devc = devc;
+ mixer_devs[devc->cmi_mixer_dev]->priority = 10; /* Possible default mixer candidate */
+ mixer_ext_set_init_fn (devc->cmi_mixer_dev, cmi8788_mix_init, 25);
+
+ /* Cold reset onboard AC97 */
+ OUTW (devc->osdev, 0x1, AC97_CTRL);
+ count = 100;
+ while ((INW (devc->osdev, AC97_CTRL) & 0x2) && (count--))
+ {
+ OUTW (devc->osdev, (INW (devc->osdev, AC97_CTRL) & ~0x2) | 0x2,
+ AC97_CTRL);
+ oss_udelay (100);
+ }
+ if (!count)
+ cmn_err (CE_WARN, "CMI8788 AC97 not ready\n");
+
+
+ sVal = INW (devc->osdev, AC97_CTRL);
+
+ devc->ac97_mixer_dev = devc->fp_mixer_dev = -1;
+
+ /* check if there's an onboard AC97 codec (CODEC 0) and install the mixer */
+ if (sVal & 0x10)
+ {
+ /* disable CODEC0 OUTPUT */
+ OUTW (devc->osdev, 0, /* INW (devc->osdev, AC97_OUT_CHAN_CONFIG) & ~0xFF00,*/
+ AC97_OUT_CHAN_CONFIG);
+
+ /* enable CODEC0 INPUT */
+ OUTW (devc->osdev, 0, /* INW (devc->osdev, AC97_IN_CHAN_CONFIG) | 0x0300,*/
+ AC97_IN_CHAN_CONFIG);
+
+ devc->ac97_mixer_dev =
+ ac97_install (&devc->ac97devc, "AC97 Input Mixer", ac97_read,
+ ac97_write, devc, devc->osdev);
+ }
+
+ /* check if there's an front panel AC97 codec (CODEC1) and install the mixer */
+ if (sVal & 0x20)
+ {
+ /* enable CODEC1 OUTPUT */
+ OUTW (devc->osdev, INW (devc->osdev, AC97_OUT_CHAN_CONFIG) | 0x0033,
+ AC97_OUT_CHAN_CONFIG);
+ /* enable CODEC1 INPUT */
+ OUTW (devc->osdev, INW (devc->osdev, AC97_IN_CHAN_CONFIG) | 0x0033,
+ AC97_IN_CHAN_CONFIG);
+
+ devc->fp_mixer_dev =
+ ac97_install (&devc->fp_ac97devc, "AC97 Mixer (Front Panel)",
+ fp_ac97_read, fp_ac97_write, devc, devc->osdev);
+
+ if (devc->fp_mixer_dev >= 0)
+ {
+ /* enable S/PDIF */
+ devc->fp_ac97devc.spdif_slot = SPDIF_SLOT34;
+ ac97_spdifout_ctl (devc->fp_mixer_dev, SPDIFOUT_ENABLE,
+ SNDCTL_MIX_WRITE, 1);
+ }
+ }
+
+
+
+ switch(devc->model) {
+ case SUBID_XONAR_D1:
+ case SUBID_XONAR_DX:
+ /*GPIO8 = 0x100 controls mic/line-in */
+ /*GPIO0 = 0x001controls output */
+ /*GPIO2/3 = 0x00C codec output control*/
+
+ /* setup for i2c communication mode */
+ OUTB(devc->osdev, INB (devc->osdev, FUNCTION) | 0x40, FUNCTION);
+ /* setup GPIO direction */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x010D, GPIO_CONTROL);
+ /* setup GPIO pins */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x0101, GPIO_DATA);
+
+ /* init the front and rear dacs */
+ cs4398_init(devc, XONAR_DX_FRONTDAC);
+ cs4362a_init(devc, XONAR_DX_SURRDAC);
+ /* initialize the codec 0 */
+ ac97_hwinit(devc);
+ break;
+
+
+ case SUBID_XONAR_D2:
+ case SUBID_XONAR_D2X:
+ /*GPIO7 = 0x0080 controls mic/line-in */
+ /*GPIO8 = 0x0100 controls output */
+ /*GPIO2/3 = 0x000C codec output control*/
+
+ /* setup for spi communication mode */
+ OUTB(devc->osdev, (INB (devc->osdev, FUNCTION) & ~0x40) | 0x80, FUNCTION);
+ /* setup the GPIO direction */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x018C, GPIO_CONTROL);
+ /* setup GPIO Pins */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x0100, GPIO_DATA);
+
+ /* for all 4 codecs: unmute, set to 24Bit SPI */
+ for (i = 0; i < 4; ++i) {
+ spi_write(devc, xd2_codec_map[i], 16, mix_scale(75,8)); /* left vol*/
+ spi_write(devc, xd2_codec_map[i], 17, mix_scale(75,8)); /* right vol */
+ spi_write(devc, xd2_codec_map[i], 18, 0x00| 0x30 | 0x80); /* unmute/24LSB/ATLD */
+ }
+ /* initialize the codec 0 */
+ ac97_hwinit(devc);
+ break;
+
+ case SUBID_XONAR_STX:
+ /*GPIO0 = Antipop control */
+ /*GPIO1 = frontpanel h/p control*/
+ /*GPIO7 = 0x0080 controls analog out*/
+ /*GPIO8 = 0x0100 controls mic/line in*/
+ /*GPIO2/3 = 0x000C codec input control*/
+
+ /* setup for i2c communication mode */
+ OUTB(devc->osdev, INB (devc->osdev, FUNCTION) | 0x40, FUNCTION);
+
+ /* setup the GPIO direction control register */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x018F, GPIO_CONTROL);
+ /* setup GPIO pins mic/output */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x111, GPIO_DATA);
+
+ OUTW(devc->osdev, INW(devc->osdev, I2C_CTRL)|0x0100, I2C_CTRL);
+
+ /* initialize the PCM1796 DAC */
+ i2c_write(devc, XONAR_STX_FRONTDAC, 20, 0x40); /*OS_64*/
+ i2c_write(devc, XONAR_STX_FRONTDAC, 20, 0); /*OS_64*/
+ i2c_write(devc, XONAR_STX_FRONTDAC, 16, mix_scale(75,8));
+ i2c_write(devc, XONAR_STX_FRONTDAC, 17, mix_scale(75,8));
+ i2c_write(devc, XONAR_STX_FRONTDAC, 18, 0x00|0x30|0x80); /*unmute, 24LSB, ATLD */
+ i2c_write(devc, XONAR_STX_FRONTDAC, 19, 0); /*ATS1/FLT_SHARP*/
+
+ /* initialize the codec 0 */
+ ac97_hwinit(devc);
+ break;
+
+ case SUBID_XONAR_ST:
+ /*GPIO0 = enable output*/
+ /*GPIO1 = frontpanel h/p control*/
+ /*GPIO7 = 0x0080 controls analog out line/HP*/
+ /*GPIO8 = 0x0100 controls mic/line in*/
+ /*GPIO2/3 = 0x000C codec input control*/
+
+ /* setup for i2c communication mode */
+ OUTB(devc->osdev, INB (devc->osdev, FUNCTION) | 0x40, FUNCTION);
+
+ /* setup the GPIO direction control register */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x01FF, GPIO_CONTROL);
+ /* setup GPIO pins mic/output */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x101, GPIO_DATA);
+ OUTW(devc->osdev, INW(devc->osdev, I2C_CTRL)|0x0100, I2C_CTRL);
+ /* initialize the CS2000 clock chip */
+ cs2000_init (devc, XONAR_ST_CLOCK);
+
+ /* initialize the PCM1796 DAC */
+ i2c_write(devc, XONAR_ST_FRONTDAC, 20, 0); /*normal*/
+ i2c_write(devc, XONAR_ST_FRONTDAC, 18, 0x00|0x30|0x80); /*unmute, 24LSB, ATLD */
+ i2c_write(devc, XONAR_ST_FRONTDAC, 16, mix_scale(75,8));
+ i2c_write(devc, XONAR_ST_FRONTDAC, 17, mix_scale(75,8));
+ i2c_write(devc, XONAR_ST_FRONTDAC, 19, 0); /*ATS1/FLT_SHARP*/
+
+ /* initialize the codec 0 */
+ ac97_hwinit(devc);
+
+ break;
+
+ case SUBID_XONAR_DS:
+ /* GPIO 8 = 1 output enabled 0 mute */
+ /* GPIO 7 = 1 lineout enabled 0 mute */
+ /* GPIO 6 = 1 mic select 0 line-in select */
+ /* GPIO 4 = 1 FP Headphone plugged in */
+ /* GPIO 3 = 1 FP Mic plugged in */
+
+ /* setup for spi communication mode */
+ OUTB(devc->osdev, (INB (devc->osdev, FUNCTION) & ~0x40)|0x32, FUNCTION);
+ /* setup the GPIO direction */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x1D0, GPIO_CONTROL);
+ /* setup GPIO Pins */
+ OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x1D0, GPIO_DATA);
+
+ spi_write(devc, XONAR_DS_FRONTDAC, 0x17, 0x1); /* reset */
+ spi_write(devc, XONAR_DS_FRONTDAC, 0x7, 0x90); /* dac control */
+ spi_write(devc, XONAR_DS_FRONTDAC, 0x8, 0); /* unmute */
+ spi_write(devc, XONAR_DS_FRONTDAC, 0xC, 0x22 ); /* powerdown hp */
+ spi_write(devc, XONAR_DS_FRONTDAC, 0xD, 0x8); /* powerdown hp */
+ spi_write(devc, XONAR_DS_FRONTDAC, 0xA, 0x1); /* LJust/16bit*/
+ spi_write(devc, XONAR_DS_FRONTDAC, 0xB, 0x1); /* LJust/16bit*/
+
+ spi_write(devc, XONAR_DS_SURRDAC, 0x1f, 1); /* reset */
+ spi_write(devc, XONAR_DS_SURRDAC, 0x3, 0x1|0x20); /* LJust/24bit*/
+ break;
+
+ default:
+ /* SPI default for anything else, including the */
+ OUTB(devc->osdev, (INB (devc->osdev, FUNCTION) & ~0x40) | 0x80, FUNCTION);
+ break;
+ }
+
+ /* check if MPU401 is enabled in MISC register */
+ if (INB (devc->osdev, MISC_REG) & 0x40)
+ attach_mpu (devc);
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ char tmp_name[100];
+ cmi8788_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE;
+ int fmt = AFMT_S16_LE;
+
+ switch (i)
+ {
+ case 0:
+ sprintf (tmp_name, "%s (MultiChannel)", devc->chip_name);
+ caps |= ADEV_DUPLEX;
+ fmt |= AFMT_S32_LE;
+ portc->dac_type = ADEV_MULTICH;
+ switch(devc->model)
+ {
+ case SUBID_XONAR_D1:
+ case SUBID_XONAR_DX:
+ case SUBID_XONAR_D2:
+ case SUBID_XONAR_D2X:
+ case SUBID_XONAR_STX:
+ case SUBID_XONAR_ST:
+ portc->adc_type = ADEV_I2SADC2;
+ break;
+ case SUBID_XONAR_DS:
+ portc->adc_type = ADEV_I2SADC1;
+ break;
+ default:
+ portc->adc_type = ADEV_I2SADC1;
+ OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING);
+ break;
+ }
+
+ portc->min_rate = 32000;
+ portc->max_rate = 192000;
+ portc->min_chan = 2;
+ portc->max_chan = 8;
+ break;
+
+ case 1:
+ sprintf (tmp_name, "%s (Multichannel)", devc->chip_name);
+ caps |= ADEV_DUPLEX | ADEV_SHADOW;
+ fmt |= AFMT_S32_LE;
+ portc->dac_type = ADEV_MULTICH;
+ switch(devc->model)
+ {
+ case SUBID_XONAR_D1:
+ case SUBID_XONAR_DX:
+ case SUBID_XONAR_D2:
+ case SUBID_XONAR_D2X:
+ case SUBID_XONAR_STX:
+ case SUBID_XONAR_ST:
+ portc->adc_type = ADEV_I2SADC2;
+ break;
+ case SUBID_XONAR_DS:
+ portc->adc_type = ADEV_I2SADC1;
+ break;
+ default:
+ portc->adc_type = ADEV_I2SADC1;
+ OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING);
+ break;
+ }
+
+ portc->min_rate = 32000;
+ portc->max_rate = 192000;
+ portc->min_chan = 2;
+ portc->max_chan = 8;
+ break;
+
+ case 2:
+ /* if there is no front panel AC97, then skip the device */
+ if (devc->fp_mixer_dev == -1)
+ continue;
+
+ sprintf (tmp_name, "%s (Front Panel)", devc->chip_name);
+ caps |=
+ ADEV_DUPLEX | ADEV_16BITONLY | ADEV_STEREOONLY | ADEV_SPECIAL;
+ fmt |= AFMT_AC3;
+ portc->dac_type = ADEV_FRONTPANEL;
+ portc->adc_type = ADEV_I2SADC2;
+ OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING);
+ portc->min_rate = 8000;
+ portc->max_rate = 48000;
+ portc->min_chan = 2;
+ portc->max_chan = 2;
+ break;
+
+ case 3:
+ sprintf (tmp_name, "%s (SPDIF)", devc->chip_name);
+ caps |= ADEV_DUPLEX | ADEV_STEREOONLY | ADEV_SPECIAL;
+ fmt |= AFMT_AC3 | AFMT_S32_LE;
+ portc->dac_type = ADEV_SPDIF;
+ portc->adc_type = ADEV_I2SADC3;
+ portc->min_rate = 32000;
+ portc->max_rate = 192000;
+ portc->min_chan = 2;
+ portc->max_chan = 2;
+ break;
+ }
+
+ if ((portc->audiodev =
+ oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION, devc->osdev,
+ devc->osdev, tmp_name,
+ &cmi8788_audio_driver,
+ sizeof (audiodrv_t), caps, fmt,
+ devc, -1)) < 0)
+ {
+ return 0;
+ }
+ else
+ {
+ if (first_dev == -1)
+ first_dev = portc->audiodev;
+ audio_engines[portc->audiodev]->portc = portc;
+ audio_engines[portc->audiodev]->rate_source = first_dev;
+ if (caps & ADEV_FIXEDRATE)
+ {
+ audio_engines[portc->audiodev]->min_rate = 48000;
+ audio_engines[portc->audiodev]->max_rate = 48000;
+ audio_engines[portc->audiodev]->fixed_rate = 48000;
+ }
+ audio_engines[portc->audiodev]->min_rate = portc->min_rate;
+ audio_engines[portc->audiodev]->max_rate = portc->max_rate;
+
+ audio_engines[portc->audiodev]->caps |= DSP_CAP_FREERATE;
+ audio_engines[portc->audiodev]->min_channels = portc->min_chan;
+ audio_engines[portc->audiodev]->max_channels = portc->max_chan;
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, portc->audiodev, -1, 0);
+#endif
+ }
+ }
+
+ /*
+ * Setup the default volumes to 90%
+ */
+
+ devc->mute = 0;
+
+ default_vol = mix_scale(90,8)<<8|mix_scale(90,8);
+
+ devc->playvol[0] =
+ cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev,
+ MIXER_WRITE (SOUND_MIXER_PCM), &default_vol);
+ devc->playvol[1] =
+ cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev,
+ MIXER_WRITE (SOUND_MIXER_REARVOL), &default_vol);
+ devc->playvol[2] =
+ cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev,
+ MIXER_WRITE (SOUND_MIXER_CENTERVOL), &default_vol);
+ devc->playvol[3] =
+ cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev,
+ MIXER_WRITE (SOUND_MIXER_SIDEVOL), &default_vol);
+
+ return 1;
+}
+
+int
+oss_cmi878x_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ unsigned short sub_vendor, sub_id;
+ int err;
+ cmi8788_devc *devc;
+
+ DDB (cmn_err (CE_CONT, "Entered CMEDIA CMI8788 attach routine\n"));
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor);
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_ID, &sub_id);
+
+ if (vendor != CMEDIA_VENDOR_ID || device != CMEDIA_CMI8788)
+ return 0;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+ DDB (cmn_err (CE_WARN, "CMI8788 I/O base %04x\n", pci_ioaddr));
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->irq = pci_irq_line;
+
+ /* Map the IO Base address */
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+
+ /* Remove I/O space marker in bit 0. */
+ devc->base &= ~3;
+
+ /* set the PCI_COMMAND register to master mode */
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ if (device == CMEDIA_CMI8788)
+ {
+ /* Detect Xonar device */
+ if(sub_vendor == ASUS_VENDOR_ID)
+ {
+ switch(sub_id)
+ {
+ case SUBID_XONAR_D1:
+ devc->chip_name = "Asus Xonar D1 (AV100)";
+ break;
+ case SUBID_XONAR_DX:
+ devc->chip_name = "Asus Xonar DX (AV100)";
+ break;
+ case SUBID_XONAR_D2:
+ devc->chip_name = "Asus Xonar D2 (AV200)";
+ break;
+ case SUBID_XONAR_D2X:
+ devc->chip_name = "Asus Xonar D2X (AV200)";
+ break;
+ case SUBID_XONAR_STX:
+ devc->chip_name = "Asus Xonar Essence STX (AV100)";
+ break;
+ case SUBID_XONAR_ST:
+ devc->chip_name = "Asus Xonar Essence ST (AV100)";
+ break;
+ case SUBID_XONAR_DS:
+ devc->chip_name = "Asus Xonar DS (AV66)";
+ break;
+ default:
+ devc->chip_name = "Asus Xonar (unknown)";
+ sub_id = SUBID_GENERIC;
+ break;
+ }
+ devc->model = sub_id;
+ }
+ else
+ {
+ /* If not one of the above, regular. */
+ devc->model = MDL_CMI8788;
+ devc->chip_name = "CMedia CMI8788";
+ }
+ }
+ else
+ {
+ cmn_err (CE_WARN, "Unknown CMI8788 model\n");
+ return 0;
+ }
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+ MUTEX_INIT (devc->osdev, devc->dac_mutex, MH_DRV + 2);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, cmi8788intr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't allocate IRQ%d, err=%d\n", pci_irq_line, err);
+ return 0;
+ }
+
+ return init_cmi8788 (devc); /* Detected */
+}
+
+int
+oss_cmi878x_detach (oss_device_t * osdev)
+{
+ cmi8788_devc *devc = (cmi8788_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ if (devc->mpu_attached)
+ unload_cmi8788uart (devc);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ MUTEX_CLEANUP (devc->dac_mutex);
+
+ oss_unregister_device (osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_cmi878x/oss_cmi878x.man b/kernel/drv/oss_cmi878x/oss_cmi878x.man
new file mode 100644
index 0000000..316d4c4
--- /dev/null
+++ b/kernel/drv/oss_cmi878x/oss_cmi878x.man
@@ -0,0 +1,54 @@
+NAME
+oss_cmi878x - CMedia CMI8788 audio driver.
+
+DESCRIPTION
+Open Sound System driver for CMedia Electronics CMI8788 audio
+
+CMI87xx device characteristics:
+ o 8/16/24/32 bit playback/record
+ o mono/stereo/4ch/5.1/7.1 playback
+ o 8KHz to 192Khz sample rate.
+
+The CMedia 8788 device provides 3 types of devices. The first devices is
+a Multichannel full duplex device. The second device provides Front Panel
+audio access and the SPDIF device provide SPDIF (Digital) audio I/O.
+
+ MIXER PANEL
+The CMedia chip provides some unique features that are set up
+by the Mixer chip. There are 3 mixer devices presented to the user.
+
+Main Mixer Panel (/dev/mixer0)
+
+o Master Mixer panel is for controlling output volumes for each of the 8
+channels.
+
+o Monitor buttons will allow you to monitor the input from the Rear Panel
+inputs, Front Panel Inputs and SPDIF IN.
+
+o Speaker-Spread function duplicates the front channel output on all 8
+speakers.
+
+o SPDIF Loopback simply takes SPDIF Input and Plays it out the SPDIF Output.
+panel.
+
+
+AC97 Input Mixer Panel (/dev/mixer1)
+This mixer panel is used to switch between the various inputs like line-in,
+mic, cd. When the Rear Panel Monitor button is check marked in the Main
+mixer panel, the IGAIN slider in this panel controls the level of the input
+that can be hear on the speakers.
+
+
+AC97 Front Panel Mixer (/dev/mixer2)
+This mixer controls the front panel ac97 device. It can be used to control
+all the volumes and inputs as well as SPDIF output on the front panel device.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_cmi878x.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_cmpci/.devices b/kernel/drv/oss_cmpci/.devices
new file mode 100644
index 0000000..9933503
--- /dev/null
+++ b/kernel/drv/oss_cmpci/.devices
@@ -0,0 +1,5 @@
+oss_cmpci pci13f6,100 C-Media CM8338A
+oss_cmpci pci13f6,100 MIDIMan DiO 2448
+oss_cmpci pci13f6,101 CMedia CM8338B
+oss_cmpci pci13f6,111 CMedia CM8738/CM8768
+oss_cmpci pci14af,20 Guillemot Maxi Sound MUSE
diff --git a/kernel/drv/oss_cmpci/.name b/kernel/drv/oss_cmpci/.name
new file mode 100644
index 0000000..0d987dc
--- /dev/null
+++ b/kernel/drv/oss_cmpci/.name
@@ -0,0 +1 @@
+C-Media CM833x audio chipset
diff --git a/kernel/drv/oss_cmpci/oss_cmpci.c b/kernel/drv/oss_cmpci/oss_cmpci.c
new file mode 100644
index 0000000..50ccf84
--- /dev/null
+++ b/kernel/drv/oss_cmpci/oss_cmpci.c
@@ -0,0 +1,2379 @@
+/*
+ * Purpose: Driver for CMEDIA CM8738 PCI audio controller.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_cmpci_cfg.h"
+#include "oss_pci.h"
+#include "uart401.h"
+
+#define CMEDIA_VENDOR_ID 0x13F6
+#define CMEDIA_CM8738 0x0111
+#define CMEDIA_CM8338A 0x0100
+#define CMEDIA_CM8338B 0x0101
+/*
+ * CM8338 registers definition
+ */
+
+#define FUNCTRL0 (devc->base+0x00)
+#define FUNCTRL1 (devc->base+0x04)
+#define CHFORMAT (devc->base+0x08)
+#define INT_HLDCLR (devc->base+0x0C)
+#define INT_STATUS (devc->base+0x10)
+#define LEGACY_CTRL (devc->base+0x14)
+#define MISC_CTRL (devc->base+0x18)
+#define TDMA_POS (devc->base+0x1C)
+#define MIXER (devc->base+0x20)
+#define MIXER_DATA (devc->base+0x22)
+#define MIXER_ADDR (devc->base+0x23)
+#define MIXER1 (devc->base+0x24)
+#define MIXER2 (devc->base+0x25)
+#define AUX_VOL (devc->base+0x26)
+#define MIXER3 (devc->base+0x27)
+#define AC97 (devc->base+0x28)
+
+#define CH0_FRAME1 (devc->base+0x80)
+#define CH0_FRAME2 (devc->base+0x84)
+#define CH1_FRAME1 (devc->base+0x88)
+#define CH1_FRAME2 (devc->base+0x8C)
+
+#define SPDIF_STAT (devc->base+0x90)
+#define MISC2_CTRL (devc->base+0x92)
+
+#define MPU_MIRROR (devc->base+0x40)
+#define FM_MIRROR (devc->base+0x50)
+#define JOY_MIRROR (devc->base+0x60)
+
+#define DSP_MIX_DATARESETIDX (0x00)
+#define DSP_MIX_OUTMIXIDX (0x3c)
+#define CM_CH0_ENABLE 0x01
+#define CM_CH1_ENABLE 0x02
+#define CM_CH0_RESET 0x04
+#define CM_CH1_RESET 0x08
+#define CM_CH0_RECORD 0x01
+#define CM_CH1_RECORD 0x02
+#define CM_CH0_PLAY ~0x01
+#define CM_CH1_PLAY ~0x02
+#define CM_CH0_INT 1
+#define CM_CH1_INT 2
+#define CM_EXTENT_CODEC 0x100
+#define CM_EXTENT_MIDI 0x2
+#define CM_EXTENT_SYNTH 0x4
+#define CM_CFMT_STEREO 0x01
+#define CM_CFMT_16BIT 0x02
+#define CM_CFMT_MASK 0x03
+#define CM_CFMT_DACSHIFT 0
+#define CM_CFMT_ADCSHIFT 2
+
+#define MUTE_LINE 1
+#define MUTE_CD 2
+#define MUTE_MIC 3
+#define MUTE_AUX 4
+#define REAR2LINE 5
+#define CEN2LINE 6
+#define BASS2LINE 7
+#define CEN2MIC 8
+#define MODE_4SPK 9
+#define DUALDAC 10
+#define MICBOOST 11
+#define SPDIF_PLAY 12
+#define SPDIF_LOOP 13
+#define SPDIF_REC 14
+#define SPDIF_IMON 15
+#define SPDIF_POL 16
+#define SPDIF_COPY 17
+#define SPDIF_OPT 18
+#define SPDIF_AC3 19
+#define AUX_REC 20
+#define AUX_LEVEL 21
+
+#define CHAN0 0x1
+#define CHAN1 0x2
+
+static struct
+{
+ unsigned int rate;
+ unsigned int lower;
+ unsigned int upper;
+ unsigned char freq;
+}
+rate_lookup[] =
+{
+ {
+ 5512, (0 + 5512) / 2, (5512 + 8000) / 2, 0}
+ ,
+ {
+ 8000, (5512 + 8000) / 2, (8000 + 11025) / 2, 4}
+ ,
+ {
+ 11025, (8000 + 11025) / 2, (11025 + 16000) / 2, 1}
+ ,
+ {
+ 16000, (11025 + 16000) / 2, (16000 + 22050) / 2, 5}
+ ,
+ {
+ 22050, (16000 + 22050) / 2, (22050 + 32000) / 2, 2}
+ ,
+ {
+ 32000, (22050 + 32000) / 2, (32000 + 44100) / 2, 6}
+ ,
+ {
+ 44100, (32000 + 44100) / 2, (44100 + 48000) / 2, 3}
+ ,
+ {
+ 48000, (48000 + 44100) / 2, (48000 + 96000) / 2, 7}
+};
+
+static unsigned char cmpci_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_LINE1 */
+ 0x00, /* SOUND_MIXER_RECLEV */
+ 0x00, /* SOUND_MIXER_IGAIN */
+ 0x00 /* SOUND_MIXER_OGAIN */
+};
+
+static unsigned char cmpci_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_LINE1 */
+ 0x00, /* SOUND_MIXER_RECLEV */
+ 0x00, /* SOUND_MIXER_IGAIN */
+ 0x00 /* SOUND_MIXER_OGAIN */
+};
+
+#define CMEDIA_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | \
+ SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_LINE1)
+
+#define CMEDIA_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | \
+ SOUND_MASK_LINE | SOUND_MASK_MIC | \
+ SOUND_MASK_IGAIN | SOUND_MASK_CD | \
+ SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER |\
+ SOUND_MASK_LINE1|SOUND_MASK_RECLEV)
+
+#define LEFT_CHN 0
+#define RIGHT_CHN 1
+/*
+ * Mixer registers of CMPCI
+ */
+#define CMPCI_IMASK_L 0x3d
+#define CMPCI_IMASK_R 0x3e
+
+
+int default_levels[32] = {
+ 0x5a5a, /* Master Volume */
+ 0x4b4b, /* Bass */
+ 0x4b4b, /* Treble */
+ 0x4b4b, /* FM */
+ 0x4b4b, /* PCM */
+ 0x4b4b, /* PC Speaker */
+ 0x4b4b, /* Ext Line */
+ 0x2020, /* Mic */
+ 0x4b4b, /* CD */
+ 0x0000, /* Recording monitor */
+ 0x4b4b, /* SB PCM */
+ 0x4b4b, /* Recording level */
+ 0x4b4b, /* Input gain */
+ 0x4b4b, /* Output gain */
+ 0x4040, /* Line1 */
+ 0x4040, /* Line2 */
+ 0x1515 /* Line3 */
+};
+
+typedef struct cmpci_portc
+{
+ int speed, bits, channels;
+ int open_mode;
+ int trigger_bits;
+ int audio_enabled;
+ int audiodev;
+ int dacfmt, adcfmt;
+ int chan0_play, chan0_rec;
+ int chan1_play, chan1_rec;
+}
+cmpci_portc;
+
+#define MAX_PORTC 2
+
+typedef struct cmpci_devc
+{
+ oss_device_t *osdev;
+ oss_native_word base;
+ int fm_attached;
+ int irq;
+ int max_channels;
+ volatile unsigned char intr_mask;
+ int model;
+#define MDL_CM8738 1
+#define MDL_CM8338A 2
+#define MDL_CM8338B 3
+#define MDL_CM8768 4
+ char *chip_name;
+ int chiprev;
+ int mode_4spk;
+ int dev_mode;
+#define DEFAULT_MODE 1
+#define DUALDAC_MODE 2
+#define SPDIFIN_MODE 4
+ unsigned char spdif_control_bits[24];
+ /* Audio parameters */
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+ int open_mode;
+ int audio_initialized;
+ cmpci_portc portc[MAX_PORTC];
+
+ /* spdif/ac3 stuff */
+ int spdif_enabled;
+ int can_ac3;
+
+ /* Mixer parameters */
+ int mixer_dev;
+ int *levels;
+ int recmask;
+
+ /* uart401 */
+ int uart401_attached;
+ uart401_devc uart401devc;
+}
+cmpci_devc;
+
+
+static void
+set_spdif_rate (cmpci_devc * devc, cmpci_portc * portc)
+{
+ if (portc->speed == 48000)
+ {
+ /* setup MISC control reg */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 24) | (1 << 15),
+ MISC_CTRL);
+ }
+ else
+ {
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 15),
+ MISC_CTRL);
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 24),
+ MISC_CTRL);
+ }
+}
+
+static void
+setup_ac3 (cmpci_devc * devc, cmpci_portc * portc, int value)
+{
+ if (value && (portc->speed == 48000 || portc->speed == 44100))
+ {
+ if (devc->chiprev == 37)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) | (1 << 20),
+ CHFORMAT);
+ }
+ else
+ {
+ /* Enable AC3 */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 18),
+ MISC_CTRL);
+ }
+ }
+ else
+ {
+ if (devc->chiprev == 37)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) & ~(1 << 20),
+ CHFORMAT);
+ }
+ else
+ {
+ /* Disable AC3 */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 18),
+ MISC_CTRL);
+ }
+ }
+}
+
+
+static void
+cmpci_setmixer (cmpci_devc * devc, unsigned int port, unsigned int value)
+{
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, (unsigned char) (port & 0xff), MIXER_ADDR);
+ oss_udelay (20);
+ OUTB (devc->osdev, (unsigned char) (value & 0xff), MIXER_DATA);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ oss_udelay (20);
+}
+
+static unsigned int
+cmpci_getmixer (cmpci_devc * devc, unsigned int port)
+{
+ unsigned int val;
+
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, (unsigned char) (port & 0xff), MIXER_ADDR);
+
+
+ oss_udelay (20);
+ val = INB (devc->osdev, MIXER_DATA);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ oss_udelay (20);
+ return val;
+}
+
+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;
+
+#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}}
+
+static mixer_tab cmpci_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_LINE1, 0, 0, 0, 0, 0, 0),
+ MIX_ENT (SOUND_MIXER_RECLEV, 0x3f, 7, 2, 0x40, 7, 2),
+ MIX_ENT (SOUND_MIXER_IGAIN, 0x3f, 7, 2, 0x40, 7, 2),
+ MIX_ENT (SOUND_MIXER_OGAIN, 0x41, 7, 2, 0x42, 7, 2)
+};
+
+/*ARGSUSED*/
+static void
+change_bits (cmpci_devc * devc, unsigned char *regval, int dev, int chn,
+ int newval)
+{
+ unsigned char mask;
+ int shift;
+
+ mask = (1 << cmpci_mix[dev][chn].nbits) - 1;
+ newval = (int) ((newval * mask) + 50) / 100; /* Scale */
+
+ shift = cmpci_mix[dev][chn].bitoffs - cmpci_mix[dev][LEFT_CHN].nbits + 1;
+
+ *regval &= ~(mask << shift); /* Mask out previous value */
+ *regval |= (newval & mask) << shift; /* Set the new value */
+}
+
+static int set_recmask (int dev, int mask);
+
+static int
+cmpci_mixer_set (cmpci_devc * devc, int chan, int value)
+{
+ int left = value & 0x000000ff;
+ int right = (value & 0x0000ff00) >> 8;
+
+ int regoffs;
+ unsigned char val;
+
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+
+ if (chan > 31)
+ return OSS_EINVAL;
+
+ if (!(CMEDIA_MIXER_DEVICES & (1 << chan))) /*
+ * Not supported
+ */
+ return OSS_EINVAL;
+
+ regoffs = cmpci_mix[chan][LEFT_CHN].regno;
+
+ if (regoffs == 0)
+ return OSS_EINVAL;
+
+ val = cmpci_getmixer (devc, regoffs);
+ change_bits (devc, &val, chan, LEFT_CHN, left);
+
+ devc->levels[chan] = left | (left << 8);
+
+ if (cmpci_mix[chan][RIGHT_CHN].regno != regoffs) /*
+ * Change register
+ */
+ {
+ cmpci_setmixer (devc, regoffs, val); /*
+ * Save the old one
+ */
+ regoffs = cmpci_mix[chan][RIGHT_CHN].regno;
+
+ if (regoffs == 0)
+ return left | (left << 8); /*
+ * Just left channel present
+ */
+
+ val = cmpci_getmixer (devc, regoffs); /*
+ * Read the new one
+ */
+ }
+
+ change_bits (devc, &val, chan, RIGHT_CHN, right);
+
+ cmpci_setmixer (devc, regoffs, val);
+
+ devc->levels[chan] = left | (right << 8);
+ return left | (right << 8);
+}
+
+static int cmpci_outsw (int dev, int ctrl, unsigned int cmd, int value);
+
+/*ARGSUSED*/
+static int
+cmpci_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ cmpci_devc *devc = mixer_devs[dev]->devc;
+ int val;
+
+ if (((cmd >> 8) & 0xff) == 'M')
+ {
+ if (IOC_IS_OUTPUT (cmd))
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ val = *arg;
+ if (val == SOUND_MASK_LINE1)
+ *arg = cmpci_outsw (dev, AUX_REC, SNDCTL_MIX_WRITE, 1);
+ else
+ *arg = cmpci_outsw (dev, AUX_REC, SNDCTL_MIX_WRITE, 0);
+ return *arg = set_recmask (dev, val);
+ break;
+
+ case SOUND_MIXER_LINE1:
+ val = *arg;
+ return *arg = cmpci_outsw (dev, AUX_LEVEL, SNDCTL_MIX_WRITE, val);
+ break;
+
+ default:
+ val = *arg;
+ return *arg = cmpci_mixer_set (devc, cmd & 0xff, val);
+ }
+ else
+ switch (cmd & 0xff)
+ {
+
+ case SOUND_MIXER_RECSRC:
+ return *arg = devc->recmask;
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ return *arg = CMEDIA_MIXER_DEVICES;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ return *arg = CMEDIA_MIXER_DEVICES &
+ ~(SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
+ break;
+
+ case SOUND_MIXER_RECMASK:
+ return *arg = CMEDIA_RECORDING_DEVICES;
+ break;
+
+ case SOUND_MIXER_LINE1:
+ val = cmpci_outsw (dev, AUX_LEVEL, SNDCTL_MIX_READ, 0);
+ return *arg = val;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ return *arg = SOUND_CAP_EXCL_INPUT;
+ break;
+
+ default:
+ return *arg = devc->levels[cmd & 0x1f];
+ }
+ }
+ else
+ return OSS_EINVAL;
+}
+
+static int
+set_recmask (int dev, int mask)
+{
+ cmpci_devc *devc = mixer_devs[dev]->devc;
+ int devmask = mask & CMEDIA_RECORDING_DEVICES;
+ int i;
+ unsigned char regimageL, regimageR;
+
+ if (!devmask)
+ devmask = SOUND_MASK_MIC;
+
+ regimageL = regimageR = 0;
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if ((1 << i) & devmask)
+ {
+ regimageL |= cmpci_recmasks_L[i];
+ regimageR |= cmpci_recmasks_R[i];
+ }
+ cmpci_setmixer (devc, CMPCI_IMASK_L, regimageL);
+ cmpci_setmixer (devc, CMPCI_IMASK_R, regimageR);
+ devc->recmask = devmask;
+ return devc->recmask;
+}
+
+static int
+cmpci_outsw (int dev, int ctrl, unsigned int cmd, int value)
+{
+/*
+ * Access function for CMPCI mixer extension bits
+ */
+ cmpci_devc *devc = mixer_devs[dev]->devc;
+ int left, right, tmp;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case MUTE_LINE: /* Left line in to output connection */
+ value = (cmpci_getmixer (devc, 0x3c) & 0x18) ? 0 : 1;
+ break;
+
+ case MUTE_CD: /* Cd in to output connection */
+ value = (cmpci_getmixer (devc, 0x3c) & 0x06) ? 0 : 1;
+ break;
+
+ case MUTE_MIC: /* Mic in to output connection */
+ value = (cmpci_getmixer (devc, 0x3c) & 0x01) ? 0 : 1;
+ break;
+
+ case MODE_4SPK: /* 4Speaker out */
+ value = INL (devc->osdev, MISC_CTRL) & (1 << 26) ? 1 : 0;
+ break;
+
+ case DUALDAC: /* dual dac */
+ value = devc->dev_mode & DUALDAC_MODE ? 1 : 0;
+ break;
+
+ case REAR2LINE: /* rear to line in */
+ value = INB (devc->osdev, MIXER1) & (1 << 5) ? 1 : 0;
+ break;
+
+ case CEN2LINE: /* center to line in */
+ value = INL (devc->osdev, LEGACY_CTRL) & (1 << 14) ? 1 : 0;
+ break;
+
+ case BASS2LINE: /* basss to line in */
+ value = INL (devc->osdev, LEGACY_CTRL) & (1 << 13) ? 1 : 0;
+ break;
+
+ case SPDIF_PLAY: /* spdif out */
+ value = INL (devc->osdev, LEGACY_CTRL) & (1 << 23) ? 1 : 0;
+ break;
+
+ case SPDIF_LOOP: /* S/PDIF I/O Loop */
+ value = (INL (devc->osdev, FUNCTRL1) & (1 << 7)) ? 1 : 0;
+ break;
+
+ case SPDIF_REC: /* spdif record mode */
+ value = devc->dev_mode & SPDIFIN_MODE ? 1 : 0;
+ break;
+
+ case SPDIF_IMON: /* spdif input monitor */
+ value = INB (devc->osdev, MIXER1) & 0x1 ? 1 : 0;
+ break;
+
+ case SPDIF_POL: /* spdif input reverse */
+ if (devc->chiprev < 39)
+ value = INB (devc->osdev, MIXER3) & 0x06 ? 1 : 0;
+ else
+ value = INL (devc->osdev, CHFORMAT) & 0x80 ? 1 : 0;
+ break;
+
+ case SPDIF_AC3: /* ac3 */
+ value = INL (devc->osdev, MISC_CTRL) & (1 << 18) ? 1 : 0;
+ break;
+
+ case SPDIF_COPY: /* copy protect (indirect) */
+ value = INL (devc->osdev, LEGACY_CTRL) & (1 << 22) ? 1 : 0;
+ break;
+
+ case SPDIF_OPT: /* Coax/Optical Select */
+ value = INL (devc->osdev, MISC_CTRL) & (1 << 25) ? 1 : 0;
+ break;
+
+ case CEN2MIC: /* Center2MIC */
+ if (devc->chiprev >= 39)
+ value = INB (devc->osdev, MIXER3) & 0x4 ? 1 : 0;
+ break;
+
+ case MICBOOST: /* MIC Boost */
+ value = INB (devc->osdev, MIXER2) & 0x1 ? 0 : 1;
+ break;
+
+ case AUX_LEVEL:
+ value = devc->levels[SOUND_MIXER_LINE1];
+ break;
+
+ case AUX_REC: /* set LINE1 as rec source - handled by set_recmask */
+ break;
+
+ case MUTE_AUX: /* AUX mute */
+ value = INB (devc->osdev, MIXER2) & 0x30 ? 0 : 1;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ return value;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case MUTE_LINE: /* L/R line in to output connection */
+ if (!value)
+ cmpci_setmixer (devc, 0x3c, cmpci_getmixer (devc, 0x3c) | 0x18);
+ else
+ cmpci_setmixer (devc, 0x3c, cmpci_getmixer (devc, 0x3c) & ~0x18);
+ break;
+
+ case MUTE_CD: /* Cd in to output connection */
+ if (!value)
+ cmpci_setmixer (devc, 0x3c, cmpci_getmixer (devc, 0x3c) | 0x06);
+ else
+ cmpci_setmixer (devc, 0x3c, cmpci_getmixer (devc, 0x3c) & ~0x06);
+ break;
+
+ case MUTE_MIC: /* Mic in to output connection */
+ if (!value)
+ cmpci_setmixer (devc, 0x3c, cmpci_getmixer (devc, 0x3c) | 0x01);
+ else
+ cmpci_setmixer (devc, 0x3c, cmpci_getmixer (devc, 0x3c) & ~0x01);
+ break;
+
+ case MODE_4SPK: /* 4Speaker out */
+ if (value)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 26),
+ MISC_CTRL);
+ devc->mode_4spk = 1;
+ }
+ else
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 26),
+ MISC_CTRL);
+ devc->mode_4spk = 0;
+ break;
+
+ case DUALDAC: /* DUAL DAC mode */
+ if (value)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 23),
+ MISC_CTRL);
+ /* Disable 4Speaker mode */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 26),
+ MISC_CTRL);
+ devc->dev_mode = DUALDAC_MODE;
+ }
+ else
+ {
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 23),
+ MISC_CTRL);
+
+ /* enable back the 4Speaker mode */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | 1 << 26,
+ MISC_CTRL);
+
+ devc->dev_mode = DEFAULT_MODE;
+ }
+ break;
+
+ case REAR2LINE: /* REAR TO LINEIN */
+ if (value)
+ {
+ OUTB (devc->osdev, (INB (devc->osdev, MIXER1) | (1 << 5)),
+ MIXER1);
+ }
+ else
+ OUTB (devc->osdev, (INB (devc->osdev, MIXER1) & ~(1 << 5)),
+ MIXER1);
+ break;
+
+ case CEN2LINE: /* CENTER TO LINEIN */
+ if (value)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (1 << 14),
+ LEGACY_CTRL);
+ }
+ else
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(1 << 14),
+ LEGACY_CTRL);
+ break;
+
+ case BASS2LINE: /* BASS TO LINEIN */
+ if (value)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (1 << 13),
+ LEGACY_CTRL);
+ }
+ else
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(1 << 13),
+ LEGACY_CTRL);
+ break;
+
+ case SPDIF_PLAY: /* SPDIF ENABLE */
+ if (value)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (1 << 23),
+ LEGACY_CTRL);
+
+ /* enable wave/fm/midi to spdif OUT DAC2SPDO on rev 33/37 */
+ if (devc->chiprev < 39)
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (1 << 21),
+ LEGACY_CTRL);
+ devc->spdif_enabled = 1;
+ }
+ else
+ {
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(1 << 23),
+ LEGACY_CTRL);
+ /* Disable wave/fm/midi to spdif OUT (DAC2SPDO) */
+ if (devc->chiprev < 39)
+ OUTL (devc->osdev,
+ INL (devc->osdev, LEGACY_CTRL) & ~(1 << 21),
+ LEGACY_CTRL);
+ devc->spdif_enabled = 0;
+ }
+ break;
+
+ case SPDIF_LOOP: /* S/PDIF I/O Loop */
+ if (value)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, FUNCTRL1) | (1 << 7),
+ FUNCTRL1);
+ }
+ else
+ OUTL (devc->osdev, INL (devc->osdev, FUNCTRL1) & ~(1 << 7),
+ FUNCTRL1);
+ break;
+
+ case SPDIF_REC: /* SPDIF Record Mode */
+ if (value)
+ {
+ devc->dev_mode = SPDIFIN_MODE;
+ }
+ else
+ devc->dev_mode = DEFAULT_MODE;
+ break;
+
+ case SPDIF_IMON: /* spdif monitor */
+ if (value)
+ {
+ OUTB (devc->osdev, INB (devc->osdev, MIXER1) | 0x0D, MIXER1);
+ }
+ else
+ OUTB (devc->osdev, INB (devc->osdev, MIXER1) & ~0xD, MIXER1);
+ break;
+
+ case SPDIF_POL: /* spdif reverse */
+ if (value)
+ {
+ if (devc->chiprev < 39)
+ {
+ OUTB (devc->osdev, INB (devc->osdev, MIXER3) | 0x06,
+ MIXER3);
+ }
+ else
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) | 0x80,
+ CHFORMAT);
+ }
+ else
+ {
+ if (devc->chiprev < 39)
+ {
+ OUTB (devc->osdev, INB (devc->osdev, MIXER3) & ~0x06,
+ MIXER3);
+ }
+ else
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) & ~0x80,
+ CHFORMAT);
+ }
+ break;
+
+ case SPDIF_AC3: /* AC3 enabled on S/PDIF */
+ if (value)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 18),
+ MISC_CTRL);
+ }
+ else
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 18),
+ MISC_CTRL);
+ break;
+
+ case SPDIF_COPY: /* Copy protect */
+ if (value)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (1 << 22),
+ LEGACY_CTRL);
+ }
+ else
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(1 << 22),
+ LEGACY_CTRL);
+ break;
+
+ case SPDIF_OPT: /* Coax/Optical */
+ if (value)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 25),
+ MISC_CTRL);
+ }
+ else
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 25),
+ MISC_CTRL);
+ break;
+
+ case CEN2MIC: /* Center -> Mic OUT */
+ if (value)
+ {
+ if (devc->chiprev >= 39)
+ {
+ OUTB (devc->osdev, INB (devc->osdev, MIXER3) | 0x4, MIXER3);
+ }
+ }
+ else if (devc->chiprev >= 39)
+ {
+ OUTB (devc->osdev, INB (devc->osdev, MIXER3) & ~0x4, MIXER3);
+ }
+ break;
+
+ case MICBOOST: /* Mic Boost */
+ if (!value)
+ {
+ OUTB (devc->osdev, INB (devc->osdev, MIXER2) | 0x1, MIXER2);
+ }
+ else
+ OUTB (devc->osdev, INB (devc->osdev, MIXER2) & ~0x1, MIXER2);
+ break;
+
+ case AUX_LEVEL: /* Aux levels */
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ left = mix_cvt[left];
+ right = mix_cvt[right];
+
+ tmp = ((right * ((1 << 4) - 1) / 100) << 4) |
+ (left * ((1 << 4) - 1) / 100);
+
+ OUTB (devc->osdev, tmp, AUX_VOL);
+ devc->levels[SOUND_MIXER_LINE1] = value;
+ break;
+
+ case AUX_REC: /* line1 record select */
+ if (value)
+ {
+ OUTB (devc->osdev, INB (devc->osdev, MIXER2) | 0xc0, MIXER2);
+ }
+ else
+ OUTB (devc->osdev, INB (devc->osdev, MIXER2) & ~0xc0, MIXER2);
+ break;
+
+ case MUTE_AUX: /* line1 mute control */
+ if (!value)
+ {
+ OUTB (devc->osdev, INB (devc->osdev, MIXER2) | 0x30, MIXER2);
+ }
+ else
+ OUTB (devc->osdev, INB (devc->osdev, MIXER2) & ~0x30, MIXER2);
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ return (value);
+ }
+ return OSS_EINVAL;
+}
+
+static int
+cmpci_mix_init (int dev)
+{
+ int group, err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "CMPCI_MUTECTL")) < 0)
+ return group;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, MUTE_LINE, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_LINEMUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, MUTE_CD, cmpci_outsw, MIXT_ONOFF,
+ "CMPCI_CDMUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, MUTE_MIC, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_MICMUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, MUTE_AUX, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_LINE1MUTE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "CMPCI_JACKCTL")) < 0)
+ return group;
+ if ((err =
+ mixer_ext_create_control (dev, group, REAR2LINE, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_REAR2LINE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ if ((err =
+ mixer_ext_create_control (dev, group, CEN2LINE, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_CEN2LINE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ if ((err =
+ mixer_ext_create_control (dev, group, BASS2LINE, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_BASS2LINE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, CEN2MIC, cmpci_outsw, MIXT_ONOFF,
+ "CMPCI_CEN2MIC", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+
+ if ((group = mixer_ext_create_group (dev, 0, "CMPCI_MIXEXT")) < 0)
+ return group;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, MODE_4SPK, cmpci_outsw,
+ MIXT_ENUM, "CMPCI_SPKMODE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, DUALDAC, cmpci_outsw, MIXT_ONOFF,
+ "CMPCI_DUALDAC", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, MICBOOST, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_MICBOOST", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ /* Create a new SPDIF group */
+ if ((group = mixer_ext_create_group (dev, 0, "CMPCI_SPDIF")) < 0)
+ return group;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIF_PLAY, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_Play", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIF_LOOP, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_LOOP", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ /* Having this in mixer doesn't make any sense */
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIF_REC, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_RECORD", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIF_IMON, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_IMON", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIF_POL, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_POLREV", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+#if 0
+ /* Having this in mixer doesn't make any sense */
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIF_AC3, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_AC3", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+#endif
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIF_COPY, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_COPYPROT", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIF_OPT, cmpci_outsw,
+ MIXT_ONOFF, "CMPCI_OPTICAL", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+static void
+cmpci_mixer_reset (int dev)
+{
+ int i;
+ cmpci_devc *devc = mixer_devs[dev]->devc;
+
+ devc->levels = load_mixer_volumes ("CM8738_Mixer", default_levels, 1);
+ devc->recmask = 0;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ cmpci_mixer_set (devc, i, devc->levels[i]);
+
+ set_recmask (dev, SOUND_MASK_MIC);
+}
+
+
+static mixer_driver_t cmpci_mixer_driver = {
+ cmpci_mixer_ioctl
+};
+
+
+static int
+cmpciintr (oss_device_t * osdev)
+{
+ cmpci_devc *devc = (cmpci_devc *) osdev->devc;
+ unsigned int intstat, intsrc;
+ int i;
+ int serviced = 0;
+
+ /* see if this is our interrupt */
+ intsrc = INL (devc->osdev, INT_STATUS);
+ if (intsrc & (CM_CH0_INT | CM_CH1_INT))
+ {
+ /* Handle playback */
+ serviced = 1;
+
+ intstat = INB (devc->osdev, INT_HLDCLR + 2);
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ cmpci_portc *portc = &devc->portc[i];
+
+ if (intstat & CM_CH1_INT)
+ {
+ /* do chan1 playback */
+ if ((portc->chan1_play) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ OUTB (devc->osdev, intstat & ~CM_CH1_INT, INT_HLDCLR + 2);
+ OUTB (devc->osdev, intstat | CM_CH1_INT, INT_HLDCLR + 2);
+ oss_audio_outputintr (portc->audiodev, 0);
+ }
+
+ /* do chan1 record */
+ if ((portc->chan1_rec) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ OUTB (devc->osdev, intstat & ~CM_CH1_INT, INT_HLDCLR + 2);
+ OUTB (devc->osdev, intstat | CM_CH1_INT, INT_HLDCLR + 2);
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+
+ if (intstat & CM_CH0_INT)
+ {
+ /* do chan0 playback */
+ if ((portc->chan0_play) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ OUTB (devc->osdev, intstat & ~CM_CH0_INT, INT_HLDCLR + 2);
+ OUTB (devc->osdev, intstat | CM_CH0_INT, INT_HLDCLR + 2);
+ oss_audio_outputintr (portc->audiodev, 0);
+ }
+
+ /* do chan0 record */
+ if ((portc->chan0_rec) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ OUTB (devc->osdev, intstat & ~CM_CH0_INT, INT_HLDCLR + 2);
+ OUTB (devc->osdev, intstat | CM_CH0_INT, INT_HLDCLR + 2);
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+ }
+ }
+
+ if (intsrc & 0x10000)
+ {
+ serviced = 1;
+ uart401_irq (&devc->uart401devc);
+ }
+
+ return serviced;
+}
+
+static int
+cmpci_audio_set_rate (int dev, int arg)
+{
+ cmpci_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+cmpci_audio_set_channels (int dev, short arg)
+{
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+
+ if (devc->model == MDL_CM8768)
+ {
+ if (arg>8)
+ arg=8;
+
+ if ((arg != 1) && (arg != 2) && (arg != 4) && (arg != 6) && (arg != 8))
+ return portc->channels;
+ }
+ else
+ {
+ if (arg>6)
+ arg=6;
+
+ if ((arg != 1) && (arg != 2) && (arg != 4) && (arg != 6))
+ return portc->channels;
+ }
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+cmpci_audio_set_format (int dev, unsigned int arg)
+{
+ cmpci_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE | AFMT_AC3)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+cmpci_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void cmpci_audio_trigger (int dev, int state);
+
+static void
+cmpci_audio_reset (int dev)
+{
+ cmpci_audio_trigger (dev, 0);
+}
+
+static void
+cmpci_audio_reset_input (int dev)
+{
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ cmpci_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+cmpci_audio_reset_output (int dev)
+{
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ cmpci_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+cmpci_audio_open (int dev, int mode, int open_flags)
+{
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (!(devc->dev_mode & DUALDAC_MODE))
+ {
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode |= mode;
+ }
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+cmpci_audio_close (int dev, int mode)
+{
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ cmpci_devc *devc = audio_engines[dev]->devc;
+
+ cmpci_audio_reset (dev);
+ portc->open_mode = 0;
+ devc->open_mode &= ~mode;
+ portc->audio_enabled &= ~mode;
+
+ if ((devc->spdif_enabled) || (devc->dev_mode & SPDIFIN_MODE))
+ OUTL (devc->osdev, INL (devc->osdev, FUNCTRL1) & ~(1 << 9), FUNCTRL1);
+
+ if (portc->chan0_play)
+ portc->chan0_play = 0;
+
+ if (portc->chan1_play)
+ portc->chan1_play = 0;
+
+ if (portc->chan0_rec)
+ portc->chan0_rec = 0;
+
+ if (portc->chan1_rec)
+ portc->chan1_rec = 0;
+}
+
+/*ARGSUSED*/
+static void
+cmpci_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ cmpci_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+cmpci_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ cmpci_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+cmpci_audio_trigger (int dev, int state)
+{
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ if (portc->chan0_play)
+ {
+ /* enable the channel0 */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) | CM_CH0_ENABLE,
+ FUNCTRL0 + 2);
+ OUTB (devc->osdev,
+ INB (devc->osdev, INT_HLDCLR + 2) | CM_CH0_INT,
+ INT_HLDCLR + 2);
+ }
+
+ if (portc->chan1_play)
+ {
+ /* enable the channel1 */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) | CM_CH1_ENABLE,
+ FUNCTRL0 + 2);
+ OUTB (devc->osdev,
+ INB (devc->osdev, INT_HLDCLR + 2) | CM_CH1_INT,
+ INT_HLDCLR + 2);
+ }
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ if (portc->chan0_play)
+ {
+ /* disable interrupt */
+ OUTB (devc->osdev,
+ INB (devc->osdev, INT_HLDCLR + 2) & ~CM_CH0_INT,
+ INT_HLDCLR + 2);
+
+ /* disable channel0 */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) & ~CM_CH0_ENABLE,
+ FUNCTRL0 + 2);
+ }
+ if (portc->chan1_play)
+ {
+ /* disable interrupt */
+ OUTB (devc->osdev,
+ INB (devc->osdev, INT_HLDCLR + 2) & ~CM_CH1_INT,
+ INT_HLDCLR + 2);
+
+ /* disable channel */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) & ~CM_CH1_ENABLE,
+ FUNCTRL0 + 2);
+ }
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ if (portc->chan1_rec)
+ {
+ /* enable the channel1 */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) | CM_CH1_ENABLE,
+ FUNCTRL0 + 2);
+ OUTB (devc->osdev,
+ INB (devc->osdev, INT_HLDCLR + 2) | CM_CH1_INT,
+ INT_HLDCLR + 2);
+ }
+ if (portc->chan0_rec)
+ {
+ /* enable the channel0 */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) | CM_CH0_ENABLE,
+ FUNCTRL0 + 2);
+ OUTB (devc->osdev,
+ INB (devc->osdev, INT_HLDCLR + 2) | CM_CH0_INT,
+ INT_HLDCLR + 2);
+ }
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ if (portc->chan1_rec)
+ {
+ /* disable interrupt */
+ OUTB (devc->osdev,
+ INB (devc->osdev, INT_HLDCLR + 2) & ~CM_CH1_INT,
+ INT_HLDCLR + 2);
+
+ /* disable channel 1 */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) & ~CM_CH1_ENABLE,
+ FUNCTRL0 + 2);
+ }
+ if (portc->chan0_rec)
+ {
+ /* disable interrupt */
+ OUTB (devc->osdev,
+ INB (devc->osdev, INT_HLDCLR + 2) & ~CM_CH0_INT,
+ INT_HLDCLR + 2);
+
+ /* disable channel 0 */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) & ~CM_CH0_ENABLE,
+ FUNCTRL0 + 2);
+
+ }
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+set_dac_rate (int dev, int chan_type)
+{
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ unsigned char freq = 4, val;
+ int i;
+ int rate = portc->speed;
+
+ if (rate > 48000)
+ rate = 48000;
+ if (rate < 5512)
+ rate = 5512;
+
+ for (i = 0; i < sizeof (rate_lookup) / sizeof (rate_lookup[0]); i++)
+ {
+ if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper)
+ {
+ rate = rate_lookup[i].rate;
+ freq = rate_lookup[i].freq;
+ break;
+ }
+ }
+ if (chan_type == CHAN0)
+ {
+ val = INB (devc->osdev, FUNCTRL1 + 1) & ~0x1c;
+ OUTB (devc->osdev, val | freq << 2, FUNCTRL1 + 1);
+ }
+ else
+ {
+ val = INB (devc->osdev, FUNCTRL1 + 1) & ~0xe0;
+ OUTB (devc->osdev, val | freq << 5, FUNCTRL1 + 1);
+ }
+ if (devc->spdif_enabled)
+ set_spdif_rate (devc, portc);
+}
+
+static void
+set_dac_fmt (int dev, int chan_type)
+{
+ unsigned char val;
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ int channels = portc->channels;
+ int bits = portc->bits;
+
+ if (chan_type == CHAN0)
+ {
+ /* Set the format on Channl 0 */
+ val = INB (devc->osdev, CHFORMAT) & ~0x3;
+
+ if ((channels == 1) && (bits == 8))
+ {
+ OUTB (devc->osdev, 0x00 | val, CHFORMAT);
+ portc->dacfmt = 0;
+ }
+
+ if ((channels == 2) && (bits == 8))
+ {
+ OUTB (devc->osdev, 0x01 | val, CHFORMAT);
+ portc->dacfmt = 1;
+ }
+
+ if ((channels == 1) && (bits == 16))
+ {
+ OUTB (devc->osdev, 0x02 | val, CHFORMAT);
+ portc->dacfmt = 1;
+ }
+
+ if ((channels > 1) && (bits == 16))
+ {
+ OUTB (devc->osdev, 0x03 | val, CHFORMAT);
+ portc->dacfmt = 2;
+ }
+ }
+ else
+ {
+ /* Set the format on Channel 1 */
+ val = INB (devc->osdev, CHFORMAT) & ~0xC;
+
+ if ((channels == 1) && (bits == 8))
+ {
+ OUTB (devc->osdev, 0x00 | val, CHFORMAT);
+ portc->dacfmt = 0;
+ }
+
+ if ((channels == 2) && (bits == 8))
+ {
+ OUTB (devc->osdev, 0x04 | val, CHFORMAT);
+ portc->dacfmt = 1;
+ }
+
+ if ((channels == 1) && (bits == 16))
+ {
+ OUTB (devc->osdev, 0x08 | val, CHFORMAT);
+ portc->dacfmt = 1;
+ }
+
+ if ((channels > 1) && (bits == 16))
+ {
+ OUTB (devc->osdev, 0x0C | val, CHFORMAT);
+ portc->dacfmt = 2;
+ }
+ }
+}
+
+
+static void
+set_adc_rate (int dev, int chan_type)
+{
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ unsigned char freq = 4, val;
+ int i;
+ int rate = portc->speed;
+
+ if (rate > 48000)
+ rate = 48000;
+ if (rate < 5512)
+ rate = 5512;
+ for (i = 0; i < sizeof (rate_lookup) / sizeof (rate_lookup[0]); i++)
+ {
+ if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper)
+ {
+ rate = rate_lookup[i].rate;
+ freq = rate_lookup[i].freq;
+ break;
+ }
+ }
+ if (chan_type == CHAN1)
+ {
+ val = INB (devc->osdev, FUNCTRL1 + 1) & ~0xe0;
+ OUTB (devc->osdev, val | freq << 5, FUNCTRL1 + 1);
+ }
+ else
+ {
+ val = INB (devc->osdev, FUNCTRL1 + 1) & ~0x1c;
+ OUTB (devc->osdev, val | freq << 2, FUNCTRL1 + 1);
+ }
+
+ if (devc->dev_mode & SPDIFIN_MODE)
+ set_spdif_rate (devc, portc);
+}
+
+static void
+set_adc_fmt (int dev, int chan_type)
+{
+ unsigned char val;
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ int channels = portc->channels;
+ int bits = portc->bits;
+
+ if (chan_type == CHAN1)
+ {
+ /* Set the format on Channel 1 */
+ val = INB (devc->osdev, CHFORMAT) & ~0xC;
+
+ if ((channels == 1) && (bits == 8))
+ {
+ OUTB (devc->osdev, 0x00 | val, CHFORMAT);
+ portc->adcfmt = 0;
+ }
+
+ if ((channels == 2) && (bits == 8))
+ {
+ OUTB (devc->osdev, 0x04 | val, CHFORMAT);
+ portc->adcfmt = 1;
+ }
+
+ if ((channels == 1) && (bits == 16))
+ {
+ OUTB (devc->osdev, 0x08 | val, CHFORMAT);
+ portc->adcfmt = 1;
+ }
+
+ if ((channels > 1) && (bits == 16))
+ {
+ OUTB (devc->osdev, 0x0C | val, CHFORMAT);
+ portc->adcfmt = 2;
+ }
+ }
+ else
+ {
+ /* Set the format on Channl 0 */
+ val = INB (devc->osdev, CHFORMAT) & ~0x3;
+
+ if ((channels == 1) && (bits == 8))
+ {
+ OUTB (devc->osdev, 0x00 | val, CHFORMAT);
+ portc->adcfmt = 0;
+ }
+
+ if ((channels == 2) && (bits == 8))
+ {
+ OUTB (devc->osdev, 0x01 | val, CHFORMAT);
+ portc->adcfmt = 1;
+ }
+
+ if ((channels == 1) && (bits == 16))
+ {
+ OUTB (devc->osdev, 0x02 | val, CHFORMAT);
+ portc->adcfmt = 1;
+ }
+
+ if ((channels == 2) && (bits == 16))
+ {
+ OUTB (devc->osdev, 0x03 | val, CHFORMAT);
+ portc->adcfmt = 2;
+ }
+ }
+}
+
+static void
+setup_record (int dev, int chan_type)
+{
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+
+ if (chan_type == CHAN1) /* SPDIF Record can only occur on CHAN1 */
+ {
+ /* reset and disable channel */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) | CM_CH1_RESET, FUNCTRL0 + 2);
+ oss_udelay (10);
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) & ~CM_CH1_RESET, FUNCTRL0 + 2);
+
+ cmpci_outsw (devc->mixer_dev, SPDIF_PLAY, SNDCTL_MIX_WRITE, 0);
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, CH1_FRAME1);
+ OUTW (devc->osdev, (dmap->bytes_in_use >> portc->adcfmt) - 1,
+ CH1_FRAME2);
+ OUTW (devc->osdev, (dmap->fragment_size >> portc->adcfmt),
+ CH1_FRAME2 + 2);
+
+ /* set channel 1 to record mode */
+ OUTB (devc->osdev, INB (devc->osdev, FUNCTRL0) | CM_CH1_RECORD,
+ FUNCTRL0);
+ portc->chan1_rec = 1;
+
+ /* setup SPDIF in on CHAN A */
+ OUTL (devc->osdev, INL (devc->osdev, FUNCTRL1) | (1 << 9), FUNCTRL1);
+ }
+ else /* Normal PCM record on Channel 0 */
+ {
+ /* reset and disable channel */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) | CM_CH0_RESET, FUNCTRL0 + 2);
+ oss_udelay (10);
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) & ~CM_CH0_RESET, FUNCTRL0 + 2);
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, CH0_FRAME1);
+ OUTW (devc->osdev, (dmap->bytes_in_use >> portc->adcfmt) - 1,
+ CH0_FRAME2);
+ OUTW (devc->osdev, (dmap->fragment_size >> portc->adcfmt),
+ CH0_FRAME2 + 2);
+
+ /* set channel 0 to record mode */
+ OUTB (devc->osdev, INB (devc->osdev, FUNCTRL0) | CM_CH0_RECORD,
+ FUNCTRL0);
+ portc->chan0_rec = 1;
+ }
+}
+
+/*ARGSUSED*/
+static int
+cmpci_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ switch (devc->dev_mode)
+ {
+ case DEFAULT_MODE:
+ set_adc_rate (dev, CHAN0);
+ set_adc_fmt (dev, CHAN0);
+ setup_record (dev, CHAN0);
+ break;
+
+ case DUALDAC_MODE:
+ cmn_err (CE_WARN, "Cannot record because DUALDAC mode is ON.\n");
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EIO;
+
+ case SPDIFIN_MODE:
+ if (portc->speed < 44100)
+ {
+ cmn_err (CE_WARN,
+ "Cannot record spdif at sampling rate less than 44.1Khz.\n");
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EIO;
+ }
+ set_adc_rate (dev, CHAN1);
+ set_adc_fmt (dev, CHAN1);
+ setup_record (dev, CHAN1);
+ break;
+ }
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+setup_play (int dev, int chan_type)
+{
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+
+ if (chan_type == CHAN0)
+ {
+ /* reset channel */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) | CM_CH0_RESET, FUNCTRL0 + 2);
+ oss_udelay (10);
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) & ~CM_CH0_RESET, FUNCTRL0 + 2);
+ oss_udelay (10);
+
+ /* Now set the buffer address/sizes */
+ OUTL (devc->osdev, dmap->dmabuf_phys, CH0_FRAME1);
+ OUTW (devc->osdev, (dmap->bytes_in_use >> portc->dacfmt) - 1,
+ CH0_FRAME2);
+ OUTW (devc->osdev, (dmap->fragment_size >> portc->dacfmt),
+ CH0_FRAME2 + 2);
+
+ /* set channel 0 to play mode */
+ OUTB (devc->osdev, INB (devc->osdev, FUNCTRL0) & CM_CH0_PLAY, FUNCTRL0);
+ portc->chan0_play = 1;
+
+ /* setup spdif output on CHAN A , disable CHAN B spdif */
+ if (devc->spdif_enabled)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, FUNCTRL1) | (1 << 8),
+ FUNCTRL1);
+ OUTL (devc->osdev, INL (devc->osdev, FUNCTRL1) & ~(1 << 9),
+ FUNCTRL1);
+ }
+ }
+ else
+ {
+ /* reset and disable channel */
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) | CM_CH1_RESET, FUNCTRL0 + 2);
+ oss_udelay (10);
+ OUTB (devc->osdev,
+ INB (devc->osdev, FUNCTRL0 + 2) & ~CM_CH1_RESET, FUNCTRL0 + 2);
+ oss_udelay (10);
+
+ /* Handle 4/5/6 channel mode */
+ if (portc->channels < 4)
+ {
+ /* check if 4speaker mode is enabled from mixer or not */
+ if (devc->mode_4spk)
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 26),
+ MISC_CTRL);
+
+ /* disable 4channel mode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) & ~(1 << 29),
+ CHFORMAT);
+ /* disable 5 channel mode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) & ~(0x80000000),
+ CHFORMAT);
+ /* disable 6channel mode out CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(1 << 15),
+ LEGACY_CTRL);
+ /* disable 8 channel decode on CHAN B - only for CMI8768 */
+ if (devc->model == MDL_CM8768)
+ OUTB (devc->osdev, INB (devc->osdev, MISC2_CTRL) & ~0x20,
+ MISC2_CTRL);
+ /* Set NXCNG */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(0x80000000),
+ LEGACY_CTRL);
+ }
+
+ if ((portc->channels == 4) && (devc->chiprev > 37))
+ {
+ /* disable 4 speaker mode */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 26),
+ MISC_CTRL);
+ /* enable 4channel mode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) | (1 << 29),
+ CHFORMAT);
+
+ /* disable 5 channel mode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) & ~(0x80000000),
+ CHFORMAT);
+ /* disable 6channel mode out CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(1 << 15),
+ LEGACY_CTRL);
+ /* disable center/bass channel */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 7),
+ MISC_CTRL);
+ /* disable bass */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(1 << 12),
+ LEGACY_CTRL);
+
+ /* disable 8 channel decode on CHAN B - only for CMI8768 */
+ if (devc->model == MDL_CM8768)
+ OUTB (devc->osdev, INB (devc->osdev, MISC2_CTRL) & ~0x20,
+ MISC2_CTRL);
+ /* Set NXCNG */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(0x80000000),
+ LEGACY_CTRL);
+ }
+
+ if ((portc->channels == 6) && (devc->chiprev > 37))
+ {
+ /* disable 4 speaker mode */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 26),
+ MISC_CTRL);
+ /* disable 4channel mode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) & ~(1 << 29),
+ CHFORMAT);
+
+ /* enable center channel */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 7),
+ MISC_CTRL);
+ /* enable bass */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (1 << 12),
+ LEGACY_CTRL);
+ /* enable 5 channel mode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) | (0x80000000),
+ CHFORMAT);
+ /* enable 6 channel decode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (1 << 15),
+ LEGACY_CTRL);
+
+ /* disable 8 channel decode on CHAN B - only for CMI8768 */
+ if (devc->model == MDL_CM8768)
+ OUTB (devc->osdev, INB (devc->osdev, MISC2_CTRL) & ~0x20,
+ MISC2_CTRL);
+
+ /* Set NXCNG */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (0x80000000),
+ LEGACY_CTRL);
+ }
+
+ if ((portc->channels == 8) && (devc->model == MDL_CM8768))
+ {
+ /* disable 4 speaker mode */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) & ~(1 << 26),
+ MISC_CTRL);
+ /* disable 4channel mode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) & ~(1 << 29),
+ CHFORMAT);
+
+ /* enable center channel */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 7),
+ MISC_CTRL);
+ /* enable bass channel */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (1 << 12),
+ LEGACY_CTRL);
+ /* disable 5 channel mode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, CHFORMAT) & ~(0x80000000),
+ CHFORMAT);
+ /* disable 6 channel decode on CHAN B */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) & ~(1 << 15),
+ LEGACY_CTRL);
+
+ /* enable 8 channel decode on CHAN B */
+ OUTB (devc->osdev, INB (devc->osdev, MISC2_CTRL) | 0x20,
+ MISC2_CTRL);
+ /* Set NXCNG */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (0x80000000),
+ LEGACY_CTRL);
+ }
+
+ /* Now set the buffer address/sizes */
+ OUTL (devc->osdev, dmap->dmabuf_phys, CH1_FRAME1);
+ OUTW (devc->osdev, (dmap->bytes_in_use >> portc->dacfmt) - 1,
+ CH1_FRAME2);
+ OUTW (devc->osdev, (dmap->fragment_size >> portc->dacfmt),
+ CH1_FRAME2 + 2);
+
+
+ /* set channel 1 to play mode */
+ OUTB (devc->osdev, INB (devc->osdev, FUNCTRL0) & CM_CH1_PLAY, FUNCTRL0);
+ portc->chan1_play = 1;
+
+ /* setup spdif output on CHAN B , disable CHAN A spdif */
+ if (devc->spdif_enabled)
+ {
+ OUTL (devc->osdev, INL (devc->osdev, FUNCTRL1) | (1 << 9),
+ FUNCTRL1);
+ OUTL (devc->osdev, INL (devc->osdev, FUNCTRL1) & ~(1 << 8),
+ FUNCTRL1);
+ }
+ }
+}
+
+/*ARGSUSED*/
+static int
+cmpci_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if ((portc->bits == AFMT_AC3) && devc->can_ac3)
+ {
+ portc->bits = 16;
+ portc->channels = 2;
+ cmpci_outsw (devc->mixer_dev, SPDIF_PLAY, SNDCTL_MIX_WRITE, 1);
+ setup_ac3 (devc, portc, 1);
+ }
+ else
+ setup_ac3 (devc, portc, 0);
+
+ switch (devc->dev_mode)
+ {
+ case DEFAULT_MODE:
+ /* set speed */
+ set_dac_rate (dev, CHAN1);
+ /* set format */
+ set_dac_fmt (dev, CHAN1);
+ /* set buffer address/size and other setups */
+ setup_play (dev, CHAN1);
+ break;
+
+ case DUALDAC_MODE:
+ if (dev == devc->portc[0].audiodev)
+ {
+ set_dac_rate (dev, CHAN1);
+ set_dac_fmt (dev, CHAN1);
+ setup_play (dev, CHAN1);
+ setup_ac3 (devc, portc, 0);
+ }
+ if (dev == devc->portc[1].audiodev)
+ {
+ set_dac_rate (dev, CHAN0);
+ set_dac_fmt (dev, CHAN0);
+ setup_play (dev, CHAN0);
+ setup_ac3 (devc, portc, 0);
+ }
+ break;
+
+ case SPDIFIN_MODE:
+ set_dac_rate (dev, CHAN0);
+ set_dac_fmt (dev, CHAN0);
+ setup_play (dev, CHAN0);
+ setup_ac3 (devc, portc, 0);
+ break;
+ }
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+cmpci_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ cmpci_devc *devc = audio_engines[dev]->devc;
+ cmpci_portc *portc = audio_engines[dev]->portc;
+ unsigned int ptr = 0;
+ oss_native_word flags;
+
+ if (!(portc->open_mode & direction))
+ return 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ if (portc->chan0_rec)
+ ptr = INW (devc->osdev, CH0_FRAME1);
+ if (portc->chan1_rec)
+ ptr = INW (devc->osdev, CH1_FRAME1);
+ }
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ if (portc->chan0_play)
+ ptr = INW (devc->osdev, CH0_FRAME1);
+ if (portc->chan1_play)
+ ptr = INW (devc->osdev, CH1_FRAME1);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ptr % dmap->bytes_in_use;
+}
+
+static audiodrv_t cmpci_audio_driver = {
+ cmpci_audio_open,
+ cmpci_audio_close,
+ cmpci_audio_output_block,
+ cmpci_audio_start_input,
+ cmpci_audio_ioctl,
+ cmpci_audio_prepare_for_input,
+ cmpci_audio_prepare_for_output,
+ cmpci_audio_reset,
+ NULL,
+ NULL,
+ cmpci_audio_reset_input,
+ cmpci_audio_reset_output,
+ cmpci_audio_trigger,
+ cmpci_audio_set_rate,
+ cmpci_audio_set_format,
+ cmpci_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* cmpci_alloc_buffer, */
+ NULL, /* cmpci_free_buffer, */
+ NULL,
+ NULL,
+ cmpci_get_buffer_pointer
+};
+
+#ifdef OBSOLETED_STUFF
+static void
+attach_mpu (cmpci_devc * devc)
+{
+ unsigned int base;
+
+ if (devc->chiprev == 33)
+ base = 0x330; /* Chiprev033 doen't have bas+0x40 */
+ else
+ base = MPU_MIRROR; /* base+0x40 is MPU PCI mirror */
+
+ uart401_init (&devc->uart401devc, devc->osdev, base, "Cmedia MIDI UART");
+ devc->uart401_attached = 1;
+}
+#endif
+
+static int
+init_cmpci (cmpci_devc * devc)
+{
+ oss_native_word val;
+ int first_dev = 0;
+ int i;
+
+ devc->fm_attached = 0;
+
+/*
+ * Enable BusMasterMode and IOSpace Access
+ */
+ /* Check the model number of the chip */
+ val = INL (devc->osdev, INT_HLDCLR) & 0xff000000;
+
+ if (!val)
+ {
+ val = INL (devc->osdev, CHFORMAT) & 0x1f000000;
+ if (!val)
+ {
+ devc->chiprev = 33;
+ devc->can_ac3 = 0;
+ devc->max_channels = 6;
+ }
+ else
+ {
+ devc->chiprev = 37;
+ devc->can_ac3 = 1;
+ devc->max_channels = 6;
+ }
+ }
+ else
+ {
+ if (val & 0x04000000)
+ {
+ devc->chiprev = 39;
+ devc->can_ac3 = 1;
+ devc->max_channels = 6;
+ }
+ if (val & 0x08000000)
+ {
+ devc->chiprev = 55;
+ devc->can_ac3 = 1;
+ devc->max_channels = 6;
+ }
+ if (val & 0x28000000)
+ {
+ devc->chiprev = 68;
+ devc->can_ac3 = 1;
+ devc->model = MDL_CM8768;
+ devc->max_channels = 8;
+ devc->chip_name = "CMedia CM8768";
+ }
+ }
+
+ /* enable uart, joystick in Function Control Reg1 */
+ OUTB (devc->osdev, INB (devc->osdev, FUNCTRL1) | 0x06, FUNCTRL1);
+ /* enable FM */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 19), MISC_CTRL);
+ OUTB (devc->osdev, 0, INT_HLDCLR + 2); /* disable ints */
+ OUTB (devc->osdev, 0, FUNCTRL0 + 2); /* reset channels */
+
+#ifdef OBSOLETED_STUFF
+ attach_mpu (devc);
+#endif
+
+ /* install the CMPCI mixer */
+ if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "CMedia CMPCI",
+ &cmpci_mixer_driver,
+ sizeof (mixer_driver_t),
+ devc)) < 0)
+ {
+ return 0;
+ }
+
+ mixer_devs[devc->mixer_dev]->hw_devc = devc;
+ mixer_devs[devc->mixer_dev]->priority = 1; /* Possible default mixer candidate */
+
+ cmpci_mixer_reset (devc->mixer_dev);
+ mixer_ext_set_init_fn (devc->mixer_dev, cmpci_mix_init, 25);
+ OUTB (devc->osdev, 0xF, MIXER2);
+
+ /* setup 4speaker output */
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 26), MISC_CTRL);
+ /* enable subwoofer/center channel */
+ OUTL (devc->osdev, INL (devc->osdev, LEGACY_CTRL) | (1 << 12), LEGACY_CTRL);
+ OUTL (devc->osdev, INL (devc->osdev, MISC_CTRL) | (1 << 7), MISC_CTRL);
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ char tmp_name[100];
+ cmpci_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE;
+
+ if (i == 0)
+ {
+ sprintf (tmp_name, "%s (rev %0d)", devc->chip_name, devc->chiprev);
+ caps |= ADEV_DUPLEX;
+ }
+ else
+ {
+ sprintf (tmp_name, "%s (playback only)", devc->chip_name);
+ caps |= ADEV_NOINPUT;
+ }
+ if ((portc->audiodev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &cmpci_audio_driver,
+ sizeof (audiodrv_t),
+ caps,
+ AFMT_U8 | AFMT_S16_LE |
+ AFMT_AC3, devc, -1)) < 0)
+ {
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = portc->audiodev;
+ audio_engines[portc->audiodev]->portc = portc;
+ audio_engines[portc->audiodev]->rate_source = first_dev;
+ audio_engines[portc->audiodev]->caps =
+ PCM_CAP_ANALOGOUT | PCM_CAP_ANALOGIN | PCM_CAP_DIGITALOUT |
+ PCM_CAP_DIGITALIN;
+ audio_engines[portc->audiodev]->min_rate = 5000;
+ audio_engines[portc->audiodev]->max_rate = 48000;
+ audio_engines[portc->audiodev]->caps |= PCM_CAP_FREERATE;
+ audio_engines[portc->audiodev]->min_channels = 2;
+ audio_engines[portc->audiodev]->max_channels = devc->max_channels;
+ audio_engines[portc->audiodev]->vmix_flags = VMIX_MULTIFRAG;
+ audio_engines[portc->audiodev]->dmabuf_alloc_flags |=
+ DMABUF_SIZE_16BITS;
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+ audio_engines[portc->audiodev]->mixer_dev = devc->mixer_dev;
+ devc->dev_mode = DEFAULT_MODE;
+ devc->spdif_enabled = 0;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, portc->audiodev, -1, 0);
+#endif
+ }
+ }
+ return 1;
+}
+
+int
+oss_cmpci_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ int err;
+ cmpci_devc *devc;
+
+ DDB (cmn_err (CE_CONT, "Entered CMEDIA CMPCI attach routine\n"));
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != CMEDIA_VENDOR_ID
+ || ((device != CMEDIA_CM8738) && (device != CMEDIA_CM8338A)
+ && (device != CMEDIA_CM8338B)))
+ return 0;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+ DDB (cmn_err (CE_WARN, "CMPCI I/O base %04x\n", pci_ioaddr));
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->irq = pci_irq_line;
+
+ /* Map the IO Base address */
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+
+ /* Remove I/O space marker in bit 0. */
+ devc->base &= ~3;
+
+ /* set the PCI_COMMAND register to master mode */
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ switch (device)
+ {
+ case CMEDIA_CM8738:
+ devc->model = MDL_CM8738;
+ devc->chip_name = "CMedia CM8738";
+ devc->max_channels = 6;
+ break;
+
+ case CMEDIA_CM8338A:
+ devc->model = MDL_CM8338A;
+ devc->chip_name = "CMedia CM8338A";
+ devc->max_channels = 6;
+ break;
+
+ case CMEDIA_CM8338B:
+ devc->model = MDL_CM8338B;
+ devc->chip_name = "CMedia CM8338B";
+ devc->max_channels = 6;
+ break;
+ }
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, cmpciintr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't allocate IRQ%d, err=%d\n", pci_irq_line, err);
+ return 0;
+ }
+
+ return init_cmpci (devc); /* Detected */
+}
+
+int
+oss_cmpci_detach (oss_device_t * osdev)
+{
+ cmpci_devc *devc = (cmpci_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ /* disable Interrupts */
+ OUTB (devc->osdev, 0, INT_HLDCLR + 2);
+
+ /* disable channels */
+ OUTB (devc->osdev, 0, FUNCTRL0 + 2);
+
+ /* uninstall UART401 */
+ if (devc->uart401_attached)
+ uart401_disable (&devc->uart401devc);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+
+ oss_unregister_device (osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_cmpci/oss_cmpci.man b/kernel/drv/oss_cmpci/oss_cmpci.man
new file mode 100644
index 0000000..1d817b3
--- /dev/null
+++ b/kernel/drv/oss_cmpci/oss_cmpci.man
@@ -0,0 +1,56 @@
+NAME
+oss_cmpci - CMedia CMI8738/8768 audio driver.
+
+DESCRIPTION
+Open Sound System driver for CMedia Electronics CMI8738/8768 audio
+
+CMI87xx device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo/4ch/5.1ch playback
+ o 8KHz to 48Khz sample rate.
+
+ MIXER PANEL
+The CMedia chip provides some unique features that are set up
+by the Mixer chip. Running ossxmix will display the CMI8738 mixer
+panel.
+
+Most of the sliders and buttons are self evident. However there
+are some options that need explaining:
+
+Dual Dac: Enabling this button sets the CMPCI device as two
+separate output devices with /dev/dsp1 audio going to the front and
+/dev/dsp0 going to the rear outputs. Separate audio streams can
+be send to the device simultaneously.
+
+Speaker Mode: The audio can be sent just to the front speakers or
+it can be sent simultaneously to all speakers in the "Spread" mode.
+
+AC3 passthrough only works on Models 037 and higher. This is because of
+a hardware bug in the earlier models so check the model number
+(ossinfo -a).
+
+SPDIF:
+
+o Enable will enable SPDIF output.
+
+o Rec will allow you to record from the SPDIF device. Note that when
+you have SPDIF recording enabled, you cannot play 4/6 channel audio.
+
+o Polarity - certain models require you to flip the bit otherwise you
+ get distorted audio.
+
+o IMon - monitor input via SPDIF in.
+
+o Optical - sets the SPDIF to Optical (TOSLINK) or RCA Jacks interface.
+
+
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_cmpci.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_cs4281/.devices b/kernel/drv/oss_cs4281/.devices
new file mode 100644
index 0000000..1c415d7
--- /dev/null
+++ b/kernel/drv/oss_cs4281/.devices
@@ -0,0 +1 @@
+oss_cs4281 pci1013,6005 Crystal CS4281
diff --git a/kernel/drv/oss_cs4281/.name b/kernel/drv/oss_cs4281/.name
new file mode 100644
index 0000000..6464db1
--- /dev/null
+++ b/kernel/drv/oss_cs4281/.name
@@ -0,0 +1 @@
+Crystal CS4281
diff --git a/kernel/drv/oss_cs4281/cs4281.h b/kernel/drv/oss_cs4281/cs4281.h
new file mode 100644
index 0000000..f82568f
--- /dev/null
+++ b/kernel/drv/oss_cs4281/cs4281.h
@@ -0,0 +1,1108 @@
+/*
+ * Purpose: Definitions for the cs4281 driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+/***************************************************************************** */
+/* */
+/* HWDEFS.H - Definitions of the registers and data structures used by the */
+/* CS4281 */
+/* */
+/***************************************************************************** */
+
+#ifndef _H_HWDEFS
+#define _H_HWDEFS
+
+/***************************************************************************** */
+/* */
+/* The following define the offsets of the registers accessed via base address */
+/* register zero on the CS4281 part. */
+/* */
+/***************************************************************************** */
+#define BA0_HISR 0x00000000L
+#define BA0_HICR 0x00000008L
+#define BA0_HIMR 0x0000000CL
+#define BA0_IIER 0x00000010L
+#define BA0_HDSR0 0x000000F0L
+#define BA0_HDSR1 0x000000F4L
+#define BA0_HDSR2 0x000000F8L
+#define BA0_HDSR3 0x000000FCL
+#define BA0_DCA0 0x00000110L
+#define BA0_DCC0 0x00000114L
+#define BA0_DBA0 0x00000118L
+#define BA0_DBC0 0x0000011CL
+#define BA0_DCA1 0x00000120L
+#define BA0_DCC1 0x00000124L
+#define BA0_DBA1 0x00000128L
+#define BA0_DBC1 0x0000012CL
+#define BA0_DCA2 0x00000130L
+#define BA0_DCC2 0x00000134L
+#define BA0_DBA2 0x00000138L
+#define BA0_DBC2 0x0000013CL
+#define BA0_DCA3 0x00000140L
+#define BA0_DCC3 0x00000144L
+#define BA0_DBA3 0x00000148L
+#define BA0_DBC3 0x0000014CL
+#define BA0_DMR0 0x00000150L
+#define BA0_DCR0 0x00000154L
+#define BA0_DMR1 0x00000158L
+#define BA0_DCR1 0x0000015CL
+#define BA0_DMR2 0x00000160L
+#define BA0_DCR2 0x00000164L
+#define BA0_DMR3 0x00000168L
+#define BA0_DCR3 0x0000016CL
+#define BA0_DLMR 0x00000170L
+#define BA0_DLSR 0x00000174L
+#define BA0_FCR0 0x00000180L
+#define BA0_FCR1 0x00000184L
+#define BA0_FCR2 0x00000188L
+#define BA0_FCR3 0x0000018CL
+#define BA0_FPDR0 0x00000190L
+#define BA0_FPDR1 0x00000194L
+#define BA0_FPDR2 0x00000198L
+#define BA0_FPDR3 0x0000019CL
+#define BA0_FCHS 0x0000020CL
+#define BA0_FSIC0 0x00000210L
+#define BA0_FSIC1 0x00000214L
+#define BA0_FSIC2 0x00000218L
+#define BA0_FSIC3 0x0000021CL
+#define BA0_PCICFG00 0x00000300L
+#define BA0_PCICFG04 0x00000304L
+#define BA0_PCICFG08 0x00000308L
+#define BA0_PCICFG0C 0x0000030CL
+#define BA0_PCICFG10 0x00000310L
+#define BA0_PCICFG14 0x00000314L
+#define BA0_PCICFG18 0x00000318L
+#define BA0_PCICFG1C 0x0000031CL
+#define BA0_PCICFG20 0x00000320L
+#define BA0_PCICFG24 0x00000324L
+#define BA0_PCICFG28 0x00000328L
+#define BA0_PCICFG2C 0x0000032CL
+#define BA0_PCICFG30 0x00000330L
+#define BA0_PCICFG34 0x00000334L
+#define BA0_PCICFG38 0x00000338L
+#define BA0_PCICFG3C 0x0000033CL
+#define BA0_PCICFG40 0x00000340L
+#define BA0_PMCS 0x00000344L
+#define BA0_CWPR 0x000003E0L
+#define BA0_EPPMC 0x000003E4L
+#define BA0_GPIOR 0x000003E8L
+#define BA0_SPMC 0x000003ECL
+#define BA0_CFLR 0x000003F0L
+#define BA0_IISR 0x000003F4L
+#define BA0_TMS 0x000003F8L
+#define BA0_SSVID 0x000003FCL
+#define BA0_CLKCR1 0x00000400L
+#define BA0_FRR 0x00000410L
+#define BA0_SLT12O 0x0000041CL
+#define BA0_SERMC 0x00000420L
+#define BA0_SERC1 0x00000428L
+#define BA0_SERC2 0x0000042CL
+#define BA0_SLT12M 0x0000045CL
+#define BA0_ACCTL 0x00000460L
+#define BA0_ACSTS 0x00000464L
+#define BA0_ACOSV 0x00000468L
+#define BA0_ACCAD 0x0000046CL
+#define BA0_ACCDA 0x00000470L
+#define BA0_ACISV 0x00000474L
+#define BA0_ACSAD 0x00000478L
+#define BA0_ACSDA 0x0000047CL
+#define BA0_JSPT 0x00000480L
+#define BA0_JSCTL 0x00000484L
+#define BA0_MIDCR 0x00000490L
+#define BA0_MIDCMD 0x00000494L
+#define BA0_MIDSR 0x00000494L
+#define BA0_MIDWP 0x00000498L
+#define BA0_MIDRP 0x0000049CL
+#define BA0_AODSD1 0x000004A8L
+#define BA0_AODSD2 0x000004ACL
+#define BA0_CFGI 0x000004B0L
+#define BA0_SLT12M2 0x000004DCL
+#define BA0_ACSTS2 0x000004E4L
+#define BA0_ACISV2 0x000004F4L
+#define BA0_ACSAD2 0x000004F8L
+#define BA0_ACSDA2 0x000004FCL
+#define BA0_IOTGP 0x00000500L
+#define BA0_IOTSB 0x00000504L
+#define BA0_IOTFM 0x00000508L
+#define BA0_IOTDMA 0x0000050CL
+#define BA0_IOTAC0 0x00000500L
+#define BA0_IOTAC1 0x00000504L
+#define BA0_IOTAC2 0x00000508L
+#define BA0_IOTAC3 0x0000050CL
+#define BA0_IOTPCP 0x0000052CL
+#define BA0_IOTCC 0x00000530L
+#define BA0_IOTCR 0x0000058CL
+#define BA0_PCPRR 0x00000600L
+#define BA0_PCPGR 0x00000604L
+#define BA0_PCPCR 0x00000608L
+#define BA0_PCPCIEN 0x00000608L
+#define BA0_SBMAR 0x00000700L
+#define BA0_SBMDR 0x00000704L
+#define BA0_SBRR 0x00000708L
+#define BA0_SBRDP 0x0000070CL
+#define BA0_SBWDP 0x00000710L
+#define BA0_SBWBS 0x00000710L
+#define BA0_SBRBS 0x00000714L
+#define BA0_FMSR 0x00000730L
+#define BA0_B0AP 0x00000730L
+#define BA0_FMDP 0x00000734L
+#define BA0_B1AP 0x00000738L
+#define BA0_B1DP 0x0000073CL
+#define BA0_SSPM 0x00000740L
+#define BA0_DACSR 0x00000744L
+#define BA0_ADCSR 0x00000748L
+#define BA0_SSCR 0x0000074CL
+#define BA0_FMLVC 0x00000754L
+#define BA0_FMRVC 0x00000758L
+#define BA0_SRCSA 0x0000075CL
+#define BA0_PPLVC 0x00000760L
+#define BA0_PPRVC 0x00000764L
+#define BA0_PASR 0x00000768L
+#define BA0_CASR 0x0000076CL
+
+/***************************************************************************** */
+/* */
+/* The following define the offsets of the AC97 shadow registers, which appear */
+/* as a virtual extension to the base address register zero memory range. */
+/* */
+/***************************************************************************** */
+#define AC97_REG_OFFSET_MASK 0x0000007EL
+#define AC97_CODEC_NUMBER_MASK 0x00003000L
+
+#define BA0_AC97_RESET 0x00001000L
+#define BA0_AC97_MASTER_VOLUME 0x00001002L
+#define BA0_AC97_HEADPHONE_VOLUME 0x00001004L
+#define BA0_AC97_MASTER_VOLUME_MONO 0x00001006L
+#define BA0_AC97_MASTER_TONE 0x00001008L
+#define BA0_AC97_PC_BEEP_VOLUME 0x0000100AL
+#define BA0_AC97_PHONE_VOLUME 0x0000100CL
+#define BA0_AC97_MIC_VOLUME 0x0000100EL
+#define BA0_AC97_LINE_IN_VOLUME 0x00001010L
+#define BA0_AC97_CD_VOLUME 0x00001012L
+#define BA0_AC97_VIDEO_VOLUME 0x00001014L
+#define BA0_AC97_AUX_VOLUME 0x00001016L
+#define BA0_AC97_PCM_OUT_VOLUME 0x00001018L
+#define BA0_AC97_RECORD_SELECT 0x0000101AL
+#define BA0_AC97_RECORD_GAIN 0x0000101CL
+#define BA0_AC97_RECORD_GAIN_MIC 0x0000101EL
+#define BA0_AC97_GENERAL_PURPOSE 0x00001020L
+#define BA0_AC97_3D_CONTROL 0x00001022L
+#define BA0_AC97_MODEM_RATE 0x00001024L
+#define BA0_AC97_POWERDOWN 0x00001026L
+#define BA0_AC97_EXT_AUDIO_ID 0x00001028L
+#define BA0_AC97_EXT_AUDIO_POWER 0x0000102AL
+#define BA0_AC97_PCM_FRONT_DAC_RATE 0x0000102CL
+#define BA0_AC97_PCM_SURR_DAC_RATE 0x0000102EL
+#define BA0_AC97_PCM_LFE_DAC_RATE 0x00001030L
+#define BA0_AC97_PCM_LR_ADC_RATE 0x00001032L
+#define BA0_AC97_MIC_ADC_RATE 0x00001034L
+#define BA0_AC97_6CH_VOL_C_LFE 0x00001036L
+#define BA0_AC97_6CH_VOL_SURROUND 0x00001038L
+#define BA0_AC97_RESERVED_3A 0x0000103AL
+#define BA0_AC97_EXT_MODEM_ID 0x0000103CL
+#define BA0_AC97_EXT_MODEM_POWER 0x0000103EL
+#define BA0_AC97_LINE1_CODEC_RATE 0x00001040L
+#define BA0_AC97_LINE2_CODEC_RATE 0x00001042L
+#define BA0_AC97_HANDSET_CODEC_RATE 0x00001044L
+#define BA0_AC97_LINE1_CODEC_LEVEL 0x00001046L
+#define BA0_AC97_LINE2_CODEC_LEVEL 0x00001048L
+#define BA0_AC97_HANDSET_CODEC_LEVEL 0x0000104AL
+#define BA0_AC97_GPIO_PIN_CONFIG 0x0000104CL
+#define BA0_AC97_GPIO_PIN_TYPE 0x0000104EL
+#define BA0_AC97_GPIO_PIN_STICKY 0x00001050L
+#define BA0_AC97_GPIO_PIN_WAKEUP 0x00001052L
+#define BA0_AC97_GPIO_PIN_STATUS 0x00001054L
+#define BA0_AC97_MISC_MODEM_AFE_STAT 0x00001056L
+#define BA0_AC97_RESERVED_58 0x00001058L
+#define BA0_AC97_CRYSTAL_REV_N_FAB_ID 0x0000105AL
+#define BA0_AC97_TEST_AND_MISC_CTRL 0x0000105CL
+#define BA0_AC97_AC_MODE 0x0000105EL
+#define BA0_AC97_MISC_CRYSTAL_CONTROL 0x00001060L
+#define BA0_AC97_LINE1_HYPRID_CTRL 0x00001062L
+#define BA0_AC97_VENDOR_RESERVED_64 0x00001064L
+#define BA0_AC97_VENDOR_RESERVED_66 0x00001066L
+#define BA0_AC97_SPDIF_CONTROL 0x00001068L
+#define BA0_AC97_VENDOR_RESERVED_6A 0x0000106AL
+#define BA0_AC97_VENDOR_RESERVED_6C 0x0000106CL
+#define BA0_AC97_VENDOR_RESERVED_6E 0x0000106EL
+#define BA0_AC97_VENDOR_RESERVED_70 0x00001070L
+#define BA0_AC97_VENDOR_RESERVED_72 0x00001072L
+#define BA0_AC97_VENDOR_RESERVED_74 0x00001074L
+#define BA0_AC97_CAL_ADDRESS 0x00001076L
+#define BA0_AC97_CAL_DATA 0x00001078L
+#define BA0_AC97_VENDOR_RESERVED_7A 0x0000107AL
+#define BA0_AC97_VENDOR_ID1 0x0000107CL
+#define BA0_AC97_VENDOR_ID2 0x0000107EL
+
+/***************************************************************************** */
+/* */
+/* The following define the offsets of the registers and memories accessed via */
+/* base address register one on the CS4281 part. */
+/* */
+/***************************************************************************** */
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the host interrupt status */
+/* register. */
+/* */
+/***************************************************************************** */
+#define HISR_HVOLMASK 0x00000003L
+#define HISR_VDNI 0x00000001L
+#define HISR_VUPI 0x00000002L
+#define HISR_GP1I 0x00000004L
+#define HISR_GP3I 0x00000008L
+#define HISR_GPSI 0x00000010L
+#define HISR_GPPI 0x00000020L
+#define HISR_DMAI 0x00040000L
+#define HISR_FIFOI 0x00100000L
+#define HISR_HVOL 0x00200000L
+#define HISR_MIDI 0x00400000L
+#define HISR_SBINT 0x00800000L
+#define HISR_INTENA 0x80000000UL
+#define HISR_DMA_MASK 0x00000F00L
+#define HISR_FIFO_MASK 0x0000F000L
+#define HISR_DMA_SHIFT 8L
+#define HISR_FIFO_SHIFT 12L
+#define HISR_FIFO0 0x00001000L
+#define HISR_FIFO1 0x00002000L
+#define HISR_FIFO2 0x00004000L
+#define HISR_FIFO3 0x00008000L
+#define HISR_DMA0 0x00000100L
+#define HISR_DMA1 0x00000200L
+#define HISR_DMA2 0x00000400L
+#define HISR_DMA3 0x00000800L
+#define HISR_RESERVED 0x40000000L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the host interrupt control */
+/* register. */
+/* */
+/***************************************************************************** */
+#define HICR_IEV 0x00000001L
+#define HICR_CHGM 0x00000002L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the DMA Mode Register n */
+/* (DMRn) */
+/* */
+/***************************************************************************** */
+#define DMRn_TR_MASK 0x0000000CL
+#define DMRn_TR_SHIFT 2L
+#define DMRn_AUTO 0x00000010L
+#define DMRn_TR_READ 0x00000008L
+#define DMRn_TR_WRITE 0x00000004L
+#define DMRn_TYPE_MASK 0x000000C0L
+#define DMRn_TYPE_SHIFT 6L
+#define DMRn_SIZE8 0x00010000L
+#define DMRn_MONO 0x00020000L
+#define DMRn_BEND 0x00040000L
+#define DMRn_USIGN 0x00080000L
+#define DMRn_SIZE20 0x00100000L
+#define DMRn_SWAPC 0x00400000L
+#define DMRn_CBC 0x01000000L
+#define DMRn_TBC 0x02000000L
+#define DMRn_POLL 0x10000000L
+#define DMRn_DMA 0x20000000L
+#define DMRn_FSEL_MASK 0xC0000000L
+#define DMRn_FSEL_SHIFT 30L
+#define DMRn_FSEL0 0x00000000L
+#define DMRn_FSEL1 0x40000000L
+#define DMRn_FSEL2 0x80000000L
+#define DMRn_FSEL3 0xC0000000L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the DMA Command Register n */
+/* (DCRn) */
+/* */
+/***************************************************************************** */
+#define DCRn_HTCIE 0x00020000L
+#define DCRn_TCIE 0x00010000L
+#define DCRn_MSK 0x00000001L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the FIFO Control */
+/* register n.(FCRn) */
+/* */
+/***************************************************************************** */
+#define FCRn_OF_MASK 0x0000007FL
+#define FCRn_OF_SHIFT 0L
+#define FCRn_SZ_MASK 0x00007F00L
+#define FCRn_SZ_SHIFT 8L
+#define FCRn_LS_MASK 0x001F0000L
+#define FCRn_LS_SHIFT 16L
+#define FCRn_RS_MASK 0x1F000000L
+#define FCRn_RS_SHIFT 24L
+#define FCRn_FEN 0x80000000UL
+#define FCRn_PSH 0x20000000L
+#define FCRn_DACZ 0x40000000L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the serial port Power Management */
+/* control register.(SPMC) */
+/* */
+/***************************************************************************** */
+#define SPMC_RSTN 0x00000001L
+#define SPMC_ASYN 0x00000002L
+#define SPMC_WUP1 0x00000004L
+#define SPMC_WUP2 0x00000008L
+#define SPMC_ASDI2E 0x00000100L
+#define SPMC_ESSPD 0x00000200L
+#define SPMC_GISPEN 0x00004000L
+#define SPMC_GIPPEN 0x00008000L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the Configuration Load register. */
+/* (CFLR) */
+/* */
+/***************************************************************************** */
+#define CFLR_CLOCK_SOURCE_MASK 0x00000003L
+#define CFLR_CLOCK_SOURCE_AC97 0x00000001L
+
+#define CFLR_CB0_MASK 0x000000FFL
+#define CFLR_CB1_MASK 0x0000FF00L
+#define CFLR_CB2_MASK 0x00FF0000L
+#define CFLR_CB3_MASK 0xFF000000L
+#define CFLR_CB0_SHIFT 0L
+#define CFLR_CB1_SHIFT 8L
+#define CFLR_CB2_SHIFT 16L
+#define CFLR_CB3_SHIFT 24L
+
+#define IOTCR_DMA0 0x00000000L
+#define IOTCR_DMA1 0x00000400L
+#define IOTCR_DMA2 0x00000800L
+#define IOTCR_DMA3 0x00000C00L
+#define IOTCR_CCLS 0x00000100L
+#define IOTCR_PCPCI 0x00000200L
+#define IOTCR_DDMA 0x00000300L
+
+#define SBWBS_WBB 0x00000080L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the SRC Slot Assignment Register */
+/* (SRCSA) */
+/* */
+/***************************************************************************** */
+#define SRCSA_PLSS_MASK 0x0000001FL
+#define SRCSA_PLSS_SHIFT 0L
+#define SRCSA_PRSS_MASK 0x00001F00L
+#define SRCSA_PRSS_SHIFT 8L
+#define SRCSA_CLSS_MASK 0x001F0000L
+#define SRCSA_CLSS_SHIFT 16L
+#define SRCSA_CRSS_MASK 0x1F000000L
+#define SRCSA_CRSS_SHIFT 24L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the Sound System Power Management */
+/* register.(SSPM) */
+/* */
+/***************************************************************************** */
+#define SSPM_FPDN 0x00000080L
+#define SSPM_MIXEN 0x00000040L
+#define SSPM_CSRCEN 0x00000020L
+#define SSPM_PSRCEN 0x00000010L
+#define SSPM_JSEN 0x00000008L
+#define SSPM_ACLEN 0x00000004L
+#define SSPM_FMEN 0x00000002L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the Sound System Control */
+/* Register. (SSCR) */
+/* */
+/***************************************************************************** */
+#define SSCR_SB 0x00000004L
+#define SSCR_HVC 0x00000008L
+#define SSCR_LPFIFO 0x00000040L
+#define SSCR_LPSRC 0x00000080L
+#define SSCR_XLPSRC 0x00000100L
+#define SSCR_MVMD 0x00010000L
+#define SSCR_MVAD 0x00020000L
+#define SSCR_MVLD 0x00040000L
+#define SSCR_MVCS 0x00080000L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the Clock Control Register 1. */
+/* (CLKCR1) */
+/* */
+/***************************************************************************** */
+#define CLKCR1_DLLSS_MASK 0x0000000CL
+#define CLKCR1_DLLSS_SHIFT 2L
+#define CLKCR1_DLLP 0x00000010L
+#define CLKCR1_SWCE 0x00000020L
+#define CLKCR1_DLLOS 0x00000040L
+#define CLKCR1_CKRA 0x00010000L
+#define CLKCR1_CKRN 0x00020000L
+#define CLKCR1_DLLRDY 0x01000000L
+#define CLKCR1_CLKON 0x02000000L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the Sound Blaster Read Buffer */
+/* Status.(SBRBS) */
+/* */
+/***************************************************************************** */
+#define SBRBS_RD_MASK 0x0000007FL
+#define SBRBS_RD_SHIFT 0L
+#define SBRBS_RBF 0x00000080L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the serial port master control */
+/* register.(SERMC) */
+/* */
+/***************************************************************************** */
+#define SERMC_MSPE 0x00000001L
+#define SERMC_PTC_MASK 0x0000000EL
+#define SERMC_PTC_SHIFT 1L
+#define SERMC_PTC_AC97 0x00000002L
+#define SERMC_PLB 0x00000010L
+#define SERMC_PXLB 0x00000020L
+#define SERMC_LOFV 0x00080000L
+#define SERMC_SLB 0x00100000L
+#define SERMC_SXLB 0x00200000L
+#define SERMC_ODSEN1 0x01000000L
+#define SERMC_ODSEN2 0x02000000L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the General Purpose I/O Register. */
+/* (GPIOR) */
+/* */
+/***************************************************************************** */
+#define GPIOR_VDNS 0x00000001L
+#define GPIOR_VUPS 0x00000002L
+#define GPIOR_GP1S 0x00000004L
+#define GPIOR_GP3S 0x00000008L
+#define GPIOR_GPSS 0x00000010L
+#define GPIOR_GPPS 0x00000020L
+#define GPIOR_GP1D 0x00000400L
+#define GPIOR_GP3D 0x00000800L
+#define GPIOR_VDNLT 0x00010000L
+#define GPIOR_VDNPO 0x00020000L
+#define GPIOR_VDNST 0x00040000L
+#define GPIOR_VDNW 0x00080000L
+#define GPIOR_VUPLT 0x00100000L
+#define GPIOR_VUPPO 0x00200000L
+#define GPIOR_VUPST 0x00400000L
+#define GPIOR_VUPW 0x00800000L
+#define GPIOR_GP1OE 0x01000000L
+#define GPIOR_GP1PT 0x02000000L
+#define GPIOR_GP1ST 0x04000000L
+#define GPIOR_GP1W 0x08000000L
+#define GPIOR_GP3OE 0x10000000L
+#define GPIOR_GP3PT 0x20000000L
+#define GPIOR_GP3ST 0x40000000L
+#define GPIOR_GP3W 0x80000000L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the clock control register 1. */
+/* */
+/***************************************************************************** */
+#define CLKCR1_OSCS 0x00000001L
+#define CLKCR1_OSCP 0x00000002L
+#define CLKCR1_PLLSS_MASK 0x0000000CL
+#define CLKCR1_PLLSS_SERIAL 0x00000000L
+#define CLKCR1_PLLSS_CRYSTAL 0x00000004L
+#define CLKCR1_PLLSS_PCI 0x00000008L
+#define CLKCR1_PLLSS_RESERVED 0x0000000CL
+#define CLKCR1_PLLP 0x00000010L
+#define CLKCR1_SWCE 0x00000020L
+#define CLKCR1_PLLOS 0x00000040L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the feature reporting register. */
+/* */
+/***************************************************************************** */
+#define FRR_FAB_MASK 0x00000003L
+#define FRR_MASK_MASK 0x0000001CL
+#define FRR_ID_MASK 0x00003000L
+#define FRR_FAB_SHIFT 0L
+#define FRR_MASK_SHIFT 2L
+#define FRR_ID_SHIFT 12L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the serial port 1 configuration */
+/* register. */
+/* */
+/***************************************************************************** */
+#define SERC1_VALUE 0x00000003L
+#define SERC1_SO1EN 0x00000001L
+#define SERC1_SO1F_MASK 0x0000000EL
+#define SERC1_SO1F_CS423X 0x00000000L
+#define SERC1_SO1F_AC97 0x00000002L
+#define SERC1_SO1F_DAC 0x00000004L
+#define SERC1_SO1F_SPDIF 0x00000006L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the serial port 2 configuration */
+/* register. */
+/* */
+/***************************************************************************** */
+#define SERC2_VALUE 0x00000003L
+#define SERC2_SI1EN 0x00000001L
+#define SERC2_SI1F_MASK 0x0000000EL
+#define SERC2_SI1F_CS423X 0x00000000L
+#define SERC2_SI1F_AC97 0x00000002L
+#define SERC2_SI1F_ADC 0x00000004L
+#define SERC2_SI1F_SPDIF 0x00000006L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 control register. */
+/* */
+/***************************************************************************** */
+#define ACCTL_ESYN 0x00000002L
+#define ACCTL_VFRM 0x00000004L
+#define ACCTL_DCV 0x00000008L
+#define ACCTL_CRW 0x00000010L
+#define ACCTL_TC 0x00000040L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 status register. */
+/* */
+/***************************************************************************** */
+#define ACSTS_CRDY 0x00000001L
+#define ACSTS_VSTS 0x00000002L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 output slot valid */
+/* register. */
+/* */
+/***************************************************************************** */
+#define ACOSV_SLV3 0x00000001L
+#define ACOSV_SLV4 0x00000002L
+#define ACOSV_SLV5 0x00000004L
+#define ACOSV_SLV6 0x00000008L
+#define ACOSV_SLV7 0x00000010L
+#define ACOSV_SLV8 0x00000020L
+#define ACOSV_SLV9 0x00000040L
+#define ACOSV_SLV10 0x00000080L
+#define ACOSV_SLV11 0x00000100L
+#define ACOSV_SLV12 0x00000200L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 command address */
+/* register. */
+/* */
+/***************************************************************************** */
+#define ACCAD_CI_MASK 0x0000007FL
+#define ACCAD_CI_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 command data register. */
+/* */
+/***************************************************************************** */
+#define ACCDA_CD_MASK 0x0000FFFFL
+#define ACCDA_CD_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 input slot valid */
+/* register. */
+/* */
+/***************************************************************************** */
+#define ACISV_ISV3 0x00000001L
+#define ACISV_ISV4 0x00000002L
+#define ACISV_ISV5 0x00000004L
+#define ACISV_ISV6 0x00000008L
+#define ACISV_ISV7 0x00000010L
+#define ACISV_ISV8 0x00000020L
+#define ACISV_ISV9 0x00000040L
+#define ACISV_ISV10 0x00000080L
+#define ACISV_ISV11 0x00000100L
+#define ACISV_ISV12 0x00000200L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 status address */
+/* register. */
+/* */
+/***************************************************************************** */
+#define ACSAD_SI_MASK 0x0000007FL
+#define ACSAD_SI_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 status data register. */
+/* */
+/***************************************************************************** */
+#define ACSDA_SD_MASK 0x0000FFFFL
+#define ACSDA_SD_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the I/O trap address and control */
+/* registers (all 12). */
+/* */
+/***************************************************************************** */
+#define IOTAC_SA_MASK 0x0000FFFFL
+#define IOTAC_MSK_MASK 0x000F0000L
+#define IOTAC_IODC_MASK 0x06000000L
+#define IOTAC_IODC_16_BIT 0x00000000L
+#define IOTAC_IODC_10_BIT 0x02000000L
+#define IOTAC_IODC_12_BIT 0x04000000L
+#define IOTAC_WSPI 0x08000000L
+#define IOTAC_RSPI 0x10000000L
+#define IOTAC_WSE 0x20000000L
+#define IOTAC_WE 0x40000000L
+#define IOTAC_RE 0x80000000L
+#define IOTAC_SA_SHIFT 0L
+#define IOTAC_MSK_SHIFT 16L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the PC/PCI master enable */
+/* register. */
+/* */
+/***************************************************************************** */
+#define PCPCIEN_EN 0x00000001L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the joystick poll/trigger */
+/* register. */
+/* */
+/***************************************************************************** */
+#define JSPT_CAX 0x00000001L
+#define JSPT_CAY 0x00000002L
+#define JSPT_CBX 0x00000004L
+#define JSPT_CBY 0x00000008L
+#define JSPT_BA1 0x00000010L
+#define JSPT_BA2 0x00000020L
+#define JSPT_BB1 0x00000040L
+#define JSPT_BB2 0x00000080L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the joystick control register. */
+/* */
+/***************************************************************************** */
+#define JSCTL_SP_MASK 0x00000003L
+#define JSCTL_SP_SLOW 0x00000000L
+#define JSCTL_SP_MEDIUM_SLOW 0x00000001L
+#define JSCTL_SP_MEDIUM_FAST 0x00000002L
+#define JSCTL_SP_FAST 0x00000003L
+#define JSCTL_ARE 0x00000004L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the MIDI control register. */
+/* */
+/***************************************************************************** */
+#define MIDCR_TXE 0x00000001L
+#define MIDCR_RXE 0x00000002L
+#define MIDCR_RIE 0x00000004L
+#define MIDCR_TIE 0x00000008L
+#define MIDCR_MLB 0x00000010L
+#define MIDCR_MRST 0x00000020L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the MIDI status register. */
+/* */
+/***************************************************************************** */
+#define MIDSR_TBF 0x00000040L
+#define MIDSR_RBE 0x00000080L
+#define MIDSR_RDA 0x00008000L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the MIDI write port register. */
+/* */
+/***************************************************************************** */
+#define MIDWP_MWD_MASK 0x000000FFL
+#define MIDWP_MWD_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the MIDI read port register. */
+/* */
+/***************************************************************************** */
+#define MIDRP_MRD_MASK 0x000000FFL
+#define MIDRP_MRD_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the configuration interface */
+/* register. */
+/* */
+/***************************************************************************** */
+#define CFGI_CLK 0x00000001L
+#define CFGI_DOUT 0x00000002L
+#define CFGI_DIN_EEN 0x00000004L
+#define CFGI_EELD 0x00000008L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the subsystem ID and vendor ID */
+/* register. */
+/* */
+/***************************************************************************** */
+#define SSVID_VID_MASK 0x0000FFFFL
+#define SSVID_SID_MASK 0xFFFF0000L
+#define SSVID_VID_SHIFT 0L
+#define SSVID_SID_SHIFT 16L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the GPIO pin interface register. */
+/* */
+/***************************************************************************** */
+#define GPIOR_VOLDN 0x00000001L
+#define GPIOR_VOLUP 0x00000002L
+#define GPIOR_SI2D 0x00000004L
+#define GPIOR_SI2OE 0x00000008L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 status register 2. */
+/* */
+/***************************************************************************** */
+#define ACSTS2_CRDY 0x00000001L
+#define ACSTS2_VSTS 0x00000002L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 input slot valid */
+/* register 2. */
+/* */
+/***************************************************************************** */
+#define ACISV2_ISV3 0x00000001L
+#define ACISV2_ISV4 0x00000002L
+#define ACISV2_ISV5 0x00000004L
+#define ACISV2_ISV6 0x00000008L
+#define ACISV2_ISV7 0x00000010L
+#define ACISV2_ISV8 0x00000020L
+#define ACISV2_ISV9 0x00000040L
+#define ACISV2_ISV10 0x00000080L
+#define ACISV2_ISV11 0x00000100L
+#define ACISV2_ISV12 0x00000200L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 status address */
+/* register 2. */
+/* */
+/***************************************************************************** */
+#define ACSAD2_SI_MASK 0x0000007FL
+#define ACSAD2_SI_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the AC97 status data register 2. */
+/* */
+/***************************************************************************** */
+#define ACSDA2_SD_MASK 0x0000FFFFL
+#define ACSDA2_SD_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the I/O trap control register. */
+/* */
+/***************************************************************************** */
+#define IOTCR_ITD 0x00000001L
+#define IOTCR_HRV 0x00000002L
+#define IOTCR_SRV 0x00000004L
+#define IOTCR_DTI 0x00000008L
+#define IOTCR_DFI 0x00000010L
+#define IOTCR_DDP 0x00000020L
+#define IOTCR_JTE 0x00000040L
+#define IOTCR_PPE 0x00000080L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the I/O trap address and control */
+/* registers for Hardware Master Volume. */
+/* */
+/***************************************************************************** */
+#define IOTGP_SA_MASK 0x0000FFFFL
+#define IOTGP_MSK_MASK 0x000F0000L
+#define IOTGP_IODC_MASK 0x06000000L
+#define IOTGP_IODC_16_BIT 0x00000000L
+#define IOTGP_IODC_10_BIT 0x02000000L
+#define IOTGP_IODC_12_BIT 0x04000000L
+#define IOTGP_WSPI 0x08000000L
+#define IOTGP_RSPI 0x10000000L
+#define IOTGP_WSE 0x20000000L
+#define IOTGP_WE 0x40000000L
+#define IOTGP_RE 0x80000000L
+#define IOTGP_SA_SHIFT 0L
+#define IOTGP_MSK_SHIFT 16L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the I/O trap address and control */
+/* registers for Sound Blaster */
+/* */
+/***************************************************************************** */
+#define IOTSB_SA_MASK 0x0000FFFFL
+#define IOTSB_MSK_MASK 0x000F0000L
+#define IOTSB_IODC_MASK 0x06000000L
+#define IOTSB_IODC_16_BIT 0x00000000L
+#define IOTSB_IODC_10_BIT 0x02000000L
+#define IOTSB_IODC_12_BIT 0x04000000L
+#define IOTSB_WSPI 0x08000000L
+#define IOTSB_RSPI 0x10000000L
+#define IOTSB_WSE 0x20000000L
+#define IOTSB_WE 0x40000000L
+#define IOTSB_RE 0x80000000L
+#define IOTSB_SA_SHIFT 0L
+#define IOTSB_MSK_SHIFT 16L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the I/O trap address and control */
+/* registers for FM. */
+/* */
+/***************************************************************************** */
+#define IOTFM_SA_MASK 0x0000FFFFL
+#define IOTFM_MSK_MASK 0x000F0000L
+#define IOTFM_IODC_MASK 0x06000000L
+#define IOTFM_IODC_16_BIT 0x00000000L
+#define IOTFM_IODC_10_BIT 0x02000000L
+#define IOTFM_IODC_12_BIT 0x04000000L
+#define IOTFM_WSPI 0x08000000L
+#define IOTFM_RSPI 0x10000000L
+#define IOTFM_WSE 0x20000000L
+#define IOTFM_WE 0x40000000L
+#define IOTFM_RE 0x80000000L
+#define IOTFM_SA_SHIFT 0L
+#define IOTFM_MSK_SHIFT 16L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the PC/PCI request register. */
+/* */
+/***************************************************************************** */
+#define PCPRR_RDC_MASK 0x00000007L
+#define PCPRR_REQ 0x00008000L
+#define PCPRR_RDC_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the PC/PCI grant register. */
+/* */
+/***************************************************************************** */
+#define PCPGR_GDC_MASK 0x00000007L
+#define PCPGR_VL 0x00008000L
+#define PCPGR_GDC_SHIFT 0L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the PC/PCI Control Register. */
+/* */
+/***************************************************************************** */
+#define PCPCR_EN 0x00000001L
+
+/***************************************************************************** */
+/* */
+/* The following defines are for the flags in the debug index register. */
+/* */
+/***************************************************************************** */
+#define DREG_REGID_MASK 0x0000007FL
+#define DREG_DEBUG 0x00000080L
+#define DREG_RGBK_MASK 0x00000700L
+#define DREG_TRAP 0x00000800L
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_TRAPX 0x00001000L
+#endif
+#endif
+#define DREG_REGID_SHIFT 0L
+#define DREG_RGBK_SHIFT 8L
+#define DREG_RGBK_REGID_MASK 0x0000077FL
+#define DREG_REGID_R0 0x00000010L
+#define DREG_REGID_R1 0x00000011L
+#define DREG_REGID_R2 0x00000012L
+#define DREG_REGID_R3 0x00000013L
+#define DREG_REGID_R4 0x00000014L
+#define DREG_REGID_R5 0x00000015L
+#define DREG_REGID_R6 0x00000016L
+#define DREG_REGID_R7 0x00000017L
+#define DREG_REGID_R8 0x00000018L
+#define DREG_REGID_R9 0x00000019L
+#define DREG_REGID_RA 0x0000001AL
+#define DREG_REGID_RB 0x0000001BL
+#define DREG_REGID_RC 0x0000001CL
+#define DREG_REGID_RD 0x0000001DL
+#define DREG_REGID_RE 0x0000001EL
+#define DREG_REGID_RF 0x0000001FL
+#define DREG_REGID_RA_BUS_LOW 0x00000020L
+#define DREG_REGID_RA_BUS_HIGH 0x00000038L
+#define DREG_REGID_YBUS_LOW 0x00000050L
+#define DREG_REGID_YBUS_HIGH 0x00000058L
+#define DREG_REGID_TRAP_0 0x00000100L
+#define DREG_REGID_TRAP_1 0x00000101L
+#define DREG_REGID_TRAP_2 0x00000102L
+#define DREG_REGID_TRAP_3 0x00000103L
+#define DREG_REGID_TRAP_4 0x00000104L
+#define DREG_REGID_TRAP_5 0x00000105L
+#define DREG_REGID_TRAP_6 0x00000106L
+#define DREG_REGID_TRAP_7 0x00000107L
+#define DREG_REGID_INDIRECT_ADDRESS 0x0000010EL
+#define DREG_REGID_TOP_OF_STACK 0x0000010FL
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_8 0x00000110L
+#define DREG_REGID_TRAP_9 0x00000111L
+#define DREG_REGID_TRAP_10 0x00000112L
+#define DREG_REGID_TRAP_11 0x00000113L
+#define DREG_REGID_TRAP_12 0x00000114L
+#define DREG_REGID_TRAP_13 0x00000115L
+#define DREG_REGID_TRAP_14 0x00000116L
+#define DREG_REGID_TRAP_15 0x00000117L
+#define DREG_REGID_TRAP_16 0x00000118L
+#define DREG_REGID_TRAP_17 0x00000119L
+#define DREG_REGID_TRAP_18 0x0000011AL
+#define DREG_REGID_TRAP_19 0x0000011BL
+#define DREG_REGID_TRAP_20 0x0000011CL
+#define DREG_REGID_TRAP_21 0x0000011DL
+#define DREG_REGID_TRAP_22 0x0000011EL
+#define DREG_REGID_TRAP_23 0x0000011FL
+#endif
+#endif
+#define DREG_REGID_RSA0_LOW 0x00000200L
+#define DREG_REGID_RSA0_HIGH 0x00000201L
+#define DREG_REGID_RSA1_LOW 0x00000202L
+#define DREG_REGID_RSA1_HIGH 0x00000203L
+#define DREG_REGID_RSA2 0x00000204L
+#define DREG_REGID_RSA3 0x00000205L
+#define DREG_REGID_RSI0_LOW 0x00000206L
+#define DREG_REGID_RSI0_HIGH 0x00000207L
+#define DREG_REGID_RSI1 0x00000208L
+#define DREG_REGID_RSI2 0x00000209L
+#define DREG_REGID_SAGUSTATUS 0x0000020AL
+#define DREG_REGID_RSCONFIG01_LOW 0x0000020BL
+#define DREG_REGID_RSCONFIG01_HIGH 0x0000020CL
+#define DREG_REGID_RSCONFIG23_LOW 0x0000020DL
+#define DREG_REGID_RSCONFIG23_HIGH 0x0000020EL
+#define DREG_REGID_RSDMA01E 0x0000020FL
+#define DREG_REGID_RSDMA23E 0x00000210L
+#define DREG_REGID_RSD0_LOW 0x00000211L
+#define DREG_REGID_RSD0_HIGH 0x00000212L
+#define DREG_REGID_RSD1_LOW 0x00000213L
+#define DREG_REGID_RSD1_HIGH 0x00000214L
+#define DREG_REGID_RSD2_LOW 0x00000215L
+#define DREG_REGID_RSD2_HIGH 0x00000216L
+#define DREG_REGID_RSD3_LOW 0x00000217L
+#define DREG_REGID_RSD3_HIGH 0x00000218L
+#define DREG_REGID_SRAR_HIGH 0x0000021AL
+#define DREG_REGID_SRAR_LOW 0x0000021BL
+#define DREG_REGID_DMA_STATE 0x0000021CL
+#define DREG_REGID_CURRENT_DMA_STREAM 0x0000021DL
+#define DREG_REGID_NEXT_DMA_STREAM 0x0000021EL
+#define DREG_REGID_CPU_STATUS 0x00000300L
+#define DREG_REGID_MAC_MODE 0x00000301L
+#define DREG_REGID_STACK_AND_REPEAT 0x00000302L
+#define DREG_REGID_INDEX0 0x00000304L
+#define DREG_REGID_INDEX1 0x00000305L
+#define DREG_REGID_DMA_STATE_0_3 0x00000400L
+#define DREG_REGID_DMA_STATE_4_7 0x00000404L
+#define DREG_REGID_DMA_STATE_8_11 0x00000408L
+#define DREG_REGID_DMA_STATE_12_15 0x0000040CL
+#define DREG_REGID_DMA_STATE_16_19 0x00000410L
+#define DREG_REGID_DMA_STATE_20_23 0x00000414L
+#define DREG_REGID_DMA_STATE_24_27 0x00000418L
+#define DREG_REGID_DMA_STATE_28_31 0x0000041CL
+#define DREG_REGID_DMA_STATE_32_35 0x00000420L
+#define DREG_REGID_DMA_STATE_36_39 0x00000424L
+#define DREG_REGID_DMA_STATE_40_43 0x00000428L
+#define DREG_REGID_DMA_STATE_44_47 0x0000042CL
+#define DREG_REGID_DMA_STATE_48_51 0x00000430L
+#define DREG_REGID_DMA_STATE_52_55 0x00000434L
+#define DREG_REGID_DMA_STATE_56_59 0x00000438L
+#define DREG_REGID_DMA_STATE_60_63 0x0000043CL
+#define DREG_REGID_DMA_STATE_64_67 0x00000440L
+#define DREG_REGID_DMA_STATE_68_71 0x00000444L
+#define DREG_REGID_DMA_STATE_72_75 0x00000448L
+#define DREG_REGID_DMA_STATE_76_79 0x0000044CL
+#define DREG_REGID_DMA_STATE_80_83 0x00000450L
+#define DREG_REGID_DMA_STATE_84_87 0x00000454L
+#define DREG_REGID_DMA_STATE_88_91 0x00000458L
+#define DREG_REGID_DMA_STATE_92_95 0x0000045CL
+#define DREG_REGID_TRAP_SELECT 0x00000500L
+#define DREG_REGID_TRAP_WRITE_0 0x00000500L
+#define DREG_REGID_TRAP_WRITE_1 0x00000501L
+#define DREG_REGID_TRAP_WRITE_2 0x00000502L
+#define DREG_REGID_TRAP_WRITE_3 0x00000503L
+#define DREG_REGID_TRAP_WRITE_4 0x00000504L
+#define DREG_REGID_TRAP_WRITE_5 0x00000505L
+#define DREG_REGID_TRAP_WRITE_6 0x00000506L
+#define DREG_REGID_TRAP_WRITE_7 0x00000507L
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_WRITE_8 0x00000510L
+#define DREG_REGID_TRAP_WRITE_9 0x00000511L
+#define DREG_REGID_TRAP_WRITE_10 0x00000512L
+#define DREG_REGID_TRAP_WRITE_11 0x00000513L
+#define DREG_REGID_TRAP_WRITE_12 0x00000514L
+#define DREG_REGID_TRAP_WRITE_13 0x00000515L
+#define DREG_REGID_TRAP_WRITE_14 0x00000516L
+#define DREG_REGID_TRAP_WRITE_15 0x00000517L
+#define DREG_REGID_TRAP_WRITE_16 0x00000518L
+#define DREG_REGID_TRAP_WRITE_17 0x00000519L
+#define DREG_REGID_TRAP_WRITE_18 0x0000051AL
+#define DREG_REGID_TRAP_WRITE_19 0x0000051BL
+#define DREG_REGID_TRAP_WRITE_20 0x0000051CL
+#define DREG_REGID_TRAP_WRITE_21 0x0000051DL
+#define DREG_REGID_TRAP_WRITE_22 0x0000051EL
+#define DREG_REGID_TRAP_WRITE_23 0x0000051FL
+#endif
+#endif
+#define DREG_REGID_MAC0_ACC0_LOW 0x00000600L
+#define DREG_REGID_MAC0_ACC1_LOW 0x00000601L
+#define DREG_REGID_MAC0_ACC2_LOW 0x00000602L
+#define DREG_REGID_MAC0_ACC3_LOW 0x00000603L
+#define DREG_REGID_MAC1_ACC0_LOW 0x00000604L
+#define DREG_REGID_MAC1_ACC1_LOW 0x00000605L
+#define DREG_REGID_MAC1_ACC2_LOW 0x00000606L
+#define DREG_REGID_MAC1_ACC3_LOW 0x00000607L
+#define DREG_REGID_MAC0_ACC0_MID 0x00000608L
+#define DREG_REGID_MAC0_ACC1_MID 0x00000609L
+#define DREG_REGID_MAC0_ACC2_MID 0x0000060AL
+#define DREG_REGID_MAC0_ACC3_MID 0x0000060BL
+#define DREG_REGID_MAC1_ACC0_MID 0x0000060CL
+#define DREG_REGID_MAC1_ACC1_MID 0x0000060DL
+#define DREG_REGID_MAC1_ACC2_MID 0x0000060EL
+#define DREG_REGID_MAC1_ACC3_MID 0x0000060FL
+#define DREG_REGID_MAC0_ACC0_HIGH 0x00000610L
+#define DREG_REGID_MAC0_ACC1_HIGH 0x00000611L
+#define DREG_REGID_MAC0_ACC2_HIGH 0x00000612L
+#define DREG_REGID_MAC0_ACC3_HIGH 0x00000613L
+#define DREG_REGID_MAC1_ACC0_HIGH 0x00000614L
+#define DREG_REGID_MAC1_ACC1_HIGH 0x00000615L
+#define DREG_REGID_MAC1_ACC2_HIGH 0x00000616L
+#define DREG_REGID_MAC1_ACC3_HIGH 0x00000617L
+#define DREG_REGID_RSHOUT_LOW 0x00000620L
+#define DREG_REGID_RSHOUT_MID 0x00000628L
+#define DREG_REGID_RSHOUT_HIGH 0x00000630L
+
+#endif /* _H_HWDEFS */
diff --git a/kernel/drv/oss_cs4281/oss_cs4281.c b/kernel/drv/oss_cs4281/oss_cs4281.c
new file mode 100644
index 0000000..45ceaa7
--- /dev/null
+++ b/kernel/drv/oss_cs4281/oss_cs4281.c
@@ -0,0 +1,1061 @@
+/*
+ * Purpose: Driver for Crystal PCI audio controller.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_cs4281_cfg.h"
+#include "midi_core.h"
+#include "ac97.h"
+#include "oss_pci.h"
+#include "cs4281.h"
+
+#define CRYSTAL_VENDOR_ID 0x1013
+#define CRYSTAL_CS4281_ID 0x6005
+
+#if 1
+#define WRITEB(a,d) devc->bRegister0[a] = d
+#define READB(a) devc->bRegister0[a]
+#define WRITEW(a,d) devc->wRegister0[a>>1] = d
+#define READW(a) devc->wRegister0[a>>1]
+#define READL(a) (devc->dwRegister0[a>>2])
+#define WRITEL(a, d) devc->dwRegister0[a>>2] = d
+#else
+#define WRITEB(a,d) PCI_WRITEB(devc->osdev, d, devc->bRegister0[a])
+#define READB(a) PCI_READB(devc->osdev, devc->bRegister0[a])
+#define WRITEW(a,d) PCI_WRITEW(devc->osdev, d, devc->wRegister0[a>>1])
+#define READW(a) PCI_READW(devc->osdev, devc->wRegister0[a>>1])
+#define READL(a) PCI_READL(devc->osdev, devc->dwRegister0[a>>2])
+#define WRITEL(a, d) PCI_WRITEL(devc->osdev, d, devc->dwRegister0[a>>2])
+#endif
+
+#ifdef OSS_BIG_ENDIAN
+static unsigned int
+be_swap (unsigned int x)
+{
+ return ((x & 0x000000ff) << 24) |
+ ((x & 0x0000ff00) << 8) |
+ ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
+}
+
+#define LSWAP(x) be_swap(x)
+#else
+#define LSWAP(x) x
+#endif
+
+#define MAX_PORTC 2
+
+typedef struct cs4281_portc
+{
+ int speed, bits, channels;
+ int open_mode;
+ int trigger_bits;
+ int audio_enabled;
+ int audiodev;
+}
+cs4281_portc;
+
+typedef struct cs4281_devc
+{
+ oss_device_t *osdev;
+ char *chip_name;
+ oss_native_word bar0addr, bar1addr;
+ unsigned int *bar0virt, *bar1virt;
+ volatile unsigned int *dwRegister0, *dwRegister1;
+ volatile unsigned short *wRegister0, *wRegister1;
+ volatile unsigned char *bRegister0, *bRegister1;
+ int irq;
+ volatile unsigned char intr_mask;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ /* MIDI */
+ int midi_opened;
+ int midi_dev;
+ oss_midi_inputbyte_t midi_input_intr;
+
+ /* Mixer parameters */
+ ac97_devc ac97devc;
+ int mixer_dev;
+
+ /* Audio parameters */
+ cs4281_portc portc[MAX_PORTC];
+ int open_mode;
+ int fm_attached, mpu_attached;
+}
+cs4281_devc;
+
+
+
+static int
+ac97_read (void *devc_, int reg)
+{
+ cs4281_devc *devc = devc_;
+ int count;
+ oss_native_word status, value;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /*
+ * Make sure that there is not data sitting around from a previous
+ * uncompleted access. ACSDA = Status Data Register = 47Ch
+ */
+ status = READL (BA0_ACSDA);
+ /* Get the actual AC97 register from the offset */
+ WRITEL (BA0_ACCAD, reg);
+ WRITEL (BA0_ACCDA, 0);
+ WRITEL (BA0_ACCTL, ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN);
+
+ /* Wait for the read to occur. */
+ for (count = 0; count < 500; count++)
+ {
+ /* First, we want to wait for a short time. */
+ oss_udelay (10);
+ /*
+ * Now, check to see if the read has completed.
+ * ACCTL = 460h, DCV should be reset by now and 460h = 17h
+ */
+ status = READL (BA0_ACCTL);
+ if (!(status & ACCTL_DCV))
+ {
+ break;
+ }
+ }
+
+ /* Make sure the read completed. */
+ if (status & ACCTL_DCV)
+ {
+ cmn_err (CE_WARN, "AC97 Read Timedout\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+
+ /* Wait for the valid status bit to go active. */
+
+ for (count = 0; count < 500; count++)
+ {
+ /*
+ * Read the AC97 status register.
+ * ACSTS = Status Register = 464h
+ */
+ status = READL (BA0_ACSTS);
+ /*
+ * See if we have valid status.
+ * VSTS - Valid Status
+ */
+ if (status & ACSTS_VSTS)
+ break;
+
+ /*
+ * Wait for a short while.
+ */
+ oss_udelay (10);
+ }
+ /* Make sure we got valid status. */
+ if (!(status & ACSTS_VSTS))
+ {
+ cmn_err (CE_WARN, "AC97 Read Timedout\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+
+ /*
+ * Read the data returned from the AC97 register.
+ * ACSDA = Status Data Register = 474h
+ */
+ value = READL (BA0_ACSDA);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (value);
+}
+
+static int
+ac97_write (void *devc_, int reg, int data)
+{
+ cs4281_devc *devc = devc_;
+ int count;
+ oss_native_word status, flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ WRITEL (BA0_ACCAD, reg);
+ WRITEL (BA0_ACCDA, data);
+ WRITEL (BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN);
+ for (count = 0; count < 500; count++)
+ {
+ /* First, we want to wait for a short time. */
+ oss_udelay (10);
+ /* Now, check to see if the write has completed. */
+ /* ACCTL = 460h, DCV should be reset by now and 460h = 07h */
+ status = READL (BA0_ACCTL);
+ if (!(status & ACCTL_DCV))
+ break;
+ }
+
+ /* write didn't completed. */
+ if (status & ACCTL_DCV)
+ {
+ cmn_err (CE_WARN, "AC97 Write timeout\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+
+static int
+cs4281intr (oss_device_t * osdev)
+{
+ cs4281_devc *devc = (cs4281_devc *) osdev->devc;
+ cs4281_portc *portc;
+ oss_native_word status, uart_stat;
+ int i;
+ int serviced = 0;
+
+/* Read the Interrupt Status Register */
+ status = READL (BA0_HISR);
+
+/*
+ * This is the MIDI read interrupt service. First check to see
+ * if the MIDI interrupt flag is set in the HISR register. Next
+ * read the MIDI status register. See if Receive Buffer Empty
+ * is empty (0=FIFO Not empty, 1=FIFO is empty
+ */
+ if ((devc->midi_opened & OPEN_READ) && (status & HISR_MIDI))
+ {
+ serviced = 1;
+ uart_stat = READL (BA0_MIDSR);
+/*
+ * read one byte of MIDI data and hand it off the the sequencer module
+ * to decode this. Keep checking to see if the data is available. Stop
+ * when no more data is there in the FIFO.
+ */
+ while (!(uart_stat & MIDSR_RBE))
+ {
+ unsigned char d;
+ d = READL (BA0_MIDRP);
+
+ if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr (devc->midi_dev, d);
+ uart_stat = READL (BA0_MIDSR);
+ }
+ }
+/* Audio interrupt handling */
+ if (status & (HISR_INTENA | HISR_DMAI))
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+ if ((status & HISR_DMA0) && (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ dmap_t *dmapout = audio_engines[portc->audiodev]->dmap_out;
+ unsigned int currdac;
+ int n;
+
+ serviced = 1;
+ READL (BA0_HDSR0); /* ack the DMA interrupt */
+ currdac = READL (BA0_DCA0) - dmapout->dmabuf_phys;
+ currdac /= dmapout->fragment_size;
+ n = 0;
+ while (dmap_get_qhead (dmapout) != currdac
+ && n++ < dmapout->nfrags)
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+
+ if ((status & HISR_DMA1) && (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ dmap_t *dmapin = audio_engines[portc->audiodev]->dmap_in;
+ unsigned int curradc;
+ int n;
+
+ serviced = 1;
+ READL (BA0_HDSR1); /* ack the DMA interrupt */
+ curradc = READL (BA0_DCA1) - dmapin->dmabuf_phys;
+ curradc /= dmapin->fragment_size;
+ n = 0;
+ while (dmap_get_qtail (dmapin) != curradc && n++ < dmapin->nfrags)
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ WRITEL (BA0_HICR, HICR_IEV | HICR_CHGM);
+ }
+ return serviced;
+}
+
+static int
+cs4281_audio_set_rate (int dev, int arg)
+{
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ if (arg == 0)
+ return portc->speed;
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 6023)
+ arg = 6023;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+cs4281_audio_set_channels (int dev, short arg)
+{
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ if ((arg != 1) && (arg != 2))
+ return portc->channels;
+ portc->channels = arg;
+ return portc->channels;
+}
+
+static unsigned int
+cs4281_audio_set_format (int dev, unsigned int arg)
+{
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ if (arg == 0)
+ return portc->bits;
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE)))
+ return portc->bits;
+ portc->bits = arg;
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+cs4281_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void cs4281_audio_trigger (int dev, int state);
+static void
+cs4281_audio_reset (int dev)
+{
+ cs4281_audio_trigger (dev, 0);
+}
+
+static void
+cs4281_audio_reset_input (int dev)
+{
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ cs4281_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+cs4281_audio_reset_output (int dev)
+{
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ cs4281_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+cs4281_audio_open (int dev, int mode, int open_flags)
+{
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ cs4281_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode |= mode;
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+cs4281_audio_close (int dev, int mode)
+{
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ cs4281_devc *devc = audio_engines[dev]->devc;
+ cs4281_audio_reset (dev);
+ portc->open_mode = 0;
+ devc->open_mode &= ~mode;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+cs4281_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ cs4281_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+cs4281_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ cs4281_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+cs4281_audio_trigger (int dev, int state)
+{
+ cs4281_devc *devc = audio_engines[dev]->devc;
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ oss_native_word tmp1;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ /* Clear DMA0 channel Mask bit. Start Playing. */
+ tmp1 = READL (BA0_DCR0) & ~DCRn_MSK; /*enable DMA */
+ WRITEL (BA0_DCR0, tmp1); /* (154h) */
+ WRITEL (BA0_HICR, HICR_IEV | HICR_CHGM); /*enable intr */
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ tmp1 = READL (BA0_DCR0) & ~DCRn_MSK;
+ WRITEL (BA0_DCR0, tmp1 | DCRn_MSK);
+ }
+ }
+ }
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ /* Clear DMA1 channel Mask bit. Start recording. */
+ tmp1 = READL (BA0_DCR1) & ~DCRn_MSK;
+ WRITEL (BA0_DCR1, tmp1); /* (15ch) */
+ WRITEL (BA0_HICR, HICR_IEV | HICR_CHGM); /*Set INTENA=1. */
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ tmp1 = READL (BA0_DCR1) & ~DCRn_MSK;
+ WRITEL (BA0_DCR1, tmp1 | DCRn_MSK);
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static int
+cs4281_rate (oss_native_word rate)
+{
+ int val = 0;
+
+ switch (rate)
+ {
+ case 8000:
+ val = 5;
+ break;
+ case 11025:
+ val = 4;
+ break;
+ case 16000:
+ val = 3;
+ break;
+ case 22050:
+ val = 2;
+ break;
+ case 44100:
+ val = 1;
+ break;
+ case 48000:
+ val = 0;
+ break;
+ default:
+ val = 1536000 / rate;
+ break;
+ }
+ return val;
+}
+
+/*ARGSUSED*/
+static int
+cs4281_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ cs4281_devc *devc = audio_engines[dev]->devc;
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ int count = dmap->bytes_in_use;
+ oss_native_word recordFormat;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ /* set the record rate */
+ WRITEL (BA0_ADCSR, cs4281_rate (portc->speed)); /* (748h) */
+ /* Start with defaults for the record format */
+ /* reg & modify them for the current case. */
+ recordFormat = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE;
+ if (portc->channels == 1) /* If mono, */
+ recordFormat |= DMRn_MONO; /* Turn on mono bit. */
+ if (portc->bits == 8) /* If 8-bit, */
+ recordFormat |= (DMRn_SIZE8 | DMRn_USIGN); /* turn on 8bit/unsigned. */
+ WRITEL (BA0_DMR1, recordFormat);
+ /* set input gain to 0db */
+ /* ac97_write(devc, BA0_AC97_RECORD_GAIN, 0x0808); */
+ if (portc->channels == 2) /* If stereo, */
+ count /= 2; /* halve DMA count(stereo); */
+ if (portc->bits == 16) /* If 16-bit, */
+ count /= 2;
+ /* Set the physical play buffer address DMA1 Base & Current. */
+ WRITEL (BA0_DBA1, dmap->dmabuf_phys); /* (118h) */
+ /* Set the sample count(-1) in DMA Base Count register 1. */
+ WRITEL (BA0_DBC1, count - 1);
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+cs4281_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ cs4281_devc *devc = audio_engines[dev]->devc;
+ cs4281_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ int count = dmap->bytes_in_use;
+ oss_native_word playFormat;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ /* Set the sample rate converter */
+ WRITEL (BA0_DACSR, cs4281_rate (portc->speed));
+ playFormat = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ | (1 << 6);
+ if (portc->channels == 1) /* If stereo, */
+ playFormat |= DMRn_MONO; /* Turn on mono bit. */
+ if (portc->bits == 8) /* If 16-bit, */
+ playFormat |= (DMRn_SIZE8 | DMRn_USIGN); /* turn on 8-bit/unsigned. */
+ WRITEL (BA0_DMR0, playFormat); /* (150h) */
+ if (portc->channels == 2) /* If stereo, */
+ count /= 2; /* halve DMA count(stereo); */
+ if (portc->bits == 16) /* If 16-bit, */
+ count /= 2;
+ /* Set the physical play buffer address DMA0 Base & Current. */
+ WRITEL (BA0_DBA0, dmap->dmabuf_phys & ~0x3); /* (118h) */
+ /* Set the sample count(-1) in DMA Base Count register 0. */
+ WRITEL (BA0_DBC0, count - 1);
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+cs4281_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ cs4281_devc *devc = audio_engines[dev]->devc;
+ unsigned int ptr = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ ptr = READL (BA0_DCA0);
+ }
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ ptr = READL (BA0_DCA1);
+ }
+ ptr -= dmap->dmabuf_phys;
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ptr;
+}
+
+static audiodrv_t cs4281_audio_driver = {
+ cs4281_audio_open,
+ cs4281_audio_close,
+ cs4281_audio_output_block,
+ cs4281_audio_start_input,
+ cs4281_audio_ioctl,
+ cs4281_audio_prepare_for_input,
+ cs4281_audio_prepare_for_output,
+ cs4281_audio_reset,
+ NULL,
+ NULL,
+ cs4281_audio_reset_input,
+ cs4281_audio_reset_output,
+ cs4281_audio_trigger,
+ cs4281_audio_set_rate,
+ cs4281_audio_set_format,
+ cs4281_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* cs4281_alloc_buffer, */
+ NULL, /* cs4281_free_buffer, */
+ NULL,
+ NULL,
+ cs4281_get_buffer_pointer
+};
+
+/***********************MIDI PORT ROUTINES ****************/
+/*ARGSUSED*/
+static int
+cs4281_midi_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ cs4281_devc *devc = (cs4281_devc *) midi_devs[dev]->devc;
+ if (devc->midi_opened)
+ {
+ return OSS_EBUSY;
+ }
+
+ devc->midi_input_intr = inputbyte;
+ devc->midi_opened = mode;
+ /* first reset the MIDI port */
+ WRITEL (BA0_MIDCR, 0x10);
+ WRITEL (BA0_MIDCR, 0x00);
+ /* Now check if we're in Read or Write mode */
+ if (mode & OPEN_READ)
+ {
+ /* enable MIDI Input intr and receive enable */
+ WRITEL (BA0_MIDCR, MIDCR_RXE | MIDCR_RIE);
+ }
+
+ if (mode & OPEN_WRITE)
+ {
+ /* enable MIDI transmit enable */
+ WRITEL (BA0_MIDCR, MIDCR_TXE);
+ }
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+cs4281_midi_close (int dev, int mode)
+{
+ cs4281_devc *devc = (cs4281_devc *) midi_devs[dev]->devc;
+/* Reset the device*/
+ WRITEL (BA0_MIDCR, 0x10);
+ WRITEL (BA0_MIDCR, 0x00);
+ devc->midi_opened = 0;
+}
+
+static int
+cs4281_midi_out (int dev, unsigned char midi_byte)
+{
+ cs4281_devc *devc = (cs4281_devc *) midi_devs[dev]->devc;
+ unsigned char uart_stat = READL (BA0_MIDSR);
+/* Check if Transmit buffer full flag is set - if so return */
+ if ((uart_stat & MIDSR_TBF))
+ return 0;
+/* Now put the MIDI databyte in the write port */
+ WRITEL (BA0_MIDWP, midi_byte);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+cs4281_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t cs4281_midi_driver = {
+ cs4281_midi_open,
+ cs4281_midi_close,
+ cs4281_midi_ioctl,
+ cs4281_midi_out
+};
+
+static int
+init_cs4281 (cs4281_devc * devc)
+{
+
+ int my_mixer, i;
+ oss_native_word dwAC97SlotID, tmp1;
+ int first_dev = 0;
+/****************BEGIN HARDWARE INIT*****************/
+ /* Setup CFLR */
+ tmp1 = READL (BA0_CFLR);
+ if (tmp1 != 0x01)
+ {
+ WRITEL (BA0_CFLR, 0x01); /*set up AC97 mode */
+ tmp1 = READL (BA0_CFLR);
+ if (tmp1 != 0x01)
+ {
+ tmp1 = READL (BA0_CWPR);
+ if (tmp1 != 0x4281)
+ WRITEL (BA0_CWPR, 0x4281);
+ tmp1 = READL (BA0_CWPR);
+ if (tmp1 != 0x4281)
+ {
+ cmn_err (CE_WARN, "Resetting AC97 failed\n");
+ return OSS_EIO;
+ }
+ WRITEL (BA0_CFLR, 0x1);
+ tmp1 = READL (BA0_CFLR);
+ if (tmp1 != 0x1)
+ {
+ cmn_err (CE_WARN, "Resetting AC97 still fails\n");
+ return OSS_EIO;
+ }
+ }
+ }
+ /* Setup the FM and Joystick trap address for Legacy emulation */
+ WRITEL (BA0_IOTCR, 0x1);
+ WRITEL (BA0_IOTFM, 0xc0030388);
+ WRITEL (BA0_IOTGP, 0xc0070200);
+ /**************************************** */
+ /* Set up the Sound System Configuration */
+ /**************************************** */
+ /* Set the 'Configuration Write Protect' register */
+ /* to 4281h. Allows vendor-defined configuration */
+ /* space between 0e4h and 0ffh to be written. */
+ WRITEL (BA0_CWPR, 0x4281); /* (3e0h) */
+ if ((tmp1 = READL (BA0_SERC1)) != (SERC1_SO1EN | SERC1_SO1F_AC97))
+ {
+ cmn_err (CE_WARN, "SERC1: AC97 check failed\n");
+ return OSS_EIO;
+ }
+ /* setup power management to full power */
+ WRITEL (BA0_SSPM, 0x7E);
+ /* 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. */
+ WRITEL (BA0_CLKCR1, 0); /* (400h) */
+ WRITEL (BA0_SERMC, 0); /* (420h) */
+ /* (1) 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. */
+ WRITEL (BA0_ACCTL, 0);
+ oss_udelay (50);
+ WRITEL (BA0_SPMC, 0); /* (3ech) */
+ oss_udelay (50);
+ WRITEL (BA0_SPMC, SPMC_RSTN);
+ oss_udelay (50000);
+ WRITEL (BA0_SERMC, SERMC_PTC_AC97 | SERMC_MSPE | 0x10000);
+ /* (3) Turn on the Sound System Clocks. */
+ WRITEL (BA0_CLKCR1, CLKCR1_DLLP); /* (400h) */
+ /* Wait for the PLL to stabilize. */
+ oss_udelay (50000);
+ /* Turn on clocking of the core (CLKCR1(400h) = 0x00000030) */
+ WRITEL (BA0_CLKCR1, CLKCR1_DLLP | CLKCR1_SWCE);
+ /* (5) Wait for clock stabilization. */
+ for (tmp1 = 0; tmp1 < 100; tmp1++)
+ {
+ if (READL (BA0_CLKCR1) & CLKCR1_DLLRDY)
+ break;
+ oss_udelay (50000);
+ }
+ if (!(READL (BA0_CLKCR1) & CLKCR1_DLLRDY))
+ {
+ cmn_err (CE_WARN, "DLLRDY Clock not ready\n");
+ return OSS_EIO;
+ }
+ /* (6) Enable ASYNC generation. */
+ WRITEL (BA0_ACCTL, ACCTL_ESYN); /* (460h) */
+ /* 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.) */
+ /* (7) Wait for the codec ready signal from the AC97 codec. */
+ for (tmp1 = 0; tmp1 < 100; tmp1++)
+ {
+ /* Delay a mil to let things settle out and */
+ /* to prevent retrying the read too quickly. */
+ if (READL (BA0_ACSTS) & ACSTS_CRDY) /* If ready, (464h) */
+ break; /* exit the 'for' loop. */
+ oss_udelay (50000);
+ }
+ if (!(READL (BA0_ACSTS) & ACSTS_CRDY)) /* If never came ready, */
+ {
+ cmn_err (CE_WARN, "AC97 not ready\n");
+ return OSS_EIO; /* exit initialization. */
+ }
+ /* (8) Assert the 'valid frame' signal so we can */
+ /* begin sending commands to the AC97 codec. */
+ WRITEL (BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN); /* (460h) */
+
+ /* (11) Wait until we've sampled input slots 3 & 4 as valid, meaning */
+ /* that the codec is pumping ADC data across the AC link. */
+ for (tmp1 = 0; tmp1 < 100; tmp1++)
+ {
+ /* Read the input slot valid register; See */
+ /* if input slots 3 and 4 are valid yet. */
+ if ((READL (BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == /* (474h) */
+ (ACISV_ISV3 | ACISV_ISV4))
+ break; /* Exit the 'for' if slots are valid. */
+ oss_udelay (50000);
+ }
+ /* If we never got valid data, exit initialization. */
+ if ((READL (BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) !=
+ (ACISV_ISV3 | ACISV_ISV4))
+ {
+ cmn_err (CE_WARN, "AC97 Slot not valid\n");
+ return OSS_EIO; /* If no valid data, exit initialization. */
+ }
+ /* (12) Start digital data transfer of audio data to the codec. */
+ WRITEL (BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); /* (468h) */
+
+ /* For playback, we map AC97 slot 3 and 4(Left */
+ /* & Right PCM playback) to DMA Channel 0. */
+ /* Set the fifo to be 31 bytes at offset zero. */
+ dwAC97SlotID = 0x01001F00; /* FCR0.RS[4:0]=1(=>slot4, right PCM playback). */
+ /* FCR0.LS[4:0]=0(=>slot3, left PCM playback). */
+ /* FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0. */
+ WRITEL (BA0_FCR0, dwAC97SlotID); /* (180h) */
+ WRITEL (BA0_FCR0, dwAC97SlotID | FCRn_FEN); /* Turn on FIFO Enable. */
+ /* For capture, we map AC97 slot 10 and 11(Left */
+ /* and Right PCM Record) to DMA Channel 1. */
+ /* Set the fifo to be 31 bytes at offset 32. */
+ dwAC97SlotID = 0x0B0A1F20; /* FCR1.RS[4:0]=11(=>slot11, right PCM record). */
+ /* FCR1.LS[4:0]=10(=>slot10, left PCM record). */
+ /* FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16. */
+ WRITEL (BA0_FCR1, dwAC97SlotID); /* (184h) */
+ WRITEL (BA0_FCR1, dwAC97SlotID | FCRn_FEN); /* Turn on FIFO Enable. */
+ /* Map the Playback SRC to the same AC97 slots(3 & 4-- */
+ /* --Playback left & right)as DMA channel 0. */
+ /* Map the record SRC to the same AC97 slots(10 & 11-- */
+ /* -- Record left & right) as DMA channel 1. */
+ dwAC97SlotID = 0x0b0a0100; /*SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback). */
+ /*SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback). */
+ /*SCRSA.CRSS[4:0]=11(=>slot11, right PCM record) */
+ /*SCRSA.CLSS[4:0]=10(=>slot10, left PCM record). */
+ WRITEL (BA0_SRCSA, dwAC97SlotID); /* (75ch) */
+ /* Set 'Half Terminal Count Interrupt Enable' and 'Terminal */
+ /* Count Interrupt Enable' in DMA Control Registers 0 & 1. */
+ /* Set 'MSK' flag to 1 to keep the DMA engines paused. */
+ tmp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK); /* (00030001h) */
+ WRITEL (BA0_DCR0, tmp1); /* (154h) */
+ WRITEL (BA0_DCR1, tmp1); /* (15ch) */
+ /* Set 'Auto-Initialize Control' to 'enabled'; For playback, */
+ /* set 'Transfer Type Control'(TR[1:0]) to 'read transfer', */
+ /* for record, set Transfer Type Control to 'write transfer'. */
+ /* All other bits set to zero; Some will be changed @ transfer start. */
+ tmp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ); /* (20000018h) */
+ WRITEL (BA0_DMR0, tmp1); /* (150h) */
+ tmp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE); /* (20000014h) */
+ WRITEL (BA0_DMR1, tmp1); /* (158h) */
+ /* Enable DMA interrupts generally, and */
+ /* DMA0 & DMA1 interrupts specifically. */
+ tmp1 = READL (BA0_HIMR) & 0x7fbbfcff;
+ WRITEL (BA0_HIMR, tmp1);
+ /* set up some volume defaults */
+ WRITEL (BA0_PPLVC, 0x0808);
+ WRITEL (BA0_PPRVC, 0x0808);
+ WRITEL (BA0_FMLVC, 0x0);
+ WRITEL (BA0_FMRVC, 0x0);
+/****** END OF HARDWARE INIT *****/
+
+
+ my_mixer =
+ ac97_install (&devc->ac97devc, "CS4281 AC97 Mixer", ac97_read, ac97_write,
+ devc, devc->osdev);
+ if (my_mixer < 0)
+ {
+ return 0;
+ }
+
+ devc->mixer_dev = my_mixer;
+
+ /* ac97_write(devc, 0x26, ac97_read(devc, 0x26) | 0x8000); */
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ int adev;
+ int caps = 0;
+ cs4281_portc *portc = &devc->portc[i];
+ char tmp_name[100];
+ strcpy (tmp_name, devc->chip_name);
+
+ if (i == 0)
+ {
+ caps = ADEV_AUTOMODE | ADEV_DUPLEX;
+ strcpy (tmp_name, devc->chip_name);
+ }
+ else
+ {
+ caps = ADEV_AUTOMODE | ADEV_DUPLEX | ADEV_SHADOW;
+ strcpy (tmp_name, devc->chip_name);
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &cs4281_audio_driver,
+ sizeof (audiodrv_t),
+ caps,
+ AFMT_S16_LE | AFMT_U8, devc, -1)) < 0)
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->min_rate = 6023;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ portc->open_mode = 0;
+ portc->audiodev = adev;
+ portc->audio_enabled = 0;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+ }
+
+ devc->midi_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "CS4281", "CS4281 MIDI Port", &cs4281_midi_driver, sizeof (midi_driver_t),
+ 0, devc, devc->osdev);
+ devc->midi_opened = 0;
+ return 1;
+}
+
+int
+oss_cs4281_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision, pci_irq_inta;
+ unsigned short pci_command, vendor, device;
+ unsigned int ioaddr;
+ int err;
+ cs4281_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered CS4281 probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != CRYSTAL_VENDOR_ID || device != CRYSTAL_CS4281_ID)
+ return 0;
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ oss_pci_byteswap (osdev, 1);
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_byte (osdev, PCI_INTERRUPT_LINE + 1, &pci_irq_inta);
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &ioaddr);
+ devc->bar0addr = ioaddr;
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_1, &ioaddr);
+ devc->bar1addr = ioaddr;
+
+ /* activate the device enable bus master/memory space */
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ if ((devc->bar0addr == 0) || (devc->bar1addr == 0))
+ {
+ cmn_err (CE_WARN, "undefined MEMORY I/O address.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS.\n");
+ return 0;
+ }
+
+
+ /* Map the shared memory area */
+ devc->bar0virt =
+ (unsigned int *) MAP_PCI_MEM (devc->osdev, 0, devc->bar0addr, 4 * 1024);
+ devc->bar1virt =
+ (unsigned int *) MAP_PCI_MEM (devc->osdev, 1, devc->bar1addr,
+ 1024 * 1024);
+ devc->dwRegister0 = devc->bar0virt;
+ devc->wRegister0 = (unsigned short *) devc->bar0virt;
+ devc->bRegister0 = (unsigned char *) devc->bar0virt;
+ devc->dwRegister1 = devc->bar1virt;
+ devc->wRegister1 = (unsigned short *) devc->bar1virt;
+ devc->bRegister1 = (unsigned char *) devc->bar1virt;
+
+ devc->chip_name = "CS4281";
+ devc->irq = pci_irq_line;
+ devc->open_mode = 0;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, cs4281intr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+ return init_cs4281 (devc); /*Detected */
+}
+
+
+int
+oss_cs4281_detach (oss_device_t * osdev)
+{
+ cs4281_devc *devc = (cs4281_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ WRITEL (BA0_HICR, 0x02); /*enable intena */
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+
+ UNMAP_PCI_MEM (devc->osdev, 0, devc->bar0addr, devc->bar0virt, 4 * 1024);
+ UNMAP_PCI_MEM (devc->osdev, 1, devc->bar1addr, devc->bar1virt, 1024 * 1024);
+
+ devc->bar0addr = 0;
+ devc->bar1addr = 0;
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_cs4281/oss_cs4281.man b/kernel/drv/oss_cs4281/oss_cs4281.man
new file mode 100644
index 0000000..7e19190
--- /dev/null
+++ b/kernel/drv/oss_cs4281/oss_cs4281.man
@@ -0,0 +1,21 @@
+NAME
+oss_cs4281 - Cirrus Logic CS4281 driver
+
+DESCRIPTION
+Open Sound System driver for Cirrus Logic (Crystal Semicoductor) CS4281 audio
+controller.
+
+CS4281 device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo playback/recording
+ o 8KHz to 48Khz sample rate.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_cs4281.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_cs461x/.devices b/kernel/drv/oss_cs461x/.devices
new file mode 100644
index 0000000..2ee1e6f
--- /dev/null
+++ b/kernel/drv/oss_cs461x/.devices
@@ -0,0 +1,7 @@
+oss_cs461x pci1013,6001 Crystal CS4610
+oss_cs461x pci1013,6003 Crystal CS4280
+oss_cs461x pci1013,6004 Crystal CS4615
+oss_cs461x pcs153b,112e Terratec DMX Xfire 1024
+oss_cs461x pcs1681,50 Hercules Game Theater XP
+oss_cs461x pcs1681,51 Hercules Game Theater XP+
+oss_cs461x pcs5053,3357 TurtleBeach SantaCruz / VideoLogic SonicFury
diff --git a/kernel/drv/oss_cs461x/.name b/kernel/drv/oss_cs461x/.name
new file mode 100644
index 0000000..3c0e69b
--- /dev/null
+++ b/kernel/drv/oss_cs461x/.name
@@ -0,0 +1 @@
+Crystal CS461x/CS4280
diff --git a/kernel/drv/oss_cs461x/.params b/kernel/drv/oss_cs461x/.params
new file mode 100644
index 0000000..18ed0a3
--- /dev/null
+++ b/kernel/drv/oss_cs461x/.params
@@ -0,0 +1,6 @@
+int cs461x_clkrun_fix=0;
+/*
+ * Some IBM Thinkpads require a workaround for the CLKRUN protocol.
+ * Values: 1=Enable 0=Disable Default: 0
+ */
+
diff --git a/kernel/drv/oss_cs461x/cs461x.h b/kernel/drv/oss_cs461x/cs461x.h
new file mode 100644
index 0000000..79ae7f5
--- /dev/null
+++ b/kernel/drv/oss_cs461x/cs461x.h
@@ -0,0 +1,1668 @@
+/*
+ * Purpose: Definitions for the cs461x driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+
+/*
+ * Direct registers
+ */
+
+/*
+ * The following define the offsets of the registers accessed via base address
+ * register zero on the CS461x part.
+ */
+#define BA0_HISR 0x00000000
+#define BA0_HSR0 0x00000004
+#define BA0_HICR 0x00000008
+#define BA0_DMSR 0x00000100
+#define BA0_HSAR 0x00000110
+#define BA0_HDAR 0x00000114
+#define BA0_HDMR 0x00000118
+#define BA0_HDCR 0x0000011C
+#define BA0_PFMC 0x00000200
+#define BA0_PFCV1 0x00000204
+#define BA0_PFCV2 0x00000208
+#define BA0_PCICFG00 0x00000300
+#define BA0_PCICFG04 0x00000304
+#define BA0_PCICFG08 0x00000308
+#define BA0_PCICFG0C 0x0000030C
+#define BA0_PCICFG10 0x00000310
+#define BA0_PCICFG14 0x00000314
+#define BA0_PCICFG18 0x00000318
+#define BA0_PCICFG1C 0x0000031C
+#define BA0_PCICFG20 0x00000320
+#define BA0_PCICFG24 0x00000324
+#define BA0_PCICFG28 0x00000328
+#define BA0_PCICFG2C 0x0000032C
+#define BA0_PCICFG30 0x00000330
+#define BA0_PCICFG34 0x00000334
+#define BA0_PCICFG38 0x00000338
+#define BA0_PCICFG3C 0x0000033C
+#define BA0_CLKCR1 0x00000400
+#define BA0_CLKCR2 0x00000404
+#define BA0_PLLM 0x00000408
+#define BA0_PLLCC 0x0000040C
+#define BA0_FRR 0x00000410
+#define BA0_CFL1 0x00000414
+#define BA0_CFL2 0x00000418
+#define BA0_SERMC1 0x00000420
+#define BA0_SERMC2 0x00000424
+#define BA0_SERC1 0x00000428
+#define BA0_SERC2 0x0000042C
+#define BA0_SERC3 0x00000430
+#define BA0_SERC4 0x00000434
+#define BA0_SERC5 0x00000438
+#define BA0_SERBSP 0x0000043C
+#define BA0_SERBST 0x00000440
+#define BA0_SERBCM 0x00000444
+#define BA0_SERBAD 0x00000448
+#define BA0_SERBCF 0x0000044C
+#define BA0_SERBWP 0x00000450
+#define BA0_SERBRP 0x00000454
+#ifndef NO_CS4612
+#define BA0_ASER_FADDR 0x00000458
+#endif
+#define BA0_ACCTL 0x00000460
+#define BA0_ACSTS 0x00000464
+#define BA0_ACOSV 0x00000468
+#define BA0_ACCAD 0x0000046C
+#define BA0_ACCDA 0x00000470
+#define BA0_ACISV 0x00000474
+#define BA0_ACSAD 0x00000478
+#define BA0_ACSDA 0x0000047C
+#define BA0_JSPT 0x00000480
+#define BA0_JSCTL 0x00000484
+#define BA0_JSC1 0x00000488
+#define BA0_JSC2 0x0000048C
+#define BA0_MIDCR 0x00000490
+#define BA0_MIDSR 0x00000494
+#define BA0_MIDWP 0x00000498
+#define BA0_MIDRP 0x0000049C
+#define BA0_JSIO 0x000004A0
+#ifndef NO_CS4612
+#define BA0_ASER_MASTER 0x000004A4
+#endif
+#define BA0_CFGI 0x000004B0
+#define BA0_SSVID 0x000004B4
+#define BA0_GPIOR 0x000004B8
+#ifndef NO_CS4612
+#define BA0_EGPIODR 0x000004BC
+#define BA0_EGPIOPTR 0x000004C0
+#define BA0_EGPIOTR 0x000004C4
+#define BA0_EGPIOWR 0x000004C8
+#define BA0_EGPIOSR 0x000004CC
+#define BA0_SERC6 0x000004D0
+#define BA0_SERC7 0x000004D4
+#define BA0_SERACC 0x000004D8
+#define BA0_ACCTL2 0x000004E0
+#define BA0_ACSTS2 0x000004E4
+#define BA0_ACOSV2 0x000004E8
+#define BA0_ACCAD2 0x000004EC
+#define BA0_ACCDA2 0x000004F0
+#define BA0_ACISV2 0x000004F4
+#define BA0_ACSAD2 0x000004F8
+#define BA0_ACSDA2 0x000004FC
+#define BA0_IOTAC0 0x00000500
+#define BA0_IOTAC1 0x00000504
+#define BA0_IOTAC2 0x00000508
+#define BA0_IOTAC3 0x0000050C
+#define BA0_IOTAC4 0x00000510
+#define BA0_IOTAC5 0x00000514
+#define BA0_IOTAC6 0x00000518
+#define BA0_IOTAC7 0x0000051C
+#define BA0_IOTAC8 0x00000520
+#define BA0_IOTAC9 0x00000524
+#define BA0_IOTAC10 0x00000528
+#define BA0_IOTAC11 0x0000052C
+#define BA0_IOTFR0 0x00000540
+#define BA0_IOTFR1 0x00000544
+#define BA0_IOTFR2 0x00000548
+#define BA0_IOTFR3 0x0000054C
+#define BA0_IOTFR4 0x00000550
+#define BA0_IOTFR5 0x00000554
+#define BA0_IOTFR6 0x00000558
+#define BA0_IOTFR7 0x0000055C
+#define BA0_IOTFIFO 0x00000580
+#define BA0_IOTRRD 0x00000584
+#define BA0_IOTFP 0x00000588
+#define BA0_IOTCR 0x0000058C
+#define BA0_DPCID 0x00000590
+#define BA0_DPCIA 0x00000594
+#define BA0_DPCIC 0x00000598
+#define BA0_PCPCIR 0x00000600
+#define BA0_PCPCIG 0x00000604
+#define BA0_PCPCIEN 0x00000608
+#define BA0_EPCIPMC 0x00000610
+#endif
+
+/*
+ * The following define the offsets of the registers and memories accessed via
+ * base address register one on the CS461x part.
+ */
+#define BA1_SP_DMEM0 0x00000000
+#define BA1_SP_DMEM1 0x00010000
+#define BA1_SP_PMEM 0x00020000
+#define BA1_SP_REG 0x00030000
+#define BA1_SPCR 0x00030000
+#define BA1_DREG 0x00030004
+#define BA1_DSRWP 0x00030008
+#define BA1_TWPR 0x0003000C
+#define BA1_SPWR 0x00030010
+#define BA1_SPIR 0x00030014
+#define BA1_FGR1 0x00030020
+#define BA1_SPCS 0x00030028
+#define BA1_SDSR 0x0003002C
+#define BA1_FRMT 0x00030030
+#define BA1_FRCC 0x00030034
+#define BA1_FRSC 0x00030038
+#define BA1_OMNI_MEM 0x000E0000
+
+/*
+ * The following defines are for the flags in the host interrupt status
+ * register.
+ */
+#define HISR_VC_MASK 0x0000FFFF
+#define HISR_VC0 0x00000001
+#define HISR_VC1 0x00000002
+#define HISR_VC2 0x00000004
+#define HISR_VC3 0x00000008
+#define HISR_VC4 0x00000010
+#define HISR_VC5 0x00000020
+#define HISR_VC6 0x00000040
+#define HISR_VC7 0x00000080
+#define HISR_VC8 0x00000100
+#define HISR_VC9 0x00000200
+#define HISR_VC10 0x00000400
+#define HISR_VC11 0x00000800
+#define HISR_VC12 0x00001000
+#define HISR_VC13 0x00002000
+#define HISR_VC14 0x00004000
+#define HISR_VC15 0x00008000
+#define HISR_INT0 0x00010000
+#define HISR_INT1 0x00020000
+#define HISR_DMAI 0x00040000
+#define HISR_FROVR 0x00080000
+#define HISR_MIDI 0x00100000
+#ifdef NO_CS4612
+#define HISR_RESERVED 0x0FE00000
+#else
+#define HISR_SBINT 0x00200000
+#define HISR_RESERVED 0x0FC00000
+#endif
+#define HISR_H0P 0x40000000
+#define HISR_INTENA 0x80000000
+
+/*
+ * The following defines are for the flags in the host signal register 0.
+ */
+#define HSR0_VC_MASK 0xFFFFFFFF
+#define HSR0_VC16 0x00000001
+#define HSR0_VC17 0x00000002
+#define HSR0_VC18 0x00000004
+#define HSR0_VC19 0x00000008
+#define HSR0_VC20 0x00000010
+#define HSR0_VC21 0x00000020
+#define HSR0_VC22 0x00000040
+#define HSR0_VC23 0x00000080
+#define HSR0_VC24 0x00000100
+#define HSR0_VC25 0x00000200
+#define HSR0_VC26 0x00000400
+#define HSR0_VC27 0x00000800
+#define HSR0_VC28 0x00001000
+#define HSR0_VC29 0x00002000
+#define HSR0_VC30 0x00004000
+#define HSR0_VC31 0x00008000
+#define HSR0_VC32 0x00010000
+#define HSR0_VC33 0x00020000
+#define HSR0_VC34 0x00040000
+#define HSR0_VC35 0x00080000
+#define HSR0_VC36 0x00100000
+#define HSR0_VC37 0x00200000
+#define HSR0_VC38 0x00400000
+#define HSR0_VC39 0x00800000
+#define HSR0_VC40 0x01000000
+#define HSR0_VC41 0x02000000
+#define HSR0_VC42 0x04000000
+#define HSR0_VC43 0x08000000
+#define HSR0_VC44 0x10000000
+#define HSR0_VC45 0x20000000
+#define HSR0_VC46 0x40000000
+#define HSR0_VC47 0x80000000
+
+/*
+ * The following defines are for the flags in the host interrupt control
+ * register.
+ */
+#define HICR_IEV 0x00000001
+#define HICR_CHGM 0x00000002
+
+/*
+ * The following defines are for the flags in the DMA status register.
+ */
+#define DMSR_HP 0x00000001
+#define DMSR_HR 0x00000002
+#define DMSR_SP 0x00000004
+#define DMSR_SR 0x00000008
+
+/*
+ * The following defines are for the flags in the host DMA source address
+ * register.
+ */
+#define HSAR_HOST_ADDR_MASK 0xFFFFFFFF
+#define HSAR_DSP_ADDR_MASK 0x0000FFFF
+#define HSAR_MEMID_MASK 0x000F0000
+#define HSAR_MEMID_SP_DMEM0 0x00000000
+#define HSAR_MEMID_SP_DMEM1 0x00010000
+#define HSAR_MEMID_SP_PMEM 0x00020000
+#define HSAR_MEMID_SP_DEBUG 0x00030000
+#define HSAR_MEMID_OMNI_MEM 0x000E0000
+#define HSAR_END 0x40000000
+#define HSAR_ERR 0x80000000
+
+/*
+ * The following defines are for the flags in the host DMA destination address
+ * register.
+ */
+#define HDAR_HOST_ADDR_MASK 0xFFFFFFFF
+#define HDAR_DSP_ADDR_MASK 0x0000FFFF
+#define HDAR_MEMID_MASK 0x000F0000
+#define HDAR_MEMID_SP_DMEM0 0x00000000
+#define HDAR_MEMID_SP_DMEM1 0x00010000
+#define HDAR_MEMID_SP_PMEM 0x00020000
+#define HDAR_MEMID_SP_DEBUG 0x00030000
+#define HDAR_MEMID_OMNI_MEM 0x000E0000
+#define HDAR_END 0x40000000
+#define HDAR_ERR 0x80000000
+
+/*
+ * The following defines are for the flags in the host DMA control register.
+ */
+#define HDMR_AC_MASK 0x0000F000
+#define HDMR_AC_8_16 0x00001000
+#define HDMR_AC_M_S 0x00002000
+#define HDMR_AC_B_L 0x00004000
+#define HDMR_AC_S_U 0x00008000
+
+/*
+ * The following defines are for the flags in the host DMA control register.
+ */
+#define HDCR_COUNT_MASK 0x000003FF
+#define HDCR_DONE 0x00004000
+#define HDCR_OPT 0x00008000
+#define HDCR_WBD 0x00400000
+#define HDCR_WBS 0x00800000
+#define HDCR_DMS_MASK 0x07000000
+#define HDCR_DMS_LINEAR 0x00000000
+#define HDCR_DMS_16_DWORDS 0x01000000
+#define HDCR_DMS_32_DWORDS 0x02000000
+#define HDCR_DMS_64_DWORDS 0x03000000
+#define HDCR_DMS_128_DWORDS 0x04000000
+#define HDCR_DMS_256_DWORDS 0x05000000
+#define HDCR_DMS_512_DWORDS 0x06000000
+#define HDCR_DMS_1024_DWORDS 0x07000000
+#define HDCR_DH 0x08000000
+#define HDCR_SMS_MASK 0x70000000
+#define HDCR_SMS_LINEAR 0x00000000
+#define HDCR_SMS_16_DWORDS 0x10000000
+#define HDCR_SMS_32_DWORDS 0x20000000
+#define HDCR_SMS_64_DWORDS 0x30000000
+#define HDCR_SMS_128_DWORDS 0x40000000
+#define HDCR_SMS_256_DWORDS 0x50000000
+#define HDCR_SMS_512_DWORDS 0x60000000
+#define HDCR_SMS_1024_DWORDS 0x70000000
+#define HDCR_SH 0x80000000
+#define HDCR_COUNT_SHIFT 0
+
+/*
+ * The following defines are for the flags in the performance monitor control
+ * register.
+ */
+#define PFMC_C1SS_MASK 0x0000001F
+#define PFMC_C1EV 0x00000020
+#define PFMC_C1RS 0x00008000
+#define PFMC_C2SS_MASK 0x001F0000
+#define PFMC_C2EV 0x00200000
+#define PFMC_C2RS 0x80000000
+#define PFMC_C1SS_SHIFT 0
+#define PFMC_C2SS_SHIFT 16
+#define PFMC_BUS_GRANT 0
+#define PFMC_GRANT_AFTER_REQ 1
+#define PFMC_TRANSACTION 2
+#define PFMC_DWORD_TRANSFER 3
+#define PFMC_SLAVE_READ 4
+#define PFMC_SLAVE_WRITE 5
+#define PFMC_PREEMPTION 6
+#define PFMC_DISCONNECT_RETRY 7
+#define PFMC_INTERRUPT 8
+#define PFMC_BUS_OWNERSHIP 9
+#define PFMC_TRANSACTION_LAG 10
+#define PFMC_PCI_CLOCK 11
+#define PFMC_SERIAL_CLOCK 12
+#define PFMC_SP_CLOCK 13
+
+/*
+ * The following defines are for the flags in the performance counter value 1
+ * register.
+ */
+#define PFCV1_PC1V_MASK 0xFFFFFFFF
+#define PFCV1_PC1V_SHIFT 0
+
+/*
+ * The following defines are for the flags in the performance counter value 2
+ * register.
+ */
+#define PFCV2_PC2V_MASK 0xFFFFFFFF
+#define PFCV2_PC2V_SHIFT 0
+
+/*
+ * The following defines are for the flags in the clock control register 1.
+ */
+#define CLKCR1_OSCS 0x00000001
+#define CLKCR1_OSCP 0x00000002
+#define CLKCR1_PLLSS_MASK 0x0000000C
+#define CLKCR1_PLLSS_SERIAL 0x00000000
+#define CLKCR1_PLLSS_CRYSTAL 0x00000004
+#define CLKCR1_PLLSS_PCI 0x00000008
+#define CLKCR1_PLLSS_RESERVED 0x0000000C
+#define CLKCR1_PLLP 0x00000010
+#define CLKCR1_SWCE 0x00000020
+#define CLKCR1_PLLOS 0x00000040
+
+/*
+ * The following defines are for the flags in the clock control register 2.
+ */
+#define CLKCR2_PDIVS_MASK 0x0000000F
+#define CLKCR2_PDIVS_1 0x00000001
+#define CLKCR2_PDIVS_2 0x00000002
+#define CLKCR2_PDIVS_4 0x00000004
+#define CLKCR2_PDIVS_7 0x00000007
+#define CLKCR2_PDIVS_8 0x00000008
+#define CLKCR2_PDIVS_16 0x00000000
+
+/*
+ * The following defines are for the flags in the PLL multiplier register.
+ */
+#define PLLM_MASK 0x000000FF
+#define PLLM_SHIFT 0
+
+/*
+ * The following defines are for the flags in the PLL capacitor coefficient
+ * register.
+ */
+#define PLLCC_CDR_MASK 0x00000007
+#ifndef NO_CS4610
+#define PLLCC_CDR_240_350_MHZ 0x00000000
+#define PLLCC_CDR_184_265_MHZ 0x00000001
+#define PLLCC_CDR_144_205_MHZ 0x00000002
+#define PLLCC_CDR_111_160_MHZ 0x00000003
+#define PLLCC_CDR_87_123_MHZ 0x00000004
+#define PLLCC_CDR_67_96_MHZ 0x00000005
+#define PLLCC_CDR_52_74_MHZ 0x00000006
+#define PLLCC_CDR_45_58_MHZ 0x00000007
+#endif
+#ifndef NO_CS4612
+#define PLLCC_CDR_271_398_MHZ 0x00000000
+#define PLLCC_CDR_227_330_MHZ 0x00000001
+#define PLLCC_CDR_167_239_MHZ 0x00000002
+#define PLLCC_CDR_150_215_MHZ 0x00000003
+#define PLLCC_CDR_107_154_MHZ 0x00000004
+#define PLLCC_CDR_98_140_MHZ 0x00000005
+#define PLLCC_CDR_73_104_MHZ 0x00000006
+#define PLLCC_CDR_63_90_MHZ 0x00000007
+#endif
+#define PLLCC_LPF_MASK 0x000000F8
+#ifndef NO_CS4610
+#define PLLCC_LPF_23850_60000_KHZ 0x00000000
+#define PLLCC_LPF_7960_26290_KHZ 0x00000008
+#define PLLCC_LPF_4160_10980_KHZ 0x00000018
+#define PLLCC_LPF_1740_4580_KHZ 0x00000038
+#define PLLCC_LPF_724_1910_KHZ 0x00000078
+#define PLLCC_LPF_317_798_KHZ 0x000000F8
+#endif
+#ifndef NO_CS4612
+#define PLLCC_LPF_25580_64530_KHZ 0x00000000
+#define PLLCC_LPF_14360_37270_KHZ 0x00000008
+#define PLLCC_LPF_6100_16020_KHZ 0x00000018
+#define PLLCC_LPF_2540_6690_KHZ 0x00000038
+#define PLLCC_LPF_1050_2780_KHZ 0x00000078
+#define PLLCC_LPF_450_1160_KHZ 0x000000F8
+#endif
+
+/*
+ * The following defines are for the flags in the feature reporting register.
+ */
+#define FRR_FAB_MASK 0x00000003
+#define FRR_MASK_MASK 0x0000001C
+#ifdef NO_CS4612
+#define FRR_CFOP_MASK 0x000000E0
+#else
+#define FRR_CFOP_MASK 0x00000FE0
+#endif
+#define FRR_CFOP_NOT_DVD 0x00000020
+#define FRR_CFOP_A3D 0x00000040
+#define FRR_CFOP_128_PIN 0x00000080
+#ifndef NO_CS4612
+#define FRR_CFOP_CS4280 0x00000800
+#endif
+#define FRR_FAB_SHIFT 0
+#define FRR_MASK_SHIFT 2
+#define FRR_CFOP_SHIFT 5
+
+/*
+ * The following defines are for the flags in the configuration load 1
+ * register.
+ */
+#define CFL1_CLOCK_SOURCE_MASK 0x00000003
+#define CFL1_CLOCK_SOURCE_CS423X 0x00000000
+#define CFL1_CLOCK_SOURCE_AC97 0x00000001
+#define CFL1_CLOCK_SOURCE_CRYSTAL 0x00000002
+#define CFL1_CLOCK_SOURCE_DUAL_AC97 0x00000003
+#define CFL1_VALID_DATA_MASK 0x000000FF
+
+/*
+ * The following defines are for the flags in the configuration load 2
+ * register.
+ */
+#define CFL2_VALID_DATA_MASK 0x000000FF
+
+/*
+ * The following defines are for the flags in the serial port master control
+ * register 1.
+ */
+#define SERMC1_MSPE 0x00000001
+#define SERMC1_PTC_MASK 0x0000000E
+#define SERMC1_PTC_CS423X 0x00000000
+#define SERMC1_PTC_AC97 0x00000002
+#define SERMC1_PTC_DAC 0x00000004
+#define SERMC1_PLB 0x00000010
+#define SERMC1_XLB 0x00000020
+
+/*
+ * The following defines are for the flags in the serial port master control
+ * register 2.
+ */
+#define SERMC2_LROE 0x00000001
+#define SERMC2_MCOE 0x00000002
+#define SERMC2_MCDIV 0x00000004
+
+/*
+ * The following defines are for the flags in the serial port 1 configuration
+ * register.
+ */
+#define SERC1_SO1EN 0x00000001
+#define SERC1_SO1F_MASK 0x0000000E
+#define SERC1_SO1F_CS423X 0x00000000
+#define SERC1_SO1F_AC97 0x00000002
+#define SERC1_SO1F_DAC 0x00000004
+#define SERC1_SO1F_SPDIF 0x00000006
+
+/*
+ * The following defines are for the flags in the serial port 2 configuration
+ * register.
+ */
+#define SERC2_SI1EN 0x00000001
+#define SERC2_SI1F_MASK 0x0000000E
+#define SERC2_SI1F_CS423X 0x00000000
+#define SERC2_SI1F_AC97 0x00000002
+#define SERC2_SI1F_ADC 0x00000004
+#define SERC2_SI1F_SPDIF 0x00000006
+
+/*
+ * The following defines are for the flags in the serial port 3 configuration
+ * register.
+ */
+#define SERC3_SO2EN 0x00000001
+#define SERC3_SO2F_MASK 0x00000006
+#define SERC3_SO2F_DAC 0x00000000
+#define SERC3_SO2F_SPDIF 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port 4 configuration
+ * register.
+ */
+#define SERC4_SO3EN 0x00000001
+#define SERC4_SO3F_MASK 0x00000006
+#define SERC4_SO3F_DAC 0x00000000
+#define SERC4_SO3F_SPDIF 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port 5 configuration
+ * register.
+ */
+#define SERC5_SI2EN 0x00000001
+#define SERC5_SI2F_MASK 0x00000006
+#define SERC5_SI2F_ADC 0x00000000
+#define SERC5_SI2F_SPDIF 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port backdoor sample
+ * pointer register.
+ */
+#define SERBSP_FSP_MASK 0x0000000F
+#define SERBSP_FSP_SHIFT 0
+
+/*
+ * The following defines are for the flags in the serial port backdoor status
+ * register.
+ */
+#define SERBST_RRDY 0x00000001
+#define SERBST_WBSY 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port backdoor command
+ * register.
+ */
+#define SERBCM_RDC 0x00000001
+#define SERBCM_WRC 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port backdoor address
+ * register.
+ */
+#ifdef NO_CS4612
+#define SERBAD_FAD_MASK 0x000000FF
+#else
+#define SERBAD_FAD_MASK 0x000001FF
+#endif
+#define SERBAD_FAD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the serial port backdoor
+ * configuration register.
+ */
+#define SERBCF_HBP 0x00000001
+
+/*
+ * The following defines are for the flags in the serial port backdoor write
+ * port register.
+ */
+#define SERBWP_FWD_MASK 0x000FFFFF
+#define SERBWP_FWD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the serial port backdoor read
+ * port register.
+ */
+#define SERBRP_FRD_MASK 0x000FFFFF
+#define SERBRP_FRD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the async FIFO address register.
+ */
+#ifndef NO_CS4612
+#define ASER_FADDR_A1_MASK 0x000001FF
+#define ASER_FADDR_EN1 0x00008000
+#define ASER_FADDR_A2_MASK 0x01FF0000
+#define ASER_FADDR_EN2 0x80000000
+#define ASER_FADDR_A1_SHIFT 0
+#define ASER_FADDR_A2_SHIFT 16
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 control register.
+ */
+#define ACCTL_RSTN 0x00000001
+#define ACCTL_ESYN 0x00000002
+#define ACCTL_VFRM 0x00000004
+#define ACCTL_DCV 0x00000008
+#define ACCTL_CRW 0x00000010
+#define ACCTL_ASYN 0x00000020
+#ifndef NO_CS4612
+#define ACCTL_TC 0x00000040
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 status register.
+ */
+#define ACSTS_CRDY 0x00000001
+#define ACSTS_VSTS 0x00000002
+#ifndef NO_CS4612
+#define ACSTS_WKUP 0x00000004
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 output slot valid
+ * register.
+ */
+#define ACOSV_SLV3 0x00000001
+#define ACOSV_SLV4 0x00000002
+#define ACOSV_SLV5 0x00000004
+#define ACOSV_SLV6 0x00000008
+#define ACOSV_SLV7 0x00000010
+#define ACOSV_SLV8 0x00000020
+#define ACOSV_SLV9 0x00000040
+#define ACOSV_SLV10 0x00000080
+#define ACOSV_SLV11 0x00000100
+#define ACOSV_SLV12 0x00000200
+
+/*
+ * The following defines are for the flags in the AC97 command address
+ * register.
+ */
+#define ACCAD_CI_MASK 0x0000007F
+#define ACCAD_CI_SHIFT 0
+
+/*
+ * The following defines are for the flags in the AC97 command data register.
+ */
+#define ACCDA_CD_MASK 0x0000FFFF
+#define ACCDA_CD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the AC97 input slot valid
+ * register.
+ */
+#define ACISV_ISV3 0x00000001
+#define ACISV_ISV4 0x00000002
+#define ACISV_ISV5 0x00000004
+#define ACISV_ISV6 0x00000008
+#define ACISV_ISV7 0x00000010
+#define ACISV_ISV8 0x00000020
+#define ACISV_ISV9 0x00000040
+#define ACISV_ISV10 0x00000080
+#define ACISV_ISV11 0x00000100
+#define ACISV_ISV12 0x00000200
+
+/*
+ * The following defines are for the flags in the AC97 status address
+ * register.
+ */
+#define ACSAD_SI_MASK 0x0000007F
+#define ACSAD_SI_SHIFT 0
+
+/*
+ * The following defines are for the flags in the AC97 status data register.
+ */
+#define ACSDA_SD_MASK 0x0000FFFF
+#define ACSDA_SD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the joystick poll/trigger
+ * register.
+ */
+#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
+
+/*
+ * The following defines are for the flags in the joystick control register.
+ */
+#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
+
+/*
+ * The following defines are for the flags in the joystick coordinate pair 1
+ * readback register.
+ */
+#define JSC1_Y1V_MASK 0x0000FFFF
+#define JSC1_X1V_MASK 0xFFFF0000
+#define JSC1_Y1V_SHIFT 0
+#define JSC1_X1V_SHIFT 16
+
+/*
+ * The following defines are for the flags in the joystick coordinate pair 2
+ * readback register.
+ */
+#define JSC2_Y2V_MASK 0x0000FFFF
+#define JSC2_X2V_MASK 0xFFFF0000
+#define JSC2_Y2V_SHIFT 0
+#define JSC2_X2V_SHIFT 16
+
+/*
+ * The following defines are for the flags in the MIDI control register.
+ */
+#define MIDCR_TXE 0x00000001 /* Enable transmitting. */
+#define MIDCR_RXE 0x00000002 /* Enable receiving. */
+#define MIDCR_RIE 0x00000004 /* Interrupt upon tx ready. */
+#define MIDCR_TIE 0x00000008 /* Interrupt upon rx ready. */
+#define MIDCR_MLB 0x00000010 /* Enable midi loopback. */
+#define MIDCR_MRST 0x00000020 /* Reset interface. */
+
+/*
+ * The following defines are for the flags in the MIDI status register.
+ */
+#define MIDSR_TBF 0x00000001 /* Tx FIFO is full. */
+#define MIDSR_RBE 0x00000002 /* Rx FIFO is empty. */
+
+/*
+ * The following defines are for the flags in the MIDI write port register.
+ */
+#define MIDWP_MWD_MASK 0x000000FF
+#define MIDWP_MWD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the MIDI read port register.
+ */
+#define MIDRP_MRD_MASK 0x000000FF
+#define MIDRP_MRD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the joystick GPIO register.
+ */
+#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
+
+/*
+ * The following defines are for the flags in the master async/sync serial
+ * port enable register.
+ */
+#ifndef NO_CS4612
+#define ASER_MASTER_ME 0x00000001
+#endif
+
+/*
+ * The following defines are for the flags in the configuration interface
+ * register.
+ */
+#define CFGI_CLK 0x00000001
+#define CFGI_DOUT 0x00000002
+#define CFGI_DIN_EEN 0x00000004
+#define CFGI_EELD 0x00000008
+
+/*
+ * The following defines are for the flags in the subsystem ID and vendor ID
+ * register.
+ */
+#define SSVID_VID_MASK 0x0000FFFF
+#define SSVID_SID_MASK 0xFFFF0000
+#define SSVID_VID_SHIFT 0
+#define SSVID_SID_SHIFT 16
+
+/*
+ * The following defines are for the flags in the GPIO pin interface register.
+ */
+#define GPIOR_VOLDN 0x00000001
+#define GPIOR_VOLUP 0x00000002
+#define GPIOR_SI2D 0x00000004
+#define GPIOR_SI2OE 0x00000008
+
+/*
+ * The following defines are for the flags in the extended GPIO pin direction
+ * register.
+ */
+#ifndef NO_CS4612
+#define EGPIODR_GPOE0 0x00000001
+#define EGPIODR_GPOE1 0x00000002
+#define EGPIODR_GPOE2 0x00000004
+#define EGPIODR_GPOE3 0x00000008
+#define EGPIODR_GPOE4 0x00000010
+#define EGPIODR_GPOE5 0x00000020
+#define EGPIODR_GPOE6 0x00000040
+#define EGPIODR_GPOE7 0x00000080
+#define EGPIODR_GPOE8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the extended GPIO pin polarity/
+ * type register.
+ */
+#ifndef NO_CS4612
+#define EGPIOPTR_GPPT0 0x00000001
+#define EGPIOPTR_GPPT1 0x00000002
+#define EGPIOPTR_GPPT2 0x00000004
+#define EGPIOPTR_GPPT3 0x00000008
+#define EGPIOPTR_GPPT4 0x00000010
+#define EGPIOPTR_GPPT5 0x00000020
+#define EGPIOPTR_GPPT6 0x00000040
+#define EGPIOPTR_GPPT7 0x00000080
+#define EGPIOPTR_GPPT8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the extended GPIO pin sticky
+ * register.
+ */
+#ifndef NO_CS4612
+#define EGPIOTR_GPS0 0x00000001
+#define EGPIOTR_GPS1 0x00000002
+#define EGPIOTR_GPS2 0x00000004
+#define EGPIOTR_GPS3 0x00000008
+#define EGPIOTR_GPS4 0x00000010
+#define EGPIOTR_GPS5 0x00000020
+#define EGPIOTR_GPS6 0x00000040
+#define EGPIOTR_GPS7 0x00000080
+#define EGPIOTR_GPS8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the extended GPIO ping wakeup
+ * register.
+ */
+#ifndef NO_CS4612
+#define EGPIOWR_GPW0 0x00000001
+#define EGPIOWR_GPW1 0x00000002
+#define EGPIOWR_GPW2 0x00000004
+#define EGPIOWR_GPW3 0x00000008
+#define EGPIOWR_GPW4 0x00000010
+#define EGPIOWR_GPW5 0x00000020
+#define EGPIOWR_GPW6 0x00000040
+#define EGPIOWR_GPW7 0x00000080
+#define EGPIOWR_GPW8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the extended GPIO pin status
+ * register.
+ */
+#ifndef NO_CS4612
+#define EGPIOSR_GPS0 0x00000001
+#define EGPIOSR_GPS1 0x00000002
+#define EGPIOSR_GPS2 0x00000004
+#define EGPIOSR_GPS3 0x00000008
+#define EGPIOSR_GPS4 0x00000010
+#define EGPIOSR_GPS5 0x00000020
+#define EGPIOSR_GPS6 0x00000040
+#define EGPIOSR_GPS7 0x00000080
+#define EGPIOSR_GPS8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the serial port 6 configuration
+ * register.
+ */
+#ifndef NO_CS4612
+#define SERC6_ASDO2EN 0x00000001
+#endif
+
+/*
+ * The following defines are for the flags in the serial port 7 configuration
+ * register.
+ */
+#ifndef NO_CS4612
+#define SERC7_ASDI2EN 0x00000001
+#define SERC7_POSILB 0x00000002
+#define SERC7_SIPOLB 0x00000004
+#define SERC7_SOSILB 0x00000008
+#define SERC7_SISOLB 0x00000010
+#endif
+
+/*
+ * The following defines are for the flags in the serial port AC link
+ * configuration register.
+ */
+#ifndef NO_CS4612
+#define SERACC_CODEC_TYPE_MASK 0x00000001
+#define SERACC_CODEC_TYPE_1_03 0x00000000
+#define SERACC_CODEC_TYPE_2_0 0x00000001
+#define SERACC_TWO_CODECS 0x00000002
+#define SERACC_MDM 0x00000004
+#define SERACC_HSP 0x00000008
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 control register 2.
+ */
+#ifndef NO_CS4612
+#define ACCTL2_RSTN 0x00000001
+#define ACCTL2_ESYN 0x00000002
+#define ACCTL2_VFRM 0x00000004
+#define ACCTL2_DCV 0x00000008
+#define ACCTL2_CRW 0x00000010
+#define ACCTL2_ASYN 0x00000020
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 status register 2.
+ */
+#ifndef NO_CS4612
+#define ACSTS2_CRDY 0x00000001
+#define ACSTS2_VSTS 0x00000002
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 output slot valid
+ * register 2.
+ */
+#ifndef NO_CS4612
+#define ACOSV2_SLV3 0x00000001
+#define ACOSV2_SLV4 0x00000002
+#define ACOSV2_SLV5 0x00000004
+#define ACOSV2_SLV6 0x00000008
+#define ACOSV2_SLV7 0x00000010
+#define ACOSV2_SLV8 0x00000020
+#define ACOSV2_SLV9 0x00000040
+#define ACOSV2_SLV10 0x00000080
+#define ACOSV2_SLV11 0x00000100
+#define ACOSV2_SLV12 0x00000200
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 command address
+ * register 2.
+ */
+#ifndef NO_CS4612
+#define ACCAD2_CI_MASK 0x0000007F
+#define ACCAD2_CI_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 command data register
+ * 2.
+ */
+#ifndef NO_CS4612
+#define ACCDA2_CD_MASK 0x0000FFFF
+#define ACCDA2_CD_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 input slot valid
+ * register 2.
+ */
+#ifndef NO_CS4612
+#define ACISV2_ISV3 0x00000001
+#define ACISV2_ISV4 0x00000002
+#define ACISV2_ISV5 0x00000004
+#define ACISV2_ISV6 0x00000008
+#define ACISV2_ISV7 0x00000010
+#define ACISV2_ISV8 0x00000020
+#define ACISV2_ISV9 0x00000040
+#define ACISV2_ISV10 0x00000080
+#define ACISV2_ISV11 0x00000100
+#define ACISV2_ISV12 0x00000200
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 status address
+ * register 2.
+ */
+#ifndef NO_CS4612
+#define ACSAD2_SI_MASK 0x0000007F
+#define ACSAD2_SI_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 status data register 2.
+ */
+#ifndef NO_CS4612
+#define ACSDA2_SD_MASK 0x0000FFFF
+#define ACSDA2_SD_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap address and control
+ * registers (all 12).
+ */
+#ifndef NO_CS4612
+#define IOTAC_SA_MASK 0x0000FFFF
+#define IOTAC_MSK_MASK 0x000F0000
+#define IOTAC_IODC_MASK 0x06000000
+#define IOTAC_IODC_16_BIT 0x00000000
+#define IOTAC_IODC_10_BIT 0x02000000
+#define IOTAC_IODC_12_BIT 0x04000000
+#define IOTAC_WSPI 0x08000000
+#define IOTAC_RSPI 0x10000000
+#define IOTAC_WSE 0x20000000
+#define IOTAC_WE 0x40000000
+#define IOTAC_RE 0x80000000
+#define IOTAC_SA_SHIFT 0
+#define IOTAC_MSK_SHIFT 16
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap fast read registers
+ * (all 8).
+ */
+#ifndef NO_CS4612
+#define IOTFR_D_MASK 0x0000FFFF
+#define IOTFR_A_MASK 0x000F0000
+#define IOTFR_R_MASK 0x0F000000
+#define IOTFR_ALL 0x40000000
+#define IOTFR_VL 0x80000000
+#define IOTFR_D_SHIFT 0
+#define IOTFR_A_SHIFT 16
+#define IOTFR_R_SHIFT 24
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap FIFO register.
+ */
+#ifndef NO_CS4612
+#define IOTFIFO_BA_MASK 0x00003FFF
+#define IOTFIFO_S_MASK 0x00FF0000
+#define IOTFIFO_OF 0x40000000
+#define IOTFIFO_SPIOF 0x80000000
+#define IOTFIFO_BA_SHIFT 0
+#define IOTFIFO_S_SHIFT 16
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap retry read data
+ * register.
+ */
+#ifndef NO_CS4612
+#define IOTRRD_D_MASK 0x0000FFFF
+#define IOTRRD_RDV 0x80000000
+#define IOTRRD_D_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap FIFO pointer
+ * register.
+ */
+#ifndef NO_CS4612
+#define IOTFP_CA_MASK 0x00003FFF
+#define IOTFP_PA_MASK 0x3FFF0000
+#define IOTFP_CA_SHIFT 0
+#define IOTFP_PA_SHIFT 16
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap control register.
+ */
+#ifndef NO_CS4612
+#define IOTCR_ITD 0x00000001
+#define IOTCR_HRV 0x00000002
+#define IOTCR_SRV 0x00000004
+#define IOTCR_DTI 0x00000008
+#define IOTCR_DFI 0x00000010
+#define IOTCR_DDP 0x00000020
+#define IOTCR_JTE 0x00000040
+#define IOTCR_PPE 0x00000080
+#endif
+
+/*
+ * The following defines are for the flags in the direct PCI data register.
+ */
+#ifndef NO_CS4612
+#define DPCID_D_MASK 0xFFFFFFFF
+#define DPCID_D_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the direct PCI address register.
+ */
+#ifndef NO_CS4612
+#define DPCIA_A_MASK 0xFFFFFFFF
+#define DPCIA_A_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the direct PCI command register.
+ */
+#ifndef NO_CS4612
+#define DPCIC_C_MASK 0x0000000F
+#define DPCIC_C_IOREAD 0x00000002
+#define DPCIC_C_IOWRITE 0x00000003
+#define DPCIC_BE_MASK 0x000000F0
+#endif
+
+/*
+ * The following defines are for the flags in the PC/PCI request register.
+ */
+#ifndef NO_CS4612
+#define PCPCIR_RDC_MASK 0x00000007
+#define PCPCIR_C_MASK 0x00007000
+#define PCPCIR_REQ 0x00008000
+#define PCPCIR_RDC_SHIFT 0
+#define PCPCIR_C_SHIFT 12
+#endif
+
+/*
+ * The following defines are for the flags in the PC/PCI grant register.
+ */
+#ifndef NO_CS4612
+#define PCPCIG_GDC_MASK 0x00000007
+#define PCPCIG_VL 0x00008000
+#define PCPCIG_GDC_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the PC/PCI master enable
+ * register.
+ */
+#ifndef NO_CS4612
+#define PCPCIEN_EN 0x00000001
+#endif
+
+/*
+ * The following defines are for the flags in the extended PCI power
+ * management control register.
+ */
+#ifndef NO_CS4612
+#define EPCIPMC_GWU 0x00000001
+#define EPCIPMC_FSPC 0x00000002
+#endif
+
+/*
+ * The following defines are for the flags in the SP control register.
+ */
+#define SPCR_RUN 0x00000001
+#define SPCR_STPFR 0x00000002
+#define SPCR_RUNFR 0x00000004
+#define SPCR_TICK 0x00000008
+#define SPCR_DRQEN 0x00000020
+#define SPCR_RSTSP 0x00000040
+#define SPCR_OREN 0x00000080
+#ifndef NO_CS4612
+#define SPCR_PCIINT 0x00000100
+#define SPCR_OINTD 0x00000200
+#define SPCR_CRE 0x00008000
+#endif
+
+/*
+ * The following defines are for the flags in the debug index register.
+ */
+#define DREG_REGID_MASK 0x0000007F
+#define DREG_DEBUG 0x00000080
+#define DREG_RGBK_MASK 0x00000700
+#define DREG_TRAP 0x00000800
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_TRAPX 0x00001000
+#endif
+#endif
+#define DREG_REGID_SHIFT 0
+#define DREG_RGBK_SHIFT 8
+#define DREG_RGBK_REGID_MASK 0x0000077F
+#define DREG_REGID_R0 0x00000010
+#define DREG_REGID_R1 0x00000011
+#define DREG_REGID_R2 0x00000012
+#define DREG_REGID_R3 0x00000013
+#define DREG_REGID_R4 0x00000014
+#define DREG_REGID_R5 0x00000015
+#define DREG_REGID_R6 0x00000016
+#define DREG_REGID_R7 0x00000017
+#define DREG_REGID_R8 0x00000018
+#define DREG_REGID_R9 0x00000019
+#define DREG_REGID_RA 0x0000001A
+#define DREG_REGID_RB 0x0000001B
+#define DREG_REGID_RC 0x0000001C
+#define DREG_REGID_RD 0x0000001D
+#define DREG_REGID_RE 0x0000001E
+#define DREG_REGID_RF 0x0000001F
+#define DREG_REGID_RA_BUS_LOW 0x00000020
+#define DREG_REGID_RA_BUS_HIGH 0x00000038
+#define DREG_REGID_YBUS_LOW 0x00000050
+#define DREG_REGID_YBUS_HIGH 0x00000058
+#define DREG_REGID_TRAP_0 0x00000100
+#define DREG_REGID_TRAP_1 0x00000101
+#define DREG_REGID_TRAP_2 0x00000102
+#define DREG_REGID_TRAP_3 0x00000103
+#define DREG_REGID_TRAP_4 0x00000104
+#define DREG_REGID_TRAP_5 0x00000105
+#define DREG_REGID_TRAP_6 0x00000106
+#define DREG_REGID_TRAP_7 0x00000107
+#define DREG_REGID_INDIRECT_ADDRESS 0x0000010E
+#define DREG_REGID_TOP_OF_STACK 0x0000010F
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_8 0x00000110
+#define DREG_REGID_TRAP_9 0x00000111
+#define DREG_REGID_TRAP_10 0x00000112
+#define DREG_REGID_TRAP_11 0x00000113
+#define DREG_REGID_TRAP_12 0x00000114
+#define DREG_REGID_TRAP_13 0x00000115
+#define DREG_REGID_TRAP_14 0x00000116
+#define DREG_REGID_TRAP_15 0x00000117
+#define DREG_REGID_TRAP_16 0x00000118
+#define DREG_REGID_TRAP_17 0x00000119
+#define DREG_REGID_TRAP_18 0x0000011A
+#define DREG_REGID_TRAP_19 0x0000011B
+#define DREG_REGID_TRAP_20 0x0000011C
+#define DREG_REGID_TRAP_21 0x0000011D
+#define DREG_REGID_TRAP_22 0x0000011E
+#define DREG_REGID_TRAP_23 0x0000011F
+#endif
+#endif
+#define DREG_REGID_RSA0_LOW 0x00000200
+#define DREG_REGID_RSA0_HIGH 0x00000201
+#define DREG_REGID_RSA1_LOW 0x00000202
+#define DREG_REGID_RSA1_HIGH 0x00000203
+#define DREG_REGID_RSA2 0x00000204
+#define DREG_REGID_RSA3 0x00000205
+#define DREG_REGID_RSI0_LOW 0x00000206
+#define DREG_REGID_RSI0_HIGH 0x00000207
+#define DREG_REGID_RSI1 0x00000208
+#define DREG_REGID_RSI2 0x00000209
+#define DREG_REGID_SAGUSTATUS 0x0000020A
+#define DREG_REGID_RSCONFIG01_LOW 0x0000020B
+#define DREG_REGID_RSCONFIG01_HIGH 0x0000020C
+#define DREG_REGID_RSCONFIG23_LOW 0x0000020D
+#define DREG_REGID_RSCONFIG23_HIGH 0x0000020E
+#define DREG_REGID_RSDMA01E 0x0000020F
+#define DREG_REGID_RSDMA23E 0x00000210
+#define DREG_REGID_RSD0_LOW 0x00000211
+#define DREG_REGID_RSD0_HIGH 0x00000212
+#define DREG_REGID_RSD1_LOW 0x00000213
+#define DREG_REGID_RSD1_HIGH 0x00000214
+#define DREG_REGID_RSD2_LOW 0x00000215
+#define DREG_REGID_RSD2_HIGH 0x00000216
+#define DREG_REGID_RSD3_LOW 0x00000217
+#define DREG_REGID_RSD3_HIGH 0x00000218
+#define DREG_REGID_SRAR_HIGH 0x0000021A
+#define DREG_REGID_SRAR_LOW 0x0000021B
+#define DREG_REGID_DMA_STATE 0x0000021C
+#define DREG_REGID_CURRENT_DMA_STREAM 0x0000021D
+#define DREG_REGID_NEXT_DMA_STREAM 0x0000021E
+#define DREG_REGID_CPU_STATUS 0x00000300
+#define DREG_REGID_MAC_MODE 0x00000301
+#define DREG_REGID_STACK_AND_REPEAT 0x00000302
+#define DREG_REGID_INDEX0 0x00000304
+#define DREG_REGID_INDEX1 0x00000305
+#define DREG_REGID_DMA_STATE_0_3 0x00000400
+#define DREG_REGID_DMA_STATE_4_7 0x00000404
+#define DREG_REGID_DMA_STATE_8_11 0x00000408
+#define DREG_REGID_DMA_STATE_12_15 0x0000040C
+#define DREG_REGID_DMA_STATE_16_19 0x00000410
+#define DREG_REGID_DMA_STATE_20_23 0x00000414
+#define DREG_REGID_DMA_STATE_24_27 0x00000418
+#define DREG_REGID_DMA_STATE_28_31 0x0000041C
+#define DREG_REGID_DMA_STATE_32_35 0x00000420
+#define DREG_REGID_DMA_STATE_36_39 0x00000424
+#define DREG_REGID_DMA_STATE_40_43 0x00000428
+#define DREG_REGID_DMA_STATE_44_47 0x0000042C
+#define DREG_REGID_DMA_STATE_48_51 0x00000430
+#define DREG_REGID_DMA_STATE_52_55 0x00000434
+#define DREG_REGID_DMA_STATE_56_59 0x00000438
+#define DREG_REGID_DMA_STATE_60_63 0x0000043C
+#define DREG_REGID_DMA_STATE_64_67 0x00000440
+#define DREG_REGID_DMA_STATE_68_71 0x00000444
+#define DREG_REGID_DMA_STATE_72_75 0x00000448
+#define DREG_REGID_DMA_STATE_76_79 0x0000044C
+#define DREG_REGID_DMA_STATE_80_83 0x00000450
+#define DREG_REGID_DMA_STATE_84_87 0x00000454
+#define DREG_REGID_DMA_STATE_88_91 0x00000458
+#define DREG_REGID_DMA_STATE_92_95 0x0000045C
+#define DREG_REGID_TRAP_SELECT 0x00000500
+#define DREG_REGID_TRAP_WRITE_0 0x00000500
+#define DREG_REGID_TRAP_WRITE_1 0x00000501
+#define DREG_REGID_TRAP_WRITE_2 0x00000502
+#define DREG_REGID_TRAP_WRITE_3 0x00000503
+#define DREG_REGID_TRAP_WRITE_4 0x00000504
+#define DREG_REGID_TRAP_WRITE_5 0x00000505
+#define DREG_REGID_TRAP_WRITE_6 0x00000506
+#define DREG_REGID_TRAP_WRITE_7 0x00000507
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_WRITE_8 0x00000510
+#define DREG_REGID_TRAP_WRITE_9 0x00000511
+#define DREG_REGID_TRAP_WRITE_10 0x00000512
+#define DREG_REGID_TRAP_WRITE_11 0x00000513
+#define DREG_REGID_TRAP_WRITE_12 0x00000514
+#define DREG_REGID_TRAP_WRITE_13 0x00000515
+#define DREG_REGID_TRAP_WRITE_14 0x00000516
+#define DREG_REGID_TRAP_WRITE_15 0x00000517
+#define DREG_REGID_TRAP_WRITE_16 0x00000518
+#define DREG_REGID_TRAP_WRITE_17 0x00000519
+#define DREG_REGID_TRAP_WRITE_18 0x0000051A
+#define DREG_REGID_TRAP_WRITE_19 0x0000051B
+#define DREG_REGID_TRAP_WRITE_20 0x0000051C
+#define DREG_REGID_TRAP_WRITE_21 0x0000051D
+#define DREG_REGID_TRAP_WRITE_22 0x0000051E
+#define DREG_REGID_TRAP_WRITE_23 0x0000051F
+#endif
+#endif
+#define DREG_REGID_MAC0_ACC0_LOW 0x00000600
+#define DREG_REGID_MAC0_ACC1_LOW 0x00000601
+#define DREG_REGID_MAC0_ACC2_LOW 0x00000602
+#define DREG_REGID_MAC0_ACC3_LOW 0x00000603
+#define DREG_REGID_MAC1_ACC0_LOW 0x00000604
+#define DREG_REGID_MAC1_ACC1_LOW 0x00000605
+#define DREG_REGID_MAC1_ACC2_LOW 0x00000606
+#define DREG_REGID_MAC1_ACC3_LOW 0x00000607
+#define DREG_REGID_MAC0_ACC0_MID 0x00000608
+#define DREG_REGID_MAC0_ACC1_MID 0x00000609
+#define DREG_REGID_MAC0_ACC2_MID 0x0000060A
+#define DREG_REGID_MAC0_ACC3_MID 0x0000060B
+#define DREG_REGID_MAC1_ACC0_MID 0x0000060C
+#define DREG_REGID_MAC1_ACC1_MID 0x0000060D
+#define DREG_REGID_MAC1_ACC2_MID 0x0000060E
+#define DREG_REGID_MAC1_ACC3_MID 0x0000060F
+#define DREG_REGID_MAC0_ACC0_HIGH 0x00000610
+#define DREG_REGID_MAC0_ACC1_HIGH 0x00000611
+#define DREG_REGID_MAC0_ACC2_HIGH 0x00000612
+#define DREG_REGID_MAC0_ACC3_HIGH 0x00000613
+#define DREG_REGID_MAC1_ACC0_HIGH 0x00000614
+#define DREG_REGID_MAC1_ACC1_HIGH 0x00000615
+#define DREG_REGID_MAC1_ACC2_HIGH 0x00000616
+#define DREG_REGID_MAC1_ACC3_HIGH 0x00000617
+#define DREG_REGID_RSHOUT_LOW 0x00000620
+#define DREG_REGID_RSHOUT_MID 0x00000628
+#define DREG_REGID_RSHOUT_HIGH 0x00000630
+
+/*
+ * The following defines are for the flags in the DMA stream requestor write
+ */
+#define DSRWP_DSR_MASK 0x0000000F
+#define DSRWP_DSR_BG_RQ 0x00000001
+#define DSRWP_DSR_PRIORITY_MASK 0x00000006
+#define DSRWP_DSR_PRIORITY_0 0x00000000
+#define DSRWP_DSR_PRIORITY_1 0x00000002
+#define DSRWP_DSR_PRIORITY_2 0x00000004
+#define DSRWP_DSR_PRIORITY_3 0x00000006
+#define DSRWP_DSR_RQ_PENDING 0x00000008
+
+/*
+ * The following defines are for the flags in the trap write port register.
+ */
+#define TWPR_TW_MASK 0x0000FFFF
+#define TWPR_TW_SHIFT 0
+
+/*
+ * The following defines are for the flags in the stack pointer write
+ * register.
+ */
+#define SPWR_STKP_MASK 0x0000000F
+#define SPWR_STKP_SHIFT 0
+
+/*
+ * The following defines are for the flags in the SP interrupt register.
+ */
+#define SPIR_FRI 0x00000001
+#define SPIR_DOI 0x00000002
+#define SPIR_GPI2 0x00000004
+#define SPIR_GPI3 0x00000008
+#define SPIR_IP0 0x00000010
+#define SPIR_IP1 0x00000020
+#define SPIR_IP2 0x00000040
+#define SPIR_IP3 0x00000080
+
+/*
+ * The following defines are for the flags in the functional group 1 register.
+ */
+#define FGR1_F1S_MASK 0x0000FFFF
+#define FGR1_F1S_SHIFT 0
+
+/*
+ * The following defines are for the flags in the SP clock status register.
+ */
+#define SPCS_FRI 0x00000001
+#define SPCS_DOI 0x00000002
+#define SPCS_GPI2 0x00000004
+#define SPCS_GPI3 0x00000008
+#define SPCS_IP0 0x00000010
+#define SPCS_IP1 0x00000020
+#define SPCS_IP2 0x00000040
+#define SPCS_IP3 0x00000080
+#define SPCS_SPRUN 0x00000100
+#define SPCS_SLEEP 0x00000200
+#define SPCS_FG 0x00000400
+#define SPCS_ORUN 0x00000800
+#define SPCS_IRQ 0x00001000
+#define SPCS_FGN_MASK 0x0000E000
+#define SPCS_FGN_SHIFT 13
+
+/*
+ * The following defines are for the flags in the SP DMA requestor status
+ * register.
+ */
+#define SDSR_DCS_MASK 0x000000FF
+#define SDSR_DCS_SHIFT 0
+#define SDSR_DCS_NONE 0x00000007
+
+/*
+ * The following defines are for the flags in the frame timer register.
+ */
+#define FRMT_FTV_MASK 0x0000FFFF
+#define FRMT_FTV_SHIFT 0
+
+/*
+ * The following defines are for the flags in the frame timer current count
+ * register.
+ */
+#define FRCC_FCC_MASK 0x0000FFFF
+#define FRCC_FCC_SHIFT 0
+
+/*
+ * The following defines are for the flags in the frame timer save count
+ * register.
+ */
+#define FRSC_FCS_MASK 0x0000FFFF
+#define FRSC_FCS_SHIFT 0
+
+/*
+ * The following define the various flags stored in the scatter/gather
+ * descriptors.
+ */
+#define DMA_SG_NEXT_ENTRY_MASK 0x00000FF8
+#define DMA_SG_SAMPLE_END_MASK 0x0FFF0000
+#define DMA_SG_SAMPLE_END_FLAG 0x10000000
+#define DMA_SG_LOOP_END_FLAG 0x20000000
+#define DMA_SG_SIGNAL_END_FLAG 0x40000000
+#define DMA_SG_SIGNAL_PAGE_FLAG 0x80000000
+#define DMA_SG_NEXT_ENTRY_SHIFT 3
+#define DMA_SG_SAMPLE_END_SHIFT 16
+
+/*
+ * The following define the offsets of the fields within the on-chip generic
+ * DMA requestor.
+ */
+#define DMA_RQ_CONTROL1 0x00000000
+#define DMA_RQ_CONTROL2 0x00000004
+#define DMA_RQ_SOURCE_ADDR 0x00000008
+#define DMA_RQ_DESTINATION_ADDR 0x0000000C
+#define DMA_RQ_NEXT_PAGE_ADDR 0x00000010
+#define DMA_RQ_NEXT_PAGE_SGDESC 0x00000014
+#define DMA_RQ_LOOP_START_ADDR 0x00000018
+#define DMA_RQ_POST_LOOP_ADDR 0x0000001C
+#define DMA_RQ_PAGE_MAP_ADDR 0x00000020
+
+/*
+ * The following defines are for the flags in the first control word of the
+ * on-chip generic DMA requestor.
+ */
+#define DMA_RQ_C1_COUNT_MASK 0x000003FF
+#define DMA_RQ_C1_DESTINATION_SCATTER 0x00001000
+#define DMA_RQ_C1_SOURCE_GATHER 0x00002000
+#define DMA_RQ_C1_DONE_FLAG 0x00004000
+#define DMA_RQ_C1_OPTIMIZE_STATE 0x00008000
+#define DMA_RQ_C1_SAMPLE_END_STATE_MASK 0x00030000
+#define DMA_RQ_C1_FULL_PAGE 0x00000000
+#define DMA_RQ_C1_BEFORE_SAMPLE_END 0x00010000
+#define DMA_RQ_C1_PAGE_MAP_ERROR 0x00020000
+#define DMA_RQ_C1_AT_SAMPLE_END 0x00030000
+#define DMA_RQ_C1_LOOP_END_STATE_MASK 0x000C0000
+#define DMA_RQ_C1_NOT_LOOP_END 0x00000000
+#define DMA_RQ_C1_BEFORE_LOOP_END 0x00040000
+#define DMA_RQ_C1_2PAGE_LOOP_BEGIN 0x00080000
+#define DMA_RQ_C1_LOOP_BEGIN 0x000C0000
+#define DMA_RQ_C1_PAGE_MAP_MASK 0x00300000
+#define DMA_RQ_C1_PM_NONE_PENDING 0x00000000
+#define DMA_RQ_C1_PM_NEXT_PENDING 0x00100000
+#define DMA_RQ_C1_PM_RESERVED 0x00200000
+#define DMA_RQ_C1_PM_LOOP_NEXT_PENDING 0x00300000
+#define DMA_RQ_C1_WRITEBACK_DEST_FLAG 0x00400000
+#define DMA_RQ_C1_WRITEBACK_SRC_FLAG 0x00800000
+#define DMA_RQ_C1_DEST_SIZE_MASK 0x07000000
+#define DMA_RQ_C1_DEST_LINEAR 0x00000000
+#define DMA_RQ_C1_DEST_MOD16 0x01000000
+#define DMA_RQ_C1_DEST_MOD32 0x02000000
+#define DMA_RQ_C1_DEST_MOD64 0x03000000
+#define DMA_RQ_C1_DEST_MOD128 0x04000000
+#define DMA_RQ_C1_DEST_MOD256 0x05000000
+#define DMA_RQ_C1_DEST_MOD512 0x06000000
+#define DMA_RQ_C1_DEST_MOD1024 0x07000000
+#define DMA_RQ_C1_DEST_ON_HOST 0x08000000
+#define DMA_RQ_C1_SOURCE_SIZE_MASK 0x70000000
+#define DMA_RQ_C1_SOURCE_LINEAR 0x00000000
+#define DMA_RQ_C1_SOURCE_MOD16 0x10000000
+#define DMA_RQ_C1_SOURCE_MOD32 0x20000000
+#define DMA_RQ_C1_SOURCE_MOD64 0x30000000
+#define DMA_RQ_C1_SOURCE_MOD128 0x40000000
+#define DMA_RQ_C1_SOURCE_MOD256 0x50000000
+#define DMA_RQ_C1_SOURCE_MOD512 0x60000000
+#define DMA_RQ_C1_SOURCE_MOD1024 0x70000000
+#define DMA_RQ_C1_SOURCE_ON_HOST 0x80000000
+#define DMA_RQ_C1_COUNT_SHIFT 0
+
+/*
+ * The following defines are for the flags in the second control word of the
+ * on-chip generic DMA requestor.
+ */
+#define DMA_RQ_C2_VIRTUAL_CHANNEL_MASK 0x0000003F
+#define DMA_RQ_C2_VIRTUAL_SIGNAL_MASK 0x00000300
+#define DMA_RQ_C2_NO_VIRTUAL_SIGNAL 0x00000000
+#define DMA_RQ_C2_SIGNAL_EVERY_DMA 0x00000100
+#define DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG 0x00000200
+#define DMA_RQ_C2_SIGNAL_DEST_PINGPONG 0x00000300
+#define DMA_RQ_C2_AUDIO_CONVERT_MASK 0x0000F000
+#define DMA_RQ_C2_AC_NONE 0x00000000
+#define DMA_RQ_C2_AC_8_TO_16_BIT 0x00001000
+#define DMA_RQ_C2_AC_MONO_TO_STEREO 0x00002000
+#define DMA_RQ_C2_AC_ENDIAN_CONVERT 0x00004000
+#define DMA_RQ_C2_AC_SIGNED_CONVERT 0x00008000
+#define DMA_RQ_C2_LOOP_END_MASK 0x0FFF0000
+#define DMA_RQ_C2_LOOP_MASK 0x30000000
+#define DMA_RQ_C2_NO_LOOP 0x00000000
+#define DMA_RQ_C2_ONE_PAGE_LOOP 0x10000000
+#define DMA_RQ_C2_TWO_PAGE_LOOP 0x20000000
+#define DMA_RQ_C2_MULTI_PAGE_LOOP 0x30000000
+#define DMA_RQ_C2_SIGNAL_LOOP_BACK 0x40000000
+#define DMA_RQ_C2_SIGNAL_POST_BEGIN_PAGE 0x80000000
+#define DMA_RQ_C2_VIRTUAL_CHANNEL_SHIFT 0
+#define DMA_RQ_C2_LOOP_END_SHIFT 16
+
+/*
+ * The following defines are for the flags in the source and destination words
+ * of the on-chip generic DMA requestor.
+ */
+#define DMA_RQ_SD_ADDRESS_MASK 0x0000FFFF
+#define DMA_RQ_SD_MEMORY_ID_MASK 0x000F0000
+#define DMA_RQ_SD_SP_PARAM_ADDR 0x00000000
+#define DMA_RQ_SD_SP_SAMPLE_ADDR 0x00010000
+#define DMA_RQ_SD_SP_PROGRAM_ADDR 0x00020000
+#define DMA_RQ_SD_SP_DEBUG_ADDR 0x00030000
+#define DMA_RQ_SD_OMNIMEM_ADDR 0x000E0000
+#define DMA_RQ_SD_END_FLAG 0x40000000
+#define DMA_RQ_SD_ERROR_FLAG 0x80000000
+#define DMA_RQ_SD_ADDRESS_SHIFT 0
+
+/*
+ * The following defines are for the flags in the page map address word of the
+ * on-chip generic DMA requestor.
+ */
+#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_MASK 0x00000FF8
+#define DMA_RQ_PMA_PAGE_TABLE_MASK 0xFFFFF000
+#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_SHIFT 3
+#define DMA_RQ_PMA_PAGE_TABLE_SHIFT 12
+
+#define BA1_VARIDEC_BUF_1 0x000
+
+#define BA1_PDTC 0x0c0 /* BA1_PLAY_DMA_TRANSACTION_COUNT_REG */
+#define BA1_PFIE 0x0c4 /* BA1_PLAY_FORMAT_&_INTERRUPT_ENABLE_REG */
+#define BA1_PBA 0x0c8 /* BA1_PLAY_BUFFER_ADDRESS */
+#define BA1_PVOL 0x0f8 /* BA1_PLAY_VOLUME_REG */
+#define BA1_PSRC 0x288 /* BA1_PLAY_SAMPLE_RATE_CORRECTION_REG */
+#define BA1_PCTL 0x2a4 /* BA1_PLAY_CONTROL_REG */
+#define BA1_PPI 0x2b4 /* BA1_PLAY_PHASE_INCREMENT_REG */
+
+#define BA1_CCTL 0x064 /* BA1_CAPTURE_CONTROL_REG */
+#define BA1_CIE 0x104 /* BA1_CAPTURE_INTERRUPT_ENABLE_REG */
+#define BA1_CBA 0x10c /* BA1_CAPTURE_BUFFER_ADDRESS */
+#define BA1_CSRC 0x2c8 /* BA1_CAPTURE_SAMPLE_RATE_CORRECTION_REG */
+#define BA1_CCI 0x2d8 /* BA1_CAPTURE_COEFFICIENT_INCREMENT_REG */
+#define BA1_CD 0x2e0 /* BA1_CAPTURE_DELAY_REG */
+#define BA1_CPI 0x2f4 /* BA1_CAPTURE_PHASE_INCREMENT_REG */
+#define BA1_CVOL 0x2f8 /* BA1_CAPTURE_VOLUME_REG */
+
+#define BA1_CFG1 0x134 /* BA1_CAPTURE_FRAME_GROUP_1_REG */
+#define BA1_CFG2 0x138 /* BA1_CAPTURE_FRAME_GROUP_2_REG */
+#define BA1_CCST 0x13c /* BA1_CAPTURE_CONSTANT_REG */
+#define BA1_CSPB 0x340 /* BA1_CAPTURE_SPB_ADDRESS */
+
+/*
+ *
+ */
+
+#define CS461X_MODE_OUTPUT (1<<0) /* MIDI UART - output */
+#define CS461X_MODE_INPUT (1<<1) /* MIDI UART - input */
+
+/****************************************************************************
+ *
+ * The following define the offsets of the AC97 shadow registers, which appear
+ * as a virtual extension to the base address register zero memory range.
+ *
+ ****************************************************************************/
+#define AC97_REG_OFFSET_MASK 0x0000007EL
+#define AC97_CODEC_NUMBER_MASK 0x00003000L
+
+#define BA0_AC97_RESET 0x00001000L
+#define BA0_AC97_MASTER_VOLUME 0x00001002L
+#define BA0_AC97_HEADPHONE_VOLUME 0x00001004L
+#define BA0_AC97_MASTER_VOLUME_MONO 0x00001006L
+#define BA0_AC97_MASTER_TONE 0x00001008L
+#define BA0_AC97_PC_BEEP_VOLUME 0x0000100AL
+#define BA0_AC97_PHONE_VOLUME 0x0000100CL
+#define BA0_AC97_MIC_VOLUME 0x0000100EL
+#define BA0_AC97_LINE_IN_VOLUME 0x00001010L
+#define BA0_AC97_CD_VOLUME 0x00001012L
+#define BA0_AC97_VIDEO_VOLUME 0x00001014L
+#define BA0_AC97_AUX_VOLUME 0x00001016L
+#define BA0_AC97_PCM_OUT_VOLUME 0x00001018L
+#define BA0_AC97_RECORD_SELECT 0x0000101AL
+#define BA0_AC97_RECORD_GAIN 0x0000101CL
+#define BA0_AC97_RECORD_GAIN_MIC 0x0000101EL
+#define BA0_AC97_GENERAL_PURPOSE 0x00001020L
+#define BA0_AC97_3D_CONTROL 0x00001022L
+#define BA0_AC97_MODEM_RATE 0x00001024L
+#define BA0_AC97_POWERDOWN 0x00001026L
+#define BA0_AC97_EXT_AUDIO_ID 0x00001028L
+#define BA0_AC97_EXT_AUDIO_POWER 0x0000102AL
+#define BA0_AC97_PCM_FRONT_DAC_RATE 0x0000102CL
+#define BA0_AC97_PCM_SURR_DAC_RATE 0x0000102EL
+#define BA0_AC97_PCM_LFE_DAC_RATE 0x00001030L
+#define BA0_AC97_PCM_LR_ADC_RATE 0x00001032L
+#define BA0_AC97_MIC_ADC_RATE 0x00001034L
+#define BA0_AC97_6CH_VOL_C_LFE 0x00001036L
+#define BA0_AC97_6CH_VOL_SURROUND 0x00001038L
+#define BA0_AC97_RESERVED_3A 0x0000103AL
+#define BA0_AC97_EXT_MODEM_ID 0x0000103CL
+#define BA0_AC97_EXT_MODEM_POWER 0x0000103EL
+#define BA0_AC97_LINE1_CODEC_RATE 0x00001040L
+#define BA0_AC97_LINE2_CODEC_RATE 0x00001042L
+#define BA0_AC97_HANDSET_CODEC_RATE 0x00001044L
+#define BA0_AC97_LINE1_CODEC_LEVEL 0x00001046L
+#define BA0_AC97_LINE2_CODEC_LEVEL 0x00001048L
+#define BA0_AC97_HANDSET_CODEC_LEVEL 0x0000104AL
+#define BA0_AC97_GPIO_PIN_CONFIG 0x0000104CL
+#define BA0_AC97_GPIO_PIN_TYPE 0x0000104EL
+#define BA0_AC97_GPIO_PIN_STICKY 0x00001050L
+#define BA0_AC97_GPIO_PIN_WAKEUP 0x00001052L
+#define BA0_AC97_GPIO_PIN_STATUS 0x00001054L
+#define BA0_AC97_MISC_MODEM_AFE_STAT 0x00001056L
+#define BA0_AC97_RESERVED_58 0x00001058L
+#define BA0_AC97_CRYSTAL_REV_N_FAB_ID 0x0000105AL
+#define BA0_AC97_TEST_AND_MISC_CTRL 0x0000105CL
+#define BA0_AC97_AC_MODE 0x0000105EL
+#define BA0_AC97_MISC_CRYSTAL_CONTROL 0x00001060L
+#define BA0_AC97_LINE1_HYPRID_CTRL 0x00001062L
+#define BA0_AC97_VENDOR_RESERVED_64 0x00001064L
+#define BA0_AC97_VENDOR_RESERVED_66 0x00001066L
+#define BA0_AC97_SPDIF_CONTROL 0x00001068L
+#define BA0_AC97_VENDOR_RESERVED_6A 0x0000106AL
+#define BA0_AC97_VENDOR_RESERVED_6C 0x0000106CL
+#define BA0_AC97_VENDOR_RESERVED_6E 0x0000106EL
+#define BA0_AC97_VENDOR_RESERVED_70 0x00001070L
+#define BA0_AC97_VENDOR_RESERVED_72 0x00001072L
+#define BA0_AC97_VENDOR_RESERVED_74 0x00001074L
+#define BA0_AC97_CAL_ADDRESS 0x00001076L
+#define BA0_AC97_CAL_DATA 0x00001078L
+#define BA0_AC97_VENDOR_RESERVED_7A 0x0000107AL
+#define BA0_AC97_VENDOR_ID1 0x0000107CL
+#define BA0_AC97_VENDOR_ID2 0x0000107EL
diff --git a/kernel/drv/oss_cs461x/cs461x_dsp.h b/kernel/drv/oss_cs461x/cs461x_dsp.h
new file mode 100644
index 0000000..44c6da6
--- /dev/null
+++ b/kernel/drv/oss_cs461x/cs461x_dsp.h
@@ -0,0 +1,3474 @@
+/*
+ * Purpose: Firmware for cs461x/cs461x cards.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+struct cs461x_firmware_struct cs461x_firmware = {
+ {{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,
+ 0x066a0130, 0x06350070, 0x0000929d, 0x929d929d,
+ 0x00000000, 0x0000735a, 0x00000600, 0x00000000,
+ 0x929d735a, 0x00000000, 0x00010000, 0x735a735a,
+ 0xa431ac75, 0xa431ac75, 0xa431ac75, 0xa431ac75,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x000000f0, 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, 0x07c00000, 0x00900000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000018e, 0x000000c2,
+ 0x07c00000, 0x00000000, 0x80008000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00e00100, 0x00000173, 0x00000000,
+ 0x00000000, 0x00400010, 0x00800000, 0x00e00000,
+ 0x00000000, 0x00000000, 0x08400000, 0x00900000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x01100000, 0x0000018e, 0x000000c2,
+ 0x08400000, 0x00000000, 0x80008000, 0xffffffff,
+ 0x007fff80, 0x00280058, 0x01300000, 0x00000000,
+ 0x00000000, 0x2aab0000, 0x00000000, 0x00000000,
+ 0x00000000, 0x01200000, 0x0000026c, 0x000000c2,
+ 0x08c00000, 0x18000000, 0x80008000, 0x80008000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0000805e, 0x000000c1,
+ 0x00000000, 0x01000000, 0x80008000, 0x80008000,
+ 0x00000000, 0x00000110, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000082, 0x09000000, 0x00000000,
+ 0x00000000, 0x00000600, 0x013d0233, 0x20ff0040,
+ 0x00000000, 0x0000804c, 0x000101d8, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 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,
+ 0x0007bfb0, 0x000bc240, 0x00000c2e, 0x000c6084,
+ 0x000e8630, 0x0000100c, 0x00006408, 0x000efb84,
+ 0x00016008, 0x00000000, 0x0001c088, 0x000c0000,
+ 0x000fc908, 0x000e3392, 0x0005f488, 0x000efb84,
+ 0x0001d402, 0x000b2e00, 0x0003d418, 0x00001000,
+ 0x0008d574, 0x000c4293, 0x00065625, 0x000ea30e,
+ 0x00096c01, 0x000c6f92, 0x0001a58a, 0x000c6085,
+ 0x00002f43, 0x00000000, 0x000103a0, 0x0000100d,
+ 0x0005e608, 0x000c0000, 0x00000000, 0x00000000,
+ 0x000ca108, 0x000dcca1, 0x00003bac, 0x000c3205,
+ 0x00073843, 0x00000000, 0x00040730, 0x0000100d,
+ 0x0001600a, 0x000c0000, 0x00057488, 0x00000000,
+ 0x00000000, 0x000e5084, 0x00000000, 0x000eba44,
+ 0x00087401, 0x000e4782, 0x00000734, 0x00001000,
+ 0x00010705, 0x000a6880, 0x00006a88, 0x000c75c4,
+ 0x0006a108, 0x000cf2c4, 0x0004f4c0, 0x00000000,
+ 0x000fa418, 0x0000101f, 0x0005d402, 0x0001c500,
+ 0x000e8630, 0x0000100d, 0x00004418, 0x00001380,
+ 0x000e243d, 0x000d394a, 0x00049705, 0x00000000,
+ 0x0007d530, 0x000b4240, 0x000d80f2, 0x0000100d,
+ 0x00009134, 0x000ca20a, 0x00004c90, 0x00001000,
+ 0x0005d705, 0x00000000, 0x00004f25, 0x00098240,
+ 0x00004725, 0x00000000, 0x0000e48a, 0x00000000,
+ 0x00027295, 0x0009c2c0, 0x0003df25, 0x00000000,
+ 0x000e0030, 0x0000100e, 0x0005f718, 0x000ac600,
+ 0x0007cf30, 0x000c2a01, 0x0007a630, 0x0000100e,
+ 0x000484a0, 0x0000100e, 0x00029314, 0x000bcb80,
+ 0x0003cf25, 0x000b0e00, 0x0004f5c0, 0x00000000,
+ 0x00049118, 0x000d888a, 0x0007dd02, 0x000c6efa,
+ 0x00000000, 0x00000000, 0x0004f5c0, 0x00069c80,
+ 0x0000d402, 0x00000000, 0x000e0630, 0x0000100e,
+ 0x00079130, 0x00000000, 0x00049118, 0x00090e00,
+ 0x0006c10a, 0x00000000, 0x00000000, 0x000c0000,
+ 0x0007cf30, 0x00030580, 0x00005725, 0x00000000,
+ 0x000d04a0, 0x0000100e, 0x00029314, 0x000b4780,
+ 0x0003cf25, 0x000b8600, 0x00000000, 0x00000000,
+ 0x00000000, 0x000c0000, 0x00000000, 0x00042c80,
+ 0x0001dec1, 0x000e488c, 0x00031114, 0x00000000,
+ 0x0004f5c2, 0x00000000, 0x0003640a, 0x00000000,
+ 0x00000000, 0x000e5084, 0x00000000, 0x000eb844,
+ 0x00007001, 0x00000000, 0x00000734, 0x00001000,
+ 0x00010705, 0x000a6880, 0x00006a88, 0x000c75c4,
+ 0x00036488, 0x00000000, 0x0000c403, 0x00001000,
+ 0x000fa6b1, 0x00001010, 0x00014403, 0x00001000,
+ 0x0006a6b1, 0x00001011, 0x0006a108, 0x000cf2c4,
+ 0x0004f4c0, 0x000d5384, 0x0007e48a, 0x00000000,
+ 0x00067718, 0x00001000, 0x0007a418, 0x00001000,
+ 0x0007221a, 0x00000000, 0x0005d402, 0x00014500,
+ 0x000d8630, 0x0000100f, 0x00004418, 0x00001780,
+ 0x000e243d, 0x000d394a, 0x00049705, 0x00000000,
+ 0x0007d530, 0x000b4240, 0x000cc0f2, 0x0000100f,
+ 0x00014414, 0x00000000, 0x00004c90, 0x00001000,
+ 0x0005d705, 0x00000000, 0x00004f25, 0x00098240,
+ 0x00004725, 0x00000000, 0x0000e48a, 0x00000000,
+ 0x00027295, 0x0009c2c0, 0x0007df25, 0x00000000,
+ 0x000cc030, 0x00001010, 0x0005f718, 0x000fe798,
+ 0x00029314, 0x000bcb80, 0x00000930, 0x000b0e00,
+ 0x0004f5c0, 0x000de204, 0x000a84a0, 0x00001010,
+ 0x0007cf25, 0x000e3560, 0x00049118, 0x00000000,
+ 0x00049118, 0x000d888a, 0x0007dd02, 0x000c6efa,
+ 0x0000c434, 0x00030040, 0x000fda82, 0x000c2312,
+ 0x000fdc0e, 0x00001001, 0x00083402, 0x000c2b92,
+ 0x000906b0, 0x00001010, 0x00075a82, 0x00000000,
+ 0x0000d625, 0x000b0940, 0x0000840e, 0x00001002,
+ 0x0000aabc, 0x000c511e, 0x00098730, 0x00001010,
+ 0x0000aaf4, 0x000e910a, 0x0004628a, 0x00000000,
+ 0x00006aca, 0x00000000, 0x00000930, 0x00000000,
+ 0x0004f5c0, 0x00069c80, 0x00046ac0, 0x00000000,
+ 0x0003c40a, 0x000fc898, 0x00049118, 0x00090e00,
+ 0x0006c10a, 0x00000000, 0x00000000, 0x000e5084,
+ 0x00000000, 0x000eb844, 0x00007001, 0x00000000,
+ 0x00000734, 0x00001000, 0x00010705, 0x000a6880,
+ 0x00006a88, 0x000c75c4, 0x00048f05, 0x00001402,
+ 0x00051705, 0x00001402, 0x00046dc0, 0x000feac1,
+ 0x0005a6b0, 0x00001011, 0x00085f25, 0x000c2b92,
+ 0x000475c2, 0x00000000, 0x00005f05, 0x00001400,
+ 0x00046dc2, 0x00000000, 0x00000f05, 0x00001402,
+ 0x0003a508, 0x00000000, 0x00005f05, 0x00001400,
+ 0x00046dc2, 0x00000000, 0x00004438, 0x000d9205,
+ 0x0000273d, 0x00001000, 0x00048f05, 0x00001402,
+ 0x00085f25, 0x000c2b92, 0x00046dc2, 0x000c621c,
+ 0x0003240a, 0x000c0000, 0x00046dc0, 0x00000000,
+ 0x0000273d, 0x00001000, 0x00066488, 0x00000000,
+ 0x0000c403, 0x00001000, 0x0009a6b1, 0x00001012,
+ 0x00014403, 0x00001000, 0x0003a6b1, 0x00001013,
+ 0x0006a108, 0x00000000, 0x00023c18, 0x00001000,
+ 0x0004f4c0, 0x000c3245, 0x0000a418, 0x00001000,
+ 0x0003a20a, 0x00000000, 0x00004418, 0x00001380,
+ 0x000e243d, 0x000d394a, 0x000c9705, 0x000def92,
+ 0x0006c030, 0x00001012, 0x0005f718, 0x000fe798,
+ 0x000504a0, 0x00001012, 0x00029314, 0x000b4780,
+ 0x0003cf25, 0x000b8600, 0x00005725, 0x00000000,
+ 0x00000000, 0x000c05d7, 0x00000000, 0x00042c80,
+ 0x0001dec1, 0x000e488c, 0x000b1114, 0x000c2f12,
+ 0x0004f5c2, 0x00000000, 0x0004a918, 0x00098600,
+ 0x0006c28a, 0x00000000, 0x00000000, 0x000e5084,
+ 0x00000000, 0x000eb844, 0x00007001, 0x00000000,
+ 0x00000734, 0x00001000, 0x00010705, 0x000a6880,
+ 0x00006a88, 0x000c75c4, 0x00069705, 0x00001402,
+ 0x00038f05, 0x00001400, 0x000475c0, 0x000feac1,
+ 0x000fa6b0, 0x00001012, 0x00046dc0, 0x00000000,
+ 0x00085518, 0x0000100f, 0x00045534, 0x000f9285,
+ 0x00068f05, 0x00001402, 0x00046588, 0x000feedd,
+ 0x00046dc2, 0x00000000, 0x00070f05, 0x00001402,
+ 0x0005e588, 0x000e36e1, 0x00000000, 0x000c5084,
+ 0x00002f25, 0x000f2a84, 0x00005518, 0x000017fc,
+ 0x0006550a, 0x00000000, 0x0000551a, 0x00001002,
+ 0x0003450a, 0x000f6145, 0x0000473d, 0x00001000,
+ 0x00004438, 0x000f1205, 0x00005f25, 0x00000000,
+ 0x00068f05, 0x00001402, 0x00005725, 0x000e36e1,
+ 0x0000c438, 0x000f1205, 0x0000273d, 0x00001000,
+ 0x0002a880, 0x000b4e40, 0x00042214, 0x000e5548,
+ 0x000542bf, 0x00000000, 0x00000000, 0x000481c0,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000030,
+ 0x0000072d, 0x000fbf8a, 0x00077f94, 0x000ea7df,
+ 0x0002ac95, 0x000d3145, 0x00002731, 0x00001400,
+ 0x00006288, 0x000c71c4, 0x00014108, 0x000e6044,
+ 0x00035408, 0x00000000, 0x00025418, 0x000a0ec0,
+ 0x0001443d, 0x000ca21e, 0x00046595, 0x000d730c,
+ 0x0006538e, 0x00000000, 0x0000c630, 0x00001014,
+ 0x000e7b0e, 0x000df782, 0x0001c6b0, 0x00001014,
+ 0x00036f05, 0x000c0000, 0x00043695, 0x000d598c,
+ 0x0005331a, 0x000f2185, 0x00000000, 0x00000000,
+ 0x000007ae, 0x000bdb00, 0x00040630, 0x00001400,
+ 0x0005e708, 0x000c0000, 0x0007ef30, 0x000b1c00,
+ 0x000806a0, 0x00001014, 0x00066408, 0x000c0000,
+ 0x00000000, 0x00000000, 0x00021843, 0x00000000,
+ 0x00000cac, 0x00062c00, 0x00001dac, 0x00063400,
+ 0x00002cac, 0x0006cc80, 0x000db943, 0x000e5ca1,
+ 0x00000000, 0x00000000, 0x0006680a, 0x000f3205,
+ 0x00042730, 0x00001400, 0x00014108, 0x000f2204,
+ 0x00025418, 0x000a2ec0, 0x00015dbd, 0x00038100,
+ 0x00015dbc, 0x00000000, 0x0005e415, 0x00034880,
+ 0x0001258a, 0x000d730c, 0x0006538e, 0x000baa40,
+ 0x00008630, 0x00001015, 0x00067b0e, 0x000ac380,
+ 0x0003ef05, 0x00000000, 0x0000f734, 0x0001c300,
+ 0x000586b0, 0x00001400, 0x000b6f05, 0x000c3a00,
+ 0x00048f05, 0x00000000, 0x0005b695, 0x0008c380,
+ 0x0002058e, 0x00000000, 0x000500b0, 0x00001400,
+ 0x0002b318, 0x000e998d, 0x0006430a, 0x00000000,
+ 0x00000000, 0x000ef384, 0x00004725, 0x000c0000,
+ 0x00000000, 0x000f3204, 0x00004f25, 0x000c0000,
+ 0x00080000, 0x000e5ca1, 0x000cb943, 0x000e5ca1,
+ 0x0004b943, 0x00000000, 0x00040730, 0x00001400,
+ 0x000cb943, 0x000e5ca1, 0x0004b943, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 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/kernel/drv/oss_cs461x/oss_cs461x.c b/kernel/drv/oss_cs461x/oss_cs461x.c
new file mode 100644
index 0000000..e024fc6
--- /dev/null
+++ b/kernel/drv/oss_cs461x/oss_cs461x.c
@@ -0,0 +1,1931 @@
+/*
+ * Purpose: Driver for Crystal cs461x and cs461x PCI audio controllers
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_cs461x_cfg.h"
+#include "midi_core.h"
+#include "ac97.h"
+#include "oss_pci.h"
+#include "cs461x.h"
+
+extern int cs461x_clkrun_fix;
+
+#define CRYSTAL_VENDOR_ID 0x1013
+#define CRYSTAL_CS4610_ID 0x6001
+#define CRYSTAL_CS461x_ID 0x6003
+#define CRYSTAL_CS4615_ID 0x6004
+
+#define USE_SG
+
+#define WRITEB(a,d) devc->bRegister0[a] = d
+#define READB(a) devc->bRegister0[a]
+#define WRITEW(a,d) devc->wRegister0[a>>1] = d
+#define READW(a) devc->wRegister0[a>>1]
+
+#define READ0L(a) (devc->dwRegister0[a>>2])
+#define WRITE0L(a, d) (devc->dwRegister0[a>>2] = d)
+#define READ1L(a) (devc->dwRegister1[a>>2])
+#define WRITE1L(a,d) (devc->dwRegister1[a>>2] = d)
+
+#define READ1L(a) (devc->dwRegister1[a>>2])
+
+#ifdef OSS_BIG_ENDIAN
+static unsigned int
+ymf_swap (unsigned int x)
+{
+ return ((x & 0x000000ff) << 24) |
+ ((x & 0x0000ff00) << 8) |
+ ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
+}
+
+#define LSWAP(x) ymf_swap(x)
+#else
+#define LSWAP(x) x
+#endif
+
+#define MAX_PORTC 2
+
+typedef struct cs461x_portc
+{
+ int speed, bits, channels;
+ int open_mode;
+ int audio_enabled;
+ int trigger_bits;
+ int audiodev;
+}
+cs461x_portc;
+
+typedef struct cs461x_devc
+{
+ oss_device_t *osdev;
+ char *chip_name;
+ unsigned short subsysid;
+
+ oss_native_word bar0addr, bar1addr;
+ unsigned int *bar0virt, *bar1virt;
+ volatile unsigned int *dwRegister0, *dwRegister1;
+ volatile unsigned short *wRegister0, *wRegister1;
+ volatile unsigned char *bRegister0, *bRegister1;
+ int irq;
+ int dual_codec;
+ unsigned int *play_sgbuf;
+ unsigned int play_sgbuf_phys;
+ oss_dma_handle_t play_sgbuf_dma_handle;
+
+ /* Mutex */
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ /* MIDI */
+ int midi_opened;
+ int midi_dev;
+ oss_midi_inputbyte_t midi_input_intr;
+
+ /* Mixer parameters */
+ ac97_devc ac97devc, ac97devc2;
+ int mixer_dev, mixer2_dev;
+
+ /* Audio parameters */
+ cs461x_portc portc[MAX_PORTC];
+ int open_mode;
+ oss_native_word PCTL; /*Play Control Register */
+ oss_native_word CCTL; /*Record Control Register */
+ int processor_started;
+}
+cs461x_devc;
+
+#define MAX_CS461x 6
+
+static int ac97_write (void *devc, int addr, int data);
+static int ac97_read (void *devc, int addr);
+
+static void
+PokeBA0 (cs461x_devc * devc, unsigned int offset, unsigned int value)
+{
+ WRITE0L (offset, value);
+}
+
+static unsigned int
+PeekBA0 (cs461x_devc * devc, unsigned int offset)
+{
+ unsigned int value;
+
+ value = READ0L (offset);
+ return (value);
+
+}
+
+static int
+ac97_read (void *devc_, int offset)
+{
+ cs461x_devc *devc = devc_;
+ int count;
+ unsigned int status, value;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /*
+ * Make sure that there is not data sitting around from a previous
+ * uncompleted access. ACSDA = Status Data Register = 47Ch
+ */
+ status = PeekBA0 (devc, BA0_ACSDA);
+ /* Get the actual AC97 register from the offset */
+ PokeBA0 (devc, BA0_ACCAD, offset - BA0_AC97_RESET);
+ PokeBA0 (devc, BA0_ACCDA, 0);
+ PokeBA0 (devc, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM |
+ ACCTL_ESYN | ACCTL_RSTN);
+
+ /* Wait for the read to occur. */
+ for (count = 0; count < 10; count++)
+ {
+ /* First, we want to wait for a short time. */
+ oss_udelay (100);
+ /*
+ * Now, check to see if the read has completed.
+ * ACCTL = 460h, DCV should be reset by now and 460h = 17h
+ */
+ status = PeekBA0 (devc, BA0_ACCTL);
+ if (!(status & ACCTL_DCV))
+ {
+ break;
+ }
+ }
+
+ /* Make sure the read completed. */
+ if (status & ACCTL_DCV)
+ {
+ cmn_err (CE_WARN, "AC97 Read Timedout\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+
+ /* Wait for the valid status bit to go active. */
+
+ for (count = 0; count < 10; count++)
+ {
+ /*
+ * Read the AC97 status register.
+ * ACSTS = Status Register = 464h
+ */
+ status = PeekBA0 (devc, BA0_ACSTS);
+ /*
+ * See if we have valid status.
+ * VSTS - Valid Status
+ */
+ if (status & ACSTS_VSTS)
+ break;
+
+ /*
+ * Wait for a short while.
+ */
+ oss_udelay (100);
+ }
+ /* Make sure we got valid status. */
+ if (!(status & ACSTS_VSTS))
+ {
+ cmn_err (CE_WARN, "AC97 Read Timedout(2)\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+
+ /*
+ * Read the data returned from the AC97 register.
+ * ACSDA = Status Data Register = 474h
+ */
+ value = PeekBA0 (devc, BA0_ACSDA);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (value);
+}
+
+static int
+ac97_write (void *devc_, int offset, int data)
+{
+ cs461x_devc *devc = devc_;
+ int count;
+ unsigned int status = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ PokeBA0 (devc, BA0_ACCAD, offset);
+ PokeBA0 (devc, BA0_ACCDA, data);
+ PokeBA0 (devc, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
+ for (count = 0; count < 10; count++)
+ {
+ /* First, we want to wait for a short time. */
+ oss_udelay (100);
+ /* Now, check to see if the write has completed. */
+ /* ACCTL = 460h, DCV should be reset by now and 460h = 07h */
+ status = PeekBA0 (devc, BA0_ACCTL);
+ if (!(status & ACCTL_DCV))
+ break;
+ }
+
+ /* write didn't completed. */
+ if (status & ACCTL_DCV)
+ {
+ cmn_err (CE_WARN, "AC97 Write timeout\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+static int
+ac97_read2 (void *devc_, int offset)
+{
+ cs461x_devc *devc = devc_;
+ int count;
+ unsigned int status, value;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /*
+ * Make sure that there is not data sitting around from a previous
+ * uncompleted access. ACSDA = Status Data Register = 47Ch
+ */
+ status = PeekBA0 (devc, BA0_ACSDA2);
+
+ /* Get the actual AC97 register from the offset */
+ PokeBA0 (devc, BA0_ACCAD, offset);
+ PokeBA0 (devc, BA0_ACCDA, 0);
+ PokeBA0 (devc, BA0_ACCTL,
+ ACCTL_DCV | ACCTL_TC | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN |
+ ACCTL_RSTN);
+
+
+ /* Wait for the read to occur. */
+ for (count = 0; count < 10; count++)
+ {
+ /* First, we want to wait for a short time. */
+ oss_udelay (1000);
+ /*
+ * Now, check to see if the read has completed.
+ * ACCTL = 460h, DCV should be reset by now and 460h = 17h
+ */
+ status = PeekBA0 (devc, BA0_ACCTL);
+ if (!(status & ACCTL_DCV))
+ break;
+ }
+
+ /* Make sure the read completed. */
+ if (PeekBA0 (devc, BA0_ACCTL) & ACCTL_DCV)
+ {
+ cmn_err (CE_WARN, "Secondary AC97 Read Timedout\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+
+ /* Wait for the valid status bit to go active. */
+
+ for (count = 0; count < 10; count++)
+ {
+ /*
+ * Read the AC97 status register.
+ * ACSTS = Status Register = 464h
+ */
+ status = PeekBA0 (devc, BA0_ACSTS2);
+ /*
+ * See if we have valid status.
+ * VSTS - Valid Status
+ */
+ if (status & ACSTS_VSTS)
+ break;
+
+ /*
+ * Wait for a short while.
+ */
+ oss_udelay (1000);
+ }
+ /* Make sure we got valid status */
+ if (!(status & ACSTS_VSTS))
+ {
+ cmn_err (CE_WARN, "Secondary AC97 Read Timedout(2)\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+
+ /*
+ * Read the data returned from the AC97 register.
+ * ACSDA = Status Data Register = 474h
+ */
+ value = PeekBA0 (devc, BA0_ACSDA2);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (value);
+}
+
+static int
+ac97_write2 (void *devc_, int offset, int data)
+{
+ cs461x_devc *devc = devc_;
+ int count;
+ unsigned int status = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ PokeBA0 (devc, BA0_ACCAD, offset);
+ PokeBA0 (devc, BA0_ACCDA, data);
+ PokeBA0 (devc, BA0_ACCTL,
+ ACCTL_DCV | ACCTL_TC | ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
+ for (count = 0; count < 10; count++)
+ {
+ /* First, we want to wait for a short time. */
+ oss_udelay (1000);
+ /* Now, check to see if the write has completed. */
+ /* ACCTL = 460h, DCV should be reset by now and 460h = 07h */
+ status = PeekBA0 (devc, BA0_ACCTL);
+ if (!(status & ACCTL_DCV))
+ break;
+ }
+
+ /* write didn't completed. */
+ if (status & ACCTL_DCV)
+ {
+ cmn_err (CE_WARN, "Secondary AC97 Write timeout\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+/*
+ * this is 3*1024 for parameter, 3.5*1024 for sample and 2*3.5*1024
+ * for code since each instruction is 40 bits and takes two dwords
+ */
+#define INKY_BA1_DWORD_SIZE (13 * 1024 + 512)
+/* this is parameter, sample, and code */
+#define INKY_MEMORY_COUNT 3
+struct cs461x_firmware_struct
+{
+ struct
+ {
+ unsigned int ulDestAddr;
+ unsigned int ulSourceSize;
+ }
+ MemoryStat[INKY_MEMORY_COUNT];
+ unsigned int BA1Array[INKY_BA1_DWORD_SIZE];
+};
+#include "cs461x_dsp.h"
+
+static void
+DoTransfer (cs461x_devc * devc, unsigned int *fpulSrc,
+ unsigned int ulByteDestOffset, unsigned int ulByteLength)
+{
+ int dwByteCounter;
+
+ if (ulByteDestOffset & 0x3)
+ {
+ cmn_err (CE_WARN, "invalid DMA address\n");
+ return;
+ }
+
+ for (dwByteCounter = 0; dwByteCounter < ulByteLength; dwByteCounter += 4)
+ {
+ WRITE1L ((ulByteDestOffset + dwByteCounter),
+ fpulSrc[dwByteCounter / 4]);
+ }
+}
+
+static void
+install_ucode (cs461x_devc * devc)
+{
+ unsigned int i, count;
+
+ count = 0;
+ for (i = 0; i < INKY_MEMORY_COUNT; i++)
+ {
+
+ DoTransfer (devc, (unsigned int *) (cs461x_firmware.BA1Array + count),
+ cs461x_firmware.MemoryStat[i].ulDestAddr,
+ cs461x_firmware.MemoryStat[i].ulSourceSize);
+ count += cs461x_firmware.MemoryStat[i].ulSourceSize / 4;
+ }
+}
+
+void
+clear_serial_fifo (cs461x_devc * devc)
+{
+ unsigned int ulIdx, ulLoop;
+ unsigned int ulStatus = 0;
+ unsigned int ulCLKCR1;
+
+
+ ulCLKCR1 = PeekBA0 (devc, BA0_CLKCR1);
+
+ if (!(ulCLKCR1 & CLKCR1_SWCE))
+ {
+ PokeBA0 (devc, BA0_CLKCR1, ulCLKCR1 | CLKCR1_SWCE);
+ }
+ PokeBA0 (devc, BA0_SERBWP, 0);
+
+ for (ulIdx = 0; ulIdx < 256; ulIdx++)
+ {
+ /*
+ * Make sure the previous FIFO write operation has completed.
+ */
+ for (ulLoop = 0; ulLoop < 5; ulLoop++)
+ {
+ oss_udelay (100);
+ ulStatus = PeekBA0 (devc, BA0_SERBST);
+ if (!(ulStatus & SERBST_WBSY))
+ {
+ break;
+ }
+ }
+
+ if (ulStatus & SERBST_WBSY)
+ {
+ if (!(ulCLKCR1 & CLKCR1_SWCE))
+ {
+ PokeBA0 (devc, BA0_CLKCR1, ulCLKCR1);
+ }
+ }
+
+ /* Write the serial port FIFO index. */
+
+ PokeBA0 (devc, BA0_SERBAD, ulIdx);
+
+ /*
+ * Tell the serial port to load the new value into the FIFO location.
+ */
+ PokeBA0 (devc, 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 (!(ulCLKCR1 & CLKCR1_SWCE))
+ {
+ PokeBA0 (devc, BA0_CLKCR1, ulCLKCR1);
+ }
+
+}
+
+static int
+cs461x_reset_processor (cs461x_devc * devc)
+{
+ unsigned int ulIdx;
+
+ /* Write the reset bit of the SP control register. */
+ WRITE1L (BA1_SPCR, SPCR_RSTSP);
+ WRITE1L (BA1_SPCR, SPCR_DRQEN);
+
+ /* Clear the trap registers. */
+ for (ulIdx = 0; ulIdx < 8; ulIdx++)
+ {
+ WRITE1L (BA1_DREG, DREG_REGID_TRAP_SELECT + ulIdx);
+ WRITE1L (BA1_TWPR, 0xFFFF);
+ }
+
+ WRITE1L (BA1_DREG, 0);
+ WRITE1L (BA1_FRMT, 0xadf);
+ return (0);
+}
+
+static int
+cs461x_start_processor (cs461x_devc * devc)
+{
+
+ unsigned int ulCount;
+ int ulTemp = 0;
+
+ /* reset the processor first */
+ cs461x_reset_processor (devc);
+
+ /* reload the ucode */
+ install_ucode (devc);
+
+ /* Set the frame timer to reflect the number of cycles per frame. */
+ WRITE1L (BA1_FRMT, 0xADF);
+
+ /*
+ * Turn on the run, run at frame, and DMA enable bits in the local copy of
+ * the SP control register.
+ */
+ WRITE1L (BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
+
+ /*
+ * Wait until the run at frame bit resets itself in the SP control
+ * register.
+ */
+ for (ulCount = 0; ulCount < 25; ulCount++)
+ {
+ /* Wait a little bit, so we don't issue PCI reads too frequently. */
+ oss_udelay (100);
+
+ /* Fetch the current value of the SP status register. */
+ ulTemp = READ1L (BA1_SPCR);
+
+ /* If the run at frame bit has reset, then stop waiting. */
+ if (!(ulTemp & SPCR_RUNFR))
+ break;
+ }
+ /* If the run at frame bit never reset, then return an error. */
+ if (ulTemp & SPCR_RUNFR)
+ {
+ cmn_err (CE_WARN, "Start(): SPCR_RUNFR never reset.\n");
+ }
+ devc->processor_started = 1;
+ return 0;
+}
+
+static int
+cs461xintr (oss_device_t * osdev)
+{
+ cs461x_devc *devc = (cs461x_devc *) osdev->devc;
+ cs461x_portc *portc;
+ unsigned int status;
+ int i;
+ unsigned int uart_stat;
+ int serviced = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+/* Read the Interrupt Status Register */
+ status = PeekBA0 (devc, BA0_HISR);
+
+/*
+ * This is the MIDI read interrupt service. First check to see
+ * if the MIDI interrupt flag is set in the HISR register. Next
+ * read the MIDI status register. See if Receive Buffer Empty
+ * is empty (0=FIFO Not empty, 1=FIFO is empty
+ */
+ if ((devc->midi_opened & OPEN_READ) && (status & HISR_MIDI))
+ {
+ uart_stat = PeekBA0 (devc, BA0_MIDSR);
+/*
+ * read one byte of MIDI data and hand it off the the sequencer module
+ * to decode this. Keep checking to see if the data is available. Stop
+ * when no more data is there in the FIFO.
+ */
+ while (!(uart_stat & MIDSR_RBE))
+ {
+ unsigned char d;
+ d = PeekBA0 (devc, BA0_MIDRP);
+
+ if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr (devc->midi_dev, d);
+ uart_stat = PeekBA0 (devc, BA0_MIDSR);
+ }
+ }
+
+/* Audio interrupt handling */
+ if (status & 0x3)
+ {
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+ if (status & 0x1)
+ if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
+ int ptr, n;
+
+ ptr = READ1L (BA1_PBA) - dmap->dmabuf_phys;
+ ptr = ptr / dmap->fragment_size;
+ if (ptr < 0 || ptr >= dmap->nfrags)
+ ptr = 0;
+ n = 0;
+ while (dmap_get_qhead (dmap) != ptr && n++ < dmap->nfrags)
+ oss_audio_outputintr (portc->audiodev, 0);
+ }
+
+ if (status & 0x2)
+ if (portc->trigger_bits & PCM_ENABLE_INPUT)
+ {
+
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_in;
+ int ptr, n;
+
+ ptr = READ1L (BA1_CBA) - dmap->dmabuf_phys;
+ ptr = ptr / (dmap->fragment_size);
+
+ if (ptr < 0 || ptr >= dmap->nfrags)
+ ptr = 0;
+ n = 0;
+ while (dmap_get_qtail (dmap) != ptr && n++ < dmap->nfrags)
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+ }
+
+ serviced = 1;
+ PokeBA0 (devc, BA0_HICR, 0x03);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return serviced;
+}
+
+static int
+cs461x_audio_set_rate (int dev, int arg)
+{
+ cs461x_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
+ {
+ audio_engines[dev]->fixed_rate = 48000;
+ arg = 48000;
+ }
+ else
+ audio_engines[dev]->fixed_rate = 0;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+cs461x_audio_set_channels (int dev, short arg)
+{
+ cs461x_portc *portc = audio_engines[dev]->portc;
+
+ if (audio_engines[dev]->flags & ADEV_STEREOONLY)
+ arg = 2;
+
+ if ((arg != 1) && (arg != 2))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+cs461x_audio_set_format (int dev, unsigned int arg)
+{
+ cs461x_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (audio_engines[dev]->flags & ADEV_16BITONLY)
+ arg = 16;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+cs461x_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void cs461x_audio_trigger (int dev, int state);
+
+static void
+cs461x_audio_reset (int dev)
+{
+ cs461x_audio_trigger (dev, 0);
+}
+
+static void
+cs461x_audio_reset_input (int dev)
+{
+ cs461x_portc *portc = audio_engines[dev]->portc;
+ cs461x_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+cs461x_audio_reset_output (int dev)
+{
+ cs461x_portc *portc = audio_engines[dev]->portc;
+ cs461x_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+cs461x_audio_open (int dev, int mode, int open_flags)
+{
+ cs461x_portc *portc = audio_engines[dev]->portc;
+ cs461x_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode |= mode;
+
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+#if 0
+ if (mode & OPEN_READ)
+ {
+ dmapin->buffsize = 4096;
+ audio_engines[dev]->fixed_rate = 48000;
+ audio_engines[dev]->min_rate = 48000;
+ audio_engines[dev]->max_rate = 48000;
+ audio_engines[dev]->flags |=
+ ADEV_FIXEDRATE | ADEV_16BITONLY | ADEV_STEREOONLY;
+ }
+ if (mode & OPEN_WRITE)
+ {
+ audio_engines[dev]->min_rate = 5000;
+ audio_engines[dev]->max_rate = 48000;
+ audio_engines[dev]->flags &=
+ ~(ADEV_FIXEDRATE | ADEV_16BITONLY | ADEV_STEREOONLY);
+ audio_engines[dev]->fixed_rate = 0;
+ }
+#endif
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+cs461x_audio_close (int dev, int mode)
+{
+ cs461x_portc *portc = audio_engines[dev]->portc;
+ cs461x_devc *devc = audio_engines[dev]->devc;
+
+ cs461x_audio_reset (dev);
+ portc->audio_enabled &= ~mode;
+ devc->open_mode &= ~mode;
+ portc->open_mode = 0;
+}
+
+/*ARGSUSED*/
+static void
+cs461x_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ cs461x_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+cs461x_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ cs461x_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+cs461x_audio_trigger (int dev, int state)
+{
+ oss_native_word flags, tmp;
+ cs461x_devc *devc = audio_engines[dev]->devc;
+ cs461x_portc *portc = audio_engines[dev]->portc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ tmp = READ1L (BA1_PCTL);
+ tmp &= 0xFFFF;
+ tmp |= devc->PCTL;
+ WRITE1L (BA1_PCTL, tmp);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ tmp = READ1L (BA1_PCTL);
+ tmp &= 0xFFFF;
+ WRITE1L (BA1_PCTL, tmp);
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ tmp = READ1L (BA1_CCTL);
+ tmp &= 0xFFFF0000;
+ tmp |= devc->CCTL;
+ WRITE1L (BA1_CCTL, tmp);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ tmp = READ1L (BA1_CCTL);
+ tmp &= 0xFFFF0000;
+ WRITE1L (BA1_CCTL, tmp);
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static int
+cs461x_play_rate (cs461x_devc * devc, unsigned int ulInRate)
+{
+/*define GOF_PER_SEC 200*/
+ unsigned int ulTemp1, ulTemp2;
+ unsigned int ulPhiIncr;
+ unsigned int ulCorrectionPerGOF, ulCorrectionPerSec;
+ unsigned int ulOutRate = 48000;
+
+ ulTemp1 = ulInRate << 16;
+ ulPhiIncr = ulTemp1 / ulOutRate;
+ ulTemp1 -= ulPhiIncr * ulOutRate;
+ ulTemp1 <<= 10;
+ ulPhiIncr <<= 10;
+ ulTemp2 = ulTemp1 / ulOutRate;
+ ulPhiIncr += ulTemp2;
+ ulTemp1 -= ulTemp2 * ulOutRate;
+ ulCorrectionPerGOF = ulTemp1 / 200;
+ ulTemp1 -= ulCorrectionPerGOF * 200;
+ ulCorrectionPerSec = ulTemp1;
+
+ /* Fill in the SampleRateConverter control block. */
+ WRITE1L (BA1_PSRC, ((ulCorrectionPerSec << 16) & 0xFFFF0000) |
+ (ulCorrectionPerGOF & 0xFFFF));
+ WRITE1L (BA1_PPI, ulPhiIncr);
+ return 0;
+}
+
+static int
+cs461x_record_rate (cs461x_devc * devc, int ulOutRate)
+{
+ unsigned int ulPhiIncr, ulCoeffIncr, ulTemp1, ulTemp2;
+ unsigned int ulCorrectionPerGOF, ulCorrectionPerSec, ulInitialDelay;
+ unsigned int ulInRate = 48000;
+
+ /*
+ * We can only decimate by up to a factor of 1/9th the hardware rate.
+ * Return an error if an attempt is made to stray outside that limit.
+ */
+ if ((ulOutRate * 9) < ulInRate)
+ {
+ cmn_err (CE_WARN,
+ "SetCaptureSampleRate(): Requested output rate is below 1/9th of the input rate.\n");
+ return (-1);
+ }
+
+ /*
+ * 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 (ulOutRate > ulInRate)
+ {
+ cmn_err (CE_WARN,
+ "SetCaptureSampleRate(): Requested output rate is greater than the input rate.");
+ return (-1);
+ }
+ ulTemp1 = ulOutRate << 16;
+ ulCoeffIncr = ulTemp1 / ulInRate;
+ ulTemp1 -= ulCoeffIncr * ulInRate;
+ ulTemp1 <<= 7;
+ ulCoeffIncr <<= 7;
+ ulCoeffIncr += ulTemp1 / ulInRate;
+ ulCoeffIncr ^= 0xFFFFFFFF;
+ ulCoeffIncr++;
+ ulTemp1 = ulInRate << 16;
+ ulPhiIncr = ulTemp1 / ulOutRate;
+ ulTemp1 -= ulPhiIncr * ulOutRate;
+ ulTemp1 <<= 10;
+ ulPhiIncr <<= 10;
+ ulTemp2 = ulTemp1 / ulOutRate;
+ ulPhiIncr += ulTemp2;
+ ulTemp1 -= ulTemp2 * ulOutRate;
+ ulCorrectionPerGOF = ulTemp1 / 200;
+ ulTemp1 -= ulCorrectionPerGOF * 200;
+ ulCorrectionPerSec = ulTemp1;
+ ulInitialDelay = ((ulInRate * 24) + ulOutRate - 1) / ulOutRate;
+ /* Fill in the VariDecimate control block. */
+ WRITE1L (BA1_CSRC, ((ulCorrectionPerSec << 16) & 0xFFFF0000) |
+ (ulCorrectionPerGOF & 0xFFFF));
+ WRITE1L (BA1_CCI, ulCoeffIncr);
+ WRITE1L (BA1_CD,
+ (((BA1_VARIDEC_BUF_1 + (ulInitialDelay << 2)) << 16) & 0xFFFF0000)
+ | 0x80);
+ WRITE1L (BA1_CPI, ulPhiIncr);
+#if 0
+ {
+ unsigned int frameGroupLength, cnt;
+ int rate = ulOutRate;
+
+ 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;
+ }
+
+ WRITE1L (BA1_CFG1, frameGroupLength);
+ WRITE1L (BA1_CFG2, (0x00800000 | frameGroupLength));
+ WRITE1L (BA1_CCST, 0x0000FFFF);
+ WRITE1L (BA1_CSPB, ((65536 * rate) / 24000));
+ WRITE1L ((BA1_CSPB + 4), 0x0000FFFF);
+ }
+#endif
+ return (0);
+}
+
+struct InitStruct
+{
+ unsigned long off;
+ unsigned long val;
+}
+InitArray[] =
+{
+ {
+ 0x00000040, 0x3fc0000f}
+ ,
+ {
+ 0x0000004c, 0x04800000}
+ ,
+ {
+ 0x000000b3, 0x00000780}
+ ,
+ {
+ 0x000000b7, 0x00000000}
+ ,
+ {
+ 0x000000bc, 0x07800000}
+ ,
+ {
+ 0x000000cd, 0x00800000}
+,};
+
+
+/*
+ * "SetCaptureSPValues()" -- Initialize record task values before each
+ * capture startup.
+ */
+void
+SetCaptureSPValues (cs461x_devc * devc)
+{
+ unsigned i, offset;
+ for (i = 0; i < sizeof (InitArray) / sizeof (struct InitStruct); i++)
+ {
+ offset = InitArray[i].off * 4; /* 8bit to 32bit offset value */
+ WRITE1L (offset, InitArray[i].val);
+ }
+}
+
+/*ARGSUSED*/
+static int
+cs461x_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ cs461x_devc *devc = audio_engines[dev]->devc;
+ cs461x_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ /* Start the processor */
+ if (!devc->processor_started)
+ cs461x_start_processor (devc);
+
+ /* Set Capture S/P values */
+ SetCaptureSPValues (devc);
+ /* set the record rate */
+ cs461x_record_rate (devc, portc->speed);
+
+ /* write the buffer address */
+ WRITE1L (BA1_CBA, dmap->dmabuf_phys);
+
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+cs461x_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ cs461x_devc *devc = audio_engines[dev]->devc;
+ cs461x_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ /* Start the processor */
+ if (!devc->processor_started)
+ cs461x_start_processor (devc);
+
+#ifdef USE_SG
+ {
+ unsigned int sg_temp[9], sg_npages = 0;
+ int i;
+ oss_native_word Count, playFormat, tmp, tmp2;
+
+ sg_npages = (dmap->bytes_in_use) / 4096;
+
+ devc->play_sgbuf[0] = dmap->dmabuf_phys;
+ devc->play_sgbuf[1] = 0x00000008;
+
+ for (i = 0; i < sg_npages; i++)
+ {
+ devc->play_sgbuf[2 * i] = dmap->dmabuf_phys + 4096 * i;
+ if (i == sg_npages - 1)
+ tmp2 = 0xbfff0000;
+ else
+ tmp2 = 0x80000000 + 8 * (i + 1);
+
+ devc->play_sgbuf[2 * i + 1] = tmp2;
+ }
+ sg_temp[0] = 0x82c0200d;
+ sg_temp[1] = 0xffff0000;
+ sg_temp[2] = devc->play_sgbuf[0];
+ sg_temp[3] = 0x00010600;
+ sg_temp[4] = devc->play_sgbuf[2];
+ sg_temp[5] = 0x80000010;
+ sg_temp[6] = devc->play_sgbuf[0];
+ sg_temp[7] = devc->play_sgbuf[2];
+ sg_temp[8] = (devc->play_sgbuf_phys & 0xffff000) | 0x10;
+
+ for (i = 0; i < sizeof (sg_temp) / 4; i++)
+ WRITE1L ((BA1_PDTC + i * 4), sg_temp[i]);
+
+ WRITE1L (BA1_PBA, dmap->dmabuf_phys);
+
+ cs461x_play_rate (devc, (unsigned int) portc->speed);
+
+ Count = 4;
+ playFormat = READ1L (BA1_PFIE);
+ playFormat &= ~0x0000f03f;
+
+ if ((portc->channels == 2))
+ {
+ playFormat &= ~DMA_RQ_C2_AC_MONO_TO_STEREO;
+ Count *= 2;
+ }
+ else
+ playFormat |= DMA_RQ_C2_AC_MONO_TO_STEREO;
+
+ if ((portc->bits == 16))
+ {
+ playFormat &=
+ ~(DMA_RQ_C2_AC_8_TO_16_BIT | DMA_RQ_C2_AC_SIGNED_CONVERT);
+ Count *= 2;
+ }
+ else
+ playFormat |= (DMA_RQ_C2_AC_8_TO_16_BIT | DMA_RQ_C2_AC_SIGNED_CONVERT);
+
+ WRITE1L (BA1_PFIE, playFormat);
+
+ tmp = READ1L (BA1_PDTC);
+ tmp &= 0xfffffe00;
+ WRITE1L (BA1_PDTC, tmp | --Count);
+ }
+#else
+ {
+ unsigned int pdtc_value, pfie_value;
+ /* Set the sample rate converter */
+ cs461x_play_rate (devc, (unsigned int) portc->speed);
+
+ pfie_value = READ1L (BA1_PFIE);
+ pfie_value &= ~0x0000f03f;
+
+ pdtc_value = READ1L (BA1_PDTC);
+ pdtc_value &= ~0x000003ff;
+
+ /* Now set the sample size/stereo/mono */
+ if ((portc->bits == 8) && (portc->channels == 1))
+ {
+ pdtc_value |= 0x03;
+ pfie_value |= 0xB000; /*8bit mono */
+ }
+ if ((portc->bits == 8) && (portc->channels == 2))
+ {
+ pdtc_value |= 0x07;
+ pfie_value |= 0xA000; /*8bit stereo */
+ }
+ if ((portc->bits == 16) && (portc->channels == 1))
+ {
+ pdtc_value |= 0x07;
+ pfie_value |= 0x2000; /*16bit mono */
+ }
+ if ((portc->bits == 16) && (portc->channels == 2))
+ {
+ pdtc_value |= 0x0F;
+ pfie_value |= 0x0000; /*16bit stereo */
+ }
+
+ WRITE1L (BA1_PDTC, pdtc_value);
+ WRITE1L (BA1_PFIE, pfie_value);
+ WRITE1L (BA1_PBA, dmap->dmabuf_phys);
+ }
+#endif
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+cs461x_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+
+#ifdef USE_SG
+ int err;
+#else
+ oss_native_word phaddr;
+ cs461x_devc *devc = audio_engines[dev]->devc;
+#endif
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+#ifdef USE_SG
+ if ((err = oss_alloc_dmabuf (dev, dmap, direction)) < 0)
+ {
+ cmn_err (CE_WARN, "Failed to allocate a DMA buffer\n");
+ return err;
+ }
+#else
+ dmap->dmabuf =
+ (void *) CONTIG_MALLOC (devc->osdev, 4096, MEMLIMIT_32BITS, &phaddr, dmap->dmabuf_dma_handle);
+ dmap->dmabuf_phys = phaddr;
+# ifdef linux
+ oss_reserve_pages (dmap->dmabuf, dmap->dmabuf + 4096 - 1);
+# endif
+ dmap->buffsize = 4096;
+#endif
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+cs461x_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+#ifndef USE_SG
+ cs461x_devc *devc = audio_engines[dev]->devc;
+#endif
+#ifdef USE_SG
+ oss_free_dmabuf (dev, dmap);
+ dmap->dmabuf = 0;
+#else
+ if (dmap->dmabuf == NULL)
+ return 0;
+ CONTIG_FREE (devc->osdev, dmap->dmabuf, 4096, dmap->dmabuf_dma_handle);
+# ifdef linux
+ oss_unreserve_pages (dmap->dmabuf, dmap->dmabuf + 4096 - 1);
+# endif
+ dmap->dmabuf = 0;
+#endif
+ return 0;
+
+}
+
+static int
+cs461x_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ cs461x_devc *devc = audio_engines[dev]->devc;
+ unsigned int ptr = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ ptr = READ1L (BA1_PBA) - dmap->dmabuf_phys;
+ }
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ ptr = READ1L (BA1_CBA) - dmap->dmabuf_phys;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ptr;
+}
+
+static audiodrv_t cs461x_audio_driver = {
+ cs461x_audio_open,
+ cs461x_audio_close,
+ cs461x_audio_output_block,
+ cs461x_audio_start_input,
+ cs461x_audio_ioctl,
+ cs461x_audio_prepare_for_input,
+ cs461x_audio_prepare_for_output,
+ cs461x_audio_reset,
+ NULL,
+ NULL,
+ cs461x_audio_reset_input,
+ cs461x_audio_reset_output,
+ cs461x_audio_trigger,
+ cs461x_audio_set_rate,
+ cs461x_audio_set_format,
+ cs461x_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ cs461x_alloc_buffer,
+ cs461x_free_buffer,
+ NULL,
+ NULL,
+ cs461x_get_buffer_pointer
+};
+
+/***********************MIDI PORT ROUTINES ****************/
+
+/*ARGSUSED*/
+static int
+cs461x_midi_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ cs461x_devc *devc = (cs461x_devc *) midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ if (devc->midi_opened)
+ {
+ return OSS_EBUSY;
+ }
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->midi_input_intr = inputbyte;
+ devc->midi_opened = mode;
+
+ /* first reset the MIDI port */
+ PokeBA0 (devc, BA0_MIDCR, 0x10);
+ PokeBA0 (devc, BA0_MIDCR, 0x00);
+
+ /* Now check if we're in Read or Write mode */
+ if (mode & OPEN_READ)
+ {
+ /* enable MIDI Input intr and receive enable */
+ PokeBA0 (devc, BA0_MIDCR, MIDCR_RXE | MIDCR_RIE);
+ }
+
+ if (mode & OPEN_WRITE)
+ {
+ /* enable MIDI transmit enable without interrupt mode */
+ PokeBA0 (devc, BA0_MIDCR, MIDCR_TXE);
+ }
+ PokeBA0 (devc, BA0_HICR, HICR_IEV | HICR_CHGM);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+cs461x_midi_close (int dev, int mode)
+{
+ cs461x_devc *devc = (cs461x_devc *) midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+/* Reset the device*/
+ PokeBA0 (devc, BA0_MIDCR, 0x10);
+ PokeBA0 (devc, BA0_MIDCR, 0x00);
+ devc->midi_opened = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static int
+cs461x_midi_out (int dev, unsigned char midi_byte)
+{
+ cs461x_devc *devc = (cs461x_devc *) midi_devs[dev]->devc;
+ unsigned char uart_stat;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ uart_stat = PeekBA0 (devc, BA0_MIDSR);
+
+/* Check if Transmit buffer full flag is set - if so return */
+ if ((uart_stat & MIDSR_TBF))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+/* Now put the MIDI databyte in the write port */
+ PokeBA0 (devc, BA0_MIDWP, midi_byte);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+cs461x_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t cs461x_midi_driver = {
+ cs461x_midi_open,
+ cs461x_midi_close,
+ cs461x_midi_ioctl,
+ cs461x_midi_out
+};
+
+static int
+init_cs461x (cs461x_devc * devc)
+{
+
+ int my_mixer, my_mixer2, i;
+ unsigned int ulCount = 0;
+ unsigned int ulStatus = 0;
+ unsigned int tmp;
+ int first_dev = 0;
+ int adev;
+ oss_native_word phaddr;
+
+/****************BEGIN HARDWARE INIT*****************/
+ /*
+ * 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.
+ */
+ PokeBA0 (devc, BA0_CLKCR1, 0x0);
+ PokeBA0 (devc, BA0_SERMC1, 0x0);
+ oss_udelay (1000);
+ /*
+ * 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.
+ */
+ if (devc->dual_codec)
+ PokeBA0 (devc, BA0_SERACC,
+ SERACC_HSP | SERACC_TWO_CODECS | SERACC_CODEC_TYPE_2_0);
+ else
+ PokeBA0 (devc, BA0_SERACC, SERACC_HSP | SERACC_CODEC_TYPE_1_03); /* AC97 1.03 */
+
+ /*
+ * 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.
+ */
+ PokeBA0 (devc, BA0_ACCTL, 1);
+ oss_udelay (10000);
+ PokeBA0 (devc, BA0_ACCTL, 0);
+ oss_udelay (10000);
+ PokeBA0 (devc, BA0_ACCTL, ACCTL_RSTN);
+ /*
+ * 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.
+ */
+ PokeBA0 (devc, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
+
+ /*
+ * 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).
+ */
+ oss_udelay (500000);
+ /*
+ * Set the serial port timing configuration, so that
+ * the clock control circuit gets its clock from the correct place.
+ */
+ PokeBA0 (devc, BA0_SERMC1, SERMC1_PTC_AC97);
+ oss_udelay (500000);
+ /*
+ * 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.
+ */
+ PokeBA0 (devc, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ);
+ PokeBA0 (devc, BA0_PLLM, 0x3a);
+ PokeBA0 (devc, BA0_CLKCR2, CLKCR2_PDIVS_8);
+
+ /*
+ * Power up the PLL.
+ */
+ PokeBA0 (devc, BA0_CLKCR1, CLKCR1_PLLP);
+
+ /*
+ * Wait until the PLL has stabilized.
+ */
+ oss_udelay (100000);
+ /*
+ * Turn on clocking of the core so that we can setup the serial ports.
+ */
+ tmp = PeekBA0 (devc, BA0_CLKCR1) | CLKCR1_SWCE;
+ PokeBA0 (devc, BA0_CLKCR1, tmp);
+
+ /* Clear the FIFOs */
+ clear_serial_fifo (devc);
+ /* PokeBA0 (devc, 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.
+ */
+ PokeBA0 (devc, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN);
+ PokeBA0 (devc, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN);
+ PokeBA0 (devc, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
+
+ PokeBA0 (devc, BA0_SERC7, SERC7_ASDI2EN);
+ PokeBA0 (devc, BA0_SERC3, 0);
+ PokeBA0 (devc, BA0_SERC4, 0);
+ PokeBA0 (devc, BA0_SERC5, 0);
+ PokeBA0 (devc, BA0_SERC6, 0);
+
+ oss_udelay (100000);
+
+
+ /* Wait for the codec ready signal from the AC97 codec. */
+ for (ulCount = 0; ulCount < 1000; ulCount++)
+ {
+ /*
+ * First, lets wait a short while to let things settle out a bit,
+ * and to prevent retrying the read too quickly.
+ */
+ oss_udelay (10000);
+ /*
+ * Read the AC97 status register to see if we've seen a CODEC READY
+ * signal from the AC97 codec.
+ */
+ ulStatus = PeekBA0 (devc, BA0_ACSTS);
+ if (ulStatus & ACSTS_CRDY)
+ break;
+ }
+
+ if (!(ulStatus & ACSTS_CRDY))
+ {
+ cmn_err (CE_WARN, "Initialize() Never read Codec Ready from AC97.\n");
+ return 0;
+ }
+
+ if (devc->dual_codec)
+ {
+ for (ulCount = 0; ulCount < 1000; ulCount++)
+ {
+ /*
+ *
+ * First, lets wait a short while to let things settle out a bit,
+ * and to prevent retrying the read too quickly.
+ *
+ */
+ oss_udelay (10000);
+ /*
+ * Read the AC97 status register to see if we've seen a CODEC READY
+ * signal from the AC97 codec.
+ */
+ ulStatus = PeekBA0 (devc, BA0_ACSTS2);
+ if (ulStatus & ACSTS_CRDY)
+ break;
+ }
+
+ if (!(ulStatus & ACSTS_CRDY))
+ {
+ cmn_err (CE_WARN,
+ "Initialize() Never read Codec Ready from second AC97.\n");
+ }
+ }
+ /*
+ * Assert the vaid frame signal so that we can start sending commands
+ * to the AC97 codec.
+ */
+ PokeBA0 (devc, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
+ /*
+ * Wait until we've sampled input slots 3 and 4 as valid, meaning that
+ * the codec is pumping ADC data across the AC-link.
+ */
+ for (ulCount = 0; ulCount < 1000; ulCount++)
+ {
+ /*
+ * First, lets wait a short while to let things settle out a bit,
+ * and to prevent retrying the read too quickly.
+ */
+ oss_udelay (10000);
+ /*
+ * Read the input slot valid register and see if input slots 3 and
+ * 4 are valid yet.
+ */
+ ulStatus = PeekBA0 (devc, BA0_ACISV);
+ if ((ulStatus & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
+ break;
+ }
+ /*
+ * Make sure we sampled valid input slots 3 and 4. If not, then return
+ * an error.
+ */
+ if ((ulStatus & (ACISV_ISV3 | ACISV_ISV4)) != (ACISV_ISV3 | ACISV_ISV4))
+ cmn_err (CE_WARN, "Initialize(%x) Never sampled ISV3 & ISV4 from AC97.\n",
+ (int) ulStatus);
+ /*
+ * 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.
+ */
+ PokeBA0 (devc, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
+
+ /* Reset the Processor */
+ cs461x_reset_processor (devc);
+ /* Now download the image */
+ install_ucode (devc);
+
+ devc->processor_started = 0;
+
+ /* Save the play and capture parameters and write 0 to stop DMA */
+ devc->PCTL = READ1L (BA1_PCTL) & 0xFFFF0000;
+ WRITE1L (BA1_PCTL, devc->PCTL & 0x0000FFFF);
+ devc->CCTL = READ1L (BA1_CCTL) & 0x0000FFFF;
+ WRITE1L (BA1_CCTL, devc->CCTL & 0xFFFF0000);
+
+ /*
+ * Enable interrupts on the part.
+ */
+ PokeBA0 (devc, BA0_HICR, HICR_IEV | HICR_CHGM);
+
+ ulStatus = READ1L (BA1_PFIE);
+ ulStatus &= ~0x0000f03f;
+ WRITE1L (BA1_PFIE, ulStatus); /* playback interrupt enable */
+
+ ulStatus = READ1L (BA1_CIE);
+ ulStatus &= ~0x0000003f;
+ ulStatus |= 0x00000001;
+ WRITE1L (BA1_CIE, ulStatus); /* capture interrupt enable */
+
+/****** END OF HARDWARE INIT *****/
+
+ my_mixer =
+ ac97_install (&devc->ac97devc, "CS461x AC97 Mixer", ac97_read, ac97_write,
+ devc, devc->osdev);
+
+ if (my_mixer >= 0)
+ {
+ devc->mixer_dev = my_mixer;
+ if (devc->subsysid == 0x5053) /* SantaCruz has dual codec */
+ {
+ my_mixer2 =
+ ac97_install (&devc->ac97devc2, "CS4630 AC97 Secondary",
+ ac97_read2, ac97_write2, devc, devc->osdev);
+ if (my_mixer2 >= 0)
+ {
+ devc->mixer2_dev = my_mixer2;
+ ac97_write2 (devc, BA0_AC97_6CH_VOL_C_LFE, 0x7FFF);
+ ac97_write2 (devc, BA0_AC97_6CH_VOL_SURROUND, 0x7FFF);
+ }
+ }
+ }
+ else
+ return 0;
+
+ /* Turn on amp on the CS4297 on TB/Videologic */
+ if (devc->subsysid == 0x5053)
+ {
+ unsigned short u16PinConfig, u16LogicType, u16ValidSlots, u16Idx;
+ unsigned short u16Status = 0;
+ int i;
+
+
+ ac97_write (devc, 0x26, ac97_read (devc, 0x26) | 0x8000);
+#if 0
+ /* Set SPDIF */
+ PokeBA0 (devc, BA0_ASER_MASTER, 1); /*ASER_MASTER_ME */
+ WRITE1L (0x8049, 0x00000001);
+#endif
+ /*
+ * Set GPIO pin's 7 and 8 so that they are configured for output.
+ */
+ u16PinConfig = ac97_read2 (devc, BA0_AC97_GPIO_PIN_CONFIG);
+ u16PinConfig &= 0x27F;
+ ac97_write2 (devc, BA0_AC97_GPIO_PIN_CONFIG, u16PinConfig);
+
+ /*
+ * Set GPIO pin's 7 and 8 so that they are compatible with CMOS logic.
+ */
+ u16LogicType = ac97_read2 (devc, BA0_AC97_GPIO_PIN_TYPE);
+ u16LogicType &= 0x27F;
+ ac97_write2 (devc, BA0_AC97_GPIO_PIN_TYPE, u16LogicType);
+
+ u16ValidSlots = PeekBA0 (devc, BA0_ACOSV);
+ u16ValidSlots |= 0x200;
+ PokeBA0 (devc, BA0_ACOSV, u16ValidSlots);
+
+ /*
+ * Fill slots 12 with the correct value for the GPIO pins.
+ */
+ for (u16Idx = 0x90; u16Idx <= 0x9F; u16Idx++)
+ {
+
+ /*
+ * 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.
+ */
+ PokeBA0 (devc, BA0_SERBWP, 0x1800);
+
+ /*
+ * Make sure the previous FIFO write operation has completed.
+ */
+ for (i = 0; i < 5; i++)
+ {
+ u16Status = PeekBA0 (devc, BA0_SERBST);
+ if (!(u16Status & SERBST_WBSY))
+ {
+ break;
+ }
+ oss_udelay (10000);
+ }
+
+ /*
+ * Write the serial port FIFO index.
+ */
+ PokeBA0 (devc, BA0_SERBAD, u16Idx);
+
+ /*
+ * Tell the serial port to load the new value into the FIFO location.
+ */
+ PokeBA0 (devc, BA0_SERBCM, SERBCM_WRC);
+ }
+ }
+ /* Hercules Game Theater Amp */
+ if (devc->subsysid == 0x1681)
+ {
+ PokeBA0 (devc, BA0_EGPIODR, EGPIODR_GPOE2); /* enable EGPIO2 output */
+ PokeBA0 (devc, BA0_EGPIOPTR, EGPIOPTR_GPPT2); /* open-drain on output */
+
+ }
+
+#ifdef USE_SG
+ devc->play_sgbuf =
+ (unsigned int *) CONTIG_MALLOC (devc->osdev, 4096, MEMLIMIT_32BITS,
+ &phaddr, devc->play_sgbuf_dma_handle);
+ if (devc->play_sgbuf == NULL)
+ {
+ cmn_err (CE_WARN,
+ "cs461x: Failed to allocate play scatter/gather buffer.\n");
+ return 0;
+ }
+ devc->play_sgbuf_phys = phaddr;
+#endif
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ char tmp_name[100];
+ cs461x_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE;
+
+ if (i == 0)
+ {
+ strcpy (tmp_name, devc->chip_name);
+ caps |= ADEV_DUPLEX;
+ }
+ else
+ {
+ strcpy (tmp_name, devc->chip_name);
+ caps |= ADEV_DUPLEX | ADEV_SHADOW;
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &cs461x_audio_driver,
+ sizeof (audiodrv_t),
+ caps,
+ AFMT_S16_LE | AFMT_U8, devc, -1)) < 0)
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->min_block = 4096;
+ audio_engines[adev]->max_block = 4096;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ portc->open_mode = 0;
+ portc->audiodev = adev;
+ portc->audio_enabled = 0;
+ portc->trigger_bits = 0;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+
+ }
+
+#ifndef sparc
+ devc->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "CS461x",
+ "CS461x MIDI Port", &cs461x_midi_driver,
+ sizeof (midi_driver_t),
+ 0, devc, devc->osdev);
+#endif
+ devc->midi_opened = 0;
+ return 1;
+}
+
+int
+oss_cs461x_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision, pci_irq_inta;
+ unsigned short pci_command, vendor, device;
+ unsigned int ioaddr;
+ int err;
+ cs461x_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered CS461x probe routine\n"));
+#if 0
+ if (cs461x_clkrun_fix)
+ while ((osdev = (pci_find_class (0x680 << 8, osdev))))
+
+ {
+ unsigned char pp;
+ unsigned int port, control;
+ unsigned short vendor, device;
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != 0x8086 || device != 0x7113)
+ continue;
+
+ pci_read_config_byte (osdev, 0x41, &pp);
+ port = pp << 8;
+ control = INW (devc->osdev, port + 0x10);
+ OUTW (devc->osdev, control | 0x2000, port + 0x10);
+ oss_udelay (100);
+ OUTW (devc->osdev, control & ~0x2000, port + 0x10);
+ }
+#endif
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != CRYSTAL_VENDOR_ID || device != CRYSTAL_CS461x_ID)
+ return 0;
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->open_mode = 0;
+
+ oss_pci_byteswap (osdev, 1);
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_byte (osdev, PCI_INTERRUPT_LINE + 1, &pci_irq_inta);
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &ioaddr);
+ devc->bar0addr = ioaddr;
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_1, &ioaddr);
+ devc->bar1addr = ioaddr;
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_VENDOR_ID, &devc->subsysid);
+
+ switch (device)
+ {
+ case CRYSTAL_CS461x_ID:
+ devc->chip_name = "Crystal CS461x";
+ break;
+
+ case CRYSTAL_CS4610_ID:
+ devc->chip_name = "Crystal CS4610";
+ break;
+
+ case CRYSTAL_CS4615_ID:
+ devc->chip_name = "Crystal CS4615";
+ break;
+
+ default:
+ devc->chip_name = "CrystalPCI";
+ }
+
+ if (devc->subsysid == 0x5053)
+ {
+ devc->chip_name = "Crystal CS4630";
+ devc->dual_codec = 1;
+ }
+
+ /* activate the device enable bus master/memory space */
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ if ((devc->bar0addr == 0) || (devc->bar1addr == 0))
+ {
+ cmn_err (CE_WARN, "Undefined MEMORY I/O address.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS.\n");
+ return 0;
+ }
+
+ /* Map the shared memory area */
+ devc->bar0virt =
+ (unsigned int *) MAP_PCI_MEM (devc->osdev, 0, devc->bar0addr, 0x2000);
+ devc->bar1virt =
+ (unsigned int *) MAP_PCI_MEM (devc->osdev, 1, devc->bar1addr, 0x40000);
+ devc->dwRegister0 = (unsigned int *) devc->bar0virt;
+ devc->wRegister0 = (unsigned short *) devc->bar0virt;
+ devc->bRegister0 = (unsigned char *) devc->bar0virt;
+ devc->dwRegister1 = (unsigned int *) devc->bar1virt;
+ devc->wRegister1 = (unsigned short *) devc->bar1virt;
+ devc->bRegister1 = (unsigned char *) devc->bar1virt;
+
+ devc->irq = pci_irq_line;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, cs461xintr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+
+ return init_cs461x (devc); /*Detected */
+}
+
+
+int
+oss_cs461x_detach (oss_device_t * osdev)
+{
+ cs461x_devc *devc = (cs461x_devc *) osdev->devc;
+
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ PokeBA0 (devc, BA0_HICR, 0x02); /*enable intena */
+ cs461x_reset_processor (devc);
+#ifdef USE_SG
+ CONTIG_FREE (devc->osdev, devc->play_sgbuf, 4096, devc->play_sgbuf_dma_handle);
+#endif
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+
+ UNMAP_PCI_MEM (devc->osdev, 0, devc->bar0addr, devc->bar0virt, 0x2000);
+ UNMAP_PCI_MEM (devc->osdev, 1, devc->bar1addr, devc->bar1virt, 0x40000);
+
+ devc->bar0addr = 0;
+ devc->bar1addr = 0;
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_cs461x/oss_cs461x.man b/kernel/drv/oss_cs461x/oss_cs461x.man
new file mode 100644
index 0000000..11edced
--- /dev/null
+++ b/kernel/drv/oss_cs461x/oss_cs461x.man
@@ -0,0 +1,24 @@
+NAME
+oss_cs461x - Cirrus Logic CS461x/CS4280 audio driver.
+
+DESCRIPTION
+Open Sound System driver for Crystal Semiconductor (Cirrus Logic) CS4280 and
+461x, audio controllers.
+
+CS4280 device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo playback/recording
+ o 8KHz to 48Khz sample rate.
+
+OPTIONS
+o cs461x_clk_run_fix=0|1 (feature not used anylonger)
+Certain IBM Thinkpads required the CLK_RUN bit flipped in order to wake up
+the audio device.
+
+
+FILES
+CONFIGFILEPATH/oss_cs461x.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_digi96/.devices b/kernel/drv/oss_digi96/.devices
new file mode 100644
index 0000000..84196cc
--- /dev/null
+++ b/kernel/drv/oss_digi96/.devices
@@ -0,0 +1,4 @@
+oss_digi96 pci10ee,3fc0 RME Digi96
+oss_digi96 pci10ee,3fc1 RME Digi96/8
+oss_digi96 pci10ee,3fc2 RME Digi96/8 PRO
+oss_digi96 pci10ee,3fc3 RME Digi96/8 PAD
diff --git a/kernel/drv/oss_digi96/.name b/kernel/drv/oss_digi96/.name
new file mode 100644
index 0000000..8b0b06c
--- /dev/null
+++ b/kernel/drv/oss_digi96/.name
@@ -0,0 +1 @@
+RME Digi96
diff --git a/kernel/drv/oss_digi96/oss_digi96.c b/kernel/drv/oss_digi96/oss_digi96.c
new file mode 100644
index 0000000..6a93285
--- /dev/null
+++ b/kernel/drv/oss_digi96/oss_digi96.c
@@ -0,0 +1,1097 @@
+/*
+ * Purpose: Driver for RME Digi96 family
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_digi96_cfg.h"
+#include "oss_pci.h"
+
+#define RME_VENDOR_ID2 0x10ee
+#define RME_DIGI96 0x3fc0
+#define RME_DIGI96_8 0x3fc1
+#define RME_DIGI96_PRO 0x3fc2
+#define RME_DIGI96_PAD 0x3fc3
+
+#define MAX_AUDIO_CHANNEL 2
+
+/*
+ * Control register pCTRL1
+ */
+#define CTRL1_STARTPLAY 0x00000001
+#define CTRL1_STARTREC 0x00000002
+#define CTRL1_GAIN 0x0000000c
+#define CTRL1_MODE24_PLAY 0x00000010
+#define CTRL1_MODE24_REC 0x00000020
+#define CTRL1_PLAYBM 0x00000040
+#define CTRL1_RECBM 0x00000080
+#define CTRL1_ADAT 0x00000100
+#define CTRL1_FREQ 0x00000600
+#define CTRL1_FREQ32 0x00000200
+#define CTRL1_FREQ44 0x00000400
+#define CTRL1_FREQ48 0x00000600
+#define CTRL1_DS 0x00000800
+#define CTRL1_PRO 0x00001000
+#define CTRL1_EMP 0x00002000
+#define CTRL1_SEL 0x00004000
+#define CTRL1_MASTER 0x00008000
+#define CTRL1_PD 0x00010000
+#define CTRL1_INPUTSEL 0x00060000
+#define CTRL1_INPUTSHIFT 17
+#define CTRL1_THRU 0x07f80000
+#define CTRL1_AC3 0x08000000
+#define CTRL1_MONITOR 0x30000000
+#define CTRL1_ISEL 0x40000000
+#define CTRL1_IDIS 0x80000000
+
+/*
+ * Control register pCTRL2
+ */
+#define CTRL2_WSEL 0x00000001
+#define CTRL2_ANALOG 0x00000002 /* PAD only */
+#define CTRL2_FREQAD 0x0000001c /* PAD */
+#define CTRL2_PD2 0x00000020
+#
+/* Next ones are only for new Digi96/8Pro (blue board) and PAD */
+#define CTRL2_DAC_EN 0x00000040
+#define CTRL2_CLATCH 0x00000080
+#define CTRL2_CCLK 0x00000100
+#define CTRL2_CDATA 0x00000200
+/*
+ * For reads from the pPLAYPOS and pRECPOS registers
+ */
+
+#define POS_PLAYIRQ 0x80000000
+#define POS_AUTOSYNC 0x40000000
+#define POS_FBITS 0x38000000
+#define POS_FSHIFT 27
+#define POS_ERF 0x04000000
+#define POS_CONSTANT11 0x03000000
+#define POS_LOCK 0x00800000
+#define POS_DEVID 0x00600000
+#define POS_CONSTANT000 0x008c0000
+#define POS_TOUT 0x00020000
+#define POS_RECIRQ 0x00010000
+#define POS_ADDR 0x000fffff
+
+typedef struct digi96_portc
+{
+ int open_mode;
+ int audio_dev;
+ int channels, bits;
+ int speed, speedsel;
+ int trigger_bits;
+}
+digi96_portc;
+
+typedef struct digi96_devc
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+
+ char *chip_name;
+ int have_adat;
+ int have_analog;
+ int mode;
+#define MD_SPDIF 0
+#define MD_AES 1
+#define MD_ADAT 2
+
+ oss_native_word physaddr;
+ char *linaddr;
+ unsigned int *pPLAYBUF;
+ unsigned int *pRECBUF;
+ unsigned int *pCTRL1, ctrl1_bits;
+ unsigned int *pCTRL2, ctrl2_bits;
+ unsigned int *pPLAYACK;
+ unsigned int *pRECACK;
+ unsigned int *pPLAYPOS;
+ unsigned int *pRECPOS;
+ unsigned int *pRESETPLAY;
+ unsigned int *pRESETREC;
+
+ int irq;
+
+ digi96_portc portc[MAX_AUDIO_CHANNEL];
+ int open_mode;
+#define TY_READ 0
+#define TY_WRITE 1
+#define TY_BOTH 2
+ int mixer_dev;
+
+ int master;
+ int external_locked;
+ int input_source;
+ int doublespeed;
+ int adatrate;
+}
+digi96_devc;
+
+static int fbit_tab[8] = {
+ 0, 0, 0, 96000, 88200, 48000, 44100, 32000
+};
+
+
+static void
+write_ctrl1 (digi96_devc * devc, unsigned int ctrl)
+{
+ devc->ctrl1_bits = ctrl;
+
+ PCI_WRITEL (devc->osdev, devc->pCTRL1, ctrl);
+}
+
+static void
+write_ctrl2 (digi96_devc * devc, unsigned int ctrl)
+{
+ devc->ctrl2_bits = ctrl;
+
+ PCI_WRITEL (devc->osdev, devc->pCTRL2, ctrl);
+}
+
+static int
+digi96intr (oss_device_t * osdev)
+{
+ int i, serviced = 0;
+ unsigned int playstat, recstat;
+ digi96_devc *devc = (digi96_devc *) osdev->devc;
+ digi96_portc *portc;
+
+ playstat = PCI_READL (devc->osdev, devc->pPLAYPOS);
+ recstat = PCI_READL (devc->osdev, devc->pRECPOS);
+
+ for (i = 0; i < 2; i++)
+ {
+ portc = &devc->portc[i];
+
+ if (playstat & POS_PLAYIRQ)
+ {
+ serviced = 1;
+ PCI_WRITEL (devc->osdev, devc->pPLAYACK, 0);
+ oss_audio_outputintr (portc->audio_dev, 0);
+ }
+
+ if (recstat & POS_RECIRQ)
+ {
+ serviced = 1;
+ PCI_WRITEL (devc->osdev, devc->pRECACK, 0);
+ oss_audio_inputintr (portc->audio_dev, 0);
+ }
+ }
+ return serviced;
+}
+
+
+/***********************************
+ * Audio routines
+ ***********************************/
+
+static int
+digi96_set_rate (int dev, int arg)
+{
+ digi96_devc *devc = audio_engines[dev]->devc;
+ digi96_portc *portc = audio_engines[dev]->portc;
+
+ static int speed_table[6] = { 32000, 44100, 48000, 64000, 88200, 96000 };
+ int i, best = 2, dif, bestdif = 0x7fffffff;
+
+ if (arg)
+ {
+ if (devc->external_locked || (portc->open_mode & OPEN_READ))
+ arg = portc->speed; /* Speed locked to input */
+
+ for (i = 0; i < 6; i++)
+ {
+ if (arg == speed_table[i]) /* Exact match */
+ {
+ portc->speed = arg;
+ portc->speedsel = i;
+ return portc->speed;
+ }
+
+ dif = arg - speed_table[i];
+ if (dif < 0)
+ dif *= -1;
+ if (dif <= bestdif)
+ {
+ best = i;
+ bestdif = dif;
+ }
+
+ }
+
+ portc->speed = speed_table[best];
+ portc->speedsel = best;
+ }
+
+ return portc->speed;
+}
+
+static short
+digi96_set_channels (int dev, short arg)
+{
+ digi96_portc *portc = audio_engines[dev]->portc;
+ digi96_devc *devc = audio_engines[dev]->devc;
+
+ if (arg == 0)
+ return portc->channels;
+
+ if (devc->mode == MD_ADAT)
+ arg = 8;
+ else
+ arg = 2;
+ return portc->channels = arg;
+}
+
+static unsigned int
+digi96_set_format (int dev, unsigned int arg)
+{
+ digi96_portc *portc = audio_engines[dev]->portc;
+
+ if (arg != AFMT_S16_LE && arg != AFMT_AC3 && arg != AFMT_S32_LE)
+ return portc->bits;
+
+ return portc->bits = arg;
+}
+
+/*ARGSUSED*/
+static int
+digi96_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void digi96_trigger (int dev, int state);
+
+static void
+digi96_reset (int dev)
+{
+ digi96_trigger (dev, 0);
+}
+
+static void
+digi96_reset_input (int dev)
+{
+ digi96_portc *portc = audio_engines[dev]->portc;
+ digi96_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+digi96_reset_output (int dev)
+{
+ digi96_portc *portc = audio_engines[dev]->portc;
+ digi96_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+static int
+verify_input (digi96_devc * devc, digi96_portc * portc)
+{
+ int i, status, savedstatus;
+ int tmp;
+ oss_native_word flags;
+
+ tmp = devc->ctrl1_bits & ~CTRL1_INPUTSEL;
+ tmp |= (devc->input_source & 0x3) << CTRL1_INPUTSHIFT;
+ write_ctrl1 (devc, tmp);
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ i = 0;
+ status = PCI_READL (devc->osdev, devc->pRECPOS);
+
+ if (status & POS_LOCK) /* ADAT input */
+ {
+ devc->mode = MD_ADAT;
+ portc->channels = 8;
+
+ switch (devc->adatrate)
+ {
+ case 0: /* Autodetect */
+ if (status & POS_AUTOSYNC)
+ portc->speed = 48000;
+ else
+ portc->speed = 44100;
+ DDB (cmn_err
+ (CE_WARN, "ADAT input detected, sr=%d Hz\n", portc->speed));
+ break;
+
+ case 1:
+ portc->speed = 44100;
+ break;
+
+ case 2:
+ portc->speed = 48000;
+ break;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 1;
+ }
+
+ while (i++ < 100 && status & POS_ERF)
+ {
+ oss_udelay (10);
+ status = PCI_READL (devc->osdev, devc->pRECPOS);
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ savedstatus = status;
+
+ status &= POS_ERF;
+
+ if (status)
+ cmn_err (CE_WARN, "Cannot sync with the input signal\n");
+ else
+ {
+ int fbits = (savedstatus & POS_FBITS) >> POS_FSHIFT;
+ portc->speed = fbit_tab[fbits];
+ DDB (cmn_err
+ (CE_WARN, "digi96: Measured input sampling rate is %d\n",
+ portc->speed));
+ }
+ return devc->external_locked = !status;
+}
+
+/*ARGSUSED*/
+static int
+digi96_open (int dev, int mode, int open_flags)
+{
+ unsigned int tmp;
+ digi96_portc *portc = audio_engines[dev]->portc;
+ digi96_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode != 0 || (devc->open_mode & mode)) /* Busy? */
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ devc->open_mode |= mode;
+ portc->audio_dev = dev;
+ portc->trigger_bits = 0;
+
+ tmp = devc->ctrl1_bits;
+ devc->external_locked = 0;
+ if (devc->master)
+ tmp |= CTRL1_MASTER;
+ else
+ {
+ tmp &= ~CTRL1_MASTER;
+ devc->external_locked = 1;
+ }
+ write_ctrl1 (devc, tmp);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (devc->external_locked || (portc->open_mode & OPEN_READ))
+ verify_input (devc, portc);
+
+ if (devc->mode == MD_ADAT)
+ {
+ audio_engines[dev]->min_block = 8 * 1024;
+ audio_engines[dev]->max_block = 8 * 1024;
+ audio_engines[dev]->caps &= ~DSP_CH_MASK;
+ audio_engines[dev]->caps |= DSP_CH_MULTI;
+ audio_engines[dev]->min_channels = 8;
+ audio_engines[dev]->max_channels = 8;
+ write_ctrl1 (devc, devc->ctrl1_bits & ~CTRL1_ISEL);
+ }
+ else
+ {
+ audio_engines[dev]->min_block = 2 * 1024;
+ audio_engines[dev]->max_block = 2 * 1024;
+ audio_engines[dev]->caps &= ~DSP_CH_MASK;
+ audio_engines[dev]->caps |= DSP_CH_STEREO;
+ audio_engines[dev]->min_channels = 2;
+ audio_engines[dev]->max_channels = 2;
+ write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_ISEL);
+ }
+
+ return 0;
+}
+
+static void
+digi96_close (int dev, int mode)
+{
+ digi96_devc *devc = audio_engines[dev]->devc;
+ digi96_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ digi96_reset (dev);
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->open_mode = 0;
+ devc->open_mode &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static void
+digi96_output_block (int dev, oss_native_word ptr, int count, int fragsize,
+ int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+digi96_start_input (int dev, oss_native_word ptr, int count, int fragsize,
+ int intrflag)
+{
+}
+
+static void
+digi96_trigger (int dev, int state)
+{
+ digi96_devc *devc = audio_engines[dev]->devc;
+ digi96_portc *portc = audio_engines[dev]->portc;
+ unsigned int tmp = devc->ctrl1_bits;
+
+ state &= portc->open_mode;
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ tmp |= CTRL1_STARTPLAY;
+ else
+ tmp &= ~CTRL1_STARTPLAY;
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ tmp |= CTRL1_STARTREC;
+ else
+ tmp &= ~CTRL1_STARTREC;
+ }
+
+ portc->trigger_bits = state;
+ write_ctrl1 (devc, tmp);
+}
+
+/*ARGSUSED*/
+static int
+digi96_prepare_for_output (int dev, int bsize, int bcount)
+{
+ digi96_devc *devc = audio_engines[dev]->devc;
+ digi96_portc *portc = audio_engines[dev]->portc;
+
+ int cmd = devc->ctrl1_bits;
+ int doublespeed;
+
+ PCI_WRITEL (devc->osdev, devc->pRESETPLAY, 0);
+ if (devc->master)
+ cmd |= CTRL1_MASTER;
+ else
+ cmd &= ~CTRL1_MASTER;
+ if (portc->channels == 8)
+ cmd |= CTRL1_ADAT;
+ else
+ cmd &= ~CTRL1_ADAT;
+ write_ctrl1 (devc, cmd);
+
+ if (!devc->master)
+ {
+ if (!verify_input (devc, portc))
+ return OSS_EIO;
+ }
+
+ cmd = devc->ctrl1_bits;
+ doublespeed = (portc->speedsel > 3);
+
+ cmd &= ~(CTRL1_DS | CTRL1_FREQ);
+ if (doublespeed)
+ cmd |= CTRL1_DS;
+
+ cmd |= ((portc->speedsel % 3) + 1) << 9;
+ write_ctrl1 (devc, cmd);
+
+ if (doublespeed != devc->doublespeed)
+ {
+ devc->doublespeed = doublespeed;
+ write_ctrl1 (devc, cmd | CTRL1_PD); /* Reset the DAC */
+ }
+
+ if (portc->bits == AFMT_AC3)
+ write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_AC3 | CTRL1_PD);
+ else
+ {
+ if (portc->bits == AFMT_S32_LE)
+ {
+ write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_MODE24_PLAY);
+ }
+ else
+ write_ctrl1 (devc, devc->ctrl1_bits & ~(CTRL1_MODE24_PLAY));
+
+ write_ctrl1 (devc, devc->ctrl1_bits & ~(CTRL1_AC3 | CTRL1_PD)); /* Unmute DAC */
+ }
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+digi96_prepare_for_input (int dev, int bsize, int bcount)
+{
+ digi96_devc *devc = audio_engines[dev]->devc;
+ digi96_portc *portc = audio_engines[dev]->portc;
+
+ int cmd = devc->ctrl1_bits;
+
+ if (portc->channels == 8)
+ cmd |= CTRL1_ADAT;
+ else
+ cmd &= ~CTRL1_ADAT;
+
+ if (portc->bits == AFMT_S32_LE)
+ cmd |= CTRL1_MODE24_REC;
+ else
+ cmd &= ~CTRL1_MODE24_REC;
+ write_ctrl1 (devc, cmd);
+
+ if (!verify_input (devc, portc))
+ return OSS_EIO;
+ PCI_WRITEL (devc->osdev, devc->pRESETREC, 0);
+
+ return 0;
+}
+
+static int
+digi96_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ digi96_devc *devc = audio_engines[dev]->devc;
+
+ if (direction == OPEN_WRITE)
+ {
+ dmap->dmabuf = (void *) devc->pPLAYBUF;
+ dmap->dmabuf_phys = (oss_native_word) devc->pPLAYBUF;
+ }
+ else
+ {
+ dmap->dmabuf = (void *) devc->pRECBUF;
+ dmap->dmabuf_phys = (oss_native_word) devc->pRECBUF;
+ }
+ dmap->buffsize = 64 * 1024;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+digi96_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ dmap->dmabuf = NULL;
+ dmap->dmabuf_phys = 0;
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+digi96_setup_fragments (int dev, dmap_p dmap, int direction)
+{
+ /* Make sure the whole sample RAM is covered by the buffer */
+ dmap->nfrags = dmap->buffsize / dmap->fragment_size;
+}
+
+static audiodrv_t digi96_driver = {
+ digi96_open,
+ digi96_close,
+ digi96_output_block,
+ digi96_start_input,
+ digi96_ioctl,
+ digi96_prepare_for_input,
+ digi96_prepare_for_output,
+ digi96_reset,
+ NULL,
+ NULL,
+ digi96_reset_input,
+ digi96_reset_output,
+ digi96_trigger,
+ digi96_set_rate,
+ digi96_set_format,
+ digi96_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ digi96_alloc_buffer,
+ digi96_free_buffer,
+ NULL,
+ NULL,
+ NULL, /* digi96_get_buffer_pointer */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ digi96_setup_fragments
+};
+
+/*ARGSUSED*/
+static int
+digi96_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ if (cmd == SOUND_MIXER_PRIVATE1) /* Bogus testing */
+ {
+ int val;
+
+ val = *arg;
+ return *arg = val;
+ }
+ if (cmd == SOUND_MIXER_READ_DEVMASK ||
+ cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC)
+ return *arg = 0;
+
+ if (cmd == SOUND_MIXER_READ_VOLUME || cmd == SOUND_MIXER_READ_PCM)
+ return *arg = 100 | (100 << 8);
+ if (cmd == SOUND_MIXER_WRITE_VOLUME || cmd == SOUND_MIXER_WRITE_PCM)
+ return *arg = 100 | (100 << 8);
+ return OSS_EINVAL;
+}
+
+static mixer_driver_t digi96_mixer_driver = {
+ digi96_mixer_ioctl
+};
+
+static int
+digi96_set_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ digi96_devc *devc = mixer_devs[dev]->devc;
+ unsigned int tmp;
+
+ if (ctrl < 0)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ switch (ctrl)
+ {
+ case 1:
+ return !!devc->master;
+ break;
+
+ case 2:
+ return devc->input_source;
+ break;
+
+ case 3:
+ return !!(devc->ctrl1_bits & CTRL1_SEL);
+ break;
+
+ case 4:
+ return devc->mode;
+ break;
+
+ case 5:
+ return !!(devc->ctrl2_bits & CTRL2_WSEL);
+ break;
+
+ case 6:
+ return !!(devc->ctrl1_bits & CTRL1_EMP);
+ break;
+
+ case 7:
+ return !!(devc->ctrl1_bits & CTRL1_AC3);
+ break;
+
+ case 8:
+ return devc->adatrate;
+ break;
+ }
+
+ return OSS_EINVAL;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case 1:
+ devc->master = !!value;
+ return !!value;
+ break;
+
+ case 2:
+ if (value < 0 || value > 3)
+ return OSS_EINVAL;
+
+ devc->input_source = value;
+ return value;
+ break;
+
+ case 3:
+ tmp = devc->ctrl1_bits;
+ if (value)
+ tmp |= CTRL1_SEL;
+ else
+ {
+ tmp &= ~(CTRL1_SEL | CTRL1_MASTER);
+ devc->master = 0;
+ }
+ write_ctrl1 (devc, tmp);
+ return value;
+ break;
+
+ case 4:
+ if (value > 2 || (!devc->have_adat && value > 1))
+ return OSS_EINVAL;
+
+ devc->mode = value;
+ return value;
+ break;
+
+ case 5:
+ if (value)
+ {
+ write_ctrl2 (devc, devc->ctrl2_bits | CTRL2_WSEL);
+ return 1;
+ }
+
+ write_ctrl2 (devc, devc->ctrl2_bits & ~CTRL2_WSEL);
+ return 0;
+ break;
+
+ case 6:
+ if (value)
+ {
+ write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_EMP);
+ return 1;
+ }
+
+ write_ctrl1 (devc, devc->ctrl1_bits & ~CTRL1_EMP);
+ return 0;
+ break;
+
+ case 7:
+ if (value)
+ {
+ write_ctrl1 (devc, devc->ctrl1_bits | CTRL1_AC3);
+ return 1;
+ }
+
+ write_ctrl1 (devc, devc->ctrl1_bits & ~CTRL1_AC3);
+ return 0;
+ break;
+
+ case 8:
+ if (value > 2)
+ value = 2;
+ if (value < 0)
+ value = 0;
+
+ return devc->adatrate = value;
+ break;
+
+ }
+
+ return OSS_EINVAL;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+digi96_mix_init (int dev)
+{
+ /* digi96_devc *devc = mixer_devs[dev]->devc; */
+ int group, err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "DIGI96")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 4, digi96_set_control,
+ MIXT_ENUM,
+ "DIGI96_MODE", 3,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, digi96_set_control,
+ MIXT_ENUM,
+ "DIGI96_SYNC", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, digi96_set_control,
+ MIXT_ENUM,
+ "DIGI96_INPUT", 4,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, digi96_set_control,
+ MIXT_ENUM,
+ "DIGI96_SEL", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 5, digi96_set_control,
+ MIXT_ONOFF,
+ "DIGI96_WORLDCLK", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 6, digi96_set_control,
+ MIXT_ONOFF,
+ "DIGI96_EMPH", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+#if 0
+ if ((err = mixer_ext_create_control (dev, group,
+ 7, digi96_set_control,
+ MIXT_ENUM,
+ "DIGI96_DATA", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+#endif
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 8, digi96_set_control,
+ MIXT_ENUM,
+ "DIGI96_ADATRATE", 3,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ mixer_ext_set_strings (dev, err, "AUTO 44100 48000", 0);
+
+ return 0;
+}
+
+static int
+attach_channel (digi96_devc * devc, int chnum, char *name,
+ audiodrv_t * drv, int type)
+{
+ int adev;
+ digi96_portc *portc;
+ int opts = ADEV_DUPLEX | ADEV_COLD | ADEV_AUTOMODE | ADEV_NOVIRTUAL;
+
+ if (chnum < 0 || chnum >= MAX_AUDIO_CHANNEL)
+ return 0;
+
+ if (type == TY_BOTH)
+ opts = ADEV_SHADOW;
+
+ portc = &devc->portc[chnum];
+
+ devc->master = 1;
+ devc->input_source = 0;
+ devc->doublespeed = 0;
+ devc->external_locked = 0;
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ name,
+ drv,
+ sizeof (audiodrv_t),
+ opts,
+ AFMT_AC3 | AFMT_S16_LE | AFMT_S32_LE,
+ devc, -1)) < 0)
+ {
+ return 0;
+ }
+
+ audio_engines[adev]->mixer_dev = devc->mixer_dev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->caps |= DSP_CH_STEREO;
+ audio_engines[adev]->min_block = 2 * 1024;
+ audio_engines[adev]->max_block = 2 * 1024;
+ audio_engines[adev]->min_rate = 32000;
+ audio_engines[adev]->max_rate = 96000;
+ portc->open_mode = 0;
+ devc->open_mode = 0;
+ portc->audio_dev = adev;
+
+ portc->speed = 48000;
+ portc->speedsel = 3;
+ portc->bits = AFMT_S16_LE;
+ portc->channels = 2;
+ return 1;
+}
+
+int
+init_digi96 (digi96_devc * devc)
+{
+ int my_mixer;
+ int ret;
+
+ if ((my_mixer = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "RME Digi96 Control panel",
+ &digi96_mixer_driver,
+ sizeof (mixer_driver_t), devc)) < 0)
+ {
+
+ devc->mixer_dev = -1;
+ return 0;
+ }
+ else
+
+ {
+ mixer_devs[my_mixer]->priority = -1; /* Don't use as the default mixer */
+ devc->mixer_dev = my_mixer;
+ mixer_ext_set_init_fn (my_mixer, digi96_mix_init, 20);
+ }
+
+ ret = attach_channel (devc, 0, devc->chip_name, &digi96_driver, 0);
+ if (ret > 0)
+ {
+ ret =
+ attach_channel (devc, 1, devc->chip_name, &digi96_driver, TY_BOTH);
+ }
+
+/*
+ * Set some defaults
+ */
+ write_ctrl2 (devc, 0);
+ write_ctrl1 (devc, CTRL1_ISEL | CTRL1_FREQ48 | CTRL1_PD); /* Reset DAC */
+ write_ctrl1 (devc, CTRL1_ISEL | CTRL1_FREQ48 | CTRL1_MASTER | CTRL1_SEL);
+ write_ctrl2 (devc, CTRL2_DAC_EN); /* Soft unmute the DAC (blue PRO boards) */
+ return ret;
+}
+
+
+int
+oss_digi96_attach (oss_device_t * osdev)
+{
+ digi96_devc *devc;
+ unsigned char pci_irq_line, pci_revision /*, pci_latency */ ;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ int err;
+
+ DDB (cmn_err (CE_WARN, "Entered Digi96 detect routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+ if (vendor != RME_VENDOR_ID2 ||
+ (device != RME_DIGI96_PRO &&
+ device != RME_DIGI96_PAD &&
+ device != RME_DIGI96 && device != RME_DIGI96_8))
+
+ return 0;
+
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &pci_ioaddr);
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "BAR0 not initialized by BIOS\n");
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->physaddr = pci_ioaddr;
+
+ devc->have_adat = 0;
+ devc->have_analog = 0;
+ devc->mode = MD_SPDIF;
+
+ switch (device)
+ {
+ case RME_DIGI96:
+ devc->chip_name = "RME Digi96";
+ break;
+
+ case RME_DIGI96_8:
+ devc->chip_name = "RME Digi96/8";
+ devc->have_adat = 1;
+ break;
+
+ case RME_DIGI96_PRO:
+ devc->have_adat = 1;
+ if (pci_revision < 2)
+ {
+ devc->chip_name = "RME Digi96/8 PRO (green)";
+ }
+ else
+ {
+ devc->chip_name = "RME Digi96/8 PRO (blue)";
+ }
+ break;
+
+ case RME_DIGI96_PAD:
+ devc->have_adat = 1;
+ devc->have_analog = 1;
+ devc->chip_name = "RME Digi96/8 PAD";
+ break;
+ }
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ devc->linaddr =
+ (char *) MAP_PCI_MEM (devc->osdev, 0, devc->physaddr, 0x60000);
+ if (devc->linaddr == NULL)
+ {
+ cmn_err (CE_WARN, "Can't map PCI registers (0x%08lx)\n",
+ devc->physaddr);
+ return 0;
+ }
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, digi96intr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+
+ devc->pPLAYBUF = (unsigned int *) devc->linaddr;
+ devc->pRECBUF = (unsigned int *) (devc->linaddr + 0x10000);
+ devc->pCTRL1 = (unsigned int *) (devc->linaddr + 0x20000);
+ devc->pCTRL2 = (unsigned int *) (devc->linaddr + 0x20004);
+ devc->pPLAYACK = (unsigned int *) (devc->linaddr + 0x20008);
+ devc->pRECACK = (unsigned int *) (devc->linaddr + 0x2000c);
+ devc->pPLAYPOS = (unsigned int *) (devc->linaddr + 0x20000);
+ devc->pRECPOS = (unsigned int *) (devc->linaddr + 0x30000);
+ devc->pRESETPLAY = (unsigned int *) (devc->linaddr + 0x4fffc);
+ devc->pRESETREC = (unsigned int *) (devc->linaddr + 0x5fffc);
+
+ return init_digi96 (devc); /* Detected */
+}
+
+int
+oss_digi96_detach (oss_device_t * osdev)
+{
+ digi96_devc *devc = (digi96_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ write_ctrl2 (devc, 0); /* Soft mute */
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+
+ UNMAP_PCI_MEM (devc->osdev, 0, devc->physaddr, devc->linaddr, 0x60000);
+
+ oss_unregister_device (devc->osdev);
+
+ return 1;
+
+}
diff --git a/kernel/drv/oss_digi96/oss_digi96.man b/kernel/drv/oss_digi96/oss_digi96.man
new file mode 100644
index 0000000..f13fb66
--- /dev/null
+++ b/kernel/drv/oss_digi96/oss_digi96.man
@@ -0,0 +1,63 @@
+NAME
+oss_digi96 - RME Digi96 professional audio driver.
+
+DESCRIPTION
+Audio driver for the RME Digi96 family of profressional audio controllers.
+- Only 16 and 24/32 bit audio formats are supported.
+- All Digi96 family members support 32kHz, 44.1kHz, 48kHz, 64kHz, 88.2kHz and
+96kHz. sampling rates.
+
+
+MIXER PANEL
+
+Note! For recording you need to set digi96.sync to INTERNAL and the values
+ of digi96.mode and digi96.input to match your studio setup. Otherwise
+ recordings will fail with I/O error.
+
+There are several settings that can be changed using the ossmix program
+shipped with OSS. Note that some features don't work with all Digi96
+family members. For example ADAT mode is not supported by the base
+model.
+
+o digi96.mode <SPDIF|AESEBU|ADAT>:
+This setting controls the output mode which can be S/PDIF (consumer),
+AES/EBU (professional) or ADAT. The input mode is detected automatically.
+If ADAT input is detected the output mode will be switched to ADAT
+automatically (this doesn't work in the other direction).
+
+o digi96.sync <EXTERNAL|INTERNAL>:
+This setting tells if the playback sampling rate is based on the internal
+oscillator or the sample rate detected in the input port. See also the
+definition of the digi96.worldclk setting.
+
+o digi96.input <OPTICAL|COAXIAL|INTERNAL|XLR>: Selects the active input.
+
+o digi96.sel <BYPASS|NORMAL>:
+When set to BYPASS the input signal will be routed directly to the
+output (also sets digi96.sync automatically to EXTERNAL). In this mode
+audio data written to /dev/dsp will be muted.
+
+o digi96.worldclk ON|OFF:
+Setting this control to ON will enable the optional worldclock input as
+the sample rate source (overrides the digi96.sync setting).
+
+o digi96.emph ON|OFF:
+Enables/disables the de-emphasis option on the analog (monitor) output
+connector.
+
+o digi96.data <AUDIO|AC3>:
+Specifies if the output signal is audio or AC3 data (sets the non-audio
+bit in the channel status data).
+
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_digi96.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
+
+
diff --git a/kernel/drv/oss_emu10k1x/.config b/kernel/drv/oss_emu10k1x/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_emu10k1x/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_emu10k1x/.devices b/kernel/drv/oss_emu10k1x/.devices
new file mode 100644
index 0000000..7565a33
--- /dev/null
+++ b/kernel/drv/oss_emu10k1x/.devices
@@ -0,0 +1 @@
+oss_emu10k1x pci1102,6 Creative Sound Blaster 5.1 (Dell)
diff --git a/kernel/drv/oss_emu10k1x/.name b/kernel/drv/oss_emu10k1x/.name
new file mode 100644
index 0000000..af96a5f
--- /dev/null
+++ b/kernel/drv/oss_emu10k1x/.name
@@ -0,0 +1 @@
+Creative Sound Blaster 5.1 (Dell)
diff --git a/kernel/drv/oss_emu10k1x/.params b/kernel/drv/oss_emu10k1x/.params
new file mode 100644
index 0000000..19c1a21
--- /dev/null
+++ b/kernel/drv/oss_emu10k1x/.params
@@ -0,0 +1,5 @@
+int emu10k1x_spdif_enable=0;
+/*
+ * Enable SPDIF on Combo Jack
+ * Values: 1=Enable 0=Disable Default: 0
+ */
diff --git a/kernel/drv/oss_emu10k1x/oss_emu10k1x.c b/kernel/drv/oss_emu10k1x/oss_emu10k1x.c
new file mode 100644
index 0000000..5a66ff7
--- /dev/null
+++ b/kernel/drv/oss_emu10k1x/oss_emu10k1x.c
@@ -0,0 +1,1243 @@
+/*
+ * Purpose: Driver for Creative emu10k1x audio controller
+ *
+ * This device is usually called as SB Live! 5.1 and it has been used in
+ * some Dell machines. However it has nothing to do with the original
+ * SB Live! design.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_emu10k1x_cfg.h"
+#include "oss_pci.h"
+#include "ac97.h"
+#include "midi_core.h"
+#include "remux.h"
+
+#define PCI_VENDOR_ID_CREATIVE 0x1102
+#define PCI_DEVICE_ID_CREATIVE_EMU10K1X 0x0006
+
+#define USE_DUALBUF
+
+/*
+ * Indirect registers
+ */
+
+#define PTBA 0x000
+#define PTBS 0x001
+#define PTCA 0x002
+#define PFBA 0x004
+#define PFBS 0x005
+#define CPFA 0x006
+#define PFEA 0x007
+#define CPCAV 0x008
+#define RFBA 0x010
+#define RFBS 0x011
+#define CRFA 0x012
+#define CRCAV 0x013
+#define CDL 0x020
+#define CDR 0x030
+#define SA 0x040
+#define EA_aux 0x041
+#define SCS0 0x042
+#define SCS1 0x043
+#define SCS2 0x044
+#define SPC 0x045
+#define WMARK 0x046
+#define MUDAT 0x047
+#define MUCMD 0x048
+#define RCD 0x050
+
+/* Interrupt bits
+ */
+
+#define INTR_RFF (1<<19)
+#define INTR_RFH (1<<16)
+#define INTR_PFF (1<<11)
+#define INTR_PFH (1<<8)
+#define INTR_EAI (1<<29)
+#define INTR_PCI 1
+#define INTR_UART_RX 2
+#define INTR_UART_TX 4
+#define INTR_AC97 0x10
+#define INTR_GPIO 0x40
+
+#define PLAY_INTR_ENABLE (INTR_PFF|INTR_PFH)
+#define RECORD_INTR_ENABLE (INTR_RFF|INTR_RFH)
+
+#define EMU_BUFSIZE 32*1024
+#define MAX_PORTC 3
+
+extern int emu10k1x_spdif_enable;
+
+typedef struct
+{
+ int audio_dev;
+ int port_number;
+ int open_mode;
+ int trigger_bits;
+ int audio_enabled;
+ int channels;
+ int fmt;
+ int speed;
+ unsigned char *playbuf, *recbuf;
+ oss_native_word playbuf_phys, recbuf_phys;
+
+ oss_dma_handle_t playbuf_dma_handle, recbuf_dma_handle;
+
+ int play_cfrag, play_chalf, rec_cfrag, rec_chalf;
+}
+emu10k1x_portc;
+
+typedef struct
+{
+ oss_device_t *osdev;
+ int loaded;
+ oss_native_word base;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+ int irq;
+ char *card_name;
+ unsigned int subvendor;
+
+ int mixer_dev;
+ ac97_devc ac97devc;
+
+/*
+ * UART
+ */
+ oss_midi_inputbyte_t midi_input_intr;
+ int midi_opened, midi_disabled;
+ volatile unsigned char input_byte;
+ int midi_dev;
+ int mpu_attached;
+
+ emu10k1x_portc portc[MAX_PORTC];
+
+}
+emu10k1x_devc;
+
+
+static void emu10k1xuartintr (emu10k1x_devc * devc);
+
+static unsigned int
+read_reg (emu10k1x_devc * devc, int reg, int chn)
+{
+ oss_native_word flags;
+ unsigned int val;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTL (devc->osdev, (reg << 16) | (chn & 0xffff), devc->base + 0x00); /* Pointer */
+ val = INL (devc->osdev, devc->base + 0x04); /* Data */
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+/* printk("Read reg %03x (ch %d) = %08x\n", reg, chn, val); */
+ return val;
+}
+
+static void
+write_reg (emu10k1x_devc * devc, int reg, int chn, unsigned int value)
+{
+ oss_native_word flags;
+
+ /* printk("Write reg %03x (ch %d) = %08x\n", reg, chn, value); */
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTL (devc->osdev, (reg << 16) | (chn & 0xffff), devc->base + 0x00); /* Pointer */
+ OUTL (devc->osdev, value, devc->base + 0x04); /* Data */
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+#if 0
+ {
+ char tmp[100];
+ int ok = 1;
+ sprintf (tmp, "@w%d %04x/%s %x", chn, reg, emu_regname (reg, &ok), value);
+ if (ok)
+ oss_do_timing (tmp);
+ }
+#endif
+}
+
+static void
+recording_intr (emu10k1x_devc * devc, emu10k1x_portc * portc, int status)
+{
+#ifdef USE_DUALBUF
+ unsigned char *frombuf, *tobuf;
+ dmap_p dmap = audio_engines[portc->audio_dev]->dmap_in;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ /* "Auto sync" the play half counters with the device */
+ if (status & INTR_RFH) /* 1st half completed */
+ portc->rec_chalf = 0; /* Reuse the first half */
+ else
+ portc->rec_chalf = 1; /* Reuse the second half */
+
+ tobuf = dmap->dmabuf + (portc->rec_cfrag * dmap->fragment_size);
+ frombuf = portc->recbuf + (portc->rec_chalf * dmap->fragment_size);
+
+ memcpy (tobuf, frombuf, dmap->fragment_size);
+
+/* printk("rec %d/%d\n", portc->rec_cfrag, portc->rec_chalf); */
+ portc->rec_cfrag = (portc->rec_cfrag + 1) % dmap->nfrags;
+ portc->rec_chalf = !portc->rec_chalf;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+#endif
+ oss_audio_inputintr (portc->audio_dev, 0);
+}
+
+static void
+playback_intr (emu10k1x_devc * devc, emu10k1x_portc * portc,
+ unsigned int status)
+{
+#ifdef USE_DUALBUF
+ dmap_p dmap = audio_engines[portc->audio_dev]->dmap_out;
+ unsigned char *frombuf, *tobuf;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ /* "Auto sync" the play half counters with the device */
+ if (status & (INTR_PFH << portc->port_number)) /* 1st half completed */
+ {
+ portc->play_chalf = 0; /* Reuse the first half */
+ }
+ else
+ {
+ portc->play_chalf = 1; /* Reuse the second half */
+ }
+
+
+ frombuf = dmap->dmabuf + (portc->play_cfrag * dmap->fragment_size);
+ tobuf = portc->playbuf + (portc->play_chalf * dmap->fragment_size);
+
+ memcpy (tobuf, frombuf, dmap->fragment_size);
+
+/* printk("play %d/%d\n", portc->play_cfrag, portc->play_chalf); */
+ portc->play_cfrag = (portc->play_cfrag + 1) % dmap->nfrags;
+ portc->play_chalf = !portc->play_chalf;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+#endif
+ oss_audio_outputintr (portc->audio_dev, 0);
+}
+
+static int
+emu10k1xintr (oss_device_t * osdev)
+{
+ int serviced = 0;
+ unsigned int status;
+ emu10k1x_devc *devc = (emu10k1x_devc *) osdev->devc;
+ int portnum;
+
+ status = INL (devc->osdev, devc->base + 0x08);
+
+ if (status & 0x2) /* MIDI RX interrupt */
+ {
+ emu10k1xuartintr (devc);
+ serviced = 1;
+ }
+
+ if (status & (INTR_PFF | INTR_PFH | INTR_RFF | INTR_RFH))
+ {
+ for (portnum = 0; portnum < 3; portnum++)
+ {
+ emu10k1x_portc *portc = &devc->portc[portnum];
+
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT) &&
+ (status & ((INTR_PFF | INTR_PFH) << portc->port_number)))
+ playback_intr (devc, portc, status);
+ if ((portc->trigger_bits & PCM_ENABLE_INPUT) &&
+ (status & (INTR_RFF | INTR_RFH)))
+ recording_intr (devc, portc, status);
+
+ }
+ serviced = 1;
+ OUTL (devc->osdev, status, devc->base + 0x08); /* Acknowledge */
+ }
+ return serviced;
+}
+
+/*ARGSUSED*/
+static int
+emu10k1x_set_rate (int dev, int arg)
+{
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+
+ return portc->speed = 48000;
+}
+
+static short
+emu10k1x_set_channels (int dev, short arg)
+{
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->channels;
+
+ if (portc->open_mode & OPEN_READ)
+ return portc->channels = 2;
+
+ if (arg != 1 && arg != 2)
+ return portc->channels = 2;
+ return portc->channels = arg;
+}
+
+static unsigned int
+emu10k1x_set_format (int dev, unsigned int arg)
+{
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->fmt;
+
+ if (arg == AFMT_AC3)
+ if ((portc->open_mode & OPEN_READ) || !emu10k1x_spdif_enable)
+ arg = AFMT_S16_LE;
+
+ if (arg != AFMT_AC3 && arg != AFMT_S16_LE)
+ return portc->fmt = AFMT_S16_LE;
+
+ return portc->fmt = arg;
+}
+
+/*ARGSUSED*/
+static int
+emu10k1x_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void emu10k1x_trigger (int dev, int state);
+
+static void
+emu10k1x_reset (int dev)
+{
+ emu10k1x_trigger (dev, 0);
+}
+
+static void
+emu10k1x_reset_input (int dev)
+{
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+ emu10k1x_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+emu10k1x_reset_output (int dev)
+{
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+ emu10k1x_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+emu10k1x_open (int dev, int mode, int open_flags)
+{
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+ emu10k1x_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ portc->audio_enabled = ~mode;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+emu10k1x_close (int dev, int mode)
+{
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+
+ emu10k1x_trigger (dev, 0);
+ portc->open_mode = 0;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+emu10k1x_output_block (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+emu10k1x_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+
+static void
+emu10k1x_trigger (int dev, int state)
+{
+ emu10k1x_devc *devc = audio_engines[dev]->devc;
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+ int tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ /* Enable play channel and set mono/stereo mode */
+ tmp = read_reg (devc, SA, 0);
+ tmp &= ~(0x10000 << portc->port_number);
+ if (portc->channels == 1)
+ tmp |= (0x10000 << portc->port_number);
+ tmp |= 1 << portc->port_number;
+ write_reg (devc, SA, 0, tmp);
+
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ /* Disable Play channel */
+ tmp = read_reg (devc, SA, 0);
+ tmp &= ~(1 << portc->port_number);
+ write_reg (devc, SA, 0, tmp);
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ /* Enable Rec Channel */
+ tmp = read_reg (devc, SA, 0);
+ tmp |= 0x100;
+ write_reg (devc, SA, 0, tmp);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+ /* disable channel */
+ tmp = read_reg (devc, SA, 0);
+ tmp &= ~0x100;
+ write_reg (devc, SA, 0, tmp);
+ }
+ }
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+emu10k1x_prepare_for_input (int dev, int bsize, int bcount)
+{
+ emu10k1x_devc *devc = audio_engines[dev]->devc;
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_in;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+#ifndef USE_DUALBUF
+ /* Single buffering mode */
+ dmap->nfrags = 2;
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+ write_reg (devc, RFBA, 0, dmap->dmabuf_phys);
+ write_reg (devc, RFBS, 0, (dmap->bytes_in_use - 4) << 16);
+#else
+ write_reg (devc, RFBA, 0, portc->recbuf_phys);
+ write_reg (devc, RFBS, 0, (dmap->fragment_size * 2) << 16);
+#endif
+ memset (portc->recbuf, 0, EMU_BUFSIZE);
+ portc->rec_cfrag = portc->rec_chalf = 0;
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+emu10k1x_prepare_for_output (int dev, int bsize, int bcount)
+{
+ emu10k1x_devc *devc = audio_engines[dev]->devc;
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_out;
+ unsigned int tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->fmt == AFMT_AC3)
+ portc->channels = 2;
+
+ write_reg (devc, PTBA, portc->port_number, 0);
+ write_reg (devc, PTBS, portc->port_number, 0);
+ write_reg (devc, PTCA, portc->port_number, 0);
+
+ write_reg (devc, CPFA, portc->port_number, 0);
+ write_reg (devc, PFEA, portc->port_number, 0);
+ write_reg (devc, CPCAV, portc->port_number, 0);
+
+#ifndef USE_DUALBUF
+ /* Single buffering mode */
+ dmap->nfrags = 2;
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+ write_reg (devc, PFBA, portc->port_number, dmap->dmabuf_phys);
+ write_reg (devc, PFBS, portc->port_number, (dmap->bytes_in_use - 4) << 16);
+#else
+ /* Dual buffering mode */
+ write_reg (devc, PFBA, portc->port_number, portc->playbuf_phys);
+ write_reg (devc, PFBS, portc->port_number, (dmap->fragment_size * 2) << 16);
+#endif
+ memset (portc->playbuf, 0, EMU_BUFSIZE);
+ portc->play_cfrag = portc->play_chalf = 0;
+
+ if (portc->fmt == AFMT_AC3)
+ {
+ tmp = read_reg (devc, EA_aux, 0);
+ tmp &= ~(0x03 << (portc->port_number * 2));
+ if (portc->port_number == 2)
+ tmp &= ~0x10000;
+ write_reg (devc, EA_aux, 0, tmp);
+ write_reg (devc, SCS0 + portc->port_number, 0, 0x02108506); /* Data */
+ }
+ else
+ {
+ tmp = read_reg (devc, EA_aux, 0);
+ tmp |= (0x03 << (portc->port_number * 2));
+
+ if (emu10k1x_spdif_enable == 0)
+ if (portc->port_number == 2)
+ tmp |= 0x10000;
+
+ write_reg (devc, EA_aux, 0, tmp);
+ write_reg (devc, SCS0 + portc->port_number, 0, 0x02108504); /* Audio */
+ }
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+emu10k1x_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ int err;
+ emu10k1x_devc *devc = audio_engines[dev]->devc;
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+ oss_native_word phaddr;
+
+ if ((err = oss_alloc_dmabuf (dev, dmap, direction)) < 0)
+ return err;
+
+ if (direction == OPEN_READ)
+ {
+ if (portc->port_number == 0)
+ {
+ portc->recbuf =
+ CONTIG_MALLOC (devc->osdev, EMU_BUFSIZE, MEMLIMIT_32BITS, &phaddr, portc->recbuf_dma_handle);
+ if (portc->recbuf == NULL)
+ return OSS_ENOMEM;
+ portc->recbuf_phys = phaddr;
+ }
+ }
+ else
+ {
+ portc->playbuf =
+ CONTIG_MALLOC (devc->osdev, EMU_BUFSIZE, MEMLIMIT_32BITS, &phaddr, portc->playbuf_dma_handle);
+ if (portc->playbuf == NULL)
+ return OSS_ENOMEM;
+ portc->playbuf_phys = phaddr;
+ }
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+emu10k1x_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ emu10k1x_devc *devc = audio_engines[dev]->devc;
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+
+ oss_free_dmabuf (dev, dmap);
+
+ if (portc->playbuf != NULL)
+ {
+ CONTIG_FREE (devc->osdev, portc->playbuf, EMU_BUFSIZE, portc->playbuf_dma_handle);
+ portc->playbuf = NULL;
+ }
+
+ if (portc->recbuf != NULL)
+ {
+ CONTIG_FREE (devc->osdev, portc->recbuf, EMU_BUFSIZE, portc->recbuf_dma_handle);
+ portc->recbuf = NULL;
+ }
+
+ return 0;
+}
+
+#if 0
+static int
+emu10k1x_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ unsigned int p = 0;
+
+ emu10k1x_devc *devc = audio_engines[dev]->devc;
+ emu10k1x_portc *portc = audio_engines[dev]->portc;
+
+ dmap = audio_engines[dev]->dmap_out;
+ if (direction == PCM_ENABLE_OUTPUT)
+ p = read_reg (devc, CPFA, portc->port_number);
+
+ if (direction == PCM_ENABLE_INPUT)
+ p = read_reg (devc, CRFA, portc->port_number);
+
+ p %= (dmap->bytes_in_use - 4);
+
+ return p;
+}
+#endif
+
+static audiodrv_t emu10k1x_audio_driver = {
+ emu10k1x_open,
+ emu10k1x_close,
+ emu10k1x_output_block,
+ emu10k1x_start_input,
+ emu10k1x_ioctl,
+ emu10k1x_prepare_for_input,
+ emu10k1x_prepare_for_output,
+ emu10k1x_reset,
+ NULL,
+ NULL,
+ emu10k1x_reset_input,
+ emu10k1x_reset_output,
+ emu10k1x_trigger,
+ emu10k1x_set_rate,
+ emu10k1x_set_format,
+ emu10k1x_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ emu10k1x_alloc_buffer,
+ emu10k1x_free_buffer,
+ NULL,
+ NULL,
+ NULL /*emu10k1x_get_buffer_pointer */
+};
+
+
+#define MUADAT 0x47
+#define MUACMD 0x48
+#define MUASTAT 0x48
+
+static __inline__ int
+emu10k1xuart_status (emu10k1x_devc * devc)
+{
+ return read_reg (devc, MUASTAT, 0);
+}
+
+#define input_avail(devc) (!(emu10k1xuart_status(devc)&INPUT_AVAIL))
+#define output_ready(devc) (!(emu10k1xuart_status(devc)&OUTPUT_READY))
+static void
+emu10k1xuart_cmd (emu10k1x_devc * devc, unsigned char cmd)
+{
+ write_reg (devc, MUACMD, 0, cmd);
+}
+
+static __inline__ int
+emu10k1xuart_read (emu10k1x_devc * devc)
+{
+ return read_reg (devc, MUADAT, 0);
+}
+
+static __inline__ void
+emu10k1xuart_write (emu10k1x_devc * devc, unsigned char byte)
+{
+ write_reg (devc, MUADAT, 0, byte);
+}
+
+#define OUTPUT_READY 0x40
+#define INPUT_AVAIL 0x80
+#define MPU_ACK 0xFE
+#define MPU_RESET 0xFF
+#define UART_MODE_ON 0x3F
+
+static int reset_emu10k1xuart (emu10k1x_devc * devc);
+static void enter_uart_mode (emu10k1x_devc * devc);
+
+static void
+emu10k1xuart_input_loop (emu10k1x_devc * devc)
+{
+ while (input_avail (devc))
+ {
+ unsigned char c = emu10k1xuart_read (devc);
+
+ if (c == MPU_ACK)
+ devc->input_byte = c;
+ else if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr (devc->midi_dev, c);
+ }
+}
+
+static void
+emu10k1xuartintr (emu10k1x_devc * devc)
+{
+ emu10k1xuart_input_loop (devc);
+}
+
+/*ARGSUSED*/
+static int
+emu10k1xuart_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ emu10k1x_devc *devc = (emu10k1x_devc *) midi_devs[dev]->devc;
+
+ if (devc->midi_opened)
+ {
+ return OSS_EBUSY;
+ }
+
+ while (input_avail (devc))
+ emu10k1xuart_read (devc);
+
+ devc->midi_input_intr = inputbyte;
+ devc->midi_opened = mode;
+ enter_uart_mode (devc);
+ devc->midi_disabled = 0;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+emu10k1xuart_close (int dev, int mode)
+{
+ emu10k1x_devc *devc = (emu10k1x_devc *) midi_devs[dev]->devc;
+
+ reset_emu10k1xuart (devc);
+ oss_udelay (10);
+ enter_uart_mode (devc);
+ reset_emu10k1xuart (devc);
+ devc->midi_opened = 0;
+}
+
+
+static int
+emu10k1xuart_out (int dev, unsigned char midi_byte)
+{
+ int timeout;
+ emu10k1x_devc *devc = (emu10k1x_devc *) midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ /*
+ * Test for input since pending input seems to block the output.
+ */
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (input_avail (devc))
+ emu10k1xuart_input_loop (devc);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ /*
+ * Sometimes it takes about 130000 loops before the output becomes ready
+ * (After reset). Normally it takes just about 10 loops.
+ */
+
+ for (timeout = 130000; timeout > 0 && !output_ready (devc); timeout--);
+
+ if (!output_ready (devc))
+ {
+ cmn_err (CE_WARN, "UART timeout - Device not responding\n");
+ devc->midi_disabled = 1;
+ reset_emu10k1xuart (devc);
+ enter_uart_mode (devc);
+ return 1;
+ }
+
+ emu10k1xuart_write (devc, midi_byte);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+emu10k1xuart_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t emu10k1x_midi_driver = {
+ emu10k1xuart_open,
+ emu10k1xuart_close,
+ emu10k1xuart_ioctl,
+ emu10k1xuart_out
+};
+
+
+static void
+enter_uart_mode (emu10k1x_devc * devc)
+{
+ int ok, timeout;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+
+ devc->input_byte = 0;
+ emu10k1xuart_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 (emu10k1xuart_read (devc) == MPU_ACK)
+ ok = 1;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+
+void
+attach_emu10k1xuart (emu10k1x_devc * devc)
+{
+ enter_uart_mode (devc);
+
+ devc->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "EMU10K1X", "SB P16X UART",
+ &emu10k1x_midi_driver, sizeof (midi_driver_t),
+ 0, devc, devc->osdev);
+ devc->midi_opened = 0;
+}
+
+static int
+reset_emu10k1xuart (emu10k1x_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;
+ emu10k1xuart_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 (emu10k1xuart_read (devc) == MPU_ACK)
+ ok = 1;
+
+ }
+
+
+
+ if (ok)
+ emu10k1xuart_input_loop (devc); /*
+ * Flush input before enabling interrupts
+ */
+
+ return ok;
+}
+
+
+int
+probe_emu10k1xuart (emu10k1x_devc * devc)
+{
+ int ok = 0;
+ oss_native_word flags;
+
+ DDB (cmn_err (CE_CONT, "Entered probe_emu10k1xuart\n"));
+
+ devc->midi_input_intr = NULL;
+ devc->midi_opened = 0;
+ devc->input_byte = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ ok = reset_emu10k1xuart (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (ok)
+ {
+ DDB (cmn_err (CE_CONT, "Reset UART401 OK\n"));
+ }
+ else
+ {
+ DDB (cmn_err
+ (CE_WARN, "Reset UART401 failed (no hardware present?).\n"));
+ DDB (cmn_err
+ (CE_WARN, "mpu401 status %02x\n", emu10k1xuart_status (devc)));
+ }
+
+ DDB (cmn_err (CE_WARN, "emu10k1xuart detected OK\n"));
+ return ok;
+}
+
+void
+unload_emu10k1xuart (emu10k1x_devc * devc)
+{
+ reset_emu10k1xuart (devc);
+}
+
+
+static void
+attach_mpu (emu10k1x_devc * devc)
+{
+ devc->mpu_attached = 1;
+ attach_emu10k1xuart (devc);
+}
+
+
+static int
+emu10k1x_ac97_read (void *devc_, int wAddr)
+{
+ emu10k1x_devc *devc = devc_;
+ int dtemp = 0, i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, wAddr, devc->base + 0x1e);
+ for (i = 0; i < 10000; i++)
+ if (INB (devc->osdev, devc->base + 0x1e) & 0x80)
+ break;
+ dtemp = INW (devc->osdev, devc->base + 0x1c);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return dtemp & 0xffff;
+}
+
+static int
+emu10k1x_ac97_write (void *devc_, int wAddr, int wData)
+{
+ emu10k1x_devc *devc = devc_;
+ int i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, wAddr, devc->base + 0x1e);
+ for (i = 0; i < 10000; i++)
+ if (INB (devc->osdev, devc->base + 0x1e) & 0x80)
+ break;
+ OUTW (devc->osdev, wData, devc->base + 0x1c);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return 0;
+}
+
+static const int bindings[MAX_PORTC] = {
+ DSP_BIND_FRONT,
+ DSP_BIND_SURR,
+ DSP_BIND_CENTER_LFE
+};
+
+static void
+install_audio_devices (emu10k1x_devc * devc)
+{
+ int i;
+ unsigned int tmp;
+ int firstdev = -1;
+ char name[64];
+
+#if 0
+ if (emu10k1x_spdif_enable == 1)
+ n = 2;
+#endif
+
+ /* Enable play interrupts for all 3 channels */
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ tmp = INL (devc->osdev, devc->base + 0x0c);
+ tmp |= PLAY_INTR_ENABLE << i;
+ OUTL (devc->osdev, tmp, devc->base + 0x0c);
+ }
+
+ /* Enable record interrupts */
+ tmp = INL (devc->osdev, devc->base + 0x0c);
+ tmp |= RECORD_INTR_ENABLE;
+ OUTL (devc->osdev, tmp, devc->base + 0x0c);
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ int adev, flags;
+ emu10k1x_portc *portc = &devc->portc[i];
+
+ flags = ADEV_AUTOMODE | ADEV_FIXEDRATE | ADEV_16BITONLY | ADEV_COLD;
+
+ switch (i)
+ {
+ case 0:
+ sprintf (name, "%s (front)", devc->card_name);
+ break;
+ case 1:
+ sprintf (name, "%s (surround)", devc->card_name);
+ break;
+ case 2:
+ if (emu10k1x_spdif_enable == 1)
+ sprintf (name, "%s (SPDIF)", devc->card_name);
+ else
+ sprintf (name, "%s (center/LFE)", devc->card_name);
+ break;
+ }
+
+ if (i == 0)
+ flags |= ADEV_DUPLEX;
+ else
+ flags |= ADEV_NOINPUT;
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ name,
+ &emu10k1x_audio_driver,
+ sizeof (audiodrv_t),
+ flags, AFMT_S16_LE | AFMT_AC3, devc,
+ -1)) < 0)
+ {
+ return;
+ }
+
+ if (i == 0)
+ firstdev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->mixer_dev = devc->mixer_dev;
+ audio_engines[adev]->rate_source = firstdev;
+ audio_engines[adev]->min_rate = 48000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ /*audio_engines[adev]->max_block = EMU_BUFSIZE / 2; *//* Never change this */
+ audio_engines[adev]->fixed_rate = 48000;
+ audio_engines[adev]->binding = bindings[i];
+ audio_engines[adev]->vmix_flags = VMIX_MULTIFRAG;
+ portc->audio_dev = adev;
+ portc->open_mode = 0;
+ portc->port_number = i;
+ portc->channels = 2;
+ portc->fmt = AFMT_S16_LE;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+
+#ifdef USE_REMUX
+ if (firstdev >= 0)
+ {
+ if (emu10k1x_spdif_enable == 1)
+ {
+ sprintf (name, "%s 4.0 output", devc->card_name);
+ remux_install (name, devc->osdev, firstdev, firstdev + 1, -1, -1);
+ }
+ else
+ {
+ sprintf (name, "%s 5.1 output", devc->card_name);
+ remux_install (name, devc->osdev, firstdev, firstdev + 1,
+ firstdev + 2, -1);
+ }
+ }
+#endif
+}
+
+static void
+select_out3_mode (emu10k1x_devc * devc, int mode)
+{
+ /*
+ * Set the out3/spdif combo jack format.
+ * mode0=analog rear/center, 1=spdif
+ */
+
+ if (mode == 0)
+ {
+ write_reg (devc, SPC, 0, 0x00000700);
+ write_reg (devc, EA_aux, 0, 0x0001000f);
+ }
+ else
+ {
+ write_reg (devc, SPC, 0, 0x00000000);
+ write_reg (devc, EA_aux, 0, 0x0000070f);
+ }
+}
+
+int
+oss_emu10k1x_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ unsigned int subvendor;
+ int err;
+ emu10k1x_devc *devc = NULL;
+
+ DDB (cmn_err (CE_WARN, "Entered EMU10K1X probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != PCI_VENDOR_ID_CREATIVE ||
+ device != PCI_DEVICE_ID_CREATIVE_EMU10K1X)
+
+ return 0;
+
+ pci_read_config_dword (osdev, 0x2c, &subvendor);
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->card_name = "Sound Blaster Live (P16X)";
+ devc->subvendor = subvendor;
+
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+ devc->base &= ~0x3;
+
+ devc->irq = pci_irq_line;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->card_name);
+
+ if ((err =
+ oss_register_interrupts (devc->osdev, 0, emu10k1xintr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+
+/*
+ * Init mixer
+ */
+ devc->mixer_dev = ac97_install (&devc->ac97devc, devc->card_name,
+ emu10k1x_ac97_read, emu10k1x_ac97_write,
+ devc, devc->osdev);
+ if (devc->mixer_dev < 0)
+ {
+ cmn_err (CE_WARN, "Mixer install failed - cannot continue\n");
+ return 0;
+ }
+
+ write_reg (devc, SCS0, 0, 0x02108504);
+ write_reg (devc, SCS1, 0, 0x02108504);
+ write_reg (devc, SCS2, 0, 0x02108504);
+ select_out3_mode (devc, emu10k1x_spdif_enable);
+ OUTL (devc->osdev, 0x00000000, devc->base + 0x18); /* GPIO */
+ OUTL (devc->osdev, INTR_PCI | INTR_UART_RX, devc->base + 0x0c);
+ OUTL (devc->osdev, 0x00000009, devc->base + 0x14); /* Enable audio */
+ install_audio_devices (devc);
+ attach_mpu (devc);
+ return 1;
+}
+
+static void
+unload_mpu (emu10k1x_devc * devc)
+{
+ if (devc->mpu_attached)
+ {
+ unload_emu10k1xuart (devc);
+ devc->mpu_attached = 0;
+ }
+}
+
+int
+oss_emu10k1x_detach (oss_device_t * osdev)
+{
+ emu10k1x_devc *devc = (emu10k1x_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ write_reg (devc, SA, 0, 0);
+ OUTL (devc->osdev, 0x00000000, devc->base + 0x0c); /* Interrupt disable */
+ OUTL (devc->osdev, 0x00000001, devc->base + 0x14);
+
+ unload_mpu (devc);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+
+ oss_unregister_device (osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_emu10k1x/oss_emu10k1x.man b/kernel/drv/oss_emu10k1x/oss_emu10k1x.man
new file mode 100644
index 0000000..f3bb3bc
--- /dev/null
+++ b/kernel/drv/oss_emu10k1x/oss_emu10k1x.man
@@ -0,0 +1,27 @@
+NAME
+oss_emu10k1x - Creative Labs P16x (EMU10K1X) driver.
+
+DESCRIPTION
+Open Sound System driver for Creative Labs SBLive 5.1 Dell OEM version
+soundcards. The device has a chipset called the EMU10K1X and is not the same
+as the SBLive EMU10K1/EMU10K2 audio processors found in the SBLive! and Audigy
+soundcards.
+
+EMU10K1X device characteristics:
+ o 8/16/24 bit playback/record
+ o mono/stereo/4/5.1 playback
+ o 8KHz to 192Khz sample rate.
+
+OPTIONS
+o emu10k1x_spdif_enable=<0|1>
+The EMU10K1X has a versa-jack (orange) that can be set as SPDIF output
+or the Side-Surround left/right speakers in a 5.1 setup.
+When set as SPDIF, you can get play PCM/AC3 audio to a Dolby(R) capable
+receiver.
+
+FILES
+CONFIGFILEPATH/oss_emu10k1x.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_envy24/.config b/kernel/drv/oss_envy24/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_envy24/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_envy24/.devices b/kernel/drv/oss_envy24/.devices
new file mode 100644
index 0000000..cc44831
--- /dev/null
+++ b/kernel/drv/oss_envy24/.devices
@@ -0,0 +1,13 @@
+oss_envy24 pci1412,1712 Generic ENVY24 based device
+oss_envy24 pcs1412,d630 M Audio Delta 1010
+oss_envy24 pcs1412,d631 M Audio Delta DiO 2496
+oss_envy24 pcs1412,d632 M Audio Delta 66
+oss_envy24 pcs1412,d633 M Audio Delta 44
+oss_envy24 pcs1412,d634 M Audio Audiophile 2496
+oss_envy24 pcs1412,d635 M Audio Delta TDIF
+oss_envy24 pcs1412,d638 M Audio Delta 410
+oss_envy24 pcs1412,d63b M Audio Delta 1010LT
+oss_envy24 pcs153b,1115 Terratec EWS88MT
+oss_envy24 pcs153b,112b Terratec EWS88D
+oss_envy24 pcs153b,1130 Terratec EWX 24/96
+oss_envy24 pcs153b,1138 Terratec DMX 6Fire
diff --git a/kernel/drv/oss_envy24/.name b/kernel/drv/oss_envy24/.name
new file mode 100644
index 0000000..d9991f3
--- /dev/null
+++ b/kernel/drv/oss_envy24/.name
@@ -0,0 +1 @@
+VIA Envy24 (ICE1712) sound chipset
diff --git a/kernel/drv/oss_envy24/.params b/kernel/drv/oss_envy24/.params
new file mode 100644
index 0000000..d98c9f8
--- /dev/null
+++ b/kernel/drv/oss_envy24/.params
@@ -0,0 +1,80 @@
+int envy24_skipdevs = 2;
+/*
+ * envy24_skipdevs: By default OSS creates an audio device file for each
+ * stereo pair. However it's possible to change OSS to create a device file
+ * for each input/output channel. See also the envy24_force_mono option
+ * if you want to set the card to mono-only mode.
+ * Values: 1 to 8. Default is 2 (stereo mode).
+ *
+ * Note that the application(s) using the device files can request any number
+ * of channels regardless of the envy24_skipdevs option.
+ */
+int envy24_force_mono = 0;
+/*
+ * envy24_force_mono: Forces all device files to work only in mono mode
+ * (to be used together with envy24_skipdevs=1). This option is necessary
+ * with some software packages that otherwise open the devices in stereo mode.
+ * There is no need to use this option with properly implemented applications.
+ * Values: 0 (default) any number of channels can be used, 1 means that
+ * the device files will only be available in mono mode.
+ *
+ * Note that even envy24_force_mono=1 the application can request and get
+ * stereo. In this way both channel signals will be identical.
+ */
+int envy24_swapdevs = 0;
+/*
+ * envy24_swapdevs: By default OSS will create the output device files before
+ * the recording ones. Some applications may expect input devices to be before
+ * the output ones.
+ * Values: 0=outputs before inputs (default), 1=inputs before outputs.
+ */
+int envy24_devmask = 65535;
+/*
+ * envy24_devmask: Selects the device files to be created. By default OSS
+ * will create all available device files. However in some systems it may
+ * be necessary to conserve device numbers.
+ *
+ * Values: The envy24_devmask number is the SUM of the following values:
+ * 1 - Create primary (analog/ADAT/TDIF) outputs
+ * 2 - Create primary (analog/ADAT/TDIF) inputs
+ * 4 - Create S/PDIF outputs
+ * 8 - Create S/PDIF inputs
+ * 16 - Create monitor input device
+ * 32 - Create the "raw" input and output devices.
+ *
+ * For example envy24_devmask=12 (4+8) creates only the S/PDIF devices.
+ * To enable all possible (current or future) device files set envy24_devmask
+ * to 65535 (default).
+ */
+int envy24_realencoder_hack = 0;
+/*
+ * envy24_realencoder_hack: Older versions of realencoder expect a mixer device
+ * for each audio device file. This option makes OSS to create dummy micers to
+ * make realencoder happy.
+ * Values: 0=normal (default), 1=create dmmy mixers.
+ */
+int envy24_gain_sliders = 0;
+/*
+ * envy24_gain_sliders: By default OSS will create the gain controls as
+ * selection controls (+4 dB / CONSUMER / -10 dB) which is ideal for
+ * professional environments. However home users may prefer having volume
+ * sliders instead.
+ * Values: 0=level selectors (default), 1=volume sliders.
+ */
+int envy24_nfrags = 16;
+/*
+ * envy24_nfrags: For normal operation this setting must be 16.
+ */
+int envy24_mixerstyle = 1;
+/*
+ * envy24_mixerstyle: Defines layout of the peak meter and monitor mixer
+ * sections in the control panel.
+ * NOTE! The envy24_skipdevs parameter must be set to 2. Otherwise the
+ * traditional mixer style will be used regardless of the value of
+ * this parameter.
+ * Possible values:
+ * 1=Traditional mixer with separate peak meter and monitor gain sections
+ * (default).
+ * 2=Alternative style with peak meters and monitor gain sliders grouped
+ * together (separate output and input sections).
+ */
diff --git a/kernel/drv/oss_envy24/envy24.h b/kernel/drv/oss_envy24/envy24.h
new file mode 100644
index 0000000..dceac89
--- /dev/null
+++ b/kernel/drv/oss_envy24/envy24.h
@@ -0,0 +1,279 @@
+/*
+ * Purpose: Common definitions for the Envy24 driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "uart401.h"
+
+#define DEV_BUFSIZE (64*1024) /* Buffer size per channel */
+
+#define HW_PLAYBUFFSIZE (10*2048)
+#define HW_RECBUFFSIZE (12*2048)
+#define HW_ALLOCSIZE (24*1024) /* Must be bigger or equal than HW_PLAYBUFFSIZE and HW_RECBUFFSIZE */
+
+typedef struct envy24_auxdrv envy24_auxdrv_t;
+
+typedef struct
+{
+ unsigned int svid;
+ char *product;
+ int nr_outs, nr_ins; /* # of analog channels */
+ int flags;
+#define MF_MAUDIO 0x00000001 /* Made by M Audio */
+#define MF_MIDI1 0x00000002 /* Has MIDI 1 port */
+#define MF_SPDIF 0x00000004 /* Has S/PDIF */
+#define MF_AKMCODEC 0x00000008 /* Has AKM codecs */
+#define MF_WCLOCK 0x00000010 /* Has World clock input */
+#define MF_SPDSELECT 0x00000020 /* Optical+coax S/PDIF */
+#define MF_EWS88 0x00000040 /* Terratec EWS88MT */
+#define MF_AP 0x00000080 /* M Audio Audiophile family */
+#define MF_MIDI2 0x00000100 /* Has MIDI 2 port */
+#define MF_EWX2496 0x00000200 /* Terratec EWX 24/96 */
+#define MF_CONSUMER 0x00000400 /* Force consumer AC97 codec detection */
+#define MF_HOONTECH 0x00000800
+#define MF_D410 0x00001000 /* Delta 410 */
+#define MF_MEEPROM 0x00002000 /* M Audio EEPROM interface */
+#define MF_AC97 0x00004000 /* Consumer AC97 codec */
+ envy24_auxdrv_t *auxdrv;
+ unsigned char *eeprom_data;
+}
+card_spec;
+
+#define ICENSEMBLE_VENDOR_ID 0x1412
+#define ICENSEMBLE_ENVY24_ID 0x1712
+
+#define AKM_A 0x40
+#define AKM_B 0x80
+
+#ifdef USE_LICENSING
+extern int options_data;
+#endif
+
+#define MAX_ODEV 10
+#define MAX_IDEV 12
+
+#ifdef DO_RIAA
+typedef struct
+{
+ int32_t x1, x2, x3;
+ int32_t y1, y2, y3;
+}
+riaa_t;
+#endif
+
+typedef struct
+{
+ int flags;
+#define PORTC_SPDOUT 0x00000001
+#define PORTC_SPDIN 0x00000002
+ int dev;
+ int chnum;
+ int direction;
+#define DIR_INPUT ADEV_NOOUTPUT
+#define DIR_OUTPUT ADEV_NOINPUT
+ int open_mode;
+
+ char name[16];
+
+ int bits, channels;
+ volatile int is_active;
+ volatile int trigger_bits;
+ int pcm_qlen;
+ int riaa_filter;
+#ifdef DO_RIAA
+ riaa_t riaa_parms[12];
+#endif
+}
+envy24_portc;
+
+/*
+ * Hoontech specific structure
+ */
+typedef union
+{
+ struct
+ {
+ unsigned int box:2;
+ unsigned int darear:1;
+ unsigned int id0:2;
+ unsigned int clock0:1;
+ unsigned int res0:2;
+
+ unsigned int ch1:1;
+ unsigned int ch2:1;
+ unsigned int ch3:1;
+ unsigned int id1:2;
+ unsigned int clock1:1;
+ unsigned int res1:2;
+
+ unsigned int ch4:1;
+ unsigned int midiin:1;
+ unsigned int midi1:1;
+ unsigned int id2:2;
+ unsigned int clock2:1;
+ unsigned int res2:2;
+
+ unsigned int midi2:1;
+ unsigned int mute:1;
+ unsigned int insel:1;
+ unsigned int id3:2;
+ unsigned int clock3:1;
+ unsigned int res3:2;
+ }
+ b;
+
+ struct
+ {
+ unsigned int b0:8;
+ unsigned int b1:8;
+ unsigned int b2:8;
+ unsigned int b3:8;
+ }
+ w;
+
+ unsigned int dwVal;
+
+}
+ADSP;
+
+#define _adsp devc->adsp
+/*****************/
+
+typedef struct envy24d_portc
+{
+ int audio_dev;
+ int open_mode;
+ int channels;
+ int direction;
+ int trigger_bits;
+}
+envy24d_portc;
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+ int mpu1_attached, mpu2_attached;
+ oss_native_word ccs_base, mt_base;
+ int irq;
+ card_spec *model_data;
+ envy24_auxdrv_t *auxdrv;
+ int skipdevs; /* envy24_skipdevs option */
+
+ unsigned char eeprom[32];
+
+/*
+ * MT mixer
+ */
+
+ int mixer_dev;
+
+/*
+ * Consumer (AC97) mixer
+ */
+
+ ac97_devc ac97devc;
+ int consumer_mixer_dev;
+ int consumer_ac97_present;
+
+ int nr_outdevs, nr_indevs;
+ int curr_outch, curr_inch;
+ int inportmask, outportmask;
+ envy24_portc play_portc[MAX_ODEV];
+ envy24_portc rec_portc[MAX_IDEV];
+ envy24d_portc direct_portc_in, direct_portc_out;
+ int direct_audio_opened;
+
+ int rec_bufsize, play_bufsize;
+
+ unsigned char *playbuf, *recbuf;
+ int playbuffsize, recbuffsize;
+ oss_native_word playbuf_phys, recbuf_phys;
+ oss_dma_handle_t playbuf_dma_handle, recbuf_dma_handle;
+ int hw_rfragsize, hw_pfragsize, hw_fragsamples, hw_nfrags;
+ volatile int hw_playfrag, hw_recfrag;
+ volatile int active_inputs, active_outputs;
+ volatile int open_inputs, open_outputs;
+ volatile int playback_started, recording_started;
+ volatile int playback_prepared, recording_prepared;
+ int speed, pending_speed_sel, speedbits;
+ int syncsource;
+ int gpio_tmp;
+#define SYNC_INTERNAL 0
+#define SYNC_SPDIF 1
+#define SYNC_WCLOCK 2
+
+ int play_channel_mask, rec_channel_mask;
+ int nr_play_channels, nr_rec_channels;
+ int writeahead;
+
+ int use_src;
+ int ratelock;
+
+/* Spdif parameters */
+ int spdif_pro_mode;
+ unsigned char spdif_cbits[24];
+ int sync_locked;
+ int ac3_mode;
+
+ short akm_gains[0xff];
+ ADSP adsp; /* Hoontech only */
+ uart401_devc uart401devc1;
+ uart401_devc uart401devc2;
+
+ int first_dev;
+}
+envy24_devc;
+
+struct envy24_auxdrv
+{
+ void (*card_init) (envy24_devc * devc);
+ int (*mixer_init) (envy24_devc * devc, int dev, int group);
+ void (*spdif_init) (envy24_devc * devc);
+ void (*spdif_set) (envy24_devc * devc, int ctrl0);
+ int (*spdif_ioctl) (envy24_devc * devc, int dev, unsigned int cmd,
+ ioctl_arg arg);
+ int (*spdif_read_reg) (envy24_devc * devc, int reg);
+ void (*spdif_write_reg) (envy24_devc * devc, int reg, int val);
+ void (*set_rate) (envy24_devc * devc);
+ int (*get_locked_status) (envy24_devc * devc);
+ int (*spdif_mixer_init) (envy24_devc * devc, int dev, int group);
+ void (*card_uninit) (envy24_devc * devc);
+};
+
+struct speed_sel
+{
+ int speed, speedbits;
+};
+
+/* extern struct speed_sel speed_tab[]; */
+
+void envy24d_install (envy24_devc * devc);
+void envy24d_playintr (envy24_devc * devc);
+void envy24d_recintr (envy24_devc * devc);
+void envy24_prepare_play_engine (envy24_devc * devc);
+void envy24_launch_play_engine (envy24_devc * devc);
+void envy24_stop_playback (envy24_devc * devc);
+void envy24_start_recording (envy24_devc * devc);
+void envy24_launch_recording (envy24_devc * devc);
+void envy24_stop_recording (envy24_devc * devc);
+
+void envy24_write_cci (envy24_devc * devc, int pos, int data);
+int envy24_read_cci (envy24_devc * devc, int pos);
+extern int cs8427_spdif_ioctl (envy24_devc * devc, int dev, unsigned int cmd,
+ ioctl_arg arg);
+extern void init_cs8427_spdif (envy24_devc * devc);
+extern int cs8427_spdif_mixer_init (envy24_devc * devc, int dev, int group);
+void WriteGPIObit (envy24_devc * devc, int sel, int what);
+int ReadGPIObit (envy24_devc * devc, int sel);
+void write_cs8427_spdif (envy24_devc * devc, int d);
+extern void envy24_set_enum_mask (int dev, int ctl, oss_native_word mask);
diff --git a/kernel/drv/oss_envy24/envy24_1010lt.c b/kernel/drv/oss_envy24/envy24_1010lt.c
new file mode 100644
index 0000000..5d31891
--- /dev/null
+++ b/kernel/drv/oss_envy24/envy24_1010lt.c
@@ -0,0 +1,582 @@
+/*
+ * Purpose: Card specific routines for M Audio Delta 1010LT
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include <ac97.h>
+#include "envy24.h"
+
+#define CH_STEREO 0x80
+
+/* SPI chip select codes */
+#define CS8_CS 0x4
+#define CDC_CS 0x0
+#define NONE_CS 0x7
+
+#define SPI_CLK 1
+#define SPI_DIN 2
+#define SPI_DOUT 3
+#define WCLOCK_ENABLE 7
+
+#define CS8_ADDR 0x20 /* Chip SPI/I2C address */
+#define CS8_RD 0x01
+#define CS8_WR 0x00
+
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+
+#if 0
+# define PRT_STATUS(v) outb(v&0xff, 0x378)
+#else
+# define PRT_STATUS(v)
+#endif
+
+/* ----- DEFINITION OF GPIOs ----- */
+
+#define FPGA_PROGRAM_L 7 /* FPGA program control select line (active low) */
+#define FPGA_CLK 1 /* FPGA program clock */
+#define EXT_REG_CLK 0 /* Was GPIO Fast mode (debug) */
+#define FPGA_D0 3 /* FPGA program data */
+
+#define LATCH_EN_L 4 /* Strobe for external latch (active low) */
+#define FPGA_MUTE 5
+
+#define FPGA_INIT_STATE 0xFC /* Init state for extern register to allow */
+ /* FPGA initialization. */
+
+#define FPGA_MASTER 5
+
+extern int envy24_gain_sliders;
+extern int envy24_virtualout;
+extern int envy24_zerolatency; /* Testing in progress */
+
+static void
+SPI_select (envy24_devc * devc, int sel)
+{
+ int tmp;
+
+ tmp = envy24_read_cci (devc, 0x20);
+ tmp &= ~0x70;
+ tmp |= (sel & 0x7) << 4;
+ envy24_write_cci (devc, 0x20, tmp);
+}
+
+static void
+write_d1010lt_codec (envy24_devc * devc, int sel, int bRegister,
+ unsigned char bData)
+{
+ int bMask;
+
+ WriteGPIObit (devc, SPI_DOUT, 0);
+ WriteGPIObit (devc, SPI_CLK, 1);
+
+ SPI_select (devc, sel);
+ oss_udelay (1);
+ bRegister = (bRegister & 0x0F) | 0xA0; /* Add I2C address field. */
+
+ /* Assert the CODEC chip select and wait at least 150 nS. */
+ /* */
+
+ /* Write the register address byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, SPI_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bRegister)
+ WriteGPIObit (devc, SPI_DOUT, 1);
+ else
+ WriteGPIObit (devc, SPI_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, SPI_CLK, 1);
+ }
+
+
+ /* Write the data byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, SPI_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bData)
+ WriteGPIObit (devc, SPI_DOUT, 1);
+ else
+ WriteGPIObit (devc, SPI_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, SPI_CLK, 1);
+ }
+
+ /* De-assert chip select. */
+ /* */
+
+ SPI_select (devc, NONE_CS);
+}
+
+static void
+d1010lt_card_init (envy24_devc * devc)
+{
+ int i;
+
+ SPI_select (devc, NONE_CS);
+
+ for (i = 0; i < 4; i++)
+ {
+ write_d1010lt_codec (devc, i, 0, 0x07);
+ write_d1010lt_codec (devc, i, 1, 0x03);
+ write_d1010lt_codec (devc, i, 2, 0x60);
+ write_d1010lt_codec (devc, i, 3, 0x19);
+ write_d1010lt_codec (devc, i, 4, 0x7f);
+ write_d1010lt_codec (devc, i, 5, 0x7f);
+ write_d1010lt_codec (devc, i, 6, 0x7f);
+ write_d1010lt_codec (devc, i, 7, 0x7f);
+ }
+
+}
+
+static int
+envy24_set_d1010lt (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int codec, level;
+ static unsigned char levels[] = { 0x7f, 0x8c, 0x98 };
+
+ if (ctrl >= 0xff)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return devc->akm_gains[ctrl];
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+ codec = (ctrl & 0x7) / 2;
+ if (envy24_gain_sliders)
+ {
+ level = value & 0xff;
+ if (level < 0)
+ level = 0;
+ if (level > 144)
+ level = 144;
+ }
+ else
+ {
+ if (value < 0 || value > 2)
+ value = 0;
+ level = levels[value];
+ }
+
+ switch (ctrl & 0x89) /* IN/OUT, LEFT/RIGHT, Gang switches */
+ {
+ case 0x00: /* Left output channel only */
+ write_d1010lt_codec (devc, codec, 6, level);
+ break;
+
+ case 0x01: /* Right output channel only */
+ write_d1010lt_codec (devc, codec, 7, level);
+ break;
+
+ case 0x80: /* Both output channels */
+ write_d1010lt_codec (devc, codec, 6, level);
+ write_d1010lt_codec (devc, codec, 7, level);
+ break;
+
+ case 0x08: /* Left input channel only */
+ write_d1010lt_codec (devc, codec, 4, level);
+ break;
+
+ case 0x09: /* Right input channel only */
+ write_d1010lt_codec (devc, codec, 5, level);
+ break;
+
+ case 0x88: /* Both input channels */
+ write_d1010lt_codec (devc, codec, 4, level);
+ write_d1010lt_codec (devc, codec, 5, level);
+ break;
+ }
+
+ return devc->akm_gains[ctrl] = value;
+ }
+ return OSS_EINVAL;
+}
+
+
+static int
+d1010lt_mix_init (envy24_devc * devc, int dev, int group)
+{
+ int i, mask = devc->outportmask, err, skip;
+ int typ = MIXT_ENUM, range = 3;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ if (envy24_gain_sliders)
+ {
+ typ = MIXT_MONOSLIDER;
+ range = 144;
+
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0x7f;
+ }
+ else
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0;
+
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ i | CH_STEREO,
+ envy24_set_d1010lt, typ, tmp,
+ range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUTL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDOUTR");
+ else
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ i, envy24_set_d1010lt,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+
+ mask = devc->inportmask;
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDIN");
+ else
+ sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ (8 + i) | CH_STEREO,
+ envy24_set_d1010lt, typ, tmp,
+ range,
+ MIXF_RECVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDINL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDINR");
+ else
+ sprintf (tmp, "ENVY24_IN%d", i + 1);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 8 + i, envy24_set_d1010lt,
+ typ,
+ tmp, range,
+ MIXF_RECVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static void
+write_d1010lt_spdif_reg (envy24_devc * devc, int bRegister, int bData)
+{
+ unsigned char bMask;
+ unsigned char bSPI;
+
+ /* Assert the CODEC chip select and wait at least 150 nS. */
+ /* */
+ SPI_select (devc, CS8_CS);
+
+ /* Write the SPI address/cmd byte. */
+ /* */
+ bSPI = CS8_ADDR | CS8_WR;
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, SPI_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bSPI)
+ WriteGPIObit (devc, SPI_DOUT, 1);
+ else
+ WriteGPIObit (devc, SPI_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, SPI_CLK, 1);
+ }
+
+ /* Write the address (MAP) byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, SPI_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bRegister)
+ WriteGPIObit (devc, SPI_DOUT, 1);
+ else
+ WriteGPIObit (devc, SPI_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, SPI_CLK, 1);
+ }
+
+
+ /* Write the data byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, SPI_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bData)
+ WriteGPIObit (devc, SPI_DOUT, 1);
+ else
+ WriteGPIObit (devc, SPI_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, SPI_CLK, 1);
+ }
+
+ /* De-assert chip select. */
+ /* */
+ SPI_select (devc, NONE_CS);
+}
+
+static int
+read_d1010lt_spdif_reg (envy24_devc * devc, int reg)
+{
+ unsigned char bMask;
+ unsigned char bRet = 0;
+ unsigned char bSPI;
+
+
+ /****** WRITE MAP ADDRESS FIRST ******/
+
+ /* Drop the chip select low. */
+ /* Wait at least 150 nS. */
+ /* */
+ SPI_select (devc, CS8_CS);
+
+ /* Write the SPI address/cmd byte. */
+ /* */
+ bSPI = CS8_ADDR + CS8_WR; /* SPI address field plus WRITE operation. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock (GPIO5) low. */
+ WriteGPIObit (devc, SPI_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bSPI)
+ WriteGPIObit (devc, SPI_DOUT, 1);
+ else
+ WriteGPIObit (devc, SPI_DOUT, 0);
+
+ /* Raise clock (GPIO5). */
+ WriteGPIObit (devc, SPI_CLK, 1);
+ }
+
+
+ /* Write the address (MAP) byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock (GPIO5) low. */
+ WriteGPIObit (devc, SPI_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & reg)
+ WriteGPIObit (devc, SPI_DOUT, 1);
+ else
+ WriteGPIObit (devc, SPI_DOUT, 0);
+
+ /* Raise clock (GPIO5). */
+ WriteGPIObit (devc, SPI_CLK, 1);
+ }
+
+ /* De-assert chip select(s). */
+ /* */
+ SPI_select (devc, NONE_CS);
+
+
+ /****** NOW READ THE DATA ******/
+
+ /* Drop the chip select low. */
+ /* Wait at least 150 nS. */
+ /* */
+ SPI_select (devc, CS8_CS);
+
+
+ /* Write the SPI address/cmd byte. */
+ /* */
+ bSPI = CS8_ADDR + CS8_RD; /* SPI address field plus READ operation. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock (GPIO5) low. */
+ WriteGPIObit (devc, SPI_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bSPI)
+ WriteGPIObit (devc, SPI_DOUT, 1);
+ else
+ WriteGPIObit (devc, SPI_DOUT, 0);
+
+ /* Raise clock (GPIO5). */
+ WriteGPIObit (devc, SPI_CLK, 1);
+ }
+
+
+ /* Read the data byte. */
+ /* */
+ bRet = 0;
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock low. */
+ WriteGPIObit (devc, SPI_CLK, 0);
+
+ /* Read current data bit. */
+ if (ReadGPIObit (devc, SPI_DIN))
+ bRet |= bMask;
+
+ /* Raise clock. */
+ WriteGPIObit (devc, SPI_CLK, 1);
+ }
+
+
+ /* De-assert chip selects. */
+ /* */
+ SPI_select (devc, NONE_CS);
+
+ /* Return value. */
+
+ return bRet;
+}
+
+static void
+set_d1010lt_speed (envy24_devc * devc)
+{
+ int tmp;
+
+ tmp = devc->speedbits;
+
+ switch (devc->syncsource)
+ {
+ case SYNC_INTERNAL:
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ WriteGPIObit (devc, WCLOCK_ENABLE, 0);
+ write_d1010lt_spdif_reg (devc, 4,
+ read_d1010lt_spdif_reg (devc, 4) & (~BIT0));
+ break;
+
+ case SYNC_SPDIF:
+ tmp |= 0x10;
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ WriteGPIObit (devc, WCLOCK_ENABLE, 0);
+ write_d1010lt_spdif_reg (devc, 4,
+ read_d1010lt_spdif_reg (devc, 4) | BIT0);
+ break;
+
+ case SYNC_WCLOCK:
+ tmp |= 0x10;
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ WriteGPIObit (devc, WCLOCK_ENABLE, 1);
+ write_d1010lt_spdif_reg (devc, 4,
+ read_d1010lt_spdif_reg (devc, 4) & (~BIT0));
+ if (devc->model_data->svid == 0xd63014ff)
+ {
+ /*
+ * 1010 rev E only
+ * don't aks me why, but it seems to work
+ */
+ WriteGPIObit (devc, 6, 0);
+ WriteGPIObit (devc, WCLOCK_ENABLE, 1);
+ }
+ break;
+ }
+}
+
+static int
+d1010lt_get_locked_status (envy24_devc * devc)
+{
+ /* TODO */
+ return 1;
+}
+
+envy24_auxdrv_t d1010lt_auxdrv = {
+ d1010lt_card_init,
+ d1010lt_mix_init,
+ init_cs8427_spdif,
+ write_cs8427_spdif,
+ cs8427_spdif_ioctl,
+ read_d1010lt_spdif_reg,
+ write_d1010lt_spdif_reg,
+ set_d1010lt_speed,
+ d1010lt_get_locked_status,
+ cs8427_spdif_mixer_init
+};
diff --git a/kernel/drv/oss_envy24/envy24_6fire.c b/kernel/drv/oss_envy24/envy24_6fire.c
new file mode 100644
index 0000000..469ceab
--- /dev/null
+++ b/kernel/drv/oss_envy24/envy24_6fire.c
@@ -0,0 +1,781 @@
+/*
+ * Purpose: Card specific routines for Terratec DMX6fire.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "ac97.h"
+#include "envy24.h"
+
+#if 0
+# define PRT_STATUS(v) outb(v&0xff, 0x378)
+#else
+# define PRT_STATUS(v)
+#endif
+
+#define DEFAULT_FRONTBOX_SETUP 0xfd
+
+extern int envy24_gain_sliders;
+extern int envy24_virtualout;
+
+#define EWX_DIG_ADDR 0x24 /* IIC address of digital traceiver chip of 6fire */
+
+/*=============================================================================
+ Function : IIC_GetSDA
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char ->
+ Parameters : unsigned long dwPortAddr ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static unsigned char
+IIC_GetSDA (envy24_devc * devc)
+{
+
+ unsigned char bReg, bSDA;
+
+ /* FMB TEST: RW line */
+ /* set write mask */
+ bReg = ~(0x08); /* writeable */
+ envy24_write_cci (devc, 0x21, bReg);
+
+ /* set RW line LOW */
+ bReg = 0; /* writeable */
+ envy24_write_cci (devc, 0x20, bReg);
+
+ /* Set direction: SDA to input and SCL to output */
+ bReg = envy24_read_cci (devc, 0x22);
+ bReg |= 0x20; /* SCL output = 1 */
+ bReg &= ~0x10; /* SDA input = 0 */
+ envy24_write_cci (devc, 0x22, bReg);
+
+ /* Get SDA line state */
+ bSDA = envy24_read_cci (devc, 0x20);
+
+
+ /* set RW line HIGH */
+ bReg = 0x08; /* writeable */
+ envy24_write_cci (devc, 0x20, bReg);
+
+ return 1;
+ /* return ((bSDA & 0x10) == 0x10); */
+
+}
+
+/*=============================================================================
+ Function : IIC_SetIic
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : unsigned int dwPortAddr ->
+ : unsigned char fSDA ->
+ : unsigned char fSCL ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+IIC_SetIic (envy24_devc * devc, unsigned char fSDA, unsigned char fSCL)
+{
+ unsigned char bReg;
+
+ /* Set direction: SDA and SCL to output */
+ bReg = envy24_read_cci (devc, 0x22);
+ bReg |= (0x20 | 0x10); /* 1 -> output */
+ envy24_write_cci (devc, 0x22, bReg);
+
+ /* set write mask */
+ bReg = ~(0x20 | 0x10); /* writeable */
+ envy24_write_cci (devc, 0x21, bReg);
+
+ /* Set line state */
+ /* FMB TEST: RW line */
+ bReg = 0x08;
+ if (fSDA)
+ bReg += 0x10;
+ if (fSCL)
+ bReg += 0x20;
+ envy24_write_cci (devc, 0x20, bReg);
+
+}
+
+/*=============================================================================
+ Function : IIC_Start
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : unsigned int dwPortAddr ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+/*__inline */
+static void
+IIC_Start (envy24_devc * devc)
+{
+ /* falling edge of SDA while SCL is HIGH */
+ IIC_SetIic (devc, 1, 1);
+ oss_udelay (30);
+ IIC_SetIic (devc, 0, 1);
+}
+
+/*=============================================================================
+ Function : IIC_Stop
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : unsigned int dwPortAddr ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+/*__inline */
+
+static void
+IIC_Stop (envy24_devc * devc)
+{
+ /* rising edge of SDA while SCL is HIGH */
+ IIC_SetIic (devc, 0, 1);
+ IIC_SetIic (devc, 1, 1);
+}
+
+
+/*=============================================================================
+ Function : IIC_SendByte
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char ->
+ Parameters : unsigned int dwPortAddr ->
+ : unsigned char bByte ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+/*__inline */
+static unsigned char
+IIC_SendByte (envy24_devc * devc, unsigned char bByte)
+{
+ unsigned char bDataBit, bAck;
+ int i;
+
+ for (i = 7; i >= 0; i--) /* send byte (MSB first) */
+ {
+ bDataBit = (bByte >> i) & 0x01;
+
+ IIC_SetIic (devc, bDataBit, 0);
+ IIC_SetIic (devc, bDataBit, 1);
+ IIC_SetIic (devc, bDataBit, 0);
+ } /* end for i */
+
+ IIC_SetIic (devc, 1, 0);
+
+ /* Get acknowledge */
+ IIC_SetIic (devc, 1, 1);
+ bAck = IIC_GetSDA (devc);
+ /* FMB this is a start condition but never mind */
+ IIC_SetIic (devc, 0, 0);
+#if 0
+ if (bAck)
+ cmn_err (CE_CONT, "SendByte failed %02x\n", bByte);
+ else
+ cmn_err (CE_CONT, "SendByte OK %02x\n", bByte);
+#endif
+ return 1;
+ /* return (!bAck); *//* bAck = 0 --> success */
+}
+
+#if 0
+/*=============================================================================
+ Function : IIC_WriteByte
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char ->
+ Parameters : unsigned int dwPortAddr ->
+ : unsigned char bIicAddress ->
+ : unsigned char bByte ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static unsigned char
+IIC_WriteByte (envy24_devc * devc, unsigned char bIicAddress,
+ unsigned char bByte)
+{
+ IIC_Start (devc);
+
+ /* send IIC address and data byte */
+ if (!IIC_SendByte (devc, bIicAddress))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 1 failed\n");
+ goto FAILED;
+ }
+ if (!IIC_SendByte (devc, bByte))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 2 failed\n");
+ goto FAILED;
+ }
+
+ IIC_Stop (devc);
+ return 1;
+
+FAILED:
+ IIC_Stop (devc);
+ return 0;
+}
+#endif
+
+static unsigned char
+IIC_WriteWord (envy24_devc * devc, unsigned char bIicAddress,
+ unsigned char reg, unsigned char bByte)
+{
+ IIC_Start (devc);
+
+ /* send IIC address and data byte */
+ if (!IIC_SendByte (devc, bIicAddress))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 1 failed\n");
+ goto FAILED;
+ }
+ if (!IIC_SendByte (devc, reg))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 2 failed\n");
+ goto FAILED;
+ }
+ if (!IIC_SendByte (devc, bByte))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 3 failed\n");
+ goto FAILED;
+ }
+
+ IIC_Stop (devc);
+ return 1;
+
+FAILED:
+ IIC_Stop (devc);
+ return 0;
+}
+
+static void
+FrontboxControl (envy24_devc * devc, int b)
+{
+ IIC_WriteWord (devc, 0x40, 0x01, b); /* Output register */
+ devc->gpio_tmp = b;
+}
+
+static int
+HW_AK4525_SetChipSelect (envy24_devc * devc, unsigned char bCsMask)
+{
+ unsigned char b;
+ /* check validity */
+ if (bCsMask > 0x07)
+ {
+ cmn_err (CE_CONT, "Invalid bCsMask %02x\n", bCsMask);
+ return 0; /* invalid */
+ }
+
+ envy24_write_cci (devc, 0x21, 0x00);
+ envy24_write_cci (devc, 0x22, 0xff);
+ b = envy24_read_cci (devc, 0x20);
+ b &= ~0x07;
+
+ b |= bCsMask & 0x07;
+
+ envy24_write_cci (devc, 0x20, b);
+
+ return 1;
+}
+
+#define HW_AK4525_SetLines IIC_SetIic
+
+/*=============================================================================
+ FUNCTION: HW_AK4525_WriteRegister
+-------------------------------------------------------------------------------
+ PURPOSE:
+ PARAMETERS: unsigned int port - port address for IIC port
+ unsigned char bCsMask - CoDec bitmask (bits 0..3)
+ or 0xFF for all codecs together
+ unsigned char bRegIdx - offset to desired register
+ unsigned char bReg - new register value
+ RETURNS:
+-------------------------------------------------------------------------------
+ NOTES: The Chip Selects must have been set prior to this call
+ PCF8574_CODEC_IIC_ADDRESS
+
+ +-----------------------------------------------------------------+
+ | B15 B14 B13 B12 B11 B10 B09 B08|B07 B06 B05 B04 B03 B02 B01 B00 |
+ +--------+---+-------------------+--------------------------------+
+ | C1 C0 |R/W|A4 A3 A2 A1 A0 |D7 D6 D5 D4 D3 D2 D1 D0 |
+ | 1 0 |1 | <= 7 | data |
+ +--------+---+-------------------+--------------------------------+
+
+=============================================================================*/
+static unsigned char
+HW_AK4525_WriteRegister (envy24_devc * devc, unsigned char bCsMask,
+ unsigned char bRegIdx, unsigned char bRegData)
+{
+
+ unsigned short wCmd;
+ unsigned char i;
+ unsigned char fData;
+
+ /* format buffer */
+ wCmd = 0xA000 + /* chip address + R/W */
+ (((unsigned short) bRegIdx) << 8) + /* register address */
+ bRegData;
+
+ HW_AK4525_SetLines (devc, 0, 0);
+
+ /* start write cycle */
+ if (!HW_AK4525_SetChipSelect (devc, bCsMask))
+ {
+ cmn_err (CE_CONT, "HW_AK4525_SetChipSelect failed\n");
+ return 0; /* = CS to LOW -> data latched */
+ }
+
+
+ for (i = 0; i < 16; i++)
+ {
+ fData = (wCmd & 0x8000) ? 1 : 0;
+ HW_AK4525_SetLines (devc, fData, 0);
+ HW_AK4525_SetLines (devc, fData, 1); /* data is clocked in on rising edge of CCLK */
+ HW_AK4525_SetLines (devc, fData, 0);
+ wCmd <<= 1;
+ }
+
+ /* leave data line HIGH (= default for IIC) */
+ HW_AK4525_SetLines (devc, fData, 0); /* data is clocked in on rising edge of CCLK */
+
+ /* end write cycle */
+ if (!HW_AK4525_SetChipSelect (devc, 0x00))
+ {
+ cmn_err (CE_CONT, "HW_AK4525_SetChipSelect 2 failed\n");
+ return 0; /* = all CS to HIGH -> CS to default */
+ }
+
+ /* default */
+ HW_AK4525_SetLines (devc, 1, 1); /* data is clocked in on rising edge of CCLK */
+
+ return 1;
+}
+
+
+/* Register offsets */
+enum
+{
+ AK4525_REG_POWER,
+ AK4525_REG_RESET,
+ AK4525_REG_FORMAT,
+ AK4525_REG_DEEMPHASIS,
+ AK4525_REG_LEFT_INPUT,
+ AK4525_REG_RIGHT_INPUT,
+ AK4525_REG_LEFT_OUTPUT,
+ AK4525_REG_RIGHT_OUTPUT
+};
+
+
+/*=============================================================================
+ Function : HW_AK4525_Reset
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char
+ Parameters : PCUST_HW_INSTANCE_DATA devc -
+ int nCodecIdx -> 0..3 index of Codec ,-1 -> all
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static unsigned char
+HW_AK4525_Reset (envy24_devc * devc, int nCodecIdx)
+{
+ unsigned char bCodecMask = 0;
+ if (nCodecIdx == -1)
+ bCodecMask = 0x07;
+ else
+ bCodecMask = 0x01 << (nCodecIdx);
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */
+ AK4525_REG_RESET, 0x00)) /* DACs,ADCs -> reset */
+ {
+ cmn_err (CE_CONT, "REG_RESET failed\n");
+ return 0;
+ }
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */
+ AK4525_REG_FORMAT, 0x60)) /* IIS, 256 fsn, normal speed */
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */
+ AK4525_REG_RESET, 0x03)) /* DACs,ADCs -> normal operation */
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */
+ AK4525_REG_POWER, 0x07)) /* power on */
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* soft mute timeout --> short */
+ AK4525_REG_DEEMPHASIS, 0x19))
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc,
+ bCodecMask, AK4525_REG_LEFT_INPUT, 0x7f))
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc,
+ bCodecMask, AK4525_REG_RIGHT_INPUT, 0x7f))
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc,
+ bCodecMask, AK4525_REG_LEFT_OUTPUT, 0x7f))
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc,
+ bCodecMask, AK4525_REG_RIGHT_OUTPUT, 0x7f))
+ return 0;
+
+ return 1;
+}
+
+static void
+set_dmx6fire_speed (envy24_devc * devc)
+{
+ unsigned char tmp;
+
+ tmp = devc->speedbits;
+ if (devc->syncsource != SYNC_INTERNAL)
+ {
+ tmp |= 0x10; /* S/PDIF input clock select */
+ if (devc->model_data->flags & MF_WCLOCK) /* Has world clock too */
+ {
+ int cmd = envy24_read_cci (devc, 0x20);
+ cmd |= 0x10; /* S/PDIF */
+ if (devc->syncsource == SYNC_WCLOCK)
+ cmd &= ~0x10; /* World clock */
+ envy24_write_cci (devc, 0x20, cmd);
+ }
+ }
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+}
+
+#if 0
+/*
+ * S/PDIF register access doesn't work so this feature is not enabled.
+ */
+
+#define EWX_CLK 0x20
+#define EWX_DTA 0x10
+
+static void
+dmx6fire_iic_write_byte (envy24_devc * devc, unsigned char data,
+ unsigned char save)
+{
+ int i;
+ unsigned char gpio;
+
+ for (i = 0; i < 8; i++)
+ {
+ int fData = (data & 0x80) ? 1 : 0;
+
+ gpio = 0x08;
+ if (fData)
+ gpio |= EWX_DTA; /* DATA */
+ envy24_write_cci (devc, 0x20, gpio | save);
+ envy24_write_cci (devc, 0x20, gpio | EWX_CLK | save); /* Clock pulse */
+ envy24_write_cci (devc, 0x20, gpio | save);
+
+ data <<= 1;
+ }
+
+ envy24_write_cci (devc, 0x20, EWX_DTA | save);
+ envy24_write_cci (devc, 0x20, EWX_DTA | EWX_CLK | save); /* Clock pulse (ACK) */
+ envy24_write_cci (devc, 0x20, EWX_DTA | save);
+}
+
+static unsigned char
+dmx6fire_iic_read_byte (envy24_devc * devc, unsigned char save)
+{
+ int i;
+ unsigned char data = 0;
+ int b;
+
+ PRT_STATUS (0x01);
+ save |= EWX_DTA;
+ envy24_write_cci (devc, 0x20, save);
+ oss_udelay (10);
+#if 1
+ save &= ~8; /* R/W bit */
+ envy24_write_cci (devc, 0x22, ~EWX_DTA); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, EWX_DTA); /* GPIO write mask */
+#endif
+
+ for (i = 0; i < 8; i++)
+ {
+
+ envy24_write_cci (devc, 0x20, EWX_CLK | save); /* Clock pulse */
+ b = envy24_read_cci (devc, 0x20);
+ if (b & EWX_DTA)
+ data |= 0x80;
+ envy24_write_cci (devc, 0x20, save);
+
+ data >>= 1;
+ }
+
+ envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */
+ envy24_write_cci (devc, 0x20, (save & ~EWX_DTA) | 0x08); /* Low for the ACK bit */
+ envy24_write_cci (devc, 0x20, (save & ~EWX_DTA) | 0x08 | EWX_CLK); /* Clock for the ACK bit */
+ envy24_write_cci (devc, 0x20, save | 0x08);
+ oss_udelay (10);
+ return data;
+}
+
+#if 0
+static void
+dmx6fire_iic_write (envy24_devc * devc, int addr,
+ unsigned char bRegIdx, unsigned char bRegData)
+{
+ unsigned char save;
+
+ /* start write cycle */
+ envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */
+
+ save = (envy24_read_cci (devc, 0x20) & ~(EWX_CLK | EWX_DTA)) | 0x08 /* R/W bit */
+ ;
+ /* Send start */
+ envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK);
+ envy24_write_cci (devc, 0x20, save);
+
+ dmx6fire_iic_write_byte (devc, addr, save);
+ dmx6fire_iic_write_byte (devc, bRegIdx, save);
+ dmx6fire_iic_write_byte (devc, bRegData, save);
+
+ /* Send stop */
+ envy24_write_cci (devc, 0x20, save);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA);
+}
+#endif
+
+static unsigned char
+dmx6fire_iic_read (envy24_devc * devc, int addr, unsigned char bRegIdx)
+{
+ unsigned char save, data;
+
+ /* dmx6fire_iic_write(devc, addr, bRegIdx, 0x55); */
+ PRT_STATUS (0x80);
+
+ envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */
+
+ save = (envy24_read_cci (devc, 0x20) & ~(EWX_DTA | EWX_CLK)) | 0x08 /* R/W bit */
+ ;
+ PRT_STATUS (0x02);
+ /* Send start */
+ envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK);
+ envy24_write_cci (devc, 0x20, save);
+
+ dmx6fire_iic_write_byte (devc, addr | 0x01, save);
+ data = dmx6fire_iic_read_byte (devc, save);
+
+ /* Send stop */
+ envy24_write_cci (devc, 0x20, save);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA);
+ PRT_STATUS (0x00);
+ return data;
+}
+
+static int
+read_dmx6fire_spdif_reg (envy24_devc * devc, int bRegister)
+/*
+*****************************************************************************
+* Reads a byte from a specific CS8427 register.
+****************************************************************************/
+{
+
+ unsigned char ret;
+ ret = dmx6fire_iic_read (devc, EWX_DIG_ADDR, bRegister);
+
+ return ret;
+}
+
+static void
+write_dmx6fire_spdif_reg (envy24_devc * devc, int bRegister, int bData)
+{
+
+ /*dmx6fire_iic_write(devc, EWX_DIG_ADDR, bRegister, bData); */
+ IIC_WriteWord (devc, EWX_DIG_ADDR, bRegister, bData);
+}
+#else
+static int
+read_dmx6fire_spdif_reg (envy24_devc * devc, int bRegister)
+{
+ return 0;
+}
+
+static void
+write_dmx6fire_spdif_reg (envy24_devc * devc, int bRegister, int bData)
+{
+}
+#endif
+
+static void
+dmx6fire_card_init (envy24_devc * devc)
+{
+ envy24_write_cci (devc, 0x20, 0xff);
+ envy24_write_cci (devc, 0x21, 0x00);
+ envy24_write_cci (devc, 0x22, 0xff);
+ envy24_write_cci (devc, 0x20, 0xff);
+ HW_AK4525_SetChipSelect (devc, 0x00);
+#if 1
+
+ IIC_WriteWord (devc, 0x40, 0x02, 0x00); /* Polarity register */
+ IIC_WriteWord (devc, 0x40, 0x03, 0x00); /* Direction register */
+
+ FrontboxControl (devc, DEFAULT_FRONTBOX_SETUP); /* Set default values */
+
+ if (!HW_AK4525_Reset (devc, -1))
+ cmn_err (CE_CONT, "Envy24: DMX6fire reset failed\n");;
+#endif
+
+}
+
+static int
+dmx6fire_mixer_set (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ switch (ctrl)
+ {
+ case 1:
+ if (devc->skipdevs == 2)
+ return devc->rec_portc[2].riaa_filter;
+ else
+ return devc->rec_portc[4].riaa_filter;
+ break;
+
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ switch (ctrl)
+ {
+ case 1:
+ if (devc->skipdevs == 2)
+ return devc->rec_portc[2].riaa_filter = !!value;
+ else
+ return devc->rec_portc[4].riaa_filter = !!value;
+ break;
+
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+dmx6fire_mix_init (envy24_devc * devc, int dev, int group)
+{
+ int err;
+#if 0
+ int i, mask = devc->outportmask, skip, codec, ports;
+ int range = 3;
+ int typ = MIXT_ENUM;
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ if (envy24_gain_sliders)
+ {
+ typ = MIXT_MONOSLIDER;
+ range = 164;
+
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0x7f;
+ }
+ else
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0;
+
+ for (i = 0; i < 8; i += skip)
+ {
+ char tmp[32];
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = 0x0c; /* Both output ports */
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_tdif,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUTL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDOUTR");
+ else
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = (i & 1) ? 0x08 : 0x04;
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_tdif,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+#endif
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_6FIRE")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, dmx6fire_mixer_set,
+ MIXT_ONOFF,
+ "6FIRE_RIAA", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+envy24_auxdrv_t dmx6fire_auxdrv = {
+ dmx6fire_card_init,
+ dmx6fire_mix_init,
+ init_cs8427_spdif,
+ write_cs8427_spdif,
+ NULL,
+ read_dmx6fire_spdif_reg,
+ write_dmx6fire_spdif_reg,
+ set_dmx6fire_speed,
+ NULL,
+ cs8427_spdif_mixer_init
+};
diff --git a/kernel/drv/oss_envy24/envy24_default.c b/kernel/drv/oss_envy24/envy24_default.c
new file mode 100644
index 0000000..21baa45
--- /dev/null
+++ b/kernel/drv/oss_envy24/envy24_default.c
@@ -0,0 +1,2384 @@
+/*
+ * Purpose: Card specific routines for several Envy24 based cards.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "ac97.h"
+#include "envy24.h"
+
+#if 0
+# define PRT_STATUS(v) outb(v&0xff, 0x378)
+#else
+# define PRT_STATUS(v)
+#endif
+
+extern int envy24_gain_sliders;
+extern int envy24_virtualout;
+extern int envy24_zerolatency; /* Testing in progress */
+
+#define EWX_DIG_ADDR 0x20 /* IIC address of digital traceiver chip of EWX2496 */
+
+/*
+ * Playback engine management
+ */
+
+static void
+write_spdif (envy24_devc * devc, int d)
+{
+ int i, cmd;
+
+ cmd = envy24_read_cci (devc, 0x20);
+ for (i = 7; i >= 0; i--)
+ {
+ cmd &= ~0x04;
+ envy24_write_cci (devc, 0x20, cmd);
+ oss_udelay (1);
+ if (d & (1 << i))
+ cmd |= 0x08;
+ else
+ cmd &= ~0x08;
+ cmd |= 0x04;
+ envy24_write_cci (devc, 0x20, cmd);
+ oss_udelay (1);
+ }
+ cmd &= ~0x04;
+ envy24_write_cci (devc, 0x20, cmd);
+}
+
+static void
+write_codec (envy24_devc * devc, int codec, int addr, int data)
+{
+ unsigned char cmd;
+ int i;
+ int tmp;
+ cmd = envy24_read_cci (devc, 0x20);
+ cmd &= ~codec;
+ envy24_write_cci (devc, 0x20, cmd);
+ oss_udelay (1);
+ addr &= 0x07;
+ tmp = 0xa000 | (addr << 8) | data;
+ for (i = 15; i >= 0; i--)
+ {
+ cmd &= ~0x30;
+ if (tmp & (1 << i))
+ cmd |= 0x10;
+ envy24_write_cci (devc, 0x20, cmd);
+ oss_udelay (1);
+ cmd |= 0x20;
+ envy24_write_cci (devc, 0x20, cmd);
+ oss_udelay (1);
+ }
+ cmd |= codec;
+ envy24_write_cci (devc, 0x20, cmd);
+ oss_udelay (1);
+}
+
+#define CDC_CLK 1 /* Clock input to the CODEC's, rising edge clocks data. */
+#define CDC_DIN 2 /* Data input to Envy from the CODEC. */
+#define CDC_DOUT 3 /* Data output from Envy to the CODEC. */
+#define DIG_CS 4 /* Chip select (0=select) for the SPDIF tx/rx. */
+#define CDC_CS 5 /* Chip select (0=select) for the CODEC. */
+#define D410_MUTE 7 /* Delta 410 codec mute */
+#define CS_ASSERT 0 /* Asserted chip select (selects are inverted). */
+#define CS_RELEASE 1 /* Idle chip select (selects are inverted). */
+
+
+#define CS8_CLK CDC_CLK
+#define CS8_DIN CDC_DIN
+#define CS8_DOUT CDC_DOUT
+#define CS8_CS DIG_CS
+#define CS_1 CS_ASSERT
+#define CS_0 CS_RELEASE
+#define CS8_ADDR 0x20 /* Chip SPI/I2C address */
+#define CS8_RD 0x01
+#define CS8_WR 0x00
+
+#define EWX_DIG_CS 0
+#define EWX_CDC_CLK 5
+#define EWX_CDC_DOUT 4
+#define EWX_CDC_DIN EWX_CDC_DOUT
+#define EWX_IIC_WRITE 3
+#define CX_ASSERT 0 /* Asserted chip select (selects are inverted). */
+#define CX_RELEASE 1 /* Idle chip select (selects are inverted). */
+
+void
+WriteGPIObit (envy24_devc * devc, int sel, int what)
+{
+ unsigned char gpio;
+
+ gpio = envy24_read_cci (devc, 0x20);
+ gpio &= ~(1 << sel);
+ gpio |= (what << sel);
+ envy24_write_cci (devc, 0x20, gpio);
+}
+
+int
+ReadGPIObit (envy24_devc * devc, int sel)
+{
+ unsigned char gpio;
+
+ gpio = envy24_read_cci (devc, 0x20);
+ return !!(gpio & (1 << sel));
+}
+
+static void
+write_ap_codec (envy24_devc * devc, int bRegister, unsigned char bData)
+/*
+
+*****************************************************************************
+* Writes a byte to a specific register of the Delta-AP CODEC.
+* Register must be (0..15).
+****************************************************************************/
+{
+ unsigned char bMask;
+
+ if (devc->model_data->flags & MF_D410)
+ bRegister = (bRegister & 0x0F) | 0x20; /* Add I2C address field. */
+ else
+ bRegister = (bRegister & 0x0F) | 0xA0; /* Add I2C address field. */
+
+ /* Assert the CODEC chip select and wait at least 150 nS. */
+ /* */
+ WriteGPIObit (devc, CDC_CS, CS_ASSERT);
+ WriteGPIObit (devc, DIG_CS, CS_RELEASE);
+
+ /* Write the register address byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bRegister)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+
+ /* Write the data byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bData)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+ /* De-assert chip select. */
+ /* */
+ WriteGPIObit (devc, CDC_CS, CS_RELEASE);
+}
+static int
+read_ap_spdif_reg (envy24_devc * devc, int bRegister)
+/*
+*****************************************************************************
+* Reads a byte from a specific CS8427 register.
+****************************************************************************/
+{
+ unsigned char bMask;
+ unsigned char bRet = 0;
+ unsigned char bSPI;
+
+ /****** WRITE MAP ADDRESS FIRST ******/
+
+ /* Drop the chip select low. */
+ /* Wait at least 150 nS. */
+ /* */
+ WriteGPIObit (devc, DIG_CS, CS_ASSERT);
+
+ /* Write the SPI address/cmd byte. */
+ /* */
+ bSPI = CS8_ADDR + CS8_WR; /* SPI address field plus WRITE operation. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock (GPIO5) low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bSPI)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise clock (GPIO5). */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+
+ /* Write the address (MAP) byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock (GPIO5) low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bRegister)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise clock (GPIO5). */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+ /* De-assert chip select(s). */
+ /* */
+ WriteGPIObit (devc, DIG_CS, CS_RELEASE);
+
+
+ /****** NOW READ THE DATA ******/
+
+ /* Drop the chip select low. */
+ /* Wait at least 150 nS. */
+ /* */
+ WriteGPIObit (devc, DIG_CS, CS_ASSERT);
+
+
+ /* Write the SPI address/cmd byte. */
+ /* */
+ bSPI = CS8_ADDR + CS8_RD; /* SPI address field plus READ operation. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock (GPIO5) low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bSPI)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise clock (GPIO5). */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+
+ /* Read the data byte. */
+ /* */
+ bRet = 0;
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Read current data bit. */
+ if (ReadGPIObit (devc, CDC_DIN))
+ bRet |= bMask;
+
+ /* Raise clock. */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+
+ /* De-assert chip selects. */
+ /* */
+ WriteGPIObit (devc, DIG_CS, CS_RELEASE);
+
+ /* Return value. */
+
+ return bRet;
+}
+
+static unsigned char
+ewx2496_iic_read (envy24_devc * devc, int addr, unsigned char bRegIdx);
+
+static int
+read_ewx2496_spdif_reg (envy24_devc * devc, int bRegister)
+/*
+*****************************************************************************
+* Reads a byte from a specific CS8427 register.
+****************************************************************************/
+{
+ unsigned char ret;
+
+ ret = ewx2496_iic_read (devc, EWX_DIG_ADDR, bRegister);
+
+ return ret;
+}
+
+#define read_cs8427_spdif_reg(d, r) devc->model_data->auxdrv->spdif_read_reg(d, r)
+
+static void
+write_ap_spdif_reg (envy24_devc * devc, int bRegister, int bData)
+/*
+*****************************************************************************
+* Writes a byte to a specific register of the Delta-AP S/PDIF chip.
+* Register must be (0..55).
+****************************************************************************/
+{
+ unsigned char bMask;
+ unsigned char bSPI;
+
+ /* Assert the CODEC chip select and wait at least 150 nS. */
+ /* */
+ WriteGPIObit (devc, CDC_CS, CS_0);
+ WriteGPIObit (devc, CS8_CS, CS_1);
+
+ /* Write the SPI address/cmd byte. */
+ /* */
+ bSPI = CS8_ADDR | CS8_WR;
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CS8_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bSPI)
+ WriteGPIObit (devc, CS8_DOUT, 1);
+ else
+ WriteGPIObit (devc, CS8_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CS8_CLK, 1);
+ }
+
+ /* Write the address (MAP) byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CS8_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bRegister)
+ WriteGPIObit (devc, CS8_DOUT, 1);
+ else
+ WriteGPIObit (devc, CS8_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CS8_CLK, 1);
+ }
+
+
+ /* Write the data byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CS8_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bData)
+ WriteGPIObit (devc, CS8_DOUT, 1);
+ else
+ WriteGPIObit (devc, CS8_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CS8_CLK, 1);
+ }
+
+ /* De-assert chip select. */
+ /* */
+ WriteGPIObit (devc, CS8_CS, CS_0);
+}
+
+static void
+ewx2496_iic_write (envy24_devc * devc, int addr,
+ unsigned char bRegIdx, unsigned char bRegData);
+
+static void
+write_ewx2496_spdif_reg (envy24_devc * devc, int bRegister, int bData)
+{
+ ewx2496_iic_write (devc, EWX_DIG_ADDR, bRegister, bData);
+
+}
+
+#define write_cs8427_spdif_reg(d, r, b) devc->model_data->auxdrv->spdif_write_reg(d, r, b)
+
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+
+static void
+lock_cs8427_spdif (envy24_devc * devc)
+{
+ write_cs8427_spdif_reg (devc, 18, read_cs8427_spdif_reg (devc, 18) & ~BIT5);
+ write_cs8427_spdif_reg (devc, 18, read_cs8427_spdif_reg (devc, 18) | BIT2);
+}
+
+static void
+unlock_cs8427_spdif (envy24_devc * devc)
+{
+ write_cs8427_spdif_reg (devc, 18, read_cs8427_spdif_reg (devc, 18) & ~BIT2);
+}
+
+static unsigned char
+bitswap (unsigned char bIn)
+/*
+*****************************************************************************
+* Endian reversing routine.
+****************************************************************************/
+{
+ unsigned char bOut = 0;
+ unsigned char bImask = 0x01;
+ unsigned char bOmask = 0x80;
+
+ while (bImask)
+ {
+ if (bIn & bImask)
+ bOut |= bOmask;
+ bImask = bImask << 1;
+ bOmask = (bOmask >> 1) & 0x7F;
+ }
+
+ return bOut;
+}
+
+
+static unsigned char
+ReadCsByte (envy24_devc * devc, unsigned char bByteNum)
+/*
+*****************************************************************************
+* Reads a byte from Channel Status block buffer in CS8427.
+*
+* bByteNum is in the range (0..23)
+*
+* This routine assumes that CS8427 register 18 bit 5 is cleared so that the
+* CS buffer is windowed, and that register 18 bit 2 is set so that CS output
+* transfers are currently disabled.
+****************************************************************************/
+{
+ unsigned char bTemp;
+
+ /* CS block window starts at reg #32... */
+ bTemp = read_cs8427_spdif_reg (devc, bByteNum + 32);
+
+ /* CS block access is reverse endian. */
+ return bitswap (bTemp);
+}
+
+static void
+WriteCsByte (envy24_devc * devc, unsigned char bByteNum, unsigned char bData)
+/*
+*****************************************************************************
+* Writes a byte to Channel Status block buffer in CS8427.
+*
+* bByteNum is in the range (0..23)
+*
+* This routine assumes that CS8427 register 18 bit 5 is cleared so that the
+* CS buffer is windowed, and that register 18 bit 2 is set so that CS output
+* transfers are currently disabled.
+****************************************************************************/
+{
+ /* CS block access is reverse endian. */
+ bData = bitswap (bData);
+
+ /* CS Window starts at reg #32... */
+ write_cs8427_spdif_reg (devc, bByteNum + 32, bData);
+}
+
+void
+InitConsumerModeCS (envy24_devc * devc)
+{
+ int i;
+
+ /* Set CS8427 registers 32-55 to window CS block, and disable CS output. */
+ lock_cs8427_spdif (devc);
+
+ /* Zero all the general CS bits. */
+ /* */
+ for (i = 0; i < 24; i++)
+ WriteCsByte (devc, i, 0x00);
+ /* */
+ /* Consumer (usually SPDIF or AC3) mode static bit settings. */
+ /* */
+ WriteCsByte (devc, 0, 0x00); /* Consumer format (bit0 = 0). */
+ WriteCsByte (devc, 1, 0x02); /* Category = PCM encoder/decoder. */
+
+ unlock_cs8427_spdif (devc);
+}
+
+void
+init_cs8427_spdif (envy24_devc * devc)
+{
+ int tmp;
+
+ /* Select iunternal sync */
+ write_cs8427_spdif_reg (devc, 4, read_cs8427_spdif_reg (devc, 4) & (~BIT0));
+/*
+*****************************************************************************
+* Initializes core (mainly static) registers of the CS8427.
+* Returns 1 if initialization OK, otherwise 0.
+****************************************************************************/
+ /* Assumes Envy24 GPIO's have been initialized. They should be just fine */
+ /* in the Windows driver as they are initialized from EEPROM info. */
+
+ /* Verify device ID register. Must be 0x71. */
+ if ((tmp = read_cs8427_spdif_reg (devc, 127)) != 0x71 && tmp != 0)
+ {
+ cmn_err (CE_CONT, "Envy24: Unrecognized S/PDIF chip ID %02x\n",
+ read_cs8427_spdif_reg (devc, 127));
+ cmn_err (CE_CONT,
+ " Hardware stalled. Please reboot and try again.\n");
+ return;
+ }
+
+ /* Turn off RUN bit while making changes to configuration. */
+ write_cs8427_spdif_reg (devc, 4, read_cs8427_spdif_reg (devc, 4) & (~BIT6));
+
+ /* RMCK default function, set Validity, disable mutes, TCBL=output. */
+ write_cs8427_spdif_reg (devc, 1, 0x01); /* validity* is BIT6. */
+
+ /* Hold last valid audio sample, RMCK=256*Fs, normal stereo operation. */
+ write_cs8427_spdif_reg (devc, 2, 0x00);
+ /* Output drivers normal operation, Tx <== serial audio port, */
+ /* Rx ==> serial audio port. */
+ write_cs8427_spdif_reg (devc, 3, 0x0C);
+
+ /* RUN off, OMCK=256xFs, output time base = OMCK, input time base = */
+ /* recovered input clock, recovered input clock source is Envy24. */
+ write_cs8427_spdif_reg (devc, 4, 0x00);
+
+ /* Serial audio input port data format = I2S. */
+ write_cs8427_spdif_reg (devc, 5, BIT2 | BIT0); /* SIDEL=1, SILRPOL=1. */
+
+ /* Serial audio output port data format = I2S. */
+ write_cs8427_spdif_reg (devc, 6, BIT2 | BIT0); /* SODEL=1, SOLRPOL=1. */
+
+ /* Turn off CS8427 interrupt stuff that we don't implement in our hardware. */
+ write_cs8427_spdif_reg (devc, 9, 0x00);
+ write_cs8427_spdif_reg (devc, 10, 0x00);
+ write_cs8427_spdif_reg (devc, 11, 0x00);
+ write_cs8427_spdif_reg (devc, 12, 0x00);
+ write_cs8427_spdif_reg (devc, 13, 0x00);
+ write_cs8427_spdif_reg (devc, 14, 0x00);
+
+ /* Unmask the input PLL lock, V, confidence, biphase, parity status bits. */
+ write_cs8427_spdif_reg (devc, 17,
+ (unsigned char) BIT4 | BIT3 | BIT2 | BIT1 | BIT0);
+
+ /* 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 transfers of CS data. */
+ /* One-byte mode: both A/B channels get same written CS data. */
+ /* A channel info is output to chip's EMPH* pin. */
+ /* */
+ write_cs8427_spdif_reg (devc, 18, 0x18);
+
+ /* Use internal buffer to transmit User (U) data. */
+ /* Chip's U pin is an output. */
+ /* Transmit all 0's for user data. */
+ /* */
+ write_cs8427_spdif_reg (devc, 19, 0x10);
+
+ /* Turn on chip's RUN bit, rock and roll! */
+ /* */
+ write_cs8427_spdif_reg (devc, 4, read_cs8427_spdif_reg (devc, 4) | BIT6);
+ InitConsumerModeCS (devc);
+
+}
+
+#if 0
+static void
+WriteCsField (envy24_devc * devc, unsigned char bByteNum,
+ unsigned short bMask, unsigned short bBits)
+/*
+*****************************************************************************
+* Writes a specific field within the Channel Status block buffer.
+* bByteNum is CS byte number to access (0..23).
+* bMask is the field to be written (set bits define field).
+* bBits is the value to write into that field.
+*
+* Assumes: Reg 18 Bit 5 is cleared so CS buffer is accessible.
+* Reg 18 Bit 2 is set so E->F buffer transfer is stopped.
+****************************************************************************/
+{
+ /* Get current reg value. */
+ unsigned char bTemp = ReadCsByte (devc, bByteNum);
+
+ /* Clear field to be written. */
+ bTemp &= ~(bMask);
+
+ /* Set new values. */
+ WriteCsByte (devc, bByteNum, (unsigned char) (bTemp | (bBits & bMask)));
+}
+#endif
+
+/*ARGSUSED*/
+void
+write_cs8427_spdif (envy24_devc * devc, int d)
+{
+ int i;
+
+ if (devc->syncsource == SYNC_INTERNAL)
+ {
+ write_cs8427_spdif_reg (devc, 4,
+ read_cs8427_spdif_reg (devc, 4) & ~BIT0);
+ }
+ else
+ {
+ write_cs8427_spdif_reg (devc, 4,
+ read_cs8427_spdif_reg (devc, 4) | BIT0);
+ }
+
+ lock_cs8427_spdif (devc);
+ for (i = 0; i < 24; i++)
+ {
+ WriteCsByte (devc, i, devc->spdif_cbits[i]);
+ }
+ unlock_cs8427_spdif (devc);
+}
+
+/*
+ * Terratec stuff
+ */
+
+/*=============================================================================
+ Function : IIC_GetSDA
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char ->
+ Parameters : unsigned long dwPortAddr ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+/*ARGSUSED*/
+static unsigned char
+IIC_GetSDA (envy24_devc * devc, unsigned long dwPortAddr)
+{
+
+ unsigned char bReg, bSDA;
+
+ /* FMB TEST: RW line */
+ /* set write mask */
+ bReg = ~(0x08); /* writeable */
+ envy24_write_cci (devc, 0x21, bReg);
+
+ /* set RW line LOW */
+ bReg = 0; /* writeable */
+ envy24_write_cci (devc, 0x20, bReg);
+
+ /* Set direction: SDA to input and SCL to output */
+ bReg = envy24_read_cci (devc, 0x22);
+ bReg |= 0x20; /* SCL output = 1 */
+ bReg &= ~0x10; /* SDA input = 0 */
+ envy24_write_cci (devc, 0x22, bReg);
+
+ /* Get SDA line state */
+ bSDA = envy24_read_cci (devc, 0x20);
+
+
+ /* set RW line HIGH */
+ bReg = 0x08; /* writeable */
+ envy24_write_cci (devc, 0x20, bReg);
+
+ return 1;
+ /* return ((bSDA & 0x10) == 0x10); */
+
+}
+
+/*=============================================================================
+ Function : IIC_SetIic
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : unsigned int dwPortAddr ->
+ : unsigned char fSDA ->
+ : unsigned char fSCL ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+/*ARGSUSED*/
+static void
+IIC_SetIic (envy24_devc * devc, unsigned int dwPortAddr, unsigned char fSDA,
+ unsigned char fSCL)
+{
+ unsigned char bReg;
+
+ /* Set direction: SDA and SCL to output */
+ bReg = envy24_read_cci (devc, 0x22);
+ bReg |= (0x20 | 0x10); /* 1 -> output */
+ envy24_write_cci (devc, 0x22, bReg);
+
+ /* set write mask */
+ bReg = ~(0x20 | 0x10); /* writeable */
+ envy24_write_cci (devc, 0x21, bReg);
+
+ /* Set line state */
+ /* FMB TEST: RW line */
+ bReg = 0x08;
+/* bReg = 0; */
+ if (fSDA)
+ bReg += 0x10;
+ if (fSCL)
+ bReg += 0x20;
+ envy24_write_cci (devc, 0x20, bReg);
+
+}
+
+/*=============================================================================
+ Function : IIC_Start
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : unsigned int dwPortAddr ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+/*__inline */
+static void
+IIC_Start (envy24_devc * devc, unsigned int dwPortAddr)
+{
+ /* falling edge of SDA while SCL is HIGH */
+ IIC_SetIic (devc, dwPortAddr, 1, 1);
+ IIC_SetIic (devc, dwPortAddr, 0, 1);
+}
+
+/*=============================================================================
+ Function : IIC_Stop
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : unsigned int dwPortAddr ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+/*__inline */
+
+static void
+IIC_Stop (envy24_devc * devc, unsigned int dwPortAddr)
+{
+ /* rising edge of SDA while SCL is HIGH */
+ IIC_SetIic (devc, dwPortAddr, 0, 1);
+ IIC_SetIic (devc, dwPortAddr, 1, 1);
+}
+
+
+/*=============================================================================
+ Function : IIC_SendByte
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char ->
+ Parameters : unsigned int dwPortAddr ->
+ : unsigned char bByte ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+/*__inline */
+static unsigned char
+IIC_SendByte (envy24_devc * devc, unsigned int dwPortAddr,
+ unsigned char bByte)
+{
+ unsigned char bDataBit, bAck;
+ int i;
+
+ for (i = 7; i >= 0; i--) /* send byte (MSB first) */
+ {
+ bDataBit = (bByte >> i) & 0x01;
+
+ IIC_SetIic (devc, dwPortAddr, bDataBit, 0);
+ IIC_SetIic (devc, dwPortAddr, bDataBit, 1);
+ } /* end for i */
+
+ IIC_SetIic (devc, dwPortAddr, 1, 0);
+
+ /* Get acknowledge */
+ IIC_SetIic (devc, dwPortAddr, 1, 1);
+ bAck = IIC_GetSDA (devc, dwPortAddr);
+ /* FMB this is a start condition but never mind */
+ IIC_SetIic (devc, dwPortAddr, 0, 0);
+ return 1;
+ /* return (!bAck); *//* bAck = 0 --> success */
+}
+
+/*=============================================================================
+ Function : IIC_WriteByte
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char ->
+ Parameters : unsigned int dwPortAddr ->
+ : unsigned char bIicAddress ->
+ : unsigned char bByte ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static unsigned char
+IIC_WriteByte (envy24_devc * devc, int dwPortAddr, unsigned char bIicAddress,
+ unsigned char bByte)
+{
+ IIC_Start (devc, dwPortAddr);
+
+ /* send IIC address and data byte */
+ if (!IIC_SendByte (devc, dwPortAddr, bIicAddress))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 1 failed\n");
+ goto FAILED;
+ }
+ if (!IIC_SendByte (devc, dwPortAddr, bByte))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 2 failed\n");
+ goto FAILED;
+ }
+
+ IIC_Stop (devc, dwPortAddr);
+ return 1;
+
+FAILED:
+ IIC_Stop (devc, dwPortAddr);
+ return 0;
+}
+
+/*=============================================================================
+ FUNCTION: HW_AK4525_SetChipSelect
+-------------------------------------------------------------------------------
+ PURPOSE:
+ PARAMETERS: PDEVICE_EXTENSION pDevExt - contains the port address
+ and the OUT_SEL state
+ unsigned char bCsMask - AK4525 CS Mask: 1 means selected
+ RETURNS: int
+-------------------------------------------------------------------------------
+ NOTES: - We use the fact that the parameter bCsMask has the same layout
+ as the IIC command byte we have to send to the PCF8574
+ (wrong polarity, however)
+ - We also have to care that we don't change the output switch
+ setting. We remember the value in the Device Extension
+ - It is important that the CODECS are deselected (CS to HIGH)
+ after sue. Otherwise some IIC functions might accidentally
+ change our CODEC registers!!!
+=============================================================================*/
+static unsigned char
+HW_AK4525_SetChipSelect (envy24_devc * devc, unsigned char bCsMask)
+{
+ unsigned char bDataByte;
+ /* check validity */
+ if (bCsMask > 0x0F)
+ {
+ cmn_err (CE_CONT, "Invalid bCsMask %02x\n", bCsMask);
+ return 0; /* invalid */
+ }
+
+ /* Format data byte */
+ bDataByte = (~bCsMask) & 0x0F;
+ /* FMB PCF8574 HIGH means -10dbV, */
+ /* OutputLevelSwitch is 1 for +4dbU */
+ /* if (!pDevExt->Ews88mt.OutputLevelSwitch) */
+ /* bDataByte += 0x40; */
+
+ /* Set Chip select to LOW for selected Codecs (via IIC) */
+ if (!IIC_WriteByte (devc, devc->ccs_base, 0x48, bDataByte))
+ {
+ cmn_err (CE_CONT, "IIC_WriteByte failed\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+#define HW_AK4525_SetLines IIC_SetIic
+
+/*=============================================================================
+ FUNCTION: HW_AK4525_WriteRegister
+-------------------------------------------------------------------------------
+ PURPOSE:
+ PARAMETERS: unsigned int port - port address for IIC port
+ unsigned char bCsMask - CoDec bitmask (bits 0..3)
+ or 0xFF for all codecs together
+ unsigned char bRegIdx - offset to desired register
+ unsigned char bReg - new register value
+ RETURNS:
+-------------------------------------------------------------------------------
+ NOTES: The Chip Selects must have been set prior to this call
+ PCF8574_CODEC_IIC_ADDRESS
+
+ +-----------------------------------------------------------------+
+ | B15 B14 B13 B12 B11 B10 B09 B08|B07 B06 B05 B04 B03 B02 B01 B00 |
+ +--------+---+-------------------+--------------------------------+
+ | C1 C0 |R/W|A4 A3 A2 A1 A0 |D7 D6 D5 D4 D3 D2 D1 D0 |
+ | 1 0 |1 | <= 7 | data |
+ +--------+---+-------------------+--------------------------------+
+
+=============================================================================*/
+static unsigned char
+HW_AK4525_WriteRegister (envy24_devc * devc, unsigned char bCsMask,
+ unsigned char bRegIdx, unsigned char bRegData)
+{
+
+ unsigned short wCmd;
+ unsigned char i;
+ unsigned int port = devc->ccs_base;
+ unsigned char fData;
+
+ /* format buffer */
+ wCmd = 0xA000 + /* chip address + R/W */
+ (((unsigned short) bRegIdx) << 8) + /* register address */
+ bRegData;
+
+ /* start write cycle */
+ if (!HW_AK4525_SetChipSelect (devc, bCsMask))
+ {
+ cmn_err (CE_CONT, "HW_AK4525_SetChipSelect failed\n");
+ return 0; /* = CS to LOW -> data latched */
+ }
+
+
+ for (i = 0; i < 16; i++)
+ {
+ fData = (wCmd & 0x8000) ? 1 : 0;
+ HW_AK4525_SetLines (devc, port, fData, 0);
+ HW_AK4525_SetLines (devc, port, fData, 1); /* data is clocked in on rising edge of CCLK */
+ wCmd <<= 1;
+ }
+
+ /* leave data line HIGH (= default for IIC) */
+ HW_AK4525_SetLines (devc, port, fData, 0); /* data is clocked in on rising edge of CCLK */
+
+ /* end write cycle */
+ if (!HW_AK4525_SetChipSelect (devc, 0x00))
+ {
+ cmn_err (CE_CONT, "HW_AK4525_SetChipSelect 2 failed\n");
+ return 0; /* = all CS to HIGH -> CS to default */
+ }
+
+ /* default */
+ HW_AK4525_SetLines (devc, port, 1, 1); /* data is clocked in on rising edge of CCLK */
+
+ return 1;
+}
+
+#define EWX_CLK 0x20
+#define EWX_DTA 0x10
+
+static void
+ewx2496_iic_write_byte (envy24_devc * devc, unsigned char data,
+ unsigned char save)
+{
+ int i;
+ unsigned char gpio;
+
+ for (i = 0; i < 8; i++)
+ {
+ int fData = (data & 0x80) ? 1 : 0;
+
+ gpio = 0x08;
+ if (fData)
+ gpio |= EWX_DTA; /* DATA */
+ envy24_write_cci (devc, 0x20, gpio | save);
+ envy24_write_cci (devc, 0x20, gpio | EWX_CLK | save); /* Clock pulse */
+ envy24_write_cci (devc, 0x20, gpio | save);
+
+ data <<= 1;
+ }
+
+ envy24_write_cci (devc, 0x20, EWX_DTA | save);
+ oss_udelay (3);
+ envy24_write_cci (devc, 0x20, EWX_DTA | EWX_CLK | save); /* Clock pulse (ACK) */
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, EWX_DTA | save);
+ oss_udelay (1);
+}
+
+static unsigned char
+ewx2496_iic_read_byte (envy24_devc * devc, unsigned char save)
+{
+ int i;
+ unsigned char data = 0;
+ int b;
+
+ PRT_STATUS (0x01);
+ save |= EWX_DTA;
+ envy24_write_cci (devc, 0x20, save);
+ oss_udelay (10);
+#if 0
+ save &= ~8; /* R/W bit */
+ envy24_write_cci (devc, 0x22, ~EWX_DTA); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, EWX_DTA); /* GPIO write mask */
+#endif
+
+ for (i = 0; i < 8; i++)
+ {
+
+ envy24_write_cci (devc, 0x20, EWX_CLK | save); /* Clock pulse */
+ b = envy24_read_cci (devc, 0x20);
+ if (b & EWX_DTA)
+ data |= 0x80;
+ envy24_write_cci (devc, 0x20, save);
+
+ data >>= 1;
+ }
+
+ envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */
+ envy24_write_cci (devc, 0x20, (save & ~EWX_DTA) | 0x08); /* Low for the ACK bit */
+ envy24_write_cci (devc, 0x20, (save & ~EWX_DTA) | 0x08 | EWX_CLK); /* Clock for the ACK bit */
+ envy24_write_cci (devc, 0x20, save | 0x08);
+ oss_udelay (10);
+ return data;
+}
+
+static void
+ewx2496_iic_write (envy24_devc * devc, int addr,
+ unsigned char bRegIdx, unsigned char bRegData)
+{
+ unsigned char save;
+
+ /* start write cycle */
+ envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */
+
+ save = (envy24_read_cci (devc, 0x20) & ~(EWX_CLK | EWX_DTA)) | 0x08 /* R/W bit */
+ ;
+ /* Send start */
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA);
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK);
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save);
+ oss_udelay (1);
+
+ ewx2496_iic_write_byte (devc, addr, save);
+ ewx2496_iic_write_byte (devc, bRegIdx, save);
+ ewx2496_iic_write_byte (devc, bRegData, save);
+
+ /* Send stop */
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save);
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK);
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA);
+}
+
+static unsigned char
+ewx2496_iic_read (envy24_devc * devc, int addr, unsigned char bRegIdx)
+{
+ unsigned char save, data;
+
+ /* ewx2496_iic_write(devc, addr, bRegIdx, 0x55); */
+ PRT_STATUS (0x80);
+
+ envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */
+
+ save = (envy24_read_cci (devc, 0x20) & ~(EWX_DTA | EWX_CLK)) | 0x08 /* R/W bit */
+ ;
+ PRT_STATUS (0x02);
+ /* Send start */
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA);
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK);
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save);
+ oss_udelay (1);
+
+ ewx2496_iic_write_byte (devc, addr | 0x01, save);
+ oss_udelay (10);
+ data = ewx2496_iic_read_byte (devc, save);
+
+ /* Send stop */
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save);
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK);
+ oss_udelay (1);
+ envy24_write_cci (devc, 0x20, save | EWX_CLK | EWX_DTA);
+ oss_udelay (1);
+ PRT_STATUS (0x00);
+ return data;
+}
+
+static unsigned char
+write_ewx2496_codec (envy24_devc * devc,
+ unsigned char bRegIdx, unsigned char bRegData)
+{
+
+ unsigned short wCmd;
+ unsigned char i;
+ unsigned char fData;
+ unsigned char gpio, save;
+
+ /* format buffer */
+ wCmd = 0xA000 + /* chip address + R/W */
+ (((unsigned short) bRegIdx) << 8) + /* register address */
+ bRegData;
+
+ /* start write cycle */
+ envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, 0x00); /* GPIO write mask */
+
+ save = envy24_read_cci (devc, 0x20) & ~0x39;
+ envy24_write_cci (devc, 0x20, save | 0x09); /* CS inactive */
+ oss_udelay (200);
+ envy24_write_cci (devc, 0x20, 0x08); /* CS active */
+ oss_udelay (200);
+
+ gpio = 0x08;
+
+ for (i = 0; i < 16; i++)
+ {
+ fData = (wCmd & 0x8000) ? 1 : 0;
+
+ gpio = 0x08;
+ if (fData)
+ gpio |= 0x10; /* DATA */
+ envy24_write_cci (devc, 0x20, gpio | save);
+ oss_udelay (20);
+ envy24_write_cci (devc, 0x20, gpio | 0x20 | save); /* Clock pulse */
+ oss_udelay (200);
+ envy24_write_cci (devc, 0x20, gpio | save);
+
+ wCmd <<= 1;
+ }
+
+ oss_udelay (50);
+ envy24_write_cci (devc, 0x20, 0x01); /* CS inactive */
+ oss_udelay (20);
+
+ return 1;
+}
+
+/* Register offsets */
+enum
+{
+ AK4525_REG_POWER,
+ AK4525_REG_RESET,
+ AK4525_REG_FORMAT,
+ AK4525_REG_DEEMPHASIS,
+ AK4525_REG_LEFT_INPUT,
+ AK4525_REG_RIGHT_INPUT,
+ AK4525_REG_LEFT_OUTPUT,
+ AK4525_REG_RIGHT_OUTPUT
+};
+
+
+/*=============================================================================
+ Function : HW_AK4525_Reset
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char
+ Parameters : PCUST_HW_INSTANCE_DATA devc -
+ int nCodecIdx -> 0..3 index of Codec ,-1 -> all
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static unsigned char
+HW_AK4525_Reset (envy24_devc * devc, int nCodecIdx)
+{
+ unsigned char bCodecMask = 0;
+ if (nCodecIdx == -1)
+ bCodecMask = 0x0F;
+ else
+ bCodecMask = 0x01 << (nCodecIdx);
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */
+ AK4525_REG_RESET, 0x00)) /* DACs,ADCs -> reset */
+ {
+ cmn_err (CE_CONT, "REG_RESET failed\n");
+ return 0;
+ }
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */
+ AK4525_REG_FORMAT, 0x60)) /* IIS, 256 fsn, normal speed */
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */
+ AK4525_REG_RESET, 0x03)) /* DACs,ADCs -> normal operation */
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* 0x0F -> set mode for all codecs */
+ AK4525_REG_POWER, 0x07)) /* power on */
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc, bCodecMask, /* soft mute timeout --> short */
+ AK4525_REG_DEEMPHASIS, 0x19))
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc,
+ bCodecMask, AK4525_REG_LEFT_INPUT, 0x7f))
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc,
+ bCodecMask, AK4525_REG_RIGHT_INPUT, 0x7f))
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc,
+ bCodecMask, AK4525_REG_LEFT_OUTPUT, 0x7f))
+ return 0;
+
+ if (!HW_AK4525_WriteRegister (devc,
+ bCodecMask, AK4525_REG_RIGHT_OUTPUT, 0x7f))
+ return 0;
+
+ return 1;
+}
+
+unsigned char
+ewx2496_AK4525_Reset (envy24_devc * devc, int nCodecIdx)
+{
+ unsigned char bCodecMask = 0;
+ if (nCodecIdx == -1)
+ bCodecMask = 0x0F;
+ else
+ bCodecMask = 0x01 << (nCodecIdx);
+ envy24_write_cci (devc, 0x20, 0x03); /* Default value */
+
+ if (!write_ewx2496_codec (devc, AK4525_REG_RESET, 0x00)) /* DACs,ADCs -> reset */
+ {
+ cmn_err (CE_CONT, "REG_RESET failed\n");
+ return 0;
+ }
+
+ if (!write_ewx2496_codec (devc, AK4525_REG_FORMAT, 0x60)) /* IIS, 256 fsn, normal speed */
+ return 0;
+
+ if (!write_ewx2496_codec (devc, AK4525_REG_RESET, 0x03)) /* DACs,ADCs -> normal operation */
+ return 0;
+
+ if (!write_ewx2496_codec (devc, AK4525_REG_POWER, 0x07)) /* power on */
+ return 0;
+
+ if (!write_ewx2496_codec (devc, AK4525_REG_DEEMPHASIS, 0x19))
+ return 0;
+
+ if (!write_ewx2496_codec (devc, AK4525_REG_LEFT_INPUT, 0x7f))
+ return 0;
+
+ if (!write_ewx2496_codec (devc, AK4525_REG_RIGHT_INPUT, 0x7f))
+ return 0;
+
+ if (!write_ewx2496_codec (devc, AK4525_REG_LEFT_OUTPUT, 0x7f))
+ return 0;
+
+ if (!write_ewx2496_codec (devc, AK4525_REG_RIGHT_OUTPUT, 0x7f))
+ return 0;
+
+ return 1;
+}
+
+static void
+ews88_init_codecs (envy24_devc * devc)
+{
+ if (!HW_AK4525_Reset (devc, -1))
+ cmn_err (CE_CONT, "Envy24: EWS88MT reset failed\n");;
+}
+
+static void
+ewx2496_init_codecs (envy24_devc * devc)
+{
+ if (!ewx2496_AK4525_Reset (devc, -1))
+ cmn_err (CE_CONT, "Envy24: EWS88MT reset failed\n");;
+}
+
+static int
+envy24_set_akm (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int codec, level, i;
+ static unsigned char levels[] = { 0x7f, 0x8c, 0x98 };
+
+ if (ctrl >= 0xff)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (envy24_gain_sliders)
+ return devc->akm_gains[ctrl];
+ return devc->akm_gains[ctrl];
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+
+ if (envy24_gain_sliders)
+ level = value & 0xff;
+ else
+ {
+ if (value > 2)
+ return OSS_EINVAL;
+ level = levels[value];
+ }
+
+ codec = ctrl & 0xf0;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!(ctrl & (1 << i)))
+ continue;
+
+ write_codec (devc, codec, 4 + i, level);
+ }
+ return devc->akm_gains[ctrl] = value;
+ }
+ return OSS_EINVAL;
+}
+
+static int
+envy24_set_ap (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int level;
+ static unsigned char levels[] = { 0x60, 0x6f, 0x7f };
+
+ if (ctrl >= 0xff)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (envy24_gain_sliders)
+ return devc->akm_gains[ctrl];
+ return devc->akm_gains[ctrl];
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+
+ if (envy24_gain_sliders)
+ level = value & 0xff;
+ else
+ {
+ if (value > 2)
+ return OSS_EINVAL;
+ level = levels[value];
+ }
+
+ write_ap_codec (devc, 4, level);
+ write_ap_codec (devc, 5, level);
+ return devc->akm_gains[ctrl] = value;
+ }
+ return OSS_EINVAL;
+}
+
+static int
+envy24_set_d410 (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int level, n;
+ static unsigned char levels[] = { 0x00, 0x00, 0x0c };
+
+ if (ctrl >= 8)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (envy24_gain_sliders)
+ return devc->akm_gains[ctrl];
+ return devc->akm_gains[ctrl];
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+
+ if (envy24_gain_sliders)
+ level = 255 - value * 2;
+ else
+ {
+ if (value > 2)
+ return OSS_EINVAL;
+ level = levels[value];
+ }
+
+ if (ctrl < 6)
+ n = ctrl + 2;
+ else
+ n = ctrl + 5;
+ write_ap_codec (devc, n, level);
+ if (devc->skipdevs == 2)
+ write_ap_codec (devc, n + 1, level);
+ return devc->akm_gains[ctrl] = value;
+ }
+ return OSS_EINVAL;
+}
+
+static unsigned char
+write_ewx2496_codec (envy24_devc * devc,
+ unsigned char bRegIdx, unsigned char bRegData);
+
+static int
+envy24_set_ewx2496 (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int level;
+ static unsigned char levels[] = { 0x60, 0x6f, 0x7f };
+
+ if (ctrl >= 0xff)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (envy24_gain_sliders)
+ return devc->akm_gains[ctrl];
+ return devc->akm_gains[ctrl];
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+
+ if (envy24_gain_sliders)
+ level = value & 0xff;
+ else
+ {
+ if (value > 2)
+ return OSS_EINVAL;
+ level = levels[value];
+ }
+
+ write_ewx2496_codec (devc, 6, level);
+ write_ewx2496_codec (devc, 7, level);
+ return devc->akm_gains[ctrl] = value;
+ }
+ return OSS_EINVAL;
+}
+
+static unsigned char
+HW_AK4525_WriteRegister (envy24_devc * devc, unsigned char bCsMask,
+ unsigned char bRegIdx, unsigned char bRegData);
+
+static int
+envy24_set_ews88 (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int codec, level, i;
+ static unsigned char levels[] = { 0x7f, 0x8c, 0x98 };
+
+ if (ctrl >= 0xff)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (envy24_gain_sliders)
+ return devc->akm_gains[ctrl];
+ return devc->akm_gains[ctrl];
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+
+ if (envy24_gain_sliders)
+ level = value & 0xff;
+ else
+ {
+ if (value > 2)
+ return OSS_EINVAL;
+ level = levels[value];
+ }
+
+ codec = ctrl & 0xf0;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!(ctrl & (1 << i)))
+ continue;
+
+ if (!HW_AK4525_WriteRegister (devc, codec >> 4, 4 + i, level))
+ return OSS_EIO;
+ }
+ return devc->akm_gains[ctrl] = value;
+ }
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static int
+create_akm_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, skip, codec, ports;
+ int typ = MIXT_ENUM, range = 3;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ if (envy24_gain_sliders)
+ {
+ typ = MIXT_MONOSLIDER;
+ range = 144;
+
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0x7f;
+ }
+ else
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0;
+
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = 0x0c; /* Both output ports */
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_akm,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUTL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDOUTR");
+ else
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = (i & 1) ? 0x08 : 0x04;
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_akm,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+
+ mask = devc->inportmask;
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDIN");
+ else
+ sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = 0x03; /* Both output ports */
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_akm,
+ typ,
+ tmp, range,
+ MIXF_RECVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDINL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDINR");
+ else
+ sprintf (tmp, "ENVY24_IN%d", i + 1);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = (i & 1) ? 0x02 : 0x01;
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_akm,
+ typ,
+ tmp, range,
+ MIXF_RECVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+create_ap_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, skip, codec, ports;
+ int typ = MIXT_ENUM, range = 3;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ if (envy24_gain_sliders)
+ {
+ typ = MIXT_MONOSLIDER;
+ range = 164;
+
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0x7f;
+ }
+ else
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0;
+
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = 0x0c; /* Both output ports */
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_ap,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUTL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDOUTR");
+ else
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = (i & 1) ? 0x08 : 0x04;
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_ap,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+create_d410_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, skip;
+ int typ = MIXT_ENUM, range = 3;
+ int enum_mask = 0xffffff;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ if (envy24_gain_sliders)
+ {
+ typ = MIXT_MONOSLIDER;
+ range = 127;
+
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 127;
+ }
+ else
+ {
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 1;
+ enum_mask = 0x6;
+ }
+
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ i, envy24_set_d410,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUTL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDOUTR");
+ else
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ i, envy24_set_d410,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ envy24_set_enum_mask (dev, err, enum_mask);
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+create_ewx2496_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, skip, codec, ports;
+ int typ = MIXT_ENUM, range = 3;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ if (envy24_gain_sliders)
+ {
+ typ = MIXT_MONOSLIDER;
+ range = 164;
+
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0x7f;
+ }
+ else
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0;
+
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = 0x0c; /* Both output ports */
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports,
+ envy24_set_ewx2496, typ, tmp,
+ range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUTL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDOUTR");
+ else
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = (i & 1) ? 0x08 : 0x04;
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports,
+ envy24_set_ewx2496, typ, tmp,
+ range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+create_ews88_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, skip, codec, ports;
+ int typ = MIXT_ENUM, range = 3;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ if (envy24_gain_sliders)
+ {
+ typ = MIXT_MONOSLIDER;
+ range = 164;
+
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0x7f;
+ }
+ else
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0;
+
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ codec = 0x10 << (i / 2);
+ ports = 0x0c; /* Both output ports */
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports,
+ envy24_set_ews88, typ, tmp,
+ range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUTL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDOUTR");
+ else
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+
+ codec = 0x10 << (i / 2);
+ ports = (i & 1) ? 0x08 : 0x04;
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports,
+ envy24_set_ews88, typ, tmp,
+ range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+
+ mask = devc->inportmask;
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDIN");
+ else
+ sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2);
+
+ codec = 0x10 << (i / 2);
+ ports = 0x03; /* Both output ports */
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports,
+ envy24_set_ews88, typ, tmp,
+ range,
+ MIXF_RECVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDINL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDINR");
+ else
+ sprintf (tmp, "ENVY24_IN%d", i + 1);
+
+ codec = 0x10 << (i / 2);
+ ports = (i & 1) ? 0x02 : 0x01;
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports,
+ envy24_set_ews88, typ, tmp,
+ range,
+ MIXF_RECVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Hoontech DSP24 family
+ */
+
+
+typedef union
+{
+ struct
+ {
+ unsigned int data:5;
+ unsigned int clock:1;
+ unsigned int res0:2;
+ }
+ b;
+
+ unsigned int dwVal;
+}
+CLBYTE;
+
+#define HOONTECH_CLOCK 0x20
+
+static void
+hoontech_write_gpio (envy24_devc * devc, unsigned char data)
+{
+ envy24_write_cci (devc, 0x22, 0xff); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, 0xc0); /* GPIO write mask */
+
+ envy24_write_cci (devc, 0x20, data | HOONTECH_CLOCK); /* GPIO data */
+ envy24_write_cci (devc, 0x20, data & ~HOONTECH_CLOCK); /* GPIO data */
+ envy24_write_cci (devc, 0x20, data | HOONTECH_CLOCK); /* GPIO data */
+}
+
+static void
+hoontech_init (envy24_devc * devc)
+{
+ devc->adsp.b.box = 0;
+ devc->adsp.b.darear = 0;
+ devc->adsp.b.id0 = 0;
+ devc->adsp.b.clock0 = 1;
+ devc->adsp.b.res0 = 0x0;
+
+ devc->adsp.b.ch1 = 0x01;
+ devc->adsp.b.ch2 = 0x01;
+ devc->adsp.b.ch3 = 0x01;
+ devc->adsp.b.id1 = 1;
+ devc->adsp.b.clock1 = 1;
+ devc->adsp.b.res1 = 0x0;
+
+ devc->adsp.b.ch4 = 0x01;
+ devc->adsp.b.midiin = 0x01;
+ devc->adsp.b.midi1 = 0x0;
+ devc->adsp.b.id2 = 2;
+ devc->adsp.b.clock2 = 1;
+ devc->adsp.b.res2 = 0x0;
+
+ devc->adsp.b.midi2 = 0x0;
+ devc->adsp.b.mute = 0x0;
+ devc->adsp.b.insel = 0x1;
+ devc->adsp.b.id3 = 3;
+ devc->adsp.b.clock3 = 1;
+ devc->adsp.b.res3 = 0x0;
+
+ hoontech_write_gpio (devc, devc->adsp.w.b0);
+ hoontech_write_gpio (devc, devc->adsp.w.b1);
+ hoontech_write_gpio (devc, devc->adsp.w.b2);
+ hoontech_write_gpio (devc, devc->adsp.w.b3);
+}
+
+/**************************************************/
+
+static void
+default_card_init (envy24_devc * devc)
+{
+
+ if (devc->model_data->flags & MF_AKMCODEC)
+ {
+ write_codec (devc, AKM_A | AKM_B, 0, 0x07);
+ write_codec (devc, AKM_A | AKM_B, 1, 0x03);
+ write_codec (devc, AKM_A | AKM_B, 2, 0x60);
+ write_codec (devc, AKM_A | AKM_B, 3, 0x19);
+ write_codec (devc, AKM_A | AKM_B, 4, 0x7f);
+ write_codec (devc, AKM_A | AKM_B, 5, 0x7f);
+ write_codec (devc, AKM_A | AKM_B, 6, 0x7f);
+ write_codec (devc, AKM_A | AKM_B, 7, 0x7f);
+ }
+
+ if (devc->model_data->flags & MF_AP)
+ { /* Init the AK4528 codec of Audiophile 2496 */
+ write_ap_codec (devc, 0, 0x07);
+ write_ap_codec (devc, 1, 0x00);
+ write_ap_codec (devc, 2, 0x60);
+ write_ap_codec (devc, 3, 0x0d);
+ write_ap_codec (devc, 4, 0x7f);
+ write_ap_codec (devc, 1, 0x03);
+ write_ap_codec (devc, 5, 0x7f);
+ }
+
+ if (devc->model_data->flags & MF_D410)
+ { /* Init the AK4529 codec of Delta 410 */
+ OUTB (devc->osdev,
+ INB (devc->osdev, devc->mt_base + 0x02) & ~0x04,
+ devc->mt_base + 0x02);
+
+ write_ap_codec (devc, 0x00, 0x0c);
+ write_ap_codec (devc, 0x01, 0x02);
+ write_ap_codec (devc, 0x02, 0x00);
+ write_ap_codec (devc, 0x03, 0x00);
+ write_ap_codec (devc, 0x04, 0x00);
+ write_ap_codec (devc, 0x05, 0x00);
+ write_ap_codec (devc, 0x06, 0x00);
+ write_ap_codec (devc, 0x07, 0x00);
+ write_ap_codec (devc, 0x0b, 0x00);
+ write_ap_codec (devc, 0x0c, 0x00);
+ write_ap_codec (devc, 0x08, 0x15);
+ write_ap_codec (devc, 0x0a, 0x3f);
+ }
+
+ if (devc->model_data->flags & MF_EWS88)
+ ews88_init_codecs (devc);
+
+ if (devc->model_data->flags & MF_EWX2496)
+ ewx2496_init_codecs (devc);
+
+ if (devc->model_data->flags & MF_HOONTECH)
+ hoontech_init (devc);
+}
+
+static int
+default_mix_init (envy24_devc * devc, int dev, int group)
+{
+ int err;
+
+ if (devc->model_data->flags & MF_AKMCODEC)
+ {
+ if ((err = create_akm_mixer (dev, devc, group)) < 0)
+ return err;
+ }
+ else if (devc->model_data->flags & MF_AP)
+ {
+ if ((err = create_ap_mixer (dev, devc, group)) < 0)
+ return err;
+ }
+ else if (devc->model_data->flags & MF_D410)
+ {
+ if ((err = create_d410_mixer (dev, devc, group)) < 0)
+ return err;
+ }
+ else if (devc->model_data->flags & MF_EWS88)
+ {
+ if ((err = create_ews88_mixer (dev, devc, group)) < 0)
+ return err;
+ }
+ else if (devc->model_data->flags & MF_EWX2496)
+ {
+ if ((err = create_ewx2496_mixer (dev, devc, group)) < 0)
+ return err;
+ }
+ return 0;
+}
+
+/*ARGSUSED*/
+int
+cs8427_spdif_ioctl (envy24_devc * devc, int dev, unsigned int cmd,
+ ioctl_arg arg)
+{
+ oss_digital_control *ctrl = (oss_digital_control *) arg;
+
+ if (arg == NULL)
+ return OSS_EINVAL;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_READCTL:
+ {
+ int i, rq;
+ unsigned char status;
+
+ rq = ctrl->valid;
+ memset (ctrl, 0, sizeof (*ctrl));
+
+ ctrl->caps = DIG_CBITIN_FULL | DIG_CBITOUT_FULL;
+
+ if (rq & VAL_CBITIN)
+ {
+ for (i = 0; i < 24; i++)
+ ctrl->cbitin[i] = ReadCsByte (devc, i);
+ ctrl->valid |= VAL_CBITIN;
+ }
+
+ if (rq & VAL_CBITOUT)
+ {
+ for (i = 0; i < 24; i++)
+ ctrl->cbitin[i] = devc->spdif_cbits[i];
+ ctrl->valid |= VAL_CBITOUT;
+ }
+
+
+ if (rq & VAL_ISTATUS)
+ {
+ ctrl->valid |= VAL_ISTATUS;
+ status = read_cs8427_spdif_reg (devc, 15);
+ if (status & 0x04)
+ ctrl->in_data = IND_DATA;
+ else
+ ctrl->in_data = IND_AUDIO;
+
+ status = read_cs8427_spdif_reg (devc, 16);
+ if (status & 0x40)
+ ctrl->in_errors |= INERR_QCODE_CRC;
+ if (status & 0x20)
+ ctrl->in_errors |= INERR_CRC;
+
+ if (status & 0x10)
+ ctrl->in_locked = LOCK_UNLOCKED;
+ else
+ ctrl->in_locked = LOCK_LOCKED;
+
+ if (status & 0x08)
+ ctrl->in_vbit = VBIT_ON;
+ else
+ ctrl->in_vbit = VBIT_OFF;
+
+ if (status & 0x04)
+ ctrl->in_quality = IN_QUAL_POOR;
+ else
+ ctrl->in_quality = IN_QUAL_GOOD;
+
+ if (status & 0x02)
+ ctrl->in_errors |= INERR_BIPHASE;
+
+ if (status & 0x01)
+ ctrl->in_errors |= INERR_PARITY;
+
+#if 1
+ /* TODO: Better handling required */
+ write_cs8427_spdif_reg (devc, 18, 0x00);
+#endif
+ }
+ }
+ return 0;
+ break;
+
+ case SNDCTL_DSP_WRITECTL:
+ {
+ int i, rq;
+
+ rq = ctrl->valid;
+ memset (ctrl, 0, sizeof (*ctrl));
+
+ ctrl->caps = DIG_CBITOUT_FULL;
+
+ if (rq & VAL_CBITOUT)
+ {
+ for (i = 0; i < 24; i++)
+ devc->spdif_cbits[i] = ctrl->cbitout[i];
+ ctrl->valid |= VAL_CBITOUT;
+
+ lock_cs8427_spdif (devc);
+ for (i = 0; i < 24; i++)
+ {
+ WriteCsByte (devc, i, devc->spdif_cbits[i]);
+ }
+ unlock_cs8427_spdif (devc);
+ }
+ }
+ return 0;
+ break;
+
+ default:;
+ }
+ return OSS_EINVAL;
+}
+
+static int
+set_spdif_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ switch (ctrl)
+ {
+ case 1:
+ return devc->spdif_pro_mode;
+ break;
+ }
+
+ return OSS_EIO;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case 1:
+ return devc->spdif_pro_mode = !!value;
+ break;
+ }
+
+ return OSS_EIO;
+ }
+
+ return OSS_EIO;
+}
+
+/*ARGSUSED*/
+int
+cs8427_spdif_mixer_init (envy24_devc * devc, int dev, int group)
+{
+ int err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_SPDIF")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, set_spdif_control,
+ MIXT_ENUM,
+ "SPDIF_MODE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+static void
+set_ap_speed (envy24_devc * devc)
+{
+ unsigned char gpio, tmp;
+
+ tmp = devc->speedbits;
+ if (devc->syncsource != SYNC_INTERNAL)
+ {
+ tmp |= 0x10; /* S/PDIF input clock select */
+ if (devc->model_data->flags & MF_WCLOCK) /* Has world clock too */
+ {
+ int cmd = envy24_read_cci (devc, 0x20);
+ cmd |= 0x10; /* S/PDIF */
+ if (devc->syncsource == SYNC_WCLOCK)
+ cmd &= ~0x10; /* World clock */
+ envy24_write_cci (devc, 0x20, cmd);
+ }
+ }
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+
+ if (devc->speed > 48000)
+ {
+ write_ap_codec (devc, 0x01, 0x00);
+ gpio = envy24_read_cci (devc, 0x20);
+ gpio |= 0x01; /* Turn DFS ON */
+ envy24_write_cci (devc, 0x20, gpio);
+ write_ap_codec (devc, 0x02, 0x65);
+ write_ap_codec (devc, 0x01, 0x03);
+ }
+ else
+ {
+ write_ap_codec (devc, 0x01, 0x00);
+ gpio = envy24_read_cci (devc, 0x20);
+ gpio &= ~0x01; /* Turn DFS OFF */
+ envy24_write_cci (devc, 0x20, gpio);
+ write_ap_codec (devc, 0x02, 0x60);
+ write_ap_codec (devc, 0x01, 0x03);
+ }
+}
+
+envy24_auxdrv_t default_auxdrv = {
+ default_card_init,
+ default_mix_init,
+ NULL,
+ write_spdif
+};
+
+envy24_auxdrv_t ap2496_auxdrv = {
+ default_card_init,
+ default_mix_init,
+ init_cs8427_spdif,
+ write_cs8427_spdif,
+ cs8427_spdif_ioctl,
+ read_ap_spdif_reg,
+ write_ap_spdif_reg,
+ set_ap_speed,
+ NULL,
+ cs8427_spdif_mixer_init
+};
+
+envy24_auxdrv_t d410_auxdrv = {
+ default_card_init,
+ default_mix_init,
+ init_cs8427_spdif,
+ write_cs8427_spdif,
+ cs8427_spdif_ioctl,
+ read_ap_spdif_reg,
+ write_ap_spdif_reg,
+ NULL,
+ NULL,
+ cs8427_spdif_mixer_init
+};
+
+envy24_auxdrv_t ewx2496_auxdrv = {
+ default_card_init,
+ default_mix_init,
+ init_cs8427_spdif,
+ write_cs8427_spdif,
+ NULL,
+ read_ewx2496_spdif_reg,
+ write_ewx2496_spdif_reg,
+ NULL,
+ NULL,
+ cs8427_spdif_mixer_init
+};
diff --git a/kernel/drv/oss_envy24/envy24_direct.c b/kernel/drv/oss_envy24/envy24_direct.c
new file mode 100644
index 0000000..9448c6c
--- /dev/null
+++ b/kernel/drv/oss_envy24/envy24_direct.c
@@ -0,0 +1,415 @@
+/*
+ * Purpose: Direct 24 bit multich driver for Envy24.
+ *
+ * This driver implements the all inputs and all outputs audio devices for
+ * envy24. Unlike the ordinary driver this one doesn't use additional buffering.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "ac97.h"
+
+#ifdef USE_LICENSING
+#include "private/licensing/licensing.h"
+#endif
+
+#include "envy24.h"
+
+#define OUTCH_NAMES "CH1/2 CH3/4 CH5/6 CH7/8 digital"
+#define INCH_NAMES "CH1/2 CH3/4 CH5/6 CH7/8 digital monitor_mix"
+
+/*
+ * Audio routines
+ */
+extern int envy24_audio_set_rate (int dev, int arg);
+int envy24d_get_buffer_pointer (int dev, dmap_t * dmap, int direction);
+
+void
+envy24d_playintr (envy24_devc * devc)
+{
+ oss_audio_outputintr (devc->direct_portc_out.audio_dev, 0);
+}
+
+void
+envy24d_recintr (envy24_devc * devc)
+{
+ oss_audio_inputintr (devc->direct_portc_in.audio_dev, 0);
+}
+
+/*ARGSUSED*/
+static short
+envy24d_audio_set_channels (int dev, short arg)
+{
+ envy24d_portc *portc = audio_engines[dev]->portc;
+ return portc->channels;
+}
+
+/*ARGSUSED*/
+static unsigned int
+envy24d_audio_set_format (int dev, unsigned int arg)
+{
+ return AFMT_S32_LE;
+}
+
+/*ARGSUSED*/
+static int
+envy24d_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void envy24d_audio_trigger (int dev, int state);
+
+static void
+envy24d_audio_reset (int dev)
+{
+ envy24d_audio_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static int
+envy24d_audio_open (int dev, int mode, int open_flags)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+ envy24d_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ if (!(mode & portc->direction))
+ return OSS_EINVAL;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode != 0 || (devc->direct_audio_opened & mode))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (mode == OPEN_WRITE && (devc->play_channel_mask != 0))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (mode == OPEN_READ && (devc->rec_channel_mask != 0))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ devc->direct_audio_opened |= mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+envy24d_audio_close (int dev, int mode)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+ envy24d_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->open_mode = 0;
+ devc->direct_audio_opened &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static void
+envy24d_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+envy24d_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+}
+
+static void
+envy24d_audio_trigger (int dev, int state)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+ envy24d_portc *portc = audio_engines[dev]->portc;
+ int changed;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ changed = state ^ portc->trigger_bits;
+
+ if (portc->direction == OPEN_WRITE && (changed & PCM_ENABLE_OUTPUT))
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Envy24d: Trigger start output");
+#endif
+ portc->trigger_bits = state;
+ envy24_launch_play_engine (devc);
+ }
+ else
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Envy24d: Trigger stop output");
+#endif
+ portc->trigger_bits = state;
+ envy24_stop_playback (devc);
+ }
+ }
+
+ if (portc->direction == OPEN_READ && (changed & PCM_ENABLE_INPUT))
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Envy24d: Trigger start input");
+#endif
+ portc->trigger_bits = state;
+ envy24_launch_recording (devc);
+ }
+ else
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Envy24d: Trigger stop input");
+#endif
+ portc->trigger_bits = state;
+ envy24_stop_recording (devc);
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+envy24d_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+ envy24_start_recording (devc);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+envy24d_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+
+ envy24_prepare_play_engine (devc);
+ return 0;
+}
+
+static int
+envy24d_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+
+ if (direction == OPEN_WRITE)
+ {
+ if (devc->playbuf == NULL)
+ {
+ cmn_err (CE_CONT, "Envy24: No playback DMA buffer available\n");
+ return OSS_ENOSPC;
+ }
+
+ dmap->dmabuf = devc->playbuf;
+ dmap->buffsize = devc->playbuffsize;
+ dmap->dmabuf_phys = devc->playbuf_phys;
+ return 0;
+ }
+
+ if (direction == OPEN_READ)
+ {
+ if (devc->recbuf == NULL)
+ {
+ cmn_err (CE_CONT, "Envy24: No recording DMA buffer available\n");
+ return OSS_ENOSPC;
+ }
+
+ dmap->dmabuf = devc->recbuf;
+ dmap->buffsize = devc->recbuffsize;
+ dmap->dmabuf_phys = devc->recbuf_phys;
+ return 0;
+ }
+
+ return OSS_EIO;
+}
+
+/*ARGSUSED*/
+static int
+envy24d_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ dmap->dmabuf = NULL;
+ dmap->dmabuf_phys = 0;
+ dmap->buffsize = 0;
+ return 0;
+}
+
+int
+envy24d_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+
+ envy24_devc *devc = audio_engines[dev]->devc;
+ int pos;
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ pos = INW (devc->osdev, devc->mt_base + 0x14);
+ pos = (pos + 1) * 4;
+ pos = dmap->bytes_in_use - pos;
+
+ return pos;
+ }
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ pos = INW (devc->osdev, devc->mt_base + 0x24);
+ pos = (pos + 1) * 4;
+ pos = dmap->bytes_in_use - pos;
+
+ return pos;
+ }
+
+ return OSS_EIO;
+}
+
+/*ARGSUSED*/
+static int
+envy24d_check_input (int dev)
+{
+ cmn_err (CE_WARN, "Envy24d: Input timed out.\n");
+ return OSS_EIO;
+}
+
+/*ARGSUSED*/
+static int
+envy24d_check_output (int dev)
+{
+ cmn_err (CE_WARN, "Envy24d: Output timed out (%d)\n", GET_JIFFIES ());
+ return OSS_EIO;
+}
+
+static const audiodrv_t envy24d_audio_driver = {
+ envy24d_audio_open,
+ envy24d_audio_close,
+ envy24d_audio_output_block,
+ envy24d_audio_start_input,
+ envy24d_audio_ioctl,
+ envy24d_audio_prepare_for_input,
+ envy24d_audio_prepare_for_output,
+ envy24d_audio_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ envy24d_audio_trigger,
+ envy24_audio_set_rate,
+ envy24d_audio_set_format,
+ envy24d_audio_set_channels,
+ NULL,
+ NULL,
+ envy24d_check_input,
+ envy24d_check_output,
+ envy24d_alloc_buffer,
+ envy24d_free_buffer,
+ NULL,
+ NULL,
+ envy24d_get_buffer_pointer
+};
+
+void
+envy24d_install (envy24_devc * devc)
+{
+
+ int adev, out_dev, in_dev;
+ char tmpname[128];
+ envy24d_portc *portc;
+
+ /*
+ * Output device
+ */
+ sprintf (tmpname, "%s (all outputs)", devc->model_data->product);
+
+ if ((out_dev = adev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmpname,
+ &envy24d_audio_driver,
+ sizeof (audiodrv_t),
+ ADEV_NOVIRTUAL | ADEV_NOINPUT | ADEV_COLD
+ | ADEV_SPECIAL | ADEV_32BITONLY,
+ AFMT_S32_LE, devc, -1,
+ "10ch_out")) >= 0)
+ {
+ portc = &devc->direct_portc_out;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = devc->first_dev;
+ audio_engines[adev]->caps |= DSP_CH_MULTI;
+ audio_engines[adev]->min_channels = 10;
+ audio_engines[adev]->max_channels = 10;
+ audio_engines[adev]->outch_names = OUTCH_NAMES;
+ audio_engines[adev]->min_block = devc->hw_pfragsize;
+ audio_engines[adev]->max_block = devc->hw_pfragsize;
+ audio_engines[adev]->min_rate = 8000;
+ audio_engines[adev]->max_rate = 96000;
+
+ audio_engines[adev]->mixer_dev = devc->mixer_dev;
+ devc->direct_audio_opened = 0;
+ portc->open_mode = 0;
+ portc->audio_dev = adev;
+ portc->channels = 10;
+ portc->direction = OPEN_WRITE;
+ audio_engines[adev]->port_number = 0; /* First output channel */
+ }
+
+ /*
+ * Input device
+ */
+ sprintf (tmpname, "%s (all inputs)", devc->model_data->product);
+
+ if ((adev = in_dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmpname,
+ &envy24d_audio_driver,
+ sizeof (audiodrv_t),
+ ADEV_NOVIRTUAL | ADEV_NOOUTPUT | ADEV_COLD
+ | ADEV_SPECIAL | ADEV_32BITONLY,
+ AFMT_S32_LE, devc, -1,
+ "12ch_in")) >= 0)
+ {
+ portc = &devc->direct_portc_in;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = devc->first_dev;
+ audio_engines[adev]->caps |= DSP_CH_MULTI;
+ audio_engines[adev]->min_channels = 12;
+ audio_engines[adev]->max_channels = 12;
+ audio_engines[adev]->inch_names = INCH_NAMES;
+ audio_engines[adev]->min_rate = 8000;
+ audio_engines[adev]->max_rate = 96000;
+
+ audio_engines[adev]->mixer_dev = devc->mixer_dev;
+ devc->direct_audio_opened = 0;
+ portc->open_mode = 0;
+ portc->audio_dev = adev;
+ audio_engines[adev]->min_block = devc->hw_pfragsize;
+ audio_engines[adev]->max_block = devc->hw_pfragsize;
+ portc->channels = 12;
+ portc->direction = OPEN_READ;
+ audio_engines[adev]->port_number = 10; /* First input channel */
+ }
+}
diff --git a/kernel/drv/oss_envy24/envy24_ews88d.c b/kernel/drv/oss_envy24/envy24_ews88d.c
new file mode 100644
index 0000000..c68be60
--- /dev/null
+++ b/kernel/drv/oss_envy24/envy24_ews88d.c
@@ -0,0 +1,377 @@
+/*
+ * Purpose: Card specific routines for Terratec EWS88D.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "ac97.h"
+#include "envy24.h"
+
+#if 0
+# define PRT_STATUS(v) outb(v&0xff, 0x378)
+#else
+# define PRT_STATUS(v)
+#endif
+
+/* PCF8575 pin assignment (default 0xffff) */
+#define PCF_SPDIN_SELECT 0x0001 /* 0=optical 1=coax */
+#define PCF_OPTOUT 0x0002 /* 0=SPDIF 1=ADAT */
+#define PCF_CLOCKSRC 0x0004 /* 0=ADAT 1=SPDIF */
+#define PCF_ADATEN 0x0008 /* 0=ADAT disabled 1=ADAT enabled */
+#define PCF_ADATLOOP_ 0x0010 /* 0=ADAT in->out loop, 1=no loop */
+#define PCF_CS8414_ERF_ 0x0020 /* Inverted CS8414 ERF */
+#define PCF_SPDIF_ERR 0x0040 /* OR'ed from CS8414 E0..E2 */
+#define PCF_ADAT_ERROR 0x0080 /* ADAT error input */
+
+extern int envy24_gain_sliders;
+extern int envy24_virtualout;
+extern int envy24_zerolatency; /* Testing in progress */
+/*
+ * Terratec stuff
+ */
+
+/*=============================================================================
+ Function : IIC_GetSDA
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char ->
+ Parameters : unsigned long dwPortAddr ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static __inline__ unsigned char
+IIC_GetSDA (envy24_devc * devc, unsigned long dwPortAddr)
+{
+
+ unsigned char bReg, bSDA;
+
+ /* FMB TEST: RW line */
+ /* set write mask */
+ bReg = ~(0x08); /* writeable */
+ envy24_write_cci (devc, 0x21, bReg);
+
+ /* set RW line LOW */
+ bReg = 0; /* writeable */
+ envy24_write_cci (devc, 0x20, bReg);
+
+ /* Set direction: SDA to input and SCL to output */
+ bReg = envy24_read_cci (devc, 0x22);
+ bReg |= 0x20; /* SCL output = 1 */
+ bReg &= ~0x10; /* SDA input = 0 */
+ envy24_write_cci (devc, 0x22, bReg);
+
+ /* Get SDA line state */
+ bSDA = envy24_read_cci (devc, 0x20);
+
+ /* set RW line HIGH */
+ bReg = 0x08; /* writeable */
+ envy24_write_cci (devc, 0x20, bReg);
+
+ return 1;
+ /* return ((bSDA & 0x10) == 0x10); */
+
+}
+
+/*=============================================================================
+ Function : IIC_SetIic
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : unsigned int dwPortAddr ->
+ : unsigned char fSDA ->
+ : unsigned char fSCL ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static __inline__ void
+IIC_SetIic (envy24_devc * devc, unsigned int dwPortAddr, unsigned char fSDA,
+ unsigned char fSCL)
+{
+ unsigned char bReg;
+
+ /* Set direction: SDA and SCL to output */
+ bReg = envy24_read_cci (devc, 0x22);
+ bReg |= (0x20 | 0x10); /* 1 -> output */
+ envy24_write_cci (devc, 0x22, bReg);
+
+ /* set write mask */
+ bReg = ~(0x20 | 0x10); /* writeable */
+ envy24_write_cci (devc, 0x21, bReg);
+
+ /* Set line state */
+ /* FMB TEST: RW line */
+ bReg = 0x08;
+/* bReg = 0; */
+ if (fSDA)
+ bReg += 0x10;
+ if (fSCL)
+ bReg += 0x20;
+ envy24_write_cci (devc, 0x20, bReg);
+
+}
+
+/*=============================================================================
+ Function : IIC_Start
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : unsigned int dwPortAddr ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static __inline__ void
+IIC_Start (envy24_devc * devc, unsigned int dwPortAddr)
+{
+ /* falling edge of SDA while SCL is HIGH */
+ IIC_SetIic (devc, dwPortAddr, 1, 1);
+ IIC_SetIic (devc, dwPortAddr, 0, 1);
+}
+
+/*=============================================================================
+ Function : IIC_Stop
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : unsigned int dwPortAddr ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static __inline__ void
+IIC_Stop (envy24_devc * devc, unsigned int dwPortAddr)
+{
+ /* rising edge of SDA while SCL is HIGH */
+ IIC_SetIic (devc, dwPortAddr, 0, 1);
+ IIC_SetIic (devc, dwPortAddr, 1, 1);
+}
+
+
+/*=============================================================================
+ Function : IIC_SendByte
+-------------------------------------------------------------------------------
+ Description :
+ Returns : unsigned char ->
+ Parameters : unsigned int dwPortAddr ->
+ : unsigned char bByte ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+/*__inline */
+static unsigned char
+IIC_SendByte (envy24_devc * devc, unsigned int dwPortAddr,
+ unsigned char bByte)
+{
+ unsigned char bDataBit, bAck;
+ int i;
+
+ for (i = 7; i >= 0; i--) /* send byte (MSB first) */
+ {
+ bDataBit = (bByte >> i) & 0x01;
+
+ IIC_SetIic (devc, dwPortAddr, bDataBit, 0);
+ IIC_SetIic (devc, dwPortAddr, bDataBit, 1);
+ } /* end for i */
+
+ IIC_SetIic (devc, dwPortAddr, 1, 0);
+
+ /* Get acknowledge */
+ IIC_SetIic (devc, dwPortAddr, 1, 1);
+ bAck = IIC_GetSDA (devc, dwPortAddr);
+ /* FMB this is a start condition but never mind */
+ IIC_SetIic (devc, dwPortAddr, 0, 0);
+ return 1;
+ /* return (!bAck); *//* bAck = 0 --> success */
+}
+
+static unsigned char
+IIC_WriteWord (envy24_devc * devc, int dwPortAddr, unsigned char bIicAddress,
+ unsigned short bByte)
+{
+ IIC_Start (devc, dwPortAddr);
+
+ /* send IIC address and data byte */
+ if (!IIC_SendByte (devc, dwPortAddr, bIicAddress))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 1 failed\n");
+ goto FAILED;
+ }
+ if (!IIC_SendByte (devc, dwPortAddr, bByte & 0xff))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 3 failed\n");
+ goto FAILED;
+ }
+ if (!IIC_SendByte (devc, dwPortAddr, (bByte >> 8) & 0xff))
+ {
+ cmn_err (CE_CONT, "IIC_SendByte 2 failed\n");
+ goto FAILED;
+ }
+
+ IIC_Stop (devc, dwPortAddr);
+ return 1;
+
+FAILED:
+ IIC_Stop (devc, dwPortAddr);
+ return 0;
+}
+
+static void
+ews88d_set_pcf8575 (envy24_devc * devc, unsigned short d)
+{
+ if (!IIC_WriteWord (devc, devc->ccs_base, 0x40, d))
+ {
+ cmn_err (CE_CONT, "IIC_WriteWord failed\n");
+ }
+ devc->gpio_tmp = d;
+}
+
+static void
+ews88d_card_init (envy24_devc * devc)
+{
+ ews88d_set_pcf8575 (devc, 0xffff);
+}
+
+static void
+set_ews88d_speed (envy24_devc * devc)
+{
+ int tmp;
+
+ tmp = devc->speedbits;
+
+ switch (devc->syncsource)
+ {
+ case SYNC_INTERNAL:
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ break;
+
+ case SYNC_SPDIF:
+ tmp |= 0x10;
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ devc->gpio_tmp &= ~PCF_CLOCKSRC;
+ ews88d_set_pcf8575 (devc, devc->gpio_tmp);
+ break;
+
+ case SYNC_WCLOCK:
+ tmp |= 0x10;
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ devc->gpio_tmp |= PCF_CLOCKSRC;
+ ews88d_set_pcf8575 (devc, devc->gpio_tmp);
+ break;
+ }
+
+ if (devc->speed > 48000)
+ {
+ devc->gpio_tmp &= ~PCF_ADATEN;
+ ews88d_set_pcf8575 (devc, devc->gpio_tmp);
+ }
+ else
+ {
+ devc->gpio_tmp |= PCF_ADATEN;
+ ews88d_set_pcf8575 (devc, devc->gpio_tmp);
+ }
+}
+
+static int
+ews88d_mixer_set (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ switch (ctrl)
+ {
+ case 1:
+ return !!(devc->gpio_tmp & PCF_SPDIN_SELECT);
+ break;
+
+ case 2:
+ return !!(devc->gpio_tmp & PCF_OPTOUT);
+ break;
+
+ case 3:
+ return !(devc->gpio_tmp & PCF_ADATLOOP_);
+ break;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ switch (ctrl)
+ {
+ case 1:
+ devc->gpio_tmp &= ~PCF_SPDIN_SELECT;
+ if (value)
+ devc->gpio_tmp |= PCF_SPDIN_SELECT;
+ ews88d_set_pcf8575 (devc, devc->gpio_tmp);
+ return !!(devc->gpio_tmp & PCF_SPDIN_SELECT);
+ break;
+
+ case 2:
+ devc->gpio_tmp &= ~PCF_OPTOUT;
+ if (value)
+ devc->gpio_tmp |= PCF_OPTOUT;
+ ews88d_set_pcf8575 (devc, devc->gpio_tmp);
+ return !!(devc->gpio_tmp & PCF_OPTOUT);
+ break;
+
+ case 3:
+ devc->gpio_tmp &= ~PCF_ADATLOOP_;
+ if (!value)
+ devc->gpio_tmp |= PCF_ADATLOOP_;
+ ews88d_set_pcf8575 (devc, devc->gpio_tmp);
+ return !(devc->gpio_tmp & PCF_ADATLOOP_);
+ break;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+ews88d_mix_init (envy24_devc * devc, int dev, int group)
+{
+ int err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_EWS88D")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, ews88d_mixer_set,
+ MIXT_ENUM,
+ "EWS88D_SPDIN", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, ews88d_mixer_set,
+ MIXT_ENUM,
+ "EWS88D_OPTOUT", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, ews88d_mixer_set,
+ MIXT_ONOFF,
+ "EWS88D_ADATLOOP", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+envy24_auxdrv_t ews88d_auxdrv = {
+ ews88d_card_init,
+ ews88d_mix_init,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ set_ews88d_speed,
+ NULL,
+ cs8427_spdif_mixer_init
+};
diff --git a/kernel/drv/oss_envy24/envy24_tdif.c b/kernel/drv/oss_envy24/envy24_tdif.c
new file mode 100644
index 0000000..4f247fd
--- /dev/null
+++ b/kernel/drv/oss_envy24/envy24_tdif.c
@@ -0,0 +1,687 @@
+/*
+ * Purpose: Card specific routines for M Audio Delta TDIF
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "ac97.h"
+#include "envy24.h"
+#include "envy24_tdif.h"
+
+#define CDC_CLK 1 /* Clock input to the CODEC's, rising edge clocks data. */
+#define CDC_DIN 2 /* Data input to Envy from the CODEC. */
+#define CDC_DOUT 3 /* Data output from Envy to the CODEC. */
+#define CS8_CS 2 /* Chip select (0=select) for the SPDIF tx/rx. */
+#define CDC_CS 3 /* Chip select (0=select) for the CODEC. */
+#define CS_ASSERT 0 /* Asserted chip select (selects are inverted). */
+#define CS_RELEASE 1 /* Idle chip select (selects are inverted). */
+
+
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+
+#define CS8_CLK CDC_CLK
+#define CS8_DIN CDC_DIN
+#define CS8_DOUT CDC_DOUT
+#define CS_TRUE CS_ASSERT
+#define CS_FALSE CS_RELEASE
+#define CS8_ADDR 0x20 /* Chip SPI/I2C address */
+#define CS8_RD 0x01
+#define CS8_WR 0x00
+
+#if 0
+# define PRT_STATUS(v) outb(v&0xff, 0x378)
+#else
+# define PRT_STATUS(v)
+#endif
+
+/* ----- DEFINITION OF GPIOs ----- */
+
+#define FPGA_PROGRAM_L 7 /* FPGA program control select line (active low) */
+#define FPGA_CLK 1 /* FPGA program clock */
+#define EXT_REG_CLK 0 /* Was GPIO Fast mode (debug) */
+#define FPGA_D0 3 /* FPGA program data */
+
+#define LATCH_EN_L 4 /* Strobe for external latch (active low) */
+#define FPGA_MUTE 5
+
+#define FPGA_INIT_STATE 0xFC /* Init state for extern register to allow */
+ /* FPGA initialization. */
+
+#define FPGA_MASTER 5
+
+extern int envy24_gain_sliders;
+extern int envy24_virtualout;
+extern int envy24_zerolatency; /* Testing in progress */
+
+static void
+WriteExternReg (envy24_devc * devc, unsigned char bData)
+/* Initialize external register by serially shifting the data out */
+/* and then strobe the external latch. */
+{
+ int i;
+
+ devc->gpio_tmp = bData;
+
+ WriteGPIObit (devc, LATCH_EN_L, 0); /* DISABLE External Latch */
+
+ /* FPGA clock to low */
+ WriteGPIObit (devc, EXT_REG_CLK, 0);
+
+ for (i = 0; i < 8; i++)
+ {
+ /* Present data */
+ WriteGPIObit (devc, FPGA_D0, !!(bData & 0x80));
+ /* clock data in */
+ WriteGPIObit (devc, EXT_REG_CLK, 1);
+ WriteGPIObit (devc, EXT_REG_CLK, 0);
+ /* next bit */
+ bData = bData << 1;
+ }
+
+ WriteGPIObit (devc, LATCH_EN_L, 1); /* STROBE External Latch */
+ WriteGPIObit (devc, LATCH_EN_L, 0); /* DISABLE External Latch */
+}
+
+static void
+WriteExternRegBit (envy24_devc * devc, int bit, int value)
+{
+ devc->gpio_tmp &= ~(1 << bit);
+ if (value)
+ devc->gpio_tmp |= (1 << bit);
+ WriteExternReg (devc, devc->gpio_tmp);
+}
+
+static void
+tdif_pause (int n)
+/*
+*****************************************************************************
+* Programmable pause.
+****************************************************************************/
+{
+ static int d;
+ int i;
+
+ for (i = 0; i < n; i++)
+ for (d = 1000L; d--;);
+}
+
+/****************************************************************************/
+
+
+static void
+TDIF_InitFPGA (envy24_devc * devc)
+/*
+*****************************************************************************
+* Initialize FPGA
+* wInst = PCI slot code of specific board.
+* Hardware = Spartan II FPGA (XC2S50-5TQ144)
+****************************************************************************/
+{
+ int bReadByte;
+ int i, j;
+
+#if 0
+ if (envy24_read_cci (devc, 0x20) & 0x40)
+ {
+ DDB (cmn_err (CE_CONT, "envy24: FPGA is already up and running\n"));
+ return;
+ }
+#endif
+
+ cmn_err (CE_CONT, "Envy24: Loading FPGA - please wait\n");
+
+ /*Init external register */
+ WriteGPIObit (devc, FPGA_PROGRAM_L, 1); /*DISABLE FPGA Programming */
+ WriteGPIObit (devc, LATCH_EN_L, 0); /*DISABLE External Latch */
+
+ bReadByte = FPGA_INIT_STATE;
+
+ WriteExternReg (devc, bReadByte);
+
+ /*Pull PROGRAM# pin LOW to start loading configuration data */
+ WriteGPIObit (devc, FPGA_PROGRAM_L, 0);
+ tdif_pause (10);
+ WriteGPIObit (devc, FPGA_PROGRAM_L, 1);
+
+ for (j = 0; j < sizeof (fpga_code); j++)
+ {
+ bReadByte = fpga_code[j];
+ for (i = 0; i < 8; i++)
+ {
+ /*FPGA clock to low */
+ WriteGPIObit (devc, FPGA_CLK, 0);
+ /*Present data */
+ WriteGPIObit (devc, FPGA_D0, !!(bReadByte & 0x80));
+ /*clock data in */
+ WriteGPIObit (devc, FPGA_CLK, 1);
+
+ /*next bit */
+ bReadByte = bReadByte << 1;
+ }
+
+ }
+
+ /*Some clocks to start FPGA */
+ for (i = 0; i < 64; i++)
+ {
+ /*FPGA clock to low */
+ WriteGPIObit (devc, FPGA_CLK, 0);
+ /*clock data in */
+ WriteGPIObit (devc, FPGA_CLK, 1);
+ }
+
+ if (!(envy24_read_cci (devc, 0x20) & 0x40))
+ cmn_err (CE_CONT, "Envy24: FPGA failed to initialize\n");
+ else
+ DDB (cmn_err (CE_CONT, "FPGA is up and running\n"));
+
+ oss_udelay (10);
+ WriteExternRegBit (devc, FPGA_MUTE, 1); /* Keep it still muted */
+
+}
+
+static void
+write_tdif_codec (envy24_devc * devc, int bRegister, unsigned char bData)
+/*
+
+*****************************************************************************
+* Writes a byte to a specific register of the Delta-AP CODEC.
+* Register must be (0..15).
+****************************************************************************/
+{
+ unsigned char bMask;
+
+ bRegister = (bRegister & 0x0F) | 0xA0; /* Add I2C address field. */
+
+ /* Assert the CODEC chip select and wait at least 150 nS. */
+ /* */
+ WriteExternRegBit (devc, CDC_CS, CS_TRUE);
+
+ /* Write the register address byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bRegister)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+
+ /* Write the data byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bData)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+ /* De-assert chip select. */
+ /* */
+ WriteExternRegBit (devc, CDC_CS, CS_FALSE);
+}
+
+static void write_tdif_spdif_reg (envy24_devc * devc, int bRegister,
+ int bData);
+static int read_tdif_spdif_reg (envy24_devc * devc, int bRegister);
+
+static void
+tdif_card_init (envy24_devc * devc)
+{
+ WriteExternReg (devc, 0xfc);
+ TDIF_InitFPGA (devc);
+ write_tdif_spdif_reg (devc, 4, read_tdif_spdif_reg (devc, 4) & (~BIT0));
+ WriteGPIObit (devc, FPGA_MASTER, 1);
+ WriteExternRegBit (devc, 4, 1); /* Disable TDIF master PLL */
+ WriteExternRegBit (devc, 6, 0); /* Don't route PLL master clock to Envy24. */
+
+ write_tdif_codec (devc, 0, 0x07);
+ write_tdif_codec (devc, 1, 0x00);
+ write_tdif_codec (devc, 2, 0x60);
+ write_tdif_codec (devc, 3, 0x0d);
+ write_tdif_codec (devc, 4, 0x7f);
+ write_tdif_codec (devc, 1, 0x03);
+ write_tdif_codec (devc, 5, 0x7f);
+}
+
+static void
+tdif_card_uninit (envy24_devc * devc)
+{
+ WriteGPIObit (devc, FPGA_PROGRAM_L, 1); /*DISABLE FPGA Programming */
+ WriteGPIObit (devc, LATCH_EN_L, 0); /*DISABLE External Latch */
+ WriteGPIObit (devc, FPGA_PROGRAM_L, 0);
+}
+
+static int
+envy24_set_tdif (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int level;
+ static unsigned char levels[] = { 0x60, 0x6f, 0x7f };
+
+ if (ctrl >= 0xff)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (envy24_gain_sliders)
+ return devc->akm_gains[ctrl];
+ return devc->akm_gains[ctrl];
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+
+ if (envy24_gain_sliders)
+ level = value & 0xff;
+ else
+ {
+ if (value > 2)
+ return OSS_EINVAL;
+ level = levels[value];
+ }
+
+ write_tdif_codec (devc, 4, level);
+ write_tdif_codec (devc, 5, level);
+ return devc->akm_gains[ctrl] = value;
+ }
+ return OSS_EINVAL;
+}
+
+
+static int
+tdif_mix_init (envy24_devc * devc, int dev, int group)
+{
+ int i, mask = devc->outportmask, err, skip, codec, ports;
+ int typ = MIXT_ENUM, range = 3;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_GAIN")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ if (envy24_gain_sliders)
+ {
+ typ = MIXT_MONOSLIDER;
+ range = 164;
+
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0x7f;
+ }
+ else
+ for (i = 0; i < 0xff; i++)
+ devc->akm_gains[i] = 0;
+
+ for (i = 0; i < 8; i += skip)
+ {
+
+ if (!(mask & (1 << i)))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = 0x0c; /* Both output ports */
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_tdif,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUTL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDOUTR");
+ else
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+
+ codec = (i > 1) ? AKM_B : AKM_A;
+ ports = (i & 1) ? 0x08 : 0x04;
+ if ((err = mixer_ext_create_control (dev, group,
+ codec | ports, envy24_set_tdif,
+ typ,
+ tmp, range,
+ MIXF_MAINVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static void
+set_tdif_speed (envy24_devc * devc)
+{
+ int tmp;
+
+ WriteExternRegBit (devc, FPGA_MUTE, 1); /* Mute FPGA */
+ /* Set the TDIF sampling rate */
+ devc->gpio_tmp &= ~0x03;
+ switch (devc->speed)
+ {
+ case 32000:
+ devc->gpio_tmp |= 0x01;
+ break;
+ case 44100:
+ devc->gpio_tmp |= 0x02;
+ break;
+ case 48000:
+ devc->gpio_tmp |= 0x01;
+ break;
+ default:
+ devc->gpio_tmp |= 0x01;
+ break;
+ }
+ WriteExternReg (devc, devc->gpio_tmp);
+
+ tmp = devc->speedbits;
+
+ switch (devc->syncsource)
+ {
+ case SYNC_INTERNAL:
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ WriteGPIObit (devc, FPGA_MASTER, 1);
+ write_tdif_spdif_reg (devc, 4, read_tdif_spdif_reg (devc, 4) & (~BIT0));
+ WriteExternRegBit (devc, 4, 1); /* Disable TDIF master PLL */
+ WriteExternRegBit (devc, 6, 0); /* Don't route PLL master clock to Envy24. */
+ break;
+
+ case SYNC_SPDIF:
+ tmp |= 0x10;
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ WriteGPIObit (devc, FPGA_MASTER, 1);
+ write_tdif_spdif_reg (devc, 4, read_tdif_spdif_reg (devc, 4) | BIT0);
+ WriteExternRegBit (devc, 6, 1); /* Do route PLL master clock to Envy24. */
+ WriteExternRegBit (devc, 4, 1); /* Disable TDIF master PLL */
+ break;
+
+ case SYNC_WCLOCK:
+ tmp |= 0x10;
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ write_tdif_spdif_reg (devc, 4, read_tdif_spdif_reg (devc, 4) & (~BIT0));
+ WriteExternRegBit (devc, 4, 0); /* Enable TDIF master PLL */
+ WriteExternRegBit (devc, 6, 1); /* Do route PLL master clock to Envy24. */
+ WriteGPIObit (devc, FPGA_MASTER, 0);
+ break;
+ }
+
+ if (devc->speed > 48000)
+ {
+ write_tdif_codec (devc, 0x01, 0x00);
+ write_tdif_codec (devc, 0x02, 0x65);
+ write_tdif_codec (devc, 0x01, 0x03);
+ }
+ else
+ {
+ write_tdif_codec (devc, 0x01, 0x00);
+ write_tdif_codec (devc, 0x02, 0x60);
+ write_tdif_codec (devc, 0x01, 0x03);
+ }
+ WriteExternRegBit (devc, FPGA_MUTE, 0); /* Unmute */
+}
+
+static void
+write_tdif_spdif_reg (envy24_devc * devc, int bRegister, int bData)
+{
+ unsigned char bMask;
+ unsigned char bSPI;
+
+ /* Assert the CODEC chip select and wait at least 150 nS. */
+ /* */
+ WriteExternRegBit (devc, CS8_CS, CS_TRUE);
+
+ /* Write the SPI address/cmd byte. */
+ /* */
+ bSPI = CS8_ADDR | CS8_WR;
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CS8_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bSPI)
+ WriteGPIObit (devc, CS8_DOUT, 1);
+ else
+ WriteGPIObit (devc, CS8_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CS8_CLK, 1);
+ }
+
+ /* Write the address (MAP) byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CS8_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bRegister)
+ WriteGPIObit (devc, CS8_DOUT, 1);
+ else
+ WriteGPIObit (devc, CS8_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CS8_CLK, 1);
+ }
+
+
+ /* Write the data byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop SPI clock low. */
+ WriteGPIObit (devc, CS8_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bData)
+ WriteGPIObit (devc, CS8_DOUT, 1);
+ else
+ WriteGPIObit (devc, CS8_DOUT, 0);
+
+ /* Raise SPI clock to "clock data in". */
+ WriteGPIObit (devc, CS8_CLK, 1);
+ }
+
+ /* De-assert chip select. */
+ /* */
+ WriteExternRegBit (devc, CS8_CS, CS_FALSE);
+}
+
+static int
+read_tdif_spdif_reg (envy24_devc * devc, int reg)
+{
+ unsigned char bMask;
+ unsigned char bRet = 0;
+ unsigned char bSPI;
+
+
+ /****** WRITE MAP ADDRESS FIRST ******/
+
+ /* Drop the chip select low. */
+ /* Wait at least 150 nS. */
+ /* */
+ WriteExternRegBit (devc, CS8_CS, CS_TRUE);
+
+ /* Write the SPI address/cmd byte. */
+ /* */
+ bSPI = CS8_ADDR + CS8_WR; /* SPI address field plus WRITE operation. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock (GPIO5) low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bSPI)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise clock (GPIO5). */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+
+ /* Write the address (MAP) byte. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock (GPIO5) low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & reg)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise clock (GPIO5). */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+ /* De-assert chip select(s). */
+ /* */
+ WriteExternRegBit (devc, CS8_CS, CS_FALSE);
+
+
+ /****** NOW READ THE DATA ******/
+
+ /* Drop the chip select low. */
+ /* Wait at least 150 nS. */
+ /* */
+ WriteExternRegBit (devc, CS8_CS, CS_TRUE);
+
+
+ /* Write the SPI address/cmd byte. */
+ /* */
+ bSPI = CS8_ADDR + CS8_RD; /* SPI address field plus READ operation. */
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock (GPIO5) low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Write current data bit. */
+ if (bMask & bSPI)
+ WriteGPIObit (devc, CDC_DOUT, 1);
+ else
+ WriteGPIObit (devc, CDC_DOUT, 0);
+
+ /* Raise clock (GPIO5). */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+
+ /* Read the data byte. */
+ /* */
+ bRet = 0;
+ /* */
+ for (bMask = 0x80; bMask; bMask = (bMask >> 1) & 0x7F)
+ {
+ /* Drop clock low. */
+ WriteGPIObit (devc, CDC_CLK, 0);
+
+ /* Read current data bit. */
+ if (ReadGPIObit (devc, CDC_DIN))
+ bRet |= bMask;
+
+ /* Raise clock. */
+ WriteGPIObit (devc, CDC_CLK, 1);
+ }
+
+
+ /* De-assert chip selects. */
+ /* */
+ WriteExternRegBit (devc, CS8_CS, CS_FALSE);
+
+ /* Return value. */
+
+ return bRet;
+}
+
+static int
+tdif_get_locked_status (envy24_devc * devc)
+{
+ switch (devc->syncsource)
+ {
+ case SYNC_INTERNAL:
+ return 1;
+ break;
+
+ case SYNC_SPDIF:
+ return !(read_tdif_spdif_reg (devc, 16) & 0x17);
+ break;
+
+ case SYNC_WCLOCK:
+ /* The SPI input pin shows the TDIF locked status */
+ if (envy24_read_cci (devc, 0x20) & (1 << 2))
+ return 1;
+ return 0;
+ break;
+ }
+
+ return 1;
+}
+
+envy24_auxdrv_t tdif_auxdrv = {
+ tdif_card_init,
+ tdif_mix_init,
+ init_cs8427_spdif,
+ write_cs8427_spdif,
+ cs8427_spdif_ioctl,
+ read_tdif_spdif_reg,
+ write_tdif_spdif_reg,
+ set_tdif_speed,
+ tdif_get_locked_status,
+ cs8427_spdif_mixer_init,
+ tdif_card_uninit
+};
diff --git a/kernel/drv/oss_envy24/envy24_tdif.h b/kernel/drv/oss_envy24/envy24_tdif.h
new file mode 100644
index 0000000..8fd1f9f
--- /dev/null
+++ b/kernel/drv/oss_envy24/envy24_tdif.h
@@ -0,0 +1,5836 @@
+/*
+ * Purpose: FPGA firmware for M-Audio Delta TDIF
+ */
+static unsigned char fpga_code[] = {
+ 0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00,
+ 0x01, 0x61, 0x00, 0x0b, 0x74, 0x64, 0x69, 0x66, 0x5f, 0x31, 0x2e, 0x6e,
+ 0x63, 0x64, 0x00, 0x62, 0x00, 0x0a, 0x32, 0x73, 0x35, 0x30, 0x74, 0x71,
+ 0x31, 0x34, 0x34, 0x00, 0x63, 0x00, 0x0b, 0x32, 0x30, 0x30, 0x31, 0x2f,
+ 0x30, 0x31, 0x2f, 0x32, 0x30, 0x00, 0x64, 0x00, 0x09, 0x30, 0x31, 0x3a,
+ 0x33, 0x38, 0x3a, 0x30, 0x38, 0x00, 0x65, 0x00, 0x01, 0x11, 0x0c, 0xff,
+ 0xff, 0xff, 0xff, 0xaa, 0x99, 0x55, 0x66, 0x30, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x07, 0x30, 0x01, 0x60, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x30,
+ 0x01, 0x20, 0x01, 0x00, 0x80, 0x3f, 0x2d, 0x30, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x09, 0x30,
+ 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x30, 0x00, 0x40, 0x00, 0x50, 0x00, 0x3e, 0x04, 0x00,
+ 0x12, 0x30, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x12, 0x30, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x12, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x12, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x12, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+ 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x28, 0x00, 0x12, 0x00, 0x02, 0x80,
+ 0x01, 0x80, 0x00, 0x70, 0x00, 0x1c, 0x00, 0x02, 0x80, 0x00, 0xa0, 0x00,
+ 0x28, 0x3f, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0x7c, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xe0, 0x03, 0xf4, 0x02, 0xc7, 0x00, 0x3f, 0xc0, 0x2c, 0xf1,
+ 0x03, 0x30, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x09, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0x90, 0x02, 0xe4, 0x20, 0x8b, 0x00, 0x2f, 0xd0, 0x08, 0xb0,
+ 0x02, 0x30, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x38, 0x02, 0xe4, 0x80, 0x83, 0x00, 0x2c, 0x44, 0x28, 0x32,
+ 0x02, 0x32, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x09, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0x98, 0x02, 0xe4, 0x10, 0x8b, 0x00, 0x2e, 0x40, 0x28, 0x30,
+ 0x02, 0x30, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0x7b, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb8, 0x03, 0xc4, 0x00, 0xcb, 0x00, 0x3f, 0xe0, 0x0c, 0xb0,
+ 0x03, 0x10, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xd0, 0x03, 0xf5, 0x00, 0xff, 0x00, 0x3e, 0xc8, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x32,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xe4, 0x40, 0xfb, 0x00, 0x3a, 0x40, 0x0e, 0xb0,
+ 0x03, 0x90, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22,
+ 0xc0, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xbf, 0x08, 0x21, 0x40, 0x08, 0xb8,
+ 0x02, 0x32, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0xa0,
+ 0xc0, 0x0b, 0x10, 0x02, 0xc7, 0x20, 0xb3, 0x80, 0x28, 0x40, 0x0a, 0x38,
+ 0x02, 0xb8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x21,
+ 0xe0, 0x0b, 0x5c, 0x02, 0xde, 0x00, 0xb7, 0x82, 0x21, 0x60, 0x08, 0x7c,
+ 0x02, 0x38, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xfb, 0x00, 0x30,
+ 0xc0, 0x0f, 0x10, 0x03, 0xc4, 0x00, 0xf3, 0x00, 0x18, 0xc0, 0x0e, 0xb0,
+ 0x83, 0x92, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xd0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc2, 0x2f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xfb, 0x10, 0x30, 0x48, 0x0c, 0xb0,
+ 0x63, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x50, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x21, 0x62, 0x28, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x58, 0x02, 0xd6, 0x00, 0xb3, 0x80, 0x21, 0xe0, 0x08, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x10, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0xa0, 0xc0, 0x08, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0x60, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x32, 0x80, 0x0c, 0xa0,
+ 0x23, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x88, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3c, 0x00, 0x0f, 0x84,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x32, 0x40, 0x0e, 0x90,
+ 0x03, 0x82, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x98, 0x02, 0x24, 0x00, 0xb1, 0x40, 0xa2, 0x40, 0x08, 0x96,
+ 0x02, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x92, 0x0a, 0x24, 0x00, 0xb9, 0x08, 0x22, 0x40, 0x2a, 0x11,
+ 0x42, 0x86, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x9a, 0x02, 0x04, 0x00, 0xb1, 0x28, 0x20, 0x4a, 0x08, 0x10,
+ 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x85, 0x03, 0x21, 0x40, 0xf8, 0x20, 0x32, 0x08, 0x0e, 0x80,
+ 0x0b, 0xae, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x28, 0x3e,
+ 0x40, 0x0f, 0xd1, 0x03, 0xf4, 0x00, 0xf9, 0x28, 0x3f, 0x40, 0x2f, 0x92,
+ 0x83, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0xd0, 0x03, 0x34, 0x00, 0xf5, 0x00, 0x3f, 0x60, 0x0c, 0xd1,
+ 0x03, 0x26, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x12, 0x20, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x08, 0x88,
+ 0x02, 0x0e, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x0a, 0x04, 0x00, 0xb3, 0x00, 0x2e, 0xc4, 0x08, 0x30,
+ 0x0a, 0x02, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x22, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x08, 0x90,
+ 0x02, 0x06, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x96, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x3c, 0x40, 0x2c, 0x90,
+ 0x03, 0x28, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x08, 0x3e, 0x50, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x4f, 0x82, 0x0b, 0x20, 0x24, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xe0, 0x02, 0x38, 0x00, 0xbe, 0x40, 0x22, 0x80, 0x0b, 0xe0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0xb0, 0x02, 0x05, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x20, 0x2d,
+ 0xc0, 0x0b, 0x30, 0x42, 0x18, 0x00, 0xb5, 0x80, 0x21, 0xc0, 0x0b, 0x60,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x58, 0x03, 0x16, 0x00, 0xf6, 0x80, 0x3d, 0xe0, 0x0f, 0x68,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0x90, 0x03, 0xe8, 0x00, 0xf8, 0x00, 0xbe, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x88, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xf2, 0x02, 0xcf, 0x80, 0x33, 0xe1, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x71, 0x02, 0xdc, 0x00, 0x8f, 0x00, 0xa1, 0xc0, 0x0b, 0x60,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x50, 0x02, 0xd0, 0x00, 0x87, 0x00, 0x21, 0xc0, 0x0b, 0x60,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x00, 0x02, 0xec, 0x40, 0x83, 0x00, 0x20, 0xc0, 0x0b, 0x10,
+ 0x02, 0x88, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xff, 0x00, 0x3e,
+ 0xc0, 0x0f, 0x80, 0x03, 0xea, 0x00, 0xc9, 0x00, 0x32, 0xc0, 0x0f, 0x90,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0x85, 0x83, 0xe9, 0x00, 0xf9, 0x00, 0xbe, 0xc0, 0x0f, 0x80,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xc0, 0x03, 0xfa, 0x00, 0xcc, 0x00, 0x3f, 0xc0, 0x0f, 0xc9,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0x8c, 0x02, 0xeb, 0x02, 0x88, 0x80, 0x2e, 0xe4, 0x0b, 0xd8,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0x88, 0x82, 0xe9, 0x80, 0x8b, 0x80, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x00, 0x02, 0xc8, 0x00, 0x83, 0x00, 0x2c, 0x40, 0x0b, 0x00,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0x80, 0x03, 0xc8, 0x00, 0xcb, 0x00, 0x3e, 0x40, 0x0f, 0x80,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xd0, 0x03, 0xf8, 0x00, 0xff, 0x00, 0x3f, 0x40, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0x7c, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf4,
+ 0x0b, 0x30, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xa0, 0x0a, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0x84,
+ 0x02, 0x30, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x26,
+ 0x02, 0x32, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xa8, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0x80,
+ 0x02, 0x30, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x6c, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xa8, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xc0,
+ 0x03, 0x10, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x01, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0x51,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0d, 0xa8, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x91,
+ 0x03, 0x10, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xbc, 0x02, 0xfc, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0x9d,
+ 0x02, 0x32, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x09, 0xb0, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x10,
+ 0x02, 0x38, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x4c, 0x02, 0xde, 0x00, 0xb7, 0x81, 0x2d, 0xe0, 0x0b, 0x69,
+ 0x02, 0x38, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0d, 0x10, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x80,
+ 0x0b, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xe0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xe0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0x80, 0x03, 0xec, 0x40, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xa0,
+ 0x03, 0x2a, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0xcb, 0xf0,
+ 0x0a, 0x32, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x48, 0x02, 0xde, 0x80, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0x30, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x82, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x4b, 0x36,
+ 0x02, 0x12, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xe8, 0xd3, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xe4,
+ 0x03, 0x3a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x00,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x9a,
+ 0x03, 0x82, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x91, 0x82, 0xe4, 0x00, 0xb9, 0x00, 0x0e, 0x40, 0x4b, 0x98,
+ 0x02, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0x86, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x12, 0x02, 0xc4, 0x80, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x32,
+ 0x82, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x85, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x82,
+ 0x0b, 0xae, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0xa0,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0xd1, 0x03, 0xe4, 0x40, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0xd2,
+ 0x83, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0xd0, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0xf8,
+ 0x83, 0x26, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x0a, 0x20, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x8c,
+ 0x02, 0x8e, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x90, 0x02, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x3a,
+ 0x82, 0x02, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x92, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x8b, 0x90,
+ 0x02, 0x86, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0x28, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x98, 0x83, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x10,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3a, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x82,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0x64, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xe0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x14, 0x02, 0xcc, 0x00, 0x93, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x81,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x50,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x39, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x80,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x68, 0x03, 0xde, 0x00, 0xd7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0d, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc1, 0x0f, 0x90,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x20,
+ 0xef, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xc8, 0x03, 0x3e, 0x00, 0xcf, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xfc, 0x00,
+ 0x87, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0x1c, 0x00, 0x87, 0x00, 0x2d, 0xc0, 0x0b, 0x50,
+ 0x0a, 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xa7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0x1c, 0x00, 0x87, 0x00, 0x2d, 0xc0, 0x0b, 0x74,
+ 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x39, 0x02, 0x0c, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x10,
+ 0x02, 0x08, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xfc, 0x00,
+ 0xeb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0x94, 0x0b, 0x2c, 0x02, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, 0xbc,
+ 0x0b, 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc1, 0x0f, 0x18,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0x60, 0x83, 0x2c, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0x20, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xd8,
+ 0x02, 0x20, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0x80, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb8,
+ 0x02, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x0a, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x18,
+ 0x0a, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0x30, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x90,
+ 0x03, 0x20, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x4f, 0x60,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xd4, 0x00, 0xff, 0x00, 0x33, 0xc0, 0x0c, 0xf1,
+ 0x03, 0x70, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xe1, 0x20, 0xbb, 0x00, 0x22, 0xc0, 0x08, 0xb0,
+ 0x06, 0x30, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xc2, 0xc0, 0xb3, 0x00, 0x20, 0xc0, 0x08, 0x32,
+ 0x02, 0x72, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xe6, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x08, 0xb0,
+ 0x02, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xe2, 0x00, 0xfb, 0x00, 0x32, 0xc0, 0x0c, 0xb0,
+ 0x03, 0x50, 0x44, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xf4, 0x00, 0xff, 0x00, 0x3d, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xe2, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, 0xb1,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2f,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xe4, 0x00, 0x87, 0x80, 0x2f, 0xc0, 0x4b, 0xb8,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xc0, 0x00, 0x83, 0x80, 0x2c, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xdf, 0x00, 0x87, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xc0, 0x02, 0xc3, 0x08, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc2, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x10, 0x3f, 0xc2, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xe0, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x91, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc8, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc8, 0x0b, 0x70,
+ 0x02, 0xf2, 0x26, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x9e, 0x10, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe8, 0x0b, 0x78, 0x02, 0xd2, 0x00, 0xb7, 0x90, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xc8, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x12, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xda, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xf8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe2, 0x00, 0xf8, 0x00, 0x1e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x04, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x01, 0x2e, 0x40, 0x0b, 0x91,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe6, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xce, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x4a, 0x0b, 0x10, 0x02, 0xc6, 0x80, 0xb1, 0x28, 0x2c, 0x4a, 0x0b, 0x10,
+ 0x02, 0xca, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x08, 0x0f, 0x80, 0x03, 0xe1, 0x40, 0xf8, 0x20, 0x3e, 0x08, 0x4f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x9d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xf4, 0x48, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x92,
+ 0x83, 0xe6, 0x24, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xf4, 0x00, 0xcd, 0x00, 0x3e, 0x40, 0x0f, 0xd4,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0x88, 0x00, 0x2e, 0x00, 0x09, 0x88,
+ 0x02, 0xce, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0x81, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xd2, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x8b, 0x90, 0x02, 0xe4, 0x00, 0x89, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x80, 0xc9, 0x00, 0x3e, 0x40, 0x8f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xc4, 0x02, 0xf9, 0x00, 0x3e, 0x40, 0x0d, 0x90,
+ 0x03, 0xd2, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x23, 0xe1, 0x20, 0xc8, 0x00, 0x32, 0x00, 0x0f, 0x80,
+ 0x03, 0xc2, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xf8, 0x00, 0x8a, 0x00, 0x22, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcf, 0x00, 0x83, 0x80, 0x20, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x42, 0xdd, 0x00, 0x81, 0xc0, 0x21, 0xc0, 0x0b, 0x70,
+ 0x82, 0xe0, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xfe, 0x02, 0xc7, 0x80, 0xb1, 0xe0, 0x0f, 0x58,
+ 0x03, 0xe2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x00, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0xc0, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xf6, 0x02, 0xcd, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x71, 0x02, 0xd4, 0x40, 0x85, 0x00, 0x2d, 0xc0, 0x0b, 0x50,
+ 0x02, 0xea, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xd4, 0x00, 0x85, 0x00, 0x2d, 0xc0, 0x0b, 0x50,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xec, 0x40, 0x81, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x00, 0xc8, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xe7, 0x00, 0xcb, 0x00, 0x2e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xe4, 0x80, 0xf9, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3d,
+ 0xc0, 0x0c, 0xf0, 0x03, 0xe6, 0x00, 0xcf, 0x40, 0x3f, 0xc0, 0x0f, 0xd0,
+ 0x03, 0xe8, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x08, 0xb0, 0x02, 0xe7, 0x20, 0x89, 0x80, 0x2e, 0xc0, 0x0b, 0xd0,
+ 0x02, 0xe8, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x08, 0xb0, 0x02, 0xe4, 0x80, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0x93, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x09, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x08, 0x30, 0x02, 0xc4, 0x00, 0x81, 0x00, 0x2c, 0xc0, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0c, 0xb0, 0x03, 0xe4, 0x02, 0xcb, 0x02, 0x7e, 0xc0, 0x0f, 0x90,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0xfd, 0x00, 0x7f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xd2, 0x0d, 0xe4,
+ 0x03, 0x30, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc1, 0x0b, 0xa0, 0x02, 0xec, 0x00, 0xbb, 0x04, 0x2e, 0xd0, 0x08, 0x94,
+ 0x22, 0x30, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0a, 0x28, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc8, 0x09, 0x16,
+ 0x02, 0x32, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb8, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xb8,
+ 0x06, 0x30, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x02, 0x3e,
+ 0xc0, 0x0e, 0x88, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x4d, 0xc8,
+ 0x0b, 0x00, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xc0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3d, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xe0, 0x0c, 0x90, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0x92,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbf, 0x00, 0x2e,
+ 0xc0, 0x08, 0x90, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x37, 0xc0, 0x0b, 0xb4,
+ 0x82, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x08, 0x20, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20, 0xc2, 0x4b, 0x8c,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x08, 0x68, 0x02, 0xde, 0x00, 0xb7, 0x82, 0x25, 0xe0, 0x0b, 0x78,
+ 0x12, 0xf8, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x02, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0c, 0x30, 0x03, 0xcc, 0x00, 0xfb, 0x00, 0x30, 0xc0, 0x0f, 0x10,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3d,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc2, 0x8f, 0xf0,
+ 0x03, 0xd0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x80, 0x32,
+ 0xc0, 0x0f, 0xa0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x07, 0x80,
+ 0x23, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x40, 0x21,
+ 0xc0, 0x0b, 0x60, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x8b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb3, 0xa0, 0xa1,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x58,
+ 0x02, 0xf0, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20,
+ 0xc0, 0x0b, 0x30, 0x42, 0xcc, 0x00, 0xb3, 0x00, 0x2e, 0xc1, 0x0b, 0x31,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x32,
+ 0x80, 0x0f, 0xe4, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xe8,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x83, 0xe0, 0x00, 0xf8, 0x01, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0c, 0x18,
+ 0x0b, 0x02, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x50, 0x08, 0x9a,
+ 0x02, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x60, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x28, 0x92,
+ 0x02, 0x06, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x28, 0x2c,
+ 0x40, 0x0b, 0x12, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x4a, 0x08, 0x12,
+ 0x82, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x20, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x88, 0x0c, 0x82,
+ 0x03, 0x2e, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0xd1, 0x03, 0xe4, 0x00, 0xf9, 0x28, 0x3e, 0x4a, 0x0f, 0xd2,
+ 0x83, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3f,
+ 0x40, 0x0f, 0xb0, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3f, 0x40, 0x0f, 0xd8,
+ 0x83, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x04, 0x2e, 0x2a, 0x0b, 0x8c,
+ 0x02, 0xce, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x32,
+ 0x82, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x94, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x8b, 0x98,
+ 0x82, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x14, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x00, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x83, 0xca, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x04, 0x1e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x84, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x02, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x04, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2f, 0xb0, 0x0b, 0xe0,
+ 0x02, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xe0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x11, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc2, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xd1, 0x0b, 0x70,
+ 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0xc0, 0x3d, 0xe0, 0x0f, 0x58,
+ 0x03, 0xca, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x90,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0x3e, 0x00, 0xff, 0x80, 0x3f, 0x60, 0x0f, 0xf8,
+ 0x03, 0xd0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0x44, 0x0b, 0x70,
+ 0x12, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0x40, 0x0b, 0x54,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x34, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2e, 0x40, 0x0b, 0x10,
+ 0x02, 0xd8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb5, 0x0b, 0x2c, 0x00, 0xff, 0x00, 0x3e, 0x40, 0x0f, 0xbc,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x04, 0x3e, 0x50, 0x0f, 0xb1,
+ 0x43, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xe0, 0x0f, 0xb0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x40, 0x0c, 0xd0,
+ 0x03, 0x20, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xe0, 0x4b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2f, 0x60, 0x08, 0x58,
+ 0x02, 0x20, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc4, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xe2, 0x08, 0xb8,
+ 0x02, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x28, 0x18,
+ 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x08, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0c, 0x90,
+ 0x03, 0x20, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x40, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x80, 0x0f, 0xe0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x40, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xf0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x83, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0x40, 0x0b, 0x72, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x10, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x4a, 0x0b, 0x12, 0x82, 0x84, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x08, 0x0f, 0x82, 0x03, 0x20, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3f,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0xa0, 0xf9, 0x00, 0x3e, 0x4a, 0x0f, 0x90,
+ 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3a, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0xc0, 0x8b, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x8b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x28, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x44, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3a, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x60, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0c, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x08, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x28, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x80, 0xb7, 0x00, 0x2d, 0xec, 0x08, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x80, 0xf7, 0x80, 0x3f, 0xe0, 0x0c, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0c, 0xf8, 0x03, 0xfe, 0x20, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0a, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xe4, 0x0a, 0x30, 0x02, 0xec, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xe0, 0x0c, 0xb0, 0x43, 0xfc, 0x00, 0xfb, 0x00, 0x3f, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x13, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xcf, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x6c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xab, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x4c, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x8b, 0x30, 0x02, 0xcc, 0x00, 0xa3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0x7c, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x40, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x40, 0x3f, 0xcc, 0x8f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2a, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0x40, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xdc, 0x09, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0x40, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x20, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2a, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0x40, 0x0b, 0xb8, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xbb, 0x00, 0x3e,
+ 0x40, 0x0f, 0xa8, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xe0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3e, 0xc1, 0x0d, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x02, 0x3e,
+ 0x40, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3a, 0xc0, 0x0e, 0xb0,
+ 0x03, 0x90, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x09, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbf, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x03, 0xc0, 0x00, 0xb0,
+ 0x02, 0x32, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xbb, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0x52, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x08, 0xc0, 0x0a, 0x30,
+ 0x00, 0xb8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x09, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0x60, 0x0b, 0x58, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x21, 0xe0, 0x08, 0x78,
+ 0x12, 0x38, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0x40, 0x0f, 0x10, 0x03, 0xcc, 0x00, 0xfb, 0x00, 0x38, 0xc0, 0x0e, 0xb0,
+ 0x03, 0x92, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x40, 0x0f, 0xd0, 0x02, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf1,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x80, 0x32,
+ 0x40, 0x0f, 0x80, 0x03, 0xee, 0x00, 0xcb, 0x00, 0x3e, 0xc4, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x20, 0x29,
+ 0xc0, 0x0b, 0x60, 0x02, 0xdc, 0x00, 0x87, 0x00, 0x2d, 0xc1, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb3, 0x90, 0x21,
+ 0x62, 0x0b, 0x78, 0x02, 0xfe, 0x02, 0x87, 0x80, 0x2d, 0xe8, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x28,
+ 0xe0, 0x0b, 0x38, 0x02, 0xcc, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x32,
+ 0x80, 0x0f, 0xea, 0x03, 0xe8, 0x00, 0xca, 0x00, 0x3e, 0x80, 0x4f, 0xa0,
+ 0x23, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x40, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x8f, 0x88, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0b, 0x80,
+ 0x01, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x80, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x2c, 0x10, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x30, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2c,
+ 0x40, 0x08, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x58, 0x08, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x28, 0x2e,
+ 0x40, 0x08, 0x12, 0x0a, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x4a, 0x8b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x20, 0x3e,
+ 0x14, 0x0c, 0x80, 0x0b, 0x00, 0x00, 0xf8, 0x00, 0x3e, 0x08, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x28, 0x3e, 0x40, 0x0b, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3f,
+ 0x40, 0x0f, 0xf1, 0x03, 0xe4, 0x00, 0xf9, 0x28, 0x3e, 0x4b, 0x0f, 0x92,
+ 0x83, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xfd, 0x00, 0x3e, 0x41, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3f,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x05, 0x3e, 0x41, 0xcf, 0x90,
+ 0x43, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xf0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x2e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x9c, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0b, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x99, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3a,
+ 0x08, 0x0f, 0x84, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xbe, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x23,
+ 0xb0, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x0e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x28,
+ 0x40, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb3, 0x80, 0x21,
+ 0x10, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x01, 0x2d, 0xc0, 0x0b, 0x73,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x39,
+ 0x20, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xf8, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0x00, 0x8f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x10, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xa0, 0x0c, 0xf9, 0x03, 0x3e, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2f,
+ 0xc0, 0x08, 0x70, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0x00, 0x08, 0x70, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0x00, 0x28, 0x38, 0x00, 0x0c, 0x00, 0xb3, 0x00, 0x2e, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xf8, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0x40, 0x0c, 0x38, 0x83, 0x2c, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0b, 0xf0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xf8, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0x21, 0x2f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x20, 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x00, 0x0c, 0xb0, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0e, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x20, 0x2a, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0x00, 0x28, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xb0, 0x00, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2c,
+ 0x80, 0x08, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0a, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb0, 0x00, 0x28, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x08, 0xb0, 0x0a, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0x00, 0x0c, 0xb0, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0e, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x00, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x02, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc1, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x26, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x37, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x0e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0b, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x92,
+ 0x83, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x4b, 0x72,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x7a,
+ 0x13, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb1,
+ 0x83, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc4, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x03, 0x6a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0xb0,
+ 0x06, 0x48, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xf0,
+ 0x03, 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x13, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0x20, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x70,
+ 0x03, 0x20, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xd0, 0x0c, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x10, 0x3f, 0xcc, 0x0f, 0xf1,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x10, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00, 0xb3, 0x20, 0x2f, 0xdc, 0x0b, 0xb2,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc8, 0x0a, 0x30, 0x02, 0xcc, 0x00, 0xa3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0a, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x01, 0x3e,
+ 0xc0, 0x2e, 0xb0, 0x03, 0xec, 0x00, 0xeb, 0x00, 0x3e, 0xc0, 0x8f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3d,
+ 0xc0, 0x0d, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3a, 0xc0, 0x0e, 0xb0,
+ 0x03, 0x10, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x6f,
+ 0xdc, 0x0b, 0xf0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x23, 0xc0, 0x08, 0xb0,
+ 0x03, 0x72, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x8b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x28, 0xc0, 0x0a, 0x30,
+ 0x02, 0x38, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x20, 0xe0, 0x08, 0x78,
+ 0x02, 0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x2c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x38, 0xc0, 0x0e, 0xb0,
+ 0x03, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc2, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb1, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xd2, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x10, 0xb7, 0x00, 0x2d,
+ 0xc8, 0x0b, 0x72, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xd0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe8, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x10, 0xbb, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xba, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x4f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x01, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x68, 0x0c, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3a, 0x40, 0x0e, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x60, 0x28, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x22, 0x40, 0x08, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2c,
+ 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x28, 0x40, 0x0a, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x48, 0x08, 0x12, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x20, 0x4a, 0x08, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x14, 0x2c, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3a, 0x08, 0x0e, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x41, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x44, 0x0f, 0x91, 0x03, 0xe4, 0x00, 0xf9, 0x28, 0x3e, 0x4a, 0x0f, 0x92,
+ 0x83, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3f,
+ 0x40, 0x0c, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x08, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x08, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x2c, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x02, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0e, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2f,
+ 0xb0, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0x3a, 0x00, 0x2e, 0x80, 0x08, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2e,
+ 0x84, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0a, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0x40, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x30, 0x2d, 0xe0, 0x08, 0x71,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0x20, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x88, 0x3f, 0xec, 0x0e, 0x7a,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x02, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x2f, 0xe4, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xa0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe2, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0x80, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0x80, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0x80, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0x80, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0x40, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x00, 0x0f, 0x70, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x3d, 0xc0, 0x0e, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0x80, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0a, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0x80, 0x0b, 0x30, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0x80, 0x0f, 0xb0, 0x03, 0x2c, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0e, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x80, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0xb3, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x82, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x32, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x42, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x01, 0x22, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x10, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x82, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2f, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x38, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb9, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb5, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf9, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb5, 0x00, 0x2d, 0xc8, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe4, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc1, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf1, 0x00, 0x3a, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x22, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2a, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x28, 0x20, 0x4a, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x20, 0x3a, 0x08, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x92, 0x83, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xfd, 0x28, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0xd0, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x8a, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x82, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x80, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x20, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0x28, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x38, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x5e, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x30, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x7a, 0x23, 0x1e, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x1f, 0x0b, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xdc, 0x1b, 0x3e, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x0a, 0x1c, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x50, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0xb0, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xf0, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xff, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x90, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3d, 0xc0, 0x2c, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0x90, 0x0a, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0x90, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x50, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0c, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0x40, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x40, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x88, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xa8, 0x0f, 0xf0, 0x03, 0xfc, 0x04, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x10, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xcb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0x90, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x00, 0x0b, 0xb0, 0x02, 0xfc, 0x00, 0xdb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0x8b, 0x00, 0x2f, 0xc0, 0x0e, 0xf0,
+ 0x02, 0x32, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0x83, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xb8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0x97, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x06, 0xee, 0x00, 0x87, 0x80, 0x2d, 0xe0, 0x0a, 0x78,
+ 0x02, 0x38, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0b, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xec, 0x00, 0x83, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xc3, 0x00, 0x3c, 0xc0, 0xcf, 0x30,
+ 0x07, 0x92, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf1, 0x03, 0xfc, 0x40, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfe, 0x00, 0xff, 0x00, 0x3f, 0xc2, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0e, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xee, 0x00, 0xcb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdd, 0x00, 0x87, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc8, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xce, 0x00, 0x87, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x7b,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0x83, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x10, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3f, 0x90, 0x0f, 0xa0, 0x03, 0xe8, 0x02, 0xca, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x08, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x13, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3c, 0x40, 0x0c, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0a, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x08, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x4a, 0x0b, 0x10, 0x02, 0xc4, 0xa0, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x4a, 0x0a, 0x12,
+ 0x82, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x08, 0x0f, 0x80, 0x03, 0xe1, 0xc0, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xf0, 0x00, 0xf8, 0x00, 0x3e, 0x08, 0x0c, 0x82,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0xa0, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3f, 0x40, 0x0f, 0x90, 0x03, 0xe6, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x28, 0x3e, 0x40, 0x0f, 0x92,
+ 0x83, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x60, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x41, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x50, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x10, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x41, 0x1c, 0x80, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x10, 0x2d, 0xc1, 0x0b, 0x72,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x80, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x7e,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x40, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x20, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0c, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x33, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0a, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xbf, 0x00, 0x35, 0xc4, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2c, 0xc0, 0x08, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x21, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xec, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0a, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x24, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xbc, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0c, 0xb0, 0x03, 0xfc, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xff, 0x00, 0x32, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xef, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3d, 0xc0, 0x0c, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0x20, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0a, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x42, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xab, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xa3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0a, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0x82, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xeb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0x20, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xdf, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0x70, 0x0b, 0x3c, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x33, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x0a, 0x0c, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x30, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb8, 0x03, 0xac, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbf, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xbb, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0x1e, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0x8c, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x91, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0x5e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x04, 0xfa, 0x01, 0x3e, 0x81, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0x68, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0b, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x98, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x26, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x28, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x20, 0x36, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x9d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x28, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0xd0, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x8b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x30, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x43, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x88, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xe4, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x20, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0xc0, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xca, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x01, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x33, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xd0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x12, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x21, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x21, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xbb, 0x00, 0x20, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xa0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xff, 0x00, 0xb2, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xa4, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xe0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xfb, 0x00, 0xb3, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xa4, 0x42, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xbc, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xd0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x0e,
+ 0xc0, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xbb, 0x00, 0x26, 0xc0, 0x09, 0xb0,
+ 0x02, 0x70, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc8, 0x09, 0xb0, 0x00, 0x2c,
+ 0x80, 0x0b, 0x30, 0x02, 0xc4, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe8, 0x00, 0xb8, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe4, 0x00, 0xbb, 0x00, 0x26, 0xc0, 0x09, 0xb0,
+ 0x02, 0x70, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x40, 0x0f, 0xc0, 0x03, 0xf8, 0x00, 0xfe, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xe8, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x8f, 0x90, 0x03, 0xe4, 0x00, 0xfa, 0x04, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xe8, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe4, 0x00, 0xba, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xc8, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x8b, 0x78, 0x02, 0xde, 0x40, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x68, 0x02, 0xda, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xc8, 0x00, 0xf0, 0x00, 0x3c,
+ 0x80, 0x0f, 0x30, 0x03, 0xc4, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xf8, 0x00, 0xfc, 0x00, 0x3f,
+ 0x80, 0x0b, 0xe0, 0x02, 0xf4, 0x00, 0xff, 0x03, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x43, 0xce, 0x00, 0xcb, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xa7, 0x00, 0x2d,
+ 0x40, 0x09, 0x40, 0x02, 0xd8, 0x00, 0xb6, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xfa, 0x00, 0x84, 0x80, 0x2d,
+ 0x20, 0x0b, 0x58, 0x02, 0xd6, 0x00, 0xb6, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xc8, 0x00, 0xa0, 0x00, 0x2c,
+ 0x24, 0x0b, 0x00, 0x02, 0xc4, 0x00, 0xb2, 0x40, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xca, 0x00, 0x3e,
+ 0xa1, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x50, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0d, 0x81, 0x03, 0xf0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x64, 0x00, 0xbd, 0x00, 0x2f,
+ 0x40, 0x0b, 0xd0, 0x02, 0xf4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb5, 0x00, 0x2d,
+ 0x40, 0x0b, 0x50, 0x02, 0xd4, 0x00, 0xb5, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xfc, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x2e, 0x40, 0x0f, 0x92, 0x83, 0xe4, 0x00, 0xfb, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x07, 0x92,
+ 0x83, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe8, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe8, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x8b, 0x80,
+ 0x02, 0xce, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x6e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x42, 0x0b, 0x90, 0x12, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x1b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x14, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x8f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x10, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe5, 0x40, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x00, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x8f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x84, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe6, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x32,
+ 0x10, 0x0c, 0x80, 0x03, 0x21, 0x00, 0xc8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x04, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x16,
+ 0x80, 0x0d, 0xa0, 0x03, 0x68, 0x00, 0xda, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x20,
+ 0xc0, 0x08, 0x30, 0x02, 0x0c, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x1b, 0x70, 0x06, 0xdc, 0x01, 0xbf, 0x80, 0x67,
+ 0xe0, 0x09, 0xf8, 0x02, 0x7e, 0x00, 0x97, 0x00, 0x2d, 0xc0, 0x0b, 0x72,
+ 0x02, 0xc8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x31,
+ 0xe0, 0x0c, 0x78, 0x03, 0x1e, 0x00, 0xc7, 0x80, 0x3d, 0xe0, 0x0f, 0x7a,
+ 0x03, 0xca, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x23, 0xcc, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb1,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x83, 0xfe, 0x00, 0xff, 0x80, 0x33,
+ 0xe0, 0x0c, 0xf8, 0x02, 0x3e, 0x00, 0xc7, 0x80, 0x33, 0xe0, 0x0f, 0xf8,
+ 0x03, 0x10, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x29,
+ 0xc0, 0x0a, 0x70, 0x02, 0x9c, 0x80, 0xa7, 0x00, 0x29, 0xc0, 0x0b, 0xf0,
+ 0x03, 0x6a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xbf, 0x00, 0x23,
+ 0xc0, 0x08, 0xf0, 0x02, 0x3c, 0x00, 0x8f, 0x00, 0x21, 0xc0, 0x0b, 0x70,
+ 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0xb0, 0x00, 0xcc, 0x00, 0xb3, 0x00, 0x28,
+ 0xc0, 0x0a, 0x30, 0x82, 0x8c, 0x20, 0xa3, 0x00, 0x28, 0xc0, 0x1b, 0x30,
+ 0x02, 0x58, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0b, 0xf0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x32,
+ 0xc0, 0x0c, 0xb0, 0x03, 0x2c, 0x00, 0xcb, 0x00, 0x32, 0xc0, 0x0f, 0xf0,
+ 0x03, 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x13, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xee, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x07, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x50, 0xfc, 0x10, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xac, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x08, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x23, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0b, 0xf0, 0x02, 0xfc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x03, 0xdc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0e, 0xf0, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x04, 0x2e, 0xc0, 0x08, 0x94, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0a, 0x04, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xa0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0e, 0x8d, 0x83, 0x2c, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x44, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3d, 0xc0, 0x0f, 0x68, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x94, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x36,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd1, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2f, 0xc0, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x00, 0x42, 0x0c, 0x00, 0xb3, 0x00, 0x24,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x28, 0x02, 0x1e, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xfc, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x10, 0x03, 0x0c, 0x00, 0xf3, 0x00, 0x34,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf1,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xe0, 0x0c, 0x80, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xd0, 0x08, 0x60, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x24, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2c, 0xe8, 0x08, 0x58, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xe0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0c, 0xe1, 0x83, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x2f, 0x00, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x13, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x4a, 0x0b, 0x12, 0x8a, 0x04, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x08, 0x0f, 0x82, 0x03, 0x20, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x4a, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0xd0, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x4f, 0x90,
+ 0x03, 0xe6, 0x26, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0c, 0x98, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x08, 0x14, 0x02, 0x04, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xd2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x08, 0x96, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0c, 0x90, 0x03, 0x24, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3c, 0x40, 0x2f, 0x10, 0x0b, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xda, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc4, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc4, 0x0b, 0x71, 0x82, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2e, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3f, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb8, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x10, 0xfc, 0x08, 0xff, 0x00, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x08, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x09, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x6e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0d, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x37,
+ 0xc0, 0x0c, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x18, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x04, 0x20,
+ 0xc0, 0x0a, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x26, 0x00, 0x09, 0x80,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x24,
+ 0x80, 0x08, 0x30, 0x02, 0xcc, 0x01, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x22, 0xec, 0x00, 0xbb, 0x00, 0x22,
+ 0x80, 0x0a, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x26, 0x00, 0x09, 0x80,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xac, 0x00, 0xfb, 0x00, 0x36,
+ 0xc0, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xec, 0x00, 0xf7, 0x00, 0x3f,
+ 0xc0, 0x0b, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xc0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xdb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x02, 0xcb, 0x00, 0x3e,
+ 0x80, 0x0e, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x2e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xfc, 0x00, 0x8f, 0x00, 0x2e,
+ 0x80, 0x0d, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x04, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0x83, 0x00, 0x2e,
+ 0xc0, 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x03, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x10, 0x5e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0x87, 0x80, 0x2d,
+ 0xe0, 0x09, 0x48, 0x02, 0xd2, 0x00, 0xb4, 0x80, 0x2d, 0x20, 0x0b, 0x48,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x4c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xb3, 0x00, 0x3c, 0xc0, 0x0f, 0x31, 0x03, 0xcc, 0x00, 0xc3, 0x00, 0x3c,
+ 0x80, 0x0e, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x10, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x80, 0x03, 0xc0, 0x02, 0xf0, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x0f, 0xc9,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x40, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb8, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x99, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x80, 0xb7, 0x60, 0x2d,
+ 0xc0, 0x0b, 0x40, 0x02, 0x90, 0x00, 0xb4, 0x04, 0x25, 0x00, 0x09, 0x40,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x91, 0xb7, 0x80, 0x2d,
+ 0xa0, 0x0b, 0xf8, 0x02, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68,
+ 0x04, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0x80, 0x0b, 0x00, 0x02, 0x80, 0x00, 0xb0, 0x00, 0x24, 0x00, 0x09, 0x00,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0x28, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x01, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x1f, 0x00, 0x0b, 0xc0,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0x99, 0x00, 0x2e,
+ 0x40, 0x0b, 0xd0, 0x02, 0xf4, 0x00, 0xbd, 0x00, 0x2f, 0x40, 0x0b, 0xd0,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x14, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0xa0, 0xb1, 0x28, 0x2c,
+ 0x40, 0x0b, 0x50, 0x02, 0xd4, 0x10, 0xb5, 0x00, 0x2d, 0x40, 0x0b, 0x50,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x80, 0xd8, 0x20, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0xc0,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x95, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x2c, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x4a, 0x07, 0x10, 0x01, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x4f, 0x90,
+ 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xd9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xc9, 0x00, 0x32, 0x40, 0x0c, 0x90,
+ 0x03, 0x26, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x18, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0xc0, 0x02, 0xa0, 0x00, 0xa8, 0x00, 0x2a, 0x00, 0x0a, 0x80,
+ 0x02, 0x8e, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0x84, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, 0x89, 0x00, 0x22, 0x40, 0x0a, 0x90,
+ 0x02, 0x02, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x04, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x42, 0x0b, 0x90, 0x02, 0xa4, 0x00, 0xa9, 0x00, 0x2a, 0x40, 0x0a, 0x90,
+ 0x02, 0x86, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0x04, 0x00, 0xc9, 0x00, 0x30, 0x40, 0x0e, 0x10,
+ 0x03, 0x28, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3e,
+ 0x10, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x81, 0x0b, 0xa0, 0x42, 0xe8, 0x10, 0xba, 0x04, 0x2e,
+ 0x80, 0x0b, 0x25, 0x02, 0xe8, 0x00, 0xb2, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x4c, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x34, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x43, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x11, 0x9c, 0x04, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0x37, 0x30, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc4, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0xa0, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0x5e, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x79, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0x7b, 0x00, 0x1e,
+ 0xd0, 0x07, 0xb0, 0x01, 0xec, 0x00, 0x7b, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0xbe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3d,
+ 0xf0, 0x0c, 0xe8, 0x03, 0xde, 0x00, 0xcf, 0x80, 0x31, 0xe0, 0x0c, 0x78,
+ 0x03, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x18, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0a, 0x61, 0x02, 0xdc, 0x40, 0xa7, 0x14, 0x29, 0xc6, 0x0a, 0x71,
+ 0x82, 0xaa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2f,
+ 0xc0, 0x08, 0x60, 0x02, 0xfc, 0x00, 0x8f, 0x00, 0x23, 0xc0, 0x0a, 0xf0,
+ 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x04, 0x8c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xbb, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0a, 0x28, 0x02, 0xce, 0x00, 0xa3, 0x80, 0x28, 0xd0, 0x0a, 0x34,
+ 0x02, 0x88, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xff, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3f,
+ 0xc0, 0x0c, 0xbc, 0x03, 0xed, 0x20, 0xcb, 0x48, 0x32, 0xe5, 0x0e, 0xb8,
+ 0x03, 0x2a, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x13, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb3, 0x03, 0xec, 0x80, 0xfb, 0x20, 0x3e, 0xc0, 0x07, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x33, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x03, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x83, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2a, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0x30, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0x6c, 0x00, 0xbb, 0x00, 0x26,
+ 0xc0, 0x09, 0xa0, 0x02, 0x2c, 0x00, 0x9b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x14, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x28, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x20, 0x02, 0x0c, 0x00, 0xb3, 0x02, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x32, 0xc0, 0x0f, 0xb0, 0x03, 0x6c, 0x00, 0xfb, 0x00, 0x37,
+ 0xc0, 0x0d, 0xa0, 0x0b, 0x2c, 0x00, 0xdb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc1, 0x0f, 0xf0, 0x43, 0xfc, 0x10, 0xff, 0x04, 0x3f,
+ 0xc1, 0x0f, 0xe0, 0x03, 0xfc, 0x00, 0xf7, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0x3b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x09, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x44, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0d, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x43, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xfe, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x24, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xe0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x26, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xd2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xda, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0x33, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x4f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x12, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3d, 0xc0, 0x0b, 0xf0, 0x03, 0x7c, 0x00, 0xff, 0x00, 0x3d,
+ 0xc0, 0x0d, 0xc0, 0x03, 0xf0, 0x00, 0xfd, 0x00, 0x3f, 0x00, 0x0f, 0xe0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0x20, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x08, 0x80, 0x02, 0xec, 0x00, 0xb9, 0x00, 0x2e, 0x80, 0x0b, 0xb0,
+ 0x02, 0x70, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0xb0, 0x02, 0x4c, 0x00, 0xb3, 0x00, 0x2e,
+ 0xc0, 0x09, 0x20, 0x02, 0xc0, 0x00, 0xb2, 0x00, 0x2c, 0x00, 0x0b, 0x20,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x04, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0x20, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x88, 0xa0, 0x02, 0xec, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xb0,
+ 0x02, 0x70, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x20, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x6c, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0d, 0x84, 0x03, 0xe0, 0x00, 0xf9, 0x00, 0x3e, 0x08, 0x0f, 0xa0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x3f,
+ 0x00, 0x0f, 0xc0, 0x03, 0xfc, 0x00, 0xfd, 0x00, 0x3f, 0x80, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x40, 0x3a, 0xc2, 0x0e, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0e, 0xa4, 0x03, 0xe0, 0x00, 0xfa, 0x00, 0x3e, 0x10, 0x0f, 0xa0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x22, 0x10, 0x08, 0x00, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2c,
+ 0x00, 0x08, 0xa0, 0x02, 0xec, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb2, 0x00, 0x28, 0xd0, 0x0a, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0a, 0x10, 0x02, 0xc0, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x20,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xbe, 0x80, 0x23, 0x20, 0x08, 0x48, 0x02, 0xd2, 0x00, 0xb4, 0x80, 0x2f,
+ 0x20, 0x08, 0x58, 0x02, 0xde, 0x00, 0xb5, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf2, 0x00, 0x38, 0xc0, 0x0e, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc4, 0x9e, 0x34, 0x03, 0xc0, 0x00, 0xf2, 0x01, 0x3c, 0x40, 0x1f, 0x20,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xf6, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x3f,
+ 0x20, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0x7e, 0x00, 0x3f, 0xc0, 0x0f, 0xf8,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfa, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xce, 0x00, 0xd3, 0x80, 0x36,
+ 0xc0, 0x0f, 0x90, 0x03, 0xe0, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0xa0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb6, 0x00, 0x2d, 0x00, 0x0b, 0x40, 0x02, 0xd0, 0x00, 0x84, 0x00, 0x21,
+ 0x00, 0x0b, 0x50, 0x02, 0xdc, 0x00, 0xb5, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb6, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xfe, 0x00, 0x9f, 0x80, 0x25,
+ 0xe0, 0x0b, 0x78, 0x02, 0xd2, 0x00, 0xb6, 0x80, 0x2d, 0x60, 0x0b, 0x68,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb2, 0x00, 0x2c, 0x00, 0x0b, 0x00, 0x02, 0xc0, 0x00, 0x80, 0x00, 0x20,
+ 0x00, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb2, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x11, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xda, 0x00, 0x36,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3c, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3f, 0x00, 0x0f, 0xc4, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x3f,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xfc, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xa4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x10, 0x03, 0x24, 0x00, 0xc9, 0x00, 0x32, 0x40, 0x0c, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0e, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x10, 0x82, 0x24, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x0a, 0x04, 0x02, 0x81, 0x00, 0xa2, 0x40, 0x28, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2f, 0x40, 0x0b, 0xd0, 0x02, 0xb4, 0x00, 0xbd, 0x00, 0x2f,
+ 0x40, 0x0b, 0xd0, 0x02, 0x34, 0x00, 0x8d, 0x00, 0x23, 0x40, 0x08, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0a, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2d, 0x40, 0x0b, 0x50, 0x02, 0x14, 0x00, 0xb5, 0x00, 0x2d,
+ 0x40, 0x0b, 0xd0, 0x02, 0x34, 0x00, 0x8d, 0x00, 0x23, 0x40, 0x08, 0x50,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xa0, 0x00, 0xf8, 0x00, 0x3f,
+ 0x00, 0x0f, 0x80, 0x03, 0x20, 0x00, 0xc8, 0x00, 0x32, 0x00, 0x0c, 0xc0,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0xa0, 0xf9, 0x00, 0x3e, 0x40, 0x0e, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x28, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x10, 0x03, 0xc4, 0x00, 0xf1, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0x24, 0x00, 0xcd, 0x00, 0x32, 0x40, 0x08, 0x90,
+ 0x03, 0x26, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2f, 0x00, 0x0b, 0xc0, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x0a, 0x00, 0x02, 0x88, 0x00, 0xa2, 0x00, 0x28, 0x80,
+ 0x0a, 0x0e, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x08, 0xb1, 0x02, 0x2c,
+ 0x40, 0x8b, 0x90, 0x22, 0x24, 0x08, 0x89, 0x00, 0x22, 0x40, 0x08, 0x90,
+ 0x02, 0x02, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0x24, 0x00, 0x89, 0x10, 0x22, 0x40, 0x48, 0x90,
+ 0x02, 0x06, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x98, 0x03, 0x24, 0x00, 0xc9, 0x60, 0x30, 0x40, 0x0c, 0x90,
+ 0x03, 0x28, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x92, 0x03, 0xf4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x32, 0x00, 0x0e, 0x80, 0x03, 0xa0, 0x00, 0xe8, 0x00, 0x3a,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xc8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x01, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x10,
+ 0xba, 0x00, 0x2a, 0x80, 0x08, 0xa0, 0x12, 0x28, 0x04, 0x8a, 0x01, 0x22,
+ 0x80, 0x4b, 0x20, 0x12, 0xc8, 0x00, 0x82, 0xa0, 0x2e, 0x80, 0x0b, 0x20,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x20, 0xc0, 0x0a, 0x30, 0x02, 0x8c, 0x00, 0xa3, 0x00, 0x28,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0x81, 0x80, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0xc0, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0xa0, 0x2b, 0xa0, 0x88, 0xf8, 0x02, 0x3e, 0x00, 0x8f, 0x80, 0x21,
+ 0xc0, 0x0b, 0x70, 0x02, 0xfc, 0x00, 0x85, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xff, 0xc0, 0x31, 0xe4, 0x0e, 0x68, 0x03, 0x9e, 0x00, 0xe7, 0x80, 0x39,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xc5, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3c, 0x90, 0x0f, 0xa0, 0x83, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xee, 0x02, 0xf9, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x01, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0x3e, 0x00, 0xf7, 0x80, 0x33, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x01, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0x80, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x29, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x60, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0xf0, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x21, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xec, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x04, 0x2c, 0xa4, 0x0b, 0x29, 0x02, 0xce, 0x40, 0xb3, 0x90, 0x2c,
+ 0xfc, 0x0b, 0x30, 0x0a, 0x0c, 0x00, 0xb3, 0x30, 0x28, 0xe0, 0x0b, 0x34,
+ 0x82, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xbc, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xff, 0x00, 0x3e, 0xe0, 0x0f, 0xb8, 0x03, 0xee, 0x00, 0xfb, 0x80, 0x3e,
+ 0xe0, 0x0f, 0xb0, 0x03, 0x2e, 0x80, 0xf9, 0x80, 0x32, 0xc0, 0x0f, 0xb4,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xbb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x82, 0x0f, 0xb0, 0x83, 0xec, 0x20, 0xfb, 0x09, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xf9, 0x00, 0x3e, 0xc4, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x02, 0xcf, 0x04, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x02, 0x3f, 0xc0, 0x0e, 0xe0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x20, 0xfd, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2c, 0x80, 0x08, 0xa0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xb9, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0a, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x14, 0x0c, 0x00, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0x80, 0x08, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x6c, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0e, 0xa0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0x80, 0x0f, 0xe0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x07, 0x70, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xdf, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x00, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x14, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x00, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x04, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x04, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x1b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x09, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xef, 0x00, 0x3f, 0x80, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xcc, 0x00, 0x3f,
+ 0x00, 0x07, 0xc0, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x33, 0xc0, 0x0d, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0x8b, 0x00, 0x2e, 0x80, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xf0, 0x00, 0x2c,
+ 0x00, 0x09, 0x80, 0x22, 0xac, 0x00, 0xbb, 0x02, 0x2a, 0xc0, 0x08, 0xb0,
+ 0x02, 0xf0, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xa3, 0x00, 0x2c, 0xc0, 0x0a, 0x00, 0x02, 0xc8, 0x00, 0x80, 0x00, 0x2c,
+ 0x00, 0x0b, 0x00, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x09, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0x8b, 0x00, 0x2e, 0xc0, 0x0b, 0x80, 0x02, 0xc8, 0x00, 0xa8, 0x00, 0x2e,
+ 0x02, 0x09, 0x00, 0x02, 0xac, 0x08, 0xbb, 0x00, 0x2a, 0xc0, 0x08, 0xb0,
+ 0x02, 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xeb, 0x00, 0x3e, 0x80, 0x0e, 0x8a, 0x03, 0xe0, 0x80, 0x8b, 0x00, 0x3e,
+ 0x90, 0x0f, 0xb0, 0x0b, 0x2c, 0x04, 0xfb, 0x00, 0x32, 0xc0, 0x0d, 0xb0,
+ 0x03, 0xd0, 0x44, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0x80, 0x0f, 0xc9, 0x03, 0xf0, 0x02, 0xff, 0x00, 0x3f,
+ 0x80, 0x0d, 0xf0, 0x83, 0xfc, 0x00, 0xf7, 0x00, 0x2f, 0xc0, 0x0b, 0xb0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0d, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xe0, 0x0f, 0x81, 0x03, 0xea, 0x20, 0xfb, 0x10, 0x32,
+ 0xb0, 0x0e, 0xb8, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0x90, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xe0, 0x0b, 0x84, 0x02, 0xea, 0x00, 0xbb, 0xc0, 0x36,
+ 0xa4, 0x0d, 0xbc, 0x03, 0x6c, 0x00, 0xbf, 0x00, 0x2c, 0xc0, 0x0b, 0xf0,
+ 0x02, 0x32, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xec, 0x00,
+ 0xb3, 0x00, 0x2c, 0x80, 0x0b, 0x30, 0x02, 0x44, 0x00, 0x90, 0x00, 0x20,
+ 0x40, 0x08, 0x00, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xa1, 0x0b, 0x7c, 0x02, 0xd6, 0x00, 0xb4, 0xc0, 0x25,
+ 0x61, 0x09, 0x48, 0x02, 0x5e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0x38, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0f, 0x30, 0x03, 0x4c, 0x00, 0xd0, 0x00, 0xb0,
+ 0x40, 0x24, 0x80, 0x0b, 0x0c, 0x40, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0x92, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf1, 0x03, 0xfc, 0x40, 0xfc, 0x00, 0x3f,
+ 0x44, 0x0f, 0xc0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xeb, 0x00, 0x3a, 0x80, 0x0f, 0xb8, 0x01, 0x24, 0x00, 0xfb, 0x80, 0x36,
+ 0xe0, 0x0c, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x91, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0x80, 0x0b, 0xf0, 0x02, 0x94, 0x00, 0xbf, 0x00, 0x23,
+ 0xc0, 0x0a, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x20, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x26, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0x9e, 0x00, 0xb7, 0x80, 0x25,
+ 0xe0, 0x08, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x90, 0x2d, 0xe0, 0x0b, 0x7b,
+ 0x02, 0xc8, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x00, 0x8c, 0x00, 0xb3, 0xc0, 0x20,
+ 0xe4, 0x0a, 0x35, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xda, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x0b, 0xa8, 0x00, 0xfa, 0xa0, 0x36,
+ 0x80, 0x2c, 0xa8, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x22, 0xe0, 0x00, 0xf8, 0x08, 0x3e,
+ 0x00, 0x0f, 0x80, 0x83, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x98, 0x02, 0xe5, 0x00, 0xb9, 0x80, 0x2e,
+ 0x50, 0x0b, 0x94, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x60, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0x99, 0x00, 0x2e, 0x40, 0x0b, 0xd8, 0x02, 0x74, 0x00, 0xbd, 0x80, 0x2f,
+ 0x40, 0x0b, 0xd0, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x44, 0x0b, 0x90,
+ 0x02, 0xce, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x50, 0x02, 0xd6, 0x00, 0xb5, 0x00, 0x2d,
+ 0x60, 0x0b, 0x58, 0x02, 0xc4, 0x00, 0xb1, 0x28, 0x2c, 0x40, 0x0b, 0x12,
+ 0x82, 0xca, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xd8, 0x00, 0x3e, 0x00, 0x0f, 0xa0, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x7e,
+ 0x00, 0x0f, 0xc0, 0x03, 0xe0, 0x00, 0xf8, 0x20, 0x3e, 0x14, 0x0f, 0x82,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x9d, 0xe4, 0x00, 0xf9, 0x28, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0xa0,
+ 0xf9, 0x00, 0x3e, 0x4a, 0x0f, 0x92, 0x83, 0xe4, 0xa0, 0xf9, 0x28, 0x3e,
+ 0x4a, 0x0f, 0x92, 0x83, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x24, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x01,
+ 0xf9, 0x00, 0x3f, 0x40, 0x0f, 0xd0, 0x03, 0x34, 0x00, 0xcd, 0x00, 0x3f,
+ 0x40, 0x0f, 0xd0, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3f, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x3e, 0x00, 0x0b, 0x80, 0x02, 0xa0, 0x00, 0xa8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0f, 0x80,
+ 0x02, 0xce, 0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0x04, 0x00, 0x81, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2a, 0x40, 0x0b, 0x10, 0x02, 0xa4, 0x00, 0xa9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0a, 0x90,
+ 0x02, 0xc6, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x48, 0x0f, 0x90, 0x0b, 0x26, 0x02, 0xc9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0b, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x80, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xd2, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x02, 0x3e, 0x10, 0x0e, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x20, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0c, 0x80,
+ 0x03, 0xc2, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x10,
+ 0xba, 0x00, 0x2e, 0x80, 0x08, 0xe2, 0x02, 0xf8, 0x00, 0xbe, 0x40, 0x2f,
+ 0x82, 0x0b, 0xe0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0xa8, 0x08, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0x93, 0x00, 0x24, 0xc0, 0x0a, 0x38, 0x02, 0xee, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x04, 0xb7, 0x30, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x80,
+ 0xb7, 0x00, 0x2d, 0x70, 0x08, 0x60, 0x02, 0xd4, 0x20, 0xb6, 0x00, 0x2d,
+ 0x40, 0x0b, 0x54, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xe0, 0x08, 0x70,
+ 0x02, 0xe0, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x80,
+ 0xd7, 0x80, 0x37, 0xe0, 0x2e, 0x58, 0x23, 0xda, 0x00, 0xf5, 0x80, 0x3d,
+ 0xa0, 0x0f, 0x68, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x2c, 0x78,
+ 0x03, 0xe2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x80, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xfa, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3c, 0xda, 0x0b, 0xb0,
+ 0x03, 0xc2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x20,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0c, 0xf8,
+ 0x03, 0xc0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x40, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2f, 0xc0, 0x0f, 0x70,
+ 0x02, 0xea, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xd8, 0x00, 0xb5, 0x00, 0x2d,
+ 0x80, 0x0b, 0x60, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0x40, 0x08, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xbb, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x1b, 0x10, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0x40, 0x0a, 0x30,
+ 0x02, 0xc8, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xff, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xfc, 0x00,
+ 0xfb, 0x00, 0x2e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x08, 0xb0,
+ 0x23, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0xa4, 0x03, 0xe1, 0x00, 0xf8, 0x40, 0x3e,
+ 0x10, 0x0f, 0x84, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3b, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x03, 0xf8, 0x00, 0xfd, 0x00, 0x3f,
+ 0x80, 0x0f, 0xe0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x60, 0x0c, 0xf0,
+ 0x03, 0xe8, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x22, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x44, 0x0b, 0x84, 0x02, 0xe1, 0x40, 0xb8, 0x50, 0x2e,
+ 0x14, 0x0b, 0x85, 0x02, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0x40, 0x0a, 0xb0,
+ 0x02, 0xe8, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2a, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x40, 0x0b, 0xb0, 0x82, 0xe4, 0x20, 0xba, 0x08, 0x2e,
+ 0x42, 0x0b, 0x90, 0x82, 0xec, 0x00, 0xbb, 0x00, 0x2c, 0xc4, 0x00, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x20, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0x40, 0x0b, 0x00, 0x02, 0xc0, 0x00, 0xb0, 0x00, 0x2c,
+ 0x00, 0x0b, 0x00, 0x02, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0a, 0x30,
+ 0x02, 0xc2, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3a, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0xa0, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3f, 0x40, 0x0c, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x7f, 0x40, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x3f,
+ 0x00, 0x0f, 0xc0, 0x03, 0x7c, 0x00, 0xff, 0x00, 0x3f, 0x40, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x04, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x07, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x33,
+ 0x00, 0x0d, 0xf0, 0x63, 0xfc, 0x00, 0xff, 0x00, 0x1f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x40, 0x0b, 0xa0, 0x02, 0xc0, 0x00, 0xba, 0x00, 0x2a,
+ 0x80, 0x89, 0xf0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0x00, 0x0b, 0x10, 0x02, 0xc0, 0x00, 0xb0, 0x00, 0x20,
+ 0x00, 0x09, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x40, 0x0b, 0xb0, 0x02, 0xe0, 0x00, 0xba, 0x00, 0x2a,
+ 0x80, 0x09, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x0e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x04, 0x0f, 0x80, 0x03, 0xec, 0x00, 0xf9, 0x00, 0xb2,
+ 0x08, 0x0d, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0x60, 0x0f, 0xe0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0x81, 0x8f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0x6c, 0x00,
+ 0xfb, 0x00, 0x3e, 0x00, 0x0c, 0x98, 0x03, 0xec, 0x00, 0xc9, 0x80, 0x3e,
+ 0x00, 0x0f, 0xb0, 0x43, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x8f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x78, 0x08, 0xb8, 0x02, 0xed, 0x00, 0x8b, 0x90, 0x2e,
+ 0xb0, 0x03, 0xf0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xa0, 0x28, 0x00, 0x02, 0xc0, 0x00, 0x88, 0x01, 0x2c,
+ 0x60, 0x03, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xf0, 0x08, 0x68, 0x02, 0xd3, 0x00, 0x86, 0x80, 0x2d,
+ 0xf2, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3e, 0x80, 0x0c, 0x10, 0x03, 0xc0, 0x02, 0xc0, 0x00, 0x3c,
+ 0x40, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x01, 0xf0, 0x00, 0xfe, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xfc, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xbb, 0x00, 0x3e, 0xa0, 0x0c, 0x80, 0x03, 0xec, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0xb4, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x08, 0x60, 0x02, 0xdc, 0x00, 0xf7, 0x06, 0x2d,
+ 0xc0, 0x0b, 0x7a, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0x97, 0x80, 0x2e, 0xa0, 0x28, 0x58, 0x02, 0xde, 0x00, 0xb5, 0x80, 0x2d,
+ 0x60, 0x0b, 0x79, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30, 0x12, 0xcf, 0x40, 0xa3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xda, 0x00, 0x3e, 0x80, 0x0c, 0xa0, 0x03, 0xea, 0x00, 0xba, 0x40, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe1, 0x20, 0x78, 0x08, 0x3e,
+ 0x10, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x20, 0x3e, 0x40, 0x0f, 0x90, 0x01, 0x64, 0x00, 0xf9, 0x90, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x62, 0x0b, 0x94, 0x02, 0xe7, 0x00, 0xb9, 0xc0, 0x2e,
+ 0x60, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2f, 0x60, 0x0b, 0xd0, 0x42, 0x76, 0x20, 0xbd, 0x00, 0x2f,
+ 0x70, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2d, 0x40, 0x0b, 0x58, 0x22, 0xd4, 0x00, 0xb5, 0x80, 0x2d,
+ 0x40, 0x0b, 0x12, 0x82, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3f,
+ 0x00, 0x0f, 0x82, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x28, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x28, 0x3e, 0x4a, 0x0f, 0x92, 0x83, 0xe4, 0xa0, 0xf9, 0x28, 0x3e,
+ 0x4a, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xfd, 0x00, 0x3f, 0x40, 0x0f, 0xd0, 0x03, 0xf4, 0x02, 0xcd, 0x00, 0x3f,
+ 0x40, 0x0c, 0x90, 0x03, 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2c, 0x00, 0x0b, 0x00, 0x02, 0xe0, 0x00, 0xa0, 0x00, 0x2e,
+ 0x00, 0x0a, 0x80, 0x02, 0x20, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0x81, 0x00, 0x2c,
+ 0x40, 0x08, 0x10, 0x02, 0x44, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0a, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x82, 0xe4, 0x00, 0xa9, 0x00, 0x2c,
+ 0x40, 0x0a, 0x90, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x94, 0x03, 0xe4, 0x00, 0xc9, 0x00, 0x3e,
+ 0x40, 0x2c, 0x90, 0x03, 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0e, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x32, 0x00, 0x0f, 0x80, 0x07, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0c, 0x80, 0x03, 0x20, 0x00, 0xf8, 0x00, 0x32,
+ 0x00, 0x0c, 0x00, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x22, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2f, 0x80, 0x08, 0xe0, 0x00, 0x38, 0x80, 0xbe, 0x00, 0x37,
+ 0x80, 0x08, 0xa0, 0x02, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0xa0, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x28, 0x30, 0x0a, 0x2c, 0x00, 0xb3, 0x00, 0xa0,
+ 0xc0, 0x28, 0x30, 0x02, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x08, 0xb7, 0xa0, 0x21, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xa0, 0x08, 0x58, 0x02, 0x18, 0x00, 0xb5, 0x80, 0x25,
+ 0x80, 0x08, 0x30, 0x02, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xff, 0xe0, 0x31, 0xe0, 0x0f, 0x78, 0x02, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0x60, 0x0c, 0x68, 0x03, 0x16, 0x00, 0xf6, 0x80, 0x33,
+ 0x60, 0x0c, 0x78, 0x03, 0x5e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x80, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x1e, 0xc0, 0x0f, 0x80, 0x01, 0xe4, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x33, 0xe0, 0x0f, 0xf8, 0x03, 0x3e, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xbf, 0x00, 0x21, 0x80, 0x0b, 0xd0, 0x82, 0x18, 0x00, 0xb5, 0x08, 0x2d,
+ 0x82, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0xa1, 0x40, 0x0b, 0x60, 0x0a, 0x9c, 0x00, 0xb6, 0x00, 0x2d,
+ 0x40, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x20, 0xd0, 0x0b, 0x08, 0x02, 0x8c, 0x00, 0xb3, 0x80, 0x2c,
+ 0xe0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xff, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xf9, 0x00, 0x32, 0xd0, 0x0f, 0xb8, 0x03, 0xac, 0x00, 0xfb, 0x80, 0x3e,
+ 0xe0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xf9, 0x00, 0x3e, 0x88, 0x0f, 0xb4, 0x01, 0x68, 0x00, 0xf9, 0x00, 0x1e,
+ 0x80, 0x07, 0xb0, 0x01, 0xec, 0x00, 0x7b, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0x40, 0x0f, 0xf2, 0x03, 0xf4, 0x00, 0xfe, 0x00, 0x3f,
+ 0x40, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb4, 0x82, 0xe4, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xb9, 0x10, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb1, 0x00, 0x2c, 0x80, 0x8b, 0x30, 0x02, 0xc8, 0x08, 0xb1, 0x02, 0x2c,
+ 0x80, 0x8b, 0x30, 0x22, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfa, 0x00, 0x3e,
+ 0x40, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x10, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x12, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x44, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd4, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xfe, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x91, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x24, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xe0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x9d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x26, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xd2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xda, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0x80, 0x0f, 0xc0, 0x03, 0x30, 0x00, 0xfc, 0x00, 0x33,
+ 0x00, 0x0c, 0xc0, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0x80, 0x02, 0xa0, 0x00, 0xba, 0x00, 0x2a,
+ 0x00, 0x0a, 0x80, 0x0a, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x00, 0xcc, 0x00,
+ 0x33, 0x00, 0x2c, 0x80, 0x0b, 0x20, 0x02, 0x08, 0x00, 0xb0, 0x00, 0x20,
+ 0x80, 0x0a, 0x00, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x26, 0xc0, 0x0b, 0x24, 0x26, 0xa8, 0x00, 0xba, 0x00, 0x28,
+ 0x82, 0x1a, 0x02, 0x02, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x80, 0x0f, 0x80, 0x03, 0x20, 0x80, 0xf8, 0x48, 0x32,
+ 0x10, 0x0e, 0x90, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x7e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x4f, 0xc0, 0x0b, 0xf0, 0x00, 0xfe, 0x08, 0x3f,
+ 0x00, 0x2f, 0xd0, 0x03, 0xfc, 0x01, 0xff, 0x01, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x01, 0xfb, 0x00, 0x7e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x80, 0x8d, 0xac, 0x83, 0x68, 0x04, 0xf8, 0xc0, 0x3e,
+ 0xb2, 0x0c, 0x90, 0x03, 0xec, 0x00, 0xcb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x8b, 0xb0, 0x22, 0xec, 0x01,
+ 0xbb, 0x00, 0x0e, 0xe0, 0x07, 0xac, 0x07, 0x6b, 0x00, 0xba, 0xc0, 0x2e,
+ 0xb0, 0x05, 0x9c, 0x02, 0xec, 0x04, 0x8b, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x12, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xa4, 0x09, 0x14, 0x02, 0x04, 0x00, 0xb9, 0x00, 0x2c,
+ 0x40, 0x09, 0x29, 0x02, 0xcc, 0x02, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0a, 0x59, 0x02, 0x57, 0x20, 0xb7, 0x80, 0x2d,
+ 0x60, 0x09, 0x6c, 0x02, 0xee, 0x00, 0x87, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xb3, 0x01, 0x3e, 0x80, 0x0d, 0xb0, 0x03, 0x4c, 0x00, 0xf1, 0x00, 0x3e,
+ 0xc0, 0x0d, 0x20, 0x03, 0xcc, 0x00, 0xc3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x07, 0xf0, 0x03, 0xfc, 0x00,
+ 0x7f, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc4, 0x0f, 0xe0, 0x03, 0xfe, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x88, 0x0f, 0x98, 0x03, 0xa4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x60, 0x0e, 0xb8, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc1, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc4, 0x0b, 0x50, 0x02, 0x14, 0x00, 0xb7, 0x00, 0x2f,
+ 0x40, 0x08, 0xf0, 0x02, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xa0, 0x0b, 0x78, 0x02, 0x9e, 0x00, 0xb5, 0x80, 0x2d,
+ 0xe0, 0x0a, 0x78, 0x02, 0x1e, 0x00, 0xb7, 0x80, 0x25, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc1, 0x0b, 0x30, 0x42, 0xcc, 0x04,
+ 0xb3, 0x00, 0x24, 0xc0, 0x0b, 0x30, 0x42, 0x8c, 0x01, 0xb3, 0x00, 0x6c,
+ 0xc0, 0x08, 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xa8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x2e, 0xa5, 0x03, 0x28, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x01, 0x61, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x84, 0x0b, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x44, 0x0f, 0x94, 0x03, 0xe4, 0x00, 0xf9, 0x10, 0x3e,
+ 0x44, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x1e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x94, 0x02, 0xe7, 0x00, 0xb9, 0x40, 0x2e,
+ 0x50, 0x0b, 0x9c, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0xd0, 0x02, 0xf7, 0x00, 0xbd, 0x00, 0x2f,
+ 0x40, 0x0b, 0xdc, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x04, 0x31, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x41, 0x0b, 0x58, 0x02, 0xd4, 0x00, 0xb5, 0x80, 0x2d,
+ 0x60, 0x0b, 0x50, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3f, 0x00, 0x0f, 0x00, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x10, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0xa0,
+ 0xf9, 0x00, 0x3e, 0x4a, 0x0f, 0x92, 0x83, 0xe4, 0xa0, 0xf9, 0x28, 0x3e,
+ 0x4a, 0x0f, 0x92, 0x83, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x02, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3f, 0x40, 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xed, 0x00, 0x33,
+ 0x40, 0x0e, 0xd0, 0x03, 0xe4, 0x00, 0xc9, 0x00, 0x3f, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x03, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xa8, 0x00, 0x2a,
+ 0x00, 0x08, 0x80, 0x02, 0xe0, 0x00, 0x88, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xa1, 0x00, 0x28,
+ 0x40, 0x0a, 0x10, 0x02, 0xe4, 0x00, 0x81, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0x64, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc4, 0x00, 0xa1, 0x00, 0x28,
+ 0x40, 0x08, 0x90, 0x02, 0xe4, 0x00, 0x89, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x14, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x98, 0x03, 0xe6, 0x02, 0xe9, 0x00, 0x3a,
+ 0x60, 0x0e, 0x90, 0x03, 0xe4, 0x00, 0xc9, 0x00, 0x1e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x00, 0xa4, 0x00, 0xf9, 0x01, 0x3e, 0x40, 0x0f, 0x90, 0x13, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x4f, 0x92, 0x13, 0xe7, 0x00, 0xf9, 0x00, 0xbe,
+ 0x48, 0x4f, 0x90, 0x03, 0xc4, 0x02, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x10, 0x3e,
+ 0x04, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0c, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x04, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x02, 0x2e, 0x80, 0x03, 0xe3, 0x00, 0xf8, 0xc0, 0x3e, 0x80, 0x0f,
+ 0x80, 0x0b, 0xe1, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0a, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0xa0, 0x2c,
+ 0xc8, 0x0b, 0x34, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0x40, 0x08, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0xc0,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x50, 0x02, 0xd8, 0x00, 0xb5, 0x00, 0x2d,
+ 0x40, 0x0b, 0x60, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0x60, 0x02, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x80,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x68, 0x03, 0xd6, 0x00, 0xf6, 0x80, 0x3d,
+ 0xa0, 0x0f, 0x58, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0x60, 0x0c, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xbb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x04, 0x3e, 0x40, 0x0f, 0xa0, 0x43, 0xe8, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x80, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3c, 0x40, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xef, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xef, 0x80, 0x33,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xbe, 0x00, 0xff, 0x80, 0x3f, 0x60, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xfc, 0x00,
+ 0x87, 0x00, 0x2d, 0xc0, 0x0b, 0x40, 0x02, 0xf4, 0x40, 0xae, 0x18, 0xa1,
+ 0x84, 0x0b, 0x70, 0x02, 0x1c, 0x40, 0xb7, 0x00, 0x2d, 0x40, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xa7, 0x00, 0x2d, 0xc0, 0x0b, 0x50, 0x02, 0xd0, 0x00, 0xa4, 0x00, 0x21,
+ 0x00, 0x0b, 0x40, 0x02, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0x40, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+ 0x14, 0xcc, 0x10, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0x83, 0x04, 0x2c, 0x50, 0x0b, 0x00, 0x42, 0xc0, 0x02, 0xa0, 0x00, 0x20,
+ 0x00, 0x0b, 0x00, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0x40, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xfc, 0x01,
+ 0xeb, 0x00, 0x3c, 0x50, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xeb, 0x80, 0x32,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x02, 0x3e, 0x40, 0x07, 0x90, 0x03, 0xe8, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x80, 0x43, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xea, 0x0c, 0x60, 0x03, 0x34, 0x00, 0xfe, 0x00, 0x3f,
+ 0x80, 0x0f, 0xf9, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x40, 0x07, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x40, 0x08, 0xa0, 0x02, 0xa8, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x80, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0x40, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x10, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x40, 0x08, 0xb0, 0x02, 0xac, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x22, 0xec, 0x04, 0xbb, 0x02, 0x2e, 0x40, 0x0b, 0xb0,
+ 0x42, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x40, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2e, 0x40, 0x28, 0x80, 0x02, 0x84, 0x00, 0xb2, 0x00, 0x2c,
+ 0x80, 0x0b, 0x10, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0x40, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0c, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0c, 0x90, 0x03, 0xa0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x07, 0x20, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0x40, 0x07, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x2f, 0x40, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0xfc, 0x00, 0x3f,
+ 0x00, 0x0f, 0xc0, 0x43, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0x40, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0xbc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00,
+ 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c,
+ 0xc0, 0x0f, 0x30, 0x03, 0xcc, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x0f, 0x30,
+ 0x03, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x00, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d,
+ 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78,
+ 0x02, 0xf0, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00,
+ 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0,
+ 0x03, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x10, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e,
+ 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x00, 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80,
+ 0x02, 0xce, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c,
+ 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e,
+ 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0xa0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e,
+ 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e,
+ 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x1c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x1e, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d,
+ 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00,
+ 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3f, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xd0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d,
+ 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc4, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xda, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x02, 0xe4, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c,
+ 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x05, 0xfc, 0x14, 0xff, 0x00, 0x3f, 0xc0, 0x0d, 0xf0, 0x01, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xc0, 0x43, 0xb0, 0x00, 0xec, 0x00, 0x33,
+ 0x00, 0x0e, 0xc0, 0x03, 0x3c, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0c, 0xf0,
+ 0x03, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x10, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0x80, 0x02, 0x20, 0x00, 0xa8, 0x00, 0x2a,
+ 0x00, 0x0a, 0x00, 0x02, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0a, 0xb0,
+ 0x02, 0xf0, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc1, 0x01, 0x30, 0x02, 0xcc, 0x08,
+ 0xb3, 0x00, 0x0c, 0xc0, 0x1b, 0x00, 0x02, 0x80, 0x00, 0xa2, 0x00, 0x20,
+ 0x00, 0x0a, 0x00, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x08, 0x30,
+ 0x02, 0xf2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0x15, 0xac, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0x6c, 0x00,
+ 0x9b, 0x00, 0x0e, 0xc0, 0x0b, 0x00, 0x02, 0x00, 0x00, 0xa2, 0x00, 0x28,
+ 0x00, 0x0a, 0x80, 0x02, 0xac, 0x04, 0xbb, 0x00, 0x0e, 0xc0, 0x1a, 0xb0,
+ 0x02, 0xf0, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0xec, 0x00, 0xfb, 0x06, 0x3e, 0xc0, 0x0d, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x0b, 0xac, 0x02, 0xe9, 0x00, 0x32,
+ 0xc0, 0x2e, 0x98, 0x03, 0x2c, 0x00, 0xfb, 0x06, 0x3e, 0xc0, 0x0c, 0xb0,
+ 0x43, 0xd0, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1,
+ 0x01, 0xbc, 0x08, 0xff, 0x00, 0x3f, 0xc0, 0x4f, 0xf0, 0x03, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x8f, 0xf0, 0x83, 0xfc, 0x00, 0xfd, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xd9, 0x03, 0xfc, 0x04, 0xff, 0x00, 0x7d, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xf8, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xac, 0x00, 0xfb, 0x06, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x10,
+ 0xfb, 0x00, 0x7e, 0xc0, 0x0f, 0xb8, 0x03, 0x6c, 0x00, 0xfb, 0x88, 0x32,
+ 0xc0, 0x03, 0x90, 0x03, 0x2c, 0x00, 0xfb, 0x02, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xd0, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x16, 0xec, 0x04,
+ 0xbb, 0x01, 0x2e, 0xc0, 0x0b, 0xbc, 0x03, 0x6d, 0x00, 0xbb, 0x80, 0x36,
+ 0xf0, 0x0b, 0x94, 0x03, 0x6c, 0x10, 0xbb, 0x02, 0x2f, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xf2, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x05, 0x4c, 0x14, 0xb3, 0x01, 0x2c, 0xc0, 0x4b, 0x30, 0x02, 0xcc, 0x10,
+ 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x04, 0x00, 0x00, 0x40, 0x30, 0x00, 0x20,
+ 0x01, 0x03, 0xa0, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x00, 0xf8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0x01, 0x1e, 0x10, 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x78, 0x02, 0xde, 0x00,
+ 0xb7, 0x80, 0x2d, 0xe0, 0x0b, 0x48, 0x02, 0x53, 0x00, 0xb4, 0x80, 0x25,
+ 0x33, 0x09, 0x6c, 0x02, 0xde, 0x00, 0xb7, 0x80, 0x0d, 0xe1, 0x0b, 0x78,
+ 0x02, 0xf8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x08, 0x0c, 0x00, 0xf3, 0x00, 0x2c, 0xc4, 0x0f, 0x30, 0x02, 0xcc, 0x54,
+ 0xf3, 0x00, 0x2c, 0xc0, 0x8f, 0x80, 0x0b, 0x40, 0x00, 0xfa, 0x00, 0xb0,
+ 0x04, 0x0f, 0x20, 0x0b, 0x8c, 0x00, 0xf3, 0x00, 0x3c, 0xc0, 0x07, 0x32,
+ 0x43, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1d, 0xbc, 0x00, 0x7f, 0x00, 0x2f, 0xc5, 0x0f, 0xf1, 0x13, 0xfc, 0x00,
+ 0xbf, 0x00, 0x3f, 0xe0, 0x0f, 0xc0, 0x13, 0xf0, 0x40, 0xfe, 0x10, 0x3f,
+ 0x00, 0x0f, 0xe1, 0x01, 0x7c, 0x00, 0xff, 0x02, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xd0, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x05, 0xec, 0x14, 0xfb, 0x00, 0x3a, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xe0, 0x0c, 0xb0, 0x03, 0xee, 0x00, 0xc9, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x43, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xea, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x42, 0xdc, 0x00,
+ 0x97, 0x00, 0x2c, 0xc0, 0x08, 0x70, 0x42, 0xfc, 0x00, 0xa5, 0x00, 0x2d,
+ 0xc0, 0x09, 0xf0, 0x02, 0x1c, 0x04, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xf2, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1,
+ 0x00, 0x9e, 0x00, 0xb7, 0x85, 0x2d, 0xe0, 0x03, 0x78, 0x02, 0xde, 0x04,
+ 0xb7, 0x84, 0x2f, 0xe0, 0x28, 0x78, 0x02, 0xde, 0x04, 0x87, 0x80, 0x6d,
+ 0xe0, 0x0b, 0x78, 0x02, 0x9e, 0x00, 0xb7, 0x80, 0x2d, 0xed, 0x0b, 0x78,
+ 0x02, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc1, 0x0b, 0x30, 0x42, 0xcc, 0x01,
+ 0xb3, 0x00, 0x6c, 0xc0, 0x08, 0x35, 0x42, 0xcc, 0x00, 0xa3, 0x40, 0x2c,
+ 0xc0, 0x0b, 0x34, 0x02, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x4b, 0x30,
+ 0x02, 0xd2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x15, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x0f, 0xa0, 0x03, 0xe8, 0x10,
+ 0xfa, 0x00, 0x3e, 0x80, 0x4c, 0xa8, 0x03, 0xeb, 0x80, 0xca, 0x00, 0x3e,
+ 0xb8, 0x0f, 0xa0, 0x0b, 0xa8, 0x00, 0xfa, 0x00, 0x3e, 0x80, 0x4f, 0xa0,
+ 0x43, 0xfa, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0x58, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x81, 0xe0, 0x20, 0xf8, 0x08, 0x3e,
+ 0x02, 0x0d, 0x80, 0x83, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xd2, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x10, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0xcf, 0x90, 0x43, 0xe4, 0x02,
+ 0xc9, 0x00, 0x3e, 0x64, 0x0f, 0x98, 0x03, 0xe4, 0x04, 0xf9, 0x00, 0x36,
+ 0x40, 0x0f, 0x90, 0x03, 0x64, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x07, 0x90,
+ 0x43, 0xc2, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x04, 0x64, 0x04, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x00,
+ 0x89, 0x00, 0x2e, 0x61, 0x0b, 0x94, 0x02, 0x66, 0x00, 0xb9, 0x40, 0x62,
+ 0x60, 0x0b, 0x98, 0x02, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x4b, 0x90,
+ 0x02, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x05, 0x24, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xc4, 0x00,
+ 0xa9, 0x00, 0x2e, 0x40, 0x0b, 0xd1, 0x02, 0xf6, 0x00, 0xb5, 0x00, 0x27,
+ 0x60, 0x0b, 0x58, 0x02, 0x64, 0x01, 0xb9, 0x00, 0x2e, 0x40, 0x1b, 0x90,
+ 0x02, 0xc6, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x04, 0x04, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xe4, 0x00,
+ 0x81, 0x04, 0x2c, 0x40, 0x0b, 0x58, 0x02, 0x54, 0x00, 0xb5, 0x80, 0x21,
+ 0xc0, 0x0b, 0x50, 0x02, 0x04, 0x00, 0xb1, 0x02, 0x2c, 0x4a, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x0d, 0x60, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xe8, 0x00, 0x3f, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00, 0xf8, 0x00, 0x36,
+ 0x00, 0x0f, 0xc0, 0x03, 0x60, 0x00, 0xf8, 0x00, 0x3e, 0x08, 0x0f, 0x80,
+ 0x43, 0xee, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x1d, 0xe4, 0x00, 0xf9, 0x00, 0x2e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00,
+ 0xf9, 0x00, 0x3e, 0x4a, 0x0f, 0x92, 0x92, 0x64, 0xa0, 0xf9, 0x28, 0x3e,
+ 0x4a, 0x0f, 0x92, 0x83, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x8f, 0x90,
+ 0x43, 0xe6, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+ 0x05, 0xe4, 0x02, 0xc9, 0x00, 0x3e, 0x41, 0x0f, 0x90, 0x03, 0xe4, 0x10,
+ 0xf9, 0x00, 0x3f, 0x40, 0x0f, 0xd0, 0x03, 0xf4, 0x00, 0xed, 0x00, 0x3f,
+ 0x40, 0x0c, 0xd0, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xe6, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+ 0x10, 0xf0, 0x00, 0x88, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x42, 0xf0, 0x00,
+ 0xb8, 0x00, 0x2e, 0x00, 0x0b, 0x80, 0x02, 0xe0, 0x02, 0x88, 0x01, 0x2e,
+ 0x00, 0x2a, 0x80, 0x02, 0xe0, 0x04, 0xb8, 0x00, 0x2e, 0x01, 0x0b, 0x80,
+ 0x02, 0xce, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x05, 0xe4, 0x00, 0x81, 0x04, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00,
+ 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10, 0x02, 0xc4, 0x00, 0xa1, 0x00, 0x2c,
+ 0x40, 0x08, 0x10, 0x02, 0xc4, 0x00, 0xb1, 0x00, 0x2c, 0x40, 0x0b, 0x10,
+ 0x02, 0xc2, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x15, 0xa4, 0x00, 0x89, 0x00, 0x2e, 0x40, 0x0b, 0x90, 0x02, 0xe4, 0x04,
+ 0x99, 0x00, 0x2e, 0x40, 0x4b, 0x90, 0x02, 0xe4, 0x00, 0x89, 0x20, 0x2e,
+ 0x40, 0x0a, 0x90, 0x02, 0xe4, 0x00, 0xb9, 0x00, 0x2e, 0x40, 0x0b, 0x90,
+ 0x02, 0xc6, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x15, 0xe4, 0x00, 0xc9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x08,
+ 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe4, 0x00, 0xe9, 0x00, 0x3e,
+ 0x40, 0x0c, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x43, 0xe8, 0x04, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x01, 0xa4, 0x00, 0xf9, 0x02, 0x3e, 0x40, 0x0f, 0x90, 0x23, 0xe4, 0x14,
+ 0xf9, 0x04, 0x3e, 0x40, 0x4f, 0x90, 0x13, 0xe4, 0x00, 0xf9, 0x00, 0x3e,
+ 0x40, 0x4f, 0x90, 0x03, 0xe4, 0x00, 0xf9, 0x00, 0x3e, 0x40, 0x0f, 0x90,
+ 0x03, 0xca, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x10, 0x80, 0x00, 0xc8, 0x00, 0x3e, 0x00, 0x0f, 0x80, 0x03, 0xe0, 0x00,
+ 0xf8, 0x04, 0x3e, 0x00, 0x0f, 0x80, 0x23, 0xe0, 0x00, 0xf8, 0x00, 0x36,
+ 0x00, 0x0f, 0x80, 0x83, 0xe0, 0x00, 0xf8, 0x00, 0x3e, 0x00, 0x0f, 0x80,
+ 0x03, 0xca, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x28, 0x08, 0x8a, 0x00, 0x2e, 0x80, 0x0b, 0xa0, 0x02, 0xe8, 0x00,
+ 0x3a, 0x00, 0x0e, 0x80, 0x0b, 0xe0, 0x02, 0xf8, 0x00, 0xbe, 0x08, 0x23,
+ 0x80, 0x0b, 0xe4, 0x02, 0xe8, 0x00, 0xba, 0x00, 0x2e, 0x80, 0x0b, 0xa0,
+ 0x02, 0xca, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+ 0x05, 0x4c, 0x02, 0x83, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0xc1, 0x03, 0x30, 0x02, 0xed, 0x80, 0xb3, 0x00, 0x26,
+ 0xc1, 0x0b, 0x30, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc1, 0x0b, 0x30,
+ 0x02, 0xca, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x01, 0x3c, 0x00, 0x87, 0x00, 0x0d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x00,
+ 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x50, 0x02, 0xd8, 0x00, 0xb5, 0x80, 0x21,
+ 0x80, 0x0b, 0x60, 0x02, 0xdc, 0x01, 0xb7, 0x00, 0x2d, 0xc0, 0x03, 0x70,
+ 0x02, 0xe8, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x08, 0x0e, 0x08, 0xc7, 0x80, 0x3d, 0xe0, 0x0f, 0x78, 0x03, 0xde, 0x00,
+ 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x68, 0x03, 0xd6, 0x00, 0xfe, 0x80, 0x35,
+ 0x60, 0x0f, 0x58, 0x03, 0xde, 0x00, 0xf7, 0x80, 0x3d, 0xe0, 0x0f, 0x78,
+ 0x03, 0xea, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x1d, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x13, 0xec, 0x00,
+ 0xfb, 0x04, 0x3e, 0xc0, 0x0f, 0xb0, 0x43, 0xe8, 0x00, 0xf9, 0x00, 0x3e,
+ 0xc0, 0x0f, 0x80, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xc2, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xfe, 0x00, 0xff, 0x90, 0x3f, 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x40,
+ 0xcf, 0x90, 0x3f, 0xe0, 0x0e, 0xf8, 0x03, 0x3e, 0x00, 0xff, 0x80, 0x3f,
+ 0xe0, 0x0f, 0xf8, 0x03, 0xfe, 0x00, 0xff, 0x80, 0x3b, 0xe0, 0x0f, 0xf8,
+ 0x03, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x11, 0x9c, 0x00, 0xb7, 0x00, 0x2d, 0xc0, 0x0b, 0x70, 0x02, 0xdc, 0x02,
+ 0x87, 0x00, 0x2f, 0xc0, 0x0f, 0x50, 0x02, 0x9c, 0x00, 0xb7, 0x12, 0x2d,
+ 0x80, 0x0b, 0x70, 0x02, 0xdc, 0x40, 0xb7, 0x04, 0x2d, 0xc0, 0x0b, 0x70,
+ 0x02, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x9e, 0x00, 0xb7, 0x02, 0x0d, 0xc0, 0x0b, 0x70, 0x02, 0xee, 0x04,
+ 0x87, 0x02, 0x2d, 0xc0, 0x0a, 0x60, 0x02, 0x14, 0x00, 0xb6, 0x00, 0x2d,
+ 0x40, 0x0b, 0x50, 0x02, 0xdc, 0x00, 0xb7, 0x00, 0x29, 0xc0, 0x0b, 0x70,
+ 0x02, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+ 0x14, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0x83, 0x04, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2e,
+ 0xc0, 0x0b, 0x10, 0x02, 0xcc, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc8, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0x15, 0xac, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xcb, 0x00, 0x3e, 0x40, 0x0e, 0xb0, 0x03, 0x2c, 0x00, 0xfb, 0x00, 0x3e,
+ 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x01, 0x3a, 0xc1, 0x0f, 0xb0,
+ 0x03, 0xea, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0xec, 0x00, 0xfb, 0x00, 0x2e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0x40, 0x0f, 0x90, 0x03, 0xe8, 0x00, 0xf9, 0x00, 0x3e,
+ 0x80, 0x0f, 0xa0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90,
+ 0x10, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc1, 0x0f, 0xf0, 0x23, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0x60, 0x03, 0x34, 0x00, 0xfe, 0x00, 0x3f,
+ 0x40, 0x0d, 0xf9, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe0, 0x44, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+ 0x04, 0x6c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0xe0, 0x0b, 0xb0, 0x02, 0xa8, 0x00, 0xb9, 0x00, 0x2e,
+ 0xc0, 0x08, 0xa0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc1, 0x0b, 0xb0,
+ 0x42, 0xe0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x05, 0x2c, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0, 0x02, 0xec, 0x00,
+ 0xbb, 0x00, 0x2e, 0x48, 0x0b, 0xb0, 0x02, 0x2c, 0x00, 0xbb, 0x00, 0x2e,
+ 0xc0, 0x09, 0xb0, 0x02, 0xec, 0x00, 0xbb, 0x00, 0x2e, 0xc0, 0x0b, 0xb0,
+ 0x02, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x04, 0x0c, 0x00, 0xb3, 0x00, 0x2c, 0xc0, 0x0b, 0x30, 0x02, 0xcc, 0x00,
+ 0xb3, 0x00, 0x2c, 0x40, 0x0b, 0x90, 0x02, 0x8c, 0x00, 0xb3, 0x00, 0x2c,
+ 0x80, 0x08, 0x30, 0x02, 0xcc, 0x08, 0x33, 0x00, 0x2c, 0xc0, 0x0b, 0x30,
+ 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x0d, 0x6c, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0, 0x03, 0xec, 0x00,
+ 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0x20, 0x03, 0x24, 0x00, 0xfa, 0x00, 0x3e,
+ 0x40, 0x0d, 0xb0, 0x03, 0xec, 0x00, 0xfb, 0x00, 0x3e, 0xc0, 0x0f, 0xb0,
+ 0x03, 0xe0, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x1d, 0xfc, 0x00, 0xff, 0x04, 0x3f, 0xc0, 0x4f, 0xf0, 0x01, 0xfc, 0x00,
+ 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f,
+ 0xc0, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0xff, 0x00, 0x3f, 0xc0, 0x0f, 0xf0,
+ 0x03, 0xe8, 0x06, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x41, 0x03, 0x70, 0x40, 0xdc, 0x10, 0x37, 0x04, 0x0d, 0xc1, 0x03,
+ 0x70, 0x40, 0xdc, 0x10, 0x37, 0x04, 0x0d, 0xc1, 0x03, 0x70, 0x40, 0xdc,
+ 0x10, 0x37, 0x04, 0x0d, 0xc1, 0x03, 0x70, 0x40, 0xdc, 0x10, 0x37, 0x04,
+ 0x0d, 0xc0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x44, 0x05, 0x71, 0x01, 0x5c, 0x40, 0x57, 0x10, 0x15, 0xc4, 0x05,
+ 0x71, 0x01, 0x5c, 0x40, 0x57, 0x10, 0x15, 0xc4, 0x05, 0x71, 0x01, 0x5c,
+ 0x40, 0x57, 0x10, 0x15, 0xc4, 0x05, 0x71, 0x01, 0x5c, 0x40, 0x57, 0x10,
+ 0x15, 0xc0, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01,
+ 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48,
+ 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08,
+ 0x04, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x01, 0x60, 0x00, 0x58, 0x00, 0x16, 0x00, 0x05, 0x80, 0x01,
+ 0x60, 0x00, 0x58, 0x00, 0x16, 0x00, 0x05, 0x80, 0x01, 0x60, 0x00, 0x58,
+ 0x00, 0x16, 0x00, 0x05, 0x80, 0x01, 0x60, 0x00, 0x58, 0x00, 0x16, 0x00,
+ 0x05, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x48, 0x05, 0x72, 0x01, 0x5c, 0x80, 0x57, 0x20, 0x15, 0xc8, 0x05,
+ 0x72, 0x01, 0x5c, 0x80, 0x57, 0x20, 0x15, 0xc8, 0x05, 0x72, 0x01, 0x5c,
+ 0x80, 0x57, 0x20, 0x15, 0xc8, 0x05, 0x72, 0x01, 0x5c, 0x80, 0x57, 0x20,
+ 0x15, 0xc0, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x40, 0x00, 0x60, 0x00, 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00,
+ 0x60, 0x00, 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x18,
+ 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x18, 0x00, 0x06, 0x00,
+ 0x01, 0x80, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x48, 0x04, 0x22, 0x01, 0x08, 0x80, 0x42, 0x20, 0x10, 0x88, 0x04,
+ 0x22, 0x01, 0x08, 0x80, 0x42, 0x20, 0x10, 0x88, 0x04, 0x22, 0x01, 0x08,
+ 0x80, 0x42, 0x20, 0x10, 0x88, 0x04, 0x22, 0x01, 0x08, 0x80, 0x42, 0x20,
+ 0x10, 0x80, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x4a, 0x05, 0x42, 0x81, 0x50, 0xa0, 0x54, 0x28, 0x15, 0x0a, 0x05,
+ 0x42, 0x81, 0x50, 0xa0, 0x54, 0x28, 0x15, 0x0a, 0x05, 0x42, 0x81, 0x50,
+ 0xa0, 0x54, 0x28, 0x15, 0x0a, 0x05, 0x42, 0x81, 0x50, 0xa0, 0x54, 0x28,
+ 0x15, 0x00, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x0c, 0x01, 0x53, 0x00, 0x54, 0xc0, 0x15, 0x30, 0x05, 0x4c, 0x01,
+ 0x53, 0x00, 0x54, 0xc0, 0x15, 0x30, 0x05, 0x4c, 0x01, 0x53, 0x00, 0x54,
+ 0xc0, 0x15, 0x30, 0x05, 0x4c, 0x01, 0x53, 0x00, 0x54, 0xc0, 0x15, 0x30,
+ 0x05, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00,
+ 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10,
+ 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00,
+ 0x01, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x60, 0x02, 0x08, 0x00, 0x82, 0x00, 0x20, 0x80, 0x08, 0x20, 0x02,
+ 0x08, 0x00, 0x82, 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82,
+ 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, 0x00, 0x20, 0x80,
+ 0x08, 0x01, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x40, 0x05, 0x60, 0x01, 0x58, 0x00, 0x56, 0x00, 0x15, 0x80, 0x05,
+ 0x60, 0x01, 0x58, 0x00, 0x56, 0x00, 0x15, 0x80, 0x05, 0x60, 0x01, 0x58,
+ 0x00, 0x56, 0x00, 0x15, 0x80, 0x05, 0x60, 0x01, 0x58, 0x00, 0x56, 0x00,
+ 0x15, 0x80, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x40, 0x03, 0x60, 0x00, 0xd8, 0x00, 0x36, 0x00, 0x0d, 0x80, 0x03,
+ 0x60, 0x00, 0xd8, 0x00, 0x36, 0x00, 0x0d, 0x80, 0x03, 0x60, 0x00, 0xd8,
+ 0x00, 0x36, 0x00, 0x0d, 0x80, 0x03, 0x60, 0x00, 0xd8, 0x00, 0x36, 0x00,
+ 0x0d, 0x80, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x42, 0x04, 0x30, 0x81, 0x0c, 0x20, 0x43, 0x08, 0x10, 0xc2, 0x04,
+ 0x30, 0x81, 0x0c, 0x20, 0x43, 0x08, 0x10, 0xc2, 0x04, 0x30, 0x81, 0x0c,
+ 0x20, 0x43, 0x08, 0x10, 0xc2, 0x04, 0x30, 0x81, 0x0c, 0x20, 0x43, 0x08,
+ 0x10, 0xc0, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
+ 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x0c,
+ 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00,
+ 0x00, 0xc0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x01, 0x30, 0x80, 0x4c, 0x20, 0x13, 0x08, 0x04, 0xc2, 0x01,
+ 0x30, 0x80, 0x4c, 0x20, 0x13, 0x08, 0x04, 0xc2, 0x01, 0x30, 0x80, 0x4c,
+ 0x20, 0x13, 0x08, 0x04, 0xc2, 0x01, 0x30, 0x80, 0x4c, 0x20, 0x13, 0x08,
+ 0x04, 0xc0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x42, 0x05, 0x60, 0x81, 0x58, 0x20, 0x56, 0x08, 0x15, 0x82, 0x05,
+ 0x60, 0x81, 0x58, 0x20, 0x56, 0x08, 0x15, 0x82, 0x05, 0x60, 0x81, 0x58,
+ 0x20, 0x56, 0x08, 0x15, 0x82, 0x05, 0x60, 0x81, 0x58, 0x20, 0x56, 0x08,
+ 0x15, 0x80, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x42, 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, 0x00,
+ 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, 0x00, 0x20, 0x80, 0x08,
+ 0x20, 0x02, 0x08, 0x00, 0x82, 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, 0x08,
+ 0x00, 0x80, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x42, 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x11, 0x82, 0x04,
+ 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x11, 0x82, 0x04, 0x60, 0x81, 0x18,
+ 0x20, 0x46, 0x08, 0x11, 0x82, 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, 0x08,
+ 0x11, 0x80, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x60, 0x05, 0x58, 0x01, 0x56, 0x00, 0x55, 0x80, 0x15, 0x60, 0x05,
+ 0x58, 0x01, 0x56, 0x00, 0x55, 0x80, 0x15, 0x60, 0x05, 0x58, 0x01, 0x56,
+ 0x00, 0x55, 0x80, 0x15, 0x60, 0x05, 0x58, 0x01, 0x56, 0x00, 0x55, 0x80,
+ 0x15, 0x40, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x06, 0x01, 0x41, 0x80, 0x50, 0x60, 0x14, 0x18, 0x05, 0x06, 0x01,
+ 0x41, 0x80, 0x50, 0x60, 0x14, 0x18, 0x05, 0x06, 0x01, 0x41, 0x80, 0x50,
+ 0x60, 0x14, 0x18, 0x05, 0x06, 0x01, 0x41, 0x80, 0x50, 0x60, 0x14, 0x18,
+ 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
+ 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40,
+ 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08,
+ 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x46, 0x03, 0x51, 0x80, 0xd4, 0x60, 0x35, 0x18, 0x0d, 0x46, 0x03,
+ 0x51, 0x80, 0xd4, 0x60, 0x35, 0x18, 0x0d, 0x46, 0x03, 0x51, 0x80, 0xd4,
+ 0x60, 0x35, 0x18, 0x0d, 0x46, 0x03, 0x51, 0x80, 0xd4, 0x60, 0x35, 0x18,
+ 0x0d, 0x40, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x46, 0x05, 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05,
+ 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05, 0x71, 0x81, 0x5c,
+ 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05, 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18,
+ 0x15, 0xc0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x46, 0x03, 0x71, 0x80, 0xdc, 0x60, 0x37, 0x18, 0x0d, 0xc6, 0x03,
+ 0x71, 0x80, 0xdc, 0x60, 0x37, 0x18, 0x0d, 0xc6, 0x03, 0x71, 0x80, 0xdc,
+ 0x60, 0x37, 0x18, 0x0d, 0xc6, 0x03, 0x71, 0x80, 0xdc, 0x60, 0x37, 0x18,
+ 0x0d, 0xc0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x46, 0x05, 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05,
+ 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05, 0x71, 0x81, 0x5c,
+ 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05, 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18,
+ 0x15, 0xc0, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01,
+ 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48,
+ 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08,
+ 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x61, 0x80, 0x58, 0x60, 0x16, 0x18, 0x05, 0x86, 0x01,
+ 0x61, 0x80, 0x58, 0x60, 0x16, 0x18, 0x05, 0x86, 0x01, 0x61, 0x80, 0x58,
+ 0x60, 0x16, 0x18, 0x05, 0x86, 0x01, 0x61, 0x80, 0x58, 0x60, 0x16, 0x18,
+ 0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x40, 0x05, 0x70, 0x01, 0x5c, 0x00, 0x57, 0x00, 0x15, 0xc0, 0x05,
+ 0x70, 0x01, 0x5c, 0x00, 0x57, 0x00, 0x15, 0xc0, 0x05, 0x70, 0x01, 0x5c,
+ 0x00, 0x57, 0x00, 0x15, 0xc0, 0x05, 0x70, 0x01, 0x5c, 0x00, 0x57, 0x00,
+ 0x15, 0xc0, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x42, 0x00, 0x60, 0x80, 0x18, 0x20, 0x06, 0x08, 0x01, 0x82, 0x00,
+ 0x60, 0x80, 0x18, 0x20, 0x06, 0x08, 0x01, 0x82, 0x00, 0x60, 0x80, 0x18,
+ 0x20, 0x06, 0x08, 0x01, 0x82, 0x00, 0x60, 0x80, 0x18, 0x20, 0x06, 0x08,
+ 0x01, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x42, 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04,
+ 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, 0x81, 0x08,
+ 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, 0x08,
+ 0x10, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x42, 0x05, 0x40, 0x81, 0x50, 0x20, 0x54, 0x08, 0x15, 0x02, 0x05,
+ 0x40, 0x81, 0x50, 0x20, 0x54, 0x08, 0x15, 0x02, 0x05, 0x40, 0x81, 0x50,
+ 0x20, 0x54, 0x08, 0x15, 0x02, 0x05, 0x40, 0x81, 0x50, 0x20, 0x54, 0x08,
+ 0x15, 0x00, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x01, 0x50, 0xc0, 0x54, 0x30, 0x15, 0x0c, 0x05, 0x43, 0x01,
+ 0x50, 0xc0, 0x54, 0x30, 0x15, 0x0c, 0x05, 0x43, 0x01, 0x50, 0xc0, 0x54,
+ 0x30, 0x15, 0x0c, 0x05, 0x43, 0x01, 0x50, 0xc0, 0x54, 0x30, 0x15, 0x0c,
+ 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x42, 0x00, 0x10, 0x80, 0x04, 0x20, 0x01, 0x08, 0x00,
+ 0x42, 0x00, 0x10, 0x80, 0x04, 0x20, 0x01, 0x08, 0x00, 0x42, 0x00, 0x10,
+ 0x80, 0x04, 0x20, 0x01, 0x08, 0x00, 0x42, 0x00, 0x10, 0x80, 0x04, 0x20,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x42, 0x02, 0x00, 0x80, 0x80, 0x20, 0x20, 0x08, 0x08, 0x02, 0x02,
+ 0x00, 0x80, 0x80, 0x20, 0x20, 0x08, 0x08, 0x02, 0x02, 0x00, 0x80, 0x80,
+ 0x20, 0x20, 0x08, 0x08, 0x02, 0x02, 0x00, 0x80, 0x80, 0x20, 0x20, 0x08,
+ 0x08, 0x00, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x40, 0x05, 0x60, 0x01, 0x58, 0x00, 0x56, 0x00, 0x15, 0x80, 0x05,
+ 0x60, 0x01, 0x58, 0x00, 0x56, 0x00, 0x15, 0x80, 0x05, 0x60, 0x01, 0x58,
+ 0x00, 0x56, 0x00, 0x15, 0x80, 0x05, 0x60, 0x01, 0x58, 0x00, 0x56, 0x00,
+ 0x15, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc5, 0x40, 0x03, 0x60, 0x00, 0xd8, 0x00, 0x36, 0x00, 0x0d, 0x80, 0x03,
+ 0x60, 0x00, 0xd8, 0x00, 0x36, 0x00, 0x0d, 0x80, 0x03, 0x60, 0x00, 0xd8,
+ 0x00, 0x36, 0x00, 0x0d, 0x80, 0x03, 0x60, 0x00, 0xd8, 0x00, 0x36, 0x00,
+ 0x0d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x30, 0x01, 0x0c, 0x00, 0x43, 0x00, 0x10, 0xc0, 0x04,
+ 0x30, 0x01, 0x0c, 0x00, 0x43, 0x00, 0x10, 0xc0, 0x04, 0x30, 0x01, 0x0c,
+ 0x00, 0x43, 0x00, 0x10, 0xc0, 0x04, 0x30, 0x01, 0x0c, 0x00, 0x43, 0x00,
+ 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
+ 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x0c,
+ 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x01, 0x31, 0x40, 0x4c, 0x50, 0x13, 0x14, 0x04, 0xc5, 0x01,
+ 0x31, 0x40, 0x4c, 0x50, 0x13, 0x14, 0x04, 0xc5, 0x01, 0x31, 0x40, 0x4c,
+ 0x50, 0x13, 0x14, 0x04, 0xc5, 0x01, 0x31, 0x40, 0x4c, 0x50, 0x13, 0x14,
+ 0x04, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x23, 0x05, 0x68, 0xc1, 0x5a, 0x30, 0x56, 0x8c, 0x15, 0xa3, 0x05,
+ 0x68, 0xc1, 0x5a, 0x30, 0x56, 0x8c, 0x15, 0xa3, 0x05, 0x68, 0xc1, 0x5a,
+ 0x30, 0x56, 0x8c, 0x15, 0xa3, 0x05, 0x68, 0xc1, 0x5a, 0x30, 0x56, 0x8c,
+ 0x15, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00,
+ 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08,
+ 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x44, 0x62, 0x11, 0x18, 0x84, 0x46, 0x21, 0x11, 0x88, 0x44,
+ 0x62, 0x11, 0x18, 0x84, 0x46, 0x21, 0x11, 0x88, 0x44, 0x62, 0x11, 0x18,
+ 0x84, 0x46, 0x21, 0x11, 0x88, 0x44, 0x62, 0x11, 0x18, 0x84, 0x46, 0x21,
+ 0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x45, 0x50, 0x11, 0x54, 0x04, 0x55, 0x01, 0x15, 0x40, 0x45,
+ 0x50, 0x11, 0x54, 0x04, 0x55, 0x01, 0x15, 0x40, 0x45, 0x50, 0x11, 0x54,
+ 0x04, 0x55, 0x01, 0x15, 0x40, 0x45, 0x50, 0x11, 0x54, 0x04, 0x55, 0x01,
+ 0x15, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x21, 0x42, 0x08, 0x50, 0x82, 0x14, 0x20, 0x85, 0x08, 0x21,
+ 0x42, 0x08, 0x50, 0x82, 0x14, 0x20, 0x85, 0x08, 0x21, 0x42, 0x08, 0x50,
+ 0x82, 0x14, 0x20, 0x85, 0x08, 0x21, 0x42, 0x08, 0x50, 0x82, 0x14, 0x20,
+ 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0a, 0x01, 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28, 0x04, 0x0a, 0x01,
+ 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28, 0x04, 0x0a, 0x01, 0x02, 0x80, 0x40,
+ 0xa0, 0x10, 0x28, 0x04, 0x0a, 0x01, 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x03, 0x53, 0x00, 0xd4, 0xc0, 0x35, 0x30, 0x0d, 0x4c, 0x03,
+ 0x53, 0x00, 0xd4, 0xc0, 0x35, 0x30, 0x0d, 0x4c, 0x03, 0x53, 0x00, 0xd4,
+ 0xc0, 0x35, 0x30, 0x0d, 0x4c, 0x03, 0x53, 0x00, 0xd4, 0xc0, 0x35, 0x30,
+ 0x0d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x05, 0x72, 0x01, 0x5c, 0x80, 0x57, 0x20, 0x15, 0xc8, 0x05,
+ 0x72, 0x01, 0x5c, 0x80, 0x57, 0x20, 0x15, 0xc8, 0x05, 0x72, 0x01, 0x5c,
+ 0x80, 0x57, 0x20, 0x15, 0xc8, 0x05, 0x72, 0x01, 0x5c, 0x80, 0x57, 0x20,
+ 0x15, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x23, 0x18, 0x48, 0xc6, 0x12, 0x31, 0x84, 0x8c, 0x61, 0x23, 0x18,
+ 0x48, 0xc6, 0x12, 0x31, 0x84, 0x8c, 0x61, 0x23, 0x18, 0x48, 0xc6, 0x12,
+ 0x31, 0x84, 0x8c, 0x61, 0x23, 0x18, 0x48, 0xc6, 0x12, 0x31, 0x84, 0x8c,
+ 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff,
+ 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3,
+ 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff,
+ 0xfd, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff,
+ 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3,
+ 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff,
+ 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff,
+ 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3,
+ 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff,
+ 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3b, 0x7e, 0x4e, 0xdf, 0x93, 0xb7, 0xe4, 0xed, 0xf9, 0x3b, 0x7e,
+ 0x4e, 0xdf, 0x93, 0xb7, 0xe4, 0xed, 0xf9, 0x3b, 0x7e, 0x4e, 0xdf, 0x93,
+ 0xb7, 0xe4, 0xed, 0xf9, 0x3b, 0x7e, 0x4e, 0xdf, 0x93, 0xb7, 0xe4, 0xed,
+ 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x02, 0x70, 0x40, 0x9c, 0x10, 0x27, 0x1c, 0x09, 0xc1, 0x02,
+ 0x70, 0x40, 0x9c, 0x10, 0x27, 0x04, 0x09, 0xc1, 0x02, 0x70, 0x40, 0x1c,
+ 0x10, 0x27, 0x04, 0x01, 0xc1, 0x02, 0x70, 0x40, 0x1c, 0x50, 0x67, 0x14,
+ 0x49, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x05, 0x71, 0x01, 0x5c, 0x40, 0x57, 0x10, 0x15, 0xc4, 0x05,
+ 0x71, 0x01, 0x5c, 0x40, 0x57, 0x10, 0x15, 0xc4, 0x05, 0x71, 0x00, 0x5c,
+ 0x40, 0x57, 0x10, 0x05, 0xc4, 0x05, 0x71, 0x01, 0x5c, 0x40, 0x77, 0x10,
+ 0x15, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01,
+ 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48,
+ 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08,
+ 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0x18, 0x00, 0x06, 0x10, 0x81, 0x80, 0x00,
+ 0x60, 0x00, 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x18,
+ 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x09, 0x18, 0x42, 0x06, 0x18,
+ 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x04, 0x72, 0x01, 0x1c, 0x80, 0x47, 0x20, 0x11, 0xc8, 0x04,
+ 0x72, 0x01, 0x1c, 0x80, 0x47, 0x20, 0x11, 0xc8, 0x04, 0x72, 0x01, 0x1c,
+ 0x80, 0x47, 0x20, 0x11, 0xc8, 0x04, 0x72, 0x01, 0x1c, 0x80, 0x07, 0x21,
+ 0x11, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00,
+ 0x60, 0x00, 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x18,
+ 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x18, 0x00, 0x06, 0x00,
+ 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x04, 0x22, 0x01, 0x08, 0x80, 0x42, 0x60, 0x10, 0x88, 0x04,
+ 0x22, 0x01, 0x08, 0x80, 0x42, 0x20, 0x10, 0x88, 0x04, 0x22, 0x01, 0x08,
+ 0x80, 0x42, 0x20, 0x10, 0x88, 0x04, 0x24, 0x01, 0x09, 0xa0, 0x02, 0x60,
+ 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x2a, 0x04, 0x4a, 0x81, 0x12, 0xa0, 0x44, 0xa8, 0x11, 0x2a, 0x04,
+ 0x4a, 0x81, 0x12, 0xa0, 0x44, 0xa8, 0x11, 0x2a, 0x04, 0x4a, 0x81, 0x12,
+ 0xa0, 0x44, 0xa8, 0x11, 0x2a, 0x04, 0x48, 0x80, 0x12, 0xa1, 0x04, 0xac,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xc0, 0x0c, 0x00, 0x53, 0x00, 0x14, 0xc0, 0x05, 0x30, 0x01, 0x4c, 0x00,
+ 0x53, 0x00, 0x14, 0xc0, 0x05, 0x30, 0x01, 0x4c, 0x00, 0x53, 0x00, 0x14,
+ 0xc0, 0x05, 0x30, 0x01, 0x4c, 0x00, 0x53, 0x00, 0x14, 0xc0, 0x05, 0x30,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x40, 0x01, 0x00, 0x00,
+ 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10,
+ 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x46, 0x00, 0x19, 0x01, 0x04, 0x40,
+ 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xc0, 0x40, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x88, 0x00, 0x02,
+ 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00,
+ 0x88, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xc0, 0x40, 0x04, 0x60, 0x01, 0x18, 0x00, 0x46, 0x00, 0x11, 0x80, 0x04,
+ 0x60, 0x01, 0x18, 0x00, 0x46, 0x00, 0x11, 0x80, 0x00, 0x60, 0x01, 0x98,
+ 0x00, 0x46, 0x00, 0x11, 0x80, 0x04, 0x60, 0x01, 0x98, 0x00, 0x46, 0x00,
+ 0x11, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x01, 0x40, 0x02, 0x60, 0x00, 0x98, 0x00, 0x26, 0x00, 0x09, 0x80, 0x02,
+ 0x40, 0x00, 0x98, 0x00, 0x26, 0x00, 0x09, 0x80, 0x02, 0x60, 0x00, 0x98,
+ 0x00, 0x26, 0x00, 0x09, 0x80, 0x02, 0x62, 0x00, 0x18, 0x00, 0x26, 0x00,
+ 0x09, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x42, 0x04, 0x30, 0x81, 0x0c, 0x20, 0x43, 0x08, 0x10, 0xc2, 0x04,
+ 0x30, 0x81, 0x0c, 0x20, 0x43, 0x08, 0x10, 0xc2, 0x04, 0x30, 0x81, 0x0c,
+ 0x20, 0x43, 0x08, 0x10, 0xc2, 0x04, 0x30, 0x81, 0x0c, 0x20, 0x43, 0x08,
+ 0x90, 0xc0, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
+ 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x0c,
+ 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x03, 0x00,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x02, 0x00, 0x30, 0x80, 0x0c, 0x20, 0x03, 0x08, 0x00, 0xc2, 0x00,
+ 0x30, 0x80, 0x0c, 0x20, 0x03, 0x08, 0x00, 0xc2, 0x00, 0x30, 0x80, 0x0c,
+ 0x20, 0x03, 0x08, 0x00, 0xc2, 0x00, 0x30, 0xc1, 0x0c, 0x20, 0x03, 0x08,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x42, 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x11, 0x82, 0x04,
+ 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x11, 0x82, 0x04, 0x60, 0x81, 0x18,
+ 0x20, 0x46, 0x08, 0x11, 0x82, 0x04, 0x60, 0xc1, 0x18, 0x20, 0x46, 0x08,
+ 0x11, 0x80, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x42, 0x00, 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, 0x00,
+ 0x20, 0x80, 0x08, 0x20, 0x02, 0x08, 0x00, 0x82, 0x00, 0x20, 0x80, 0x08,
+ 0x20, 0x02, 0x08, 0x00, 0x82, 0x00, 0x20, 0x80, 0x0c, 0x20, 0x02, 0x08,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x01, 0x42, 0x04, 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x11, 0x82, 0x04,
+ 0x60, 0x81, 0x18, 0x20, 0x46, 0x08, 0x11, 0x82, 0x04, 0x60, 0x81, 0x18,
+ 0x20, 0x46, 0x08, 0x11, 0x82, 0x04, 0x60, 0x81, 0x0c, 0x20, 0x46, 0x08,
+ 0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x40, 0x04, 0x50, 0x01, 0x14, 0x00, 0x45, 0x00, 0x11, 0x40, 0x04,
+ 0x50, 0x01, 0x14, 0x00, 0x45, 0x00, 0x11, 0x40, 0x04, 0x50, 0x01, 0x14,
+ 0x00, 0x45, 0x00, 0x11, 0x40, 0x04, 0x50, 0x00, 0x04, 0x00, 0x45, 0x00,
+ 0x11, 0x42, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0x06, 0x00, 0x41, 0x80, 0x10, 0x60, 0x04, 0x18, 0x01, 0x06, 0x00,
+ 0x41, 0x80, 0x10, 0x60, 0x04, 0x18, 0x01, 0x06, 0x00, 0x41, 0x80, 0x10,
+ 0x60, 0x04, 0x18, 0x01, 0x06, 0x00, 0x41, 0x80, 0x10, 0x60, 0x04, 0x18,
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x00, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
+ 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40,
+ 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x46, 0x03, 0x51, 0x80, 0xd4, 0x60, 0x35, 0x19, 0x0d, 0x46, 0x03,
+ 0x51, 0x80, 0xd4, 0x60, 0x35, 0x18, 0x0d, 0x46, 0x03, 0x51, 0x80, 0xd4,
+ 0x60, 0x35, 0x18, 0x0d, 0x46, 0x03, 0x51, 0x90, 0xd4, 0x64, 0x35, 0x19,
+ 0x0d, 0x40, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x46, 0x04, 0x71, 0x81, 0x1c, 0x60, 0x47, 0x18, 0x11, 0xc6, 0x04,
+ 0x71, 0x81, 0x1c, 0x60, 0x47, 0x18, 0x11, 0xc6, 0x04, 0x71, 0x81, 0x1c,
+ 0x60, 0x47, 0x18, 0x11, 0xc6, 0x04, 0x71, 0x81, 0x9c, 0x60, 0x47, 0x18,
+ 0x91, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x46, 0x02, 0x71, 0x80, 0x9c, 0x60, 0x27, 0x18, 0x09, 0xc6, 0x02,
+ 0x71, 0x80, 0x9c, 0x60, 0x27, 0x18, 0x09, 0xc6, 0x02, 0x71, 0x80, 0x9c,
+ 0x60, 0x67, 0x18, 0x09, 0xc6, 0x02, 0x71, 0x80, 0x1c, 0x60, 0x27, 0x18,
+ 0x09, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x45, 0x46, 0x05, 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05,
+ 0x71, 0x81, 0x5c, 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05, 0x71, 0x81, 0x5c,
+ 0x60, 0x57, 0x18, 0x15, 0xc6, 0x05, 0x71, 0x81, 0x0c, 0x60, 0x57, 0x18,
+ 0x15, 0xc2, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x02, 0x01, 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01,
+ 0x20, 0x80, 0x48, 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x48,
+ 0x20, 0x12, 0x08, 0x04, 0x82, 0x01, 0x20, 0x80, 0x5c, 0x20, 0x12, 0x48,
+ 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x06, 0x00, 0x61, 0x80, 0x18, 0x60, 0x06, 0x18, 0x01, 0x86, 0x10,
+ 0x61, 0x80, 0x18, 0x60, 0x06, 0x18, 0x01, 0x86, 0x00, 0x61, 0x80, 0x18,
+ 0x60, 0x06, 0x18, 0x01, 0x86, 0x00, 0x61, 0x81, 0x18, 0x60, 0x06, 0x18,
+ 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x45, 0x60, 0x04, 0x78, 0x01, 0x1e, 0x00, 0x47, 0x80, 0x11, 0xe0, 0x04,
+ 0x78, 0x01, 0x1e, 0x00, 0x47, 0x80, 0x11, 0xe0, 0x04, 0x78, 0x01, 0x1e,
+ 0x00, 0x07, 0x80, 0x11, 0xe0, 0x04, 0x78, 0x01, 0x1e, 0x00, 0x47, 0x80,
+ 0x11, 0xc0, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x42, 0x00, 0x60, 0x80, 0x18, 0x20, 0x06, 0x08, 0x01, 0x82, 0x00,
+ 0x60, 0x80, 0x18, 0x20, 0x06, 0x08, 0x01, 0x82, 0x00, 0x60, 0x80, 0x18,
+ 0x20, 0x06, 0x08, 0x01, 0x82, 0x00, 0x60, 0x80, 0x18, 0x20, 0x06, 0x48,
+ 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x42, 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04,
+ 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, 0x81, 0x08,
+ 0x20, 0x02, 0x08, 0x10, 0x82, 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, 0x08,
+ 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x42, 0x04, 0x40, 0x81, 0x10, 0x20, 0x44, 0x08, 0x11, 0x02, 0x04,
+ 0x40, 0x81, 0x10, 0x20, 0x44, 0x08, 0x11, 0x02, 0x04, 0x40, 0x81, 0x10,
+ 0x20, 0x44, 0x08, 0x11, 0x02, 0x04, 0x40, 0x80, 0x10, 0x20, 0x44, 0x08,
+ 0x11, 0x00, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x03, 0x00, 0x50, 0xc0, 0x14, 0x30, 0x05, 0x0c, 0x01, 0x43, 0x00,
+ 0x50, 0xc0, 0x14, 0x30, 0x05, 0x0c, 0x01, 0x43, 0x00, 0x50, 0xc0, 0x14,
+ 0x30, 0x05, 0x0c, 0x01, 0x43, 0x00, 0x50, 0xc0, 0x14, 0x30, 0x05, 0x08,
+ 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x08, 0x00, 0x42, 0x00, 0x10, 0x80, 0x04, 0x20, 0x01, 0x08, 0x00,
+ 0x42, 0x00, 0x10, 0x80, 0x04, 0x20, 0x01, 0x08, 0x00, 0x42, 0x00, 0x10,
+ 0x80, 0x04, 0x20, 0x01, 0x08, 0x00, 0x42, 0x00, 0x10, 0x80, 0x04, 0x20,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x42, 0x02, 0x00, 0x80, 0x80, 0x20, 0x20, 0x08, 0x08, 0x02, 0x02,
+ 0x00, 0x80, 0x80, 0x20, 0x20, 0x08, 0x08, 0x02, 0x02, 0x00, 0x80, 0x80,
+ 0x20, 0x20, 0x08, 0x08, 0x02, 0x02, 0x00, 0x80, 0x80, 0x20, 0x20, 0x08,
+ 0x08, 0x80, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x40, 0x04, 0x60, 0x01, 0x18, 0x00, 0x46, 0x00, 0x11, 0x80, 0x00,
+ 0x60, 0x01, 0x18, 0x00, 0x46, 0x00, 0x11, 0x80, 0x04, 0x60, 0x01, 0x18,
+ 0x00, 0x06, 0x00, 0x11, 0x80, 0x04, 0x60, 0x01, 0x98, 0x00, 0x46, 0x00,
+ 0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x40, 0x02, 0x60, 0x00, 0x98, 0x00, 0x26, 0x00, 0x09, 0x80, 0x02,
+ 0x60, 0x00, 0x98, 0x00, 0x26, 0x00, 0x19, 0x80, 0x02, 0x60, 0x00, 0x98,
+ 0x00, 0x26, 0x00, 0x09, 0x80, 0x02, 0x60, 0x00, 0x1c, 0x00, 0x26, 0x00,
+ 0x09, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x60, 0x04, 0x38, 0x01, 0x0e, 0x00, 0x43, 0x80, 0x10, 0xe0, 0x04,
+ 0x38, 0x01, 0x0e, 0x00, 0x43, 0x80, 0x10, 0xe0, 0x04, 0x38, 0x01, 0x0e,
+ 0x00, 0x43, 0x80, 0x10, 0xe0, 0x04, 0x38, 0x01, 0x1a, 0x00, 0x43, 0x80,
+ 0x10, 0xc0, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x00, 0x01, 0x00, 0x30, 0x40, 0x0c, 0x10, 0x03, 0x04, 0x00, 0xc1, 0x00,
+ 0x30, 0x40, 0x0c, 0x10, 0x03, 0x04, 0x00, 0xc1, 0x00, 0x30, 0x40, 0x0c,
+ 0x10, 0x03, 0x04, 0x00, 0xc1, 0x00, 0x30, 0x40, 0x08, 0x10, 0x03, 0x04,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x05, 0x00, 0x31, 0x44, 0x0c, 0x50, 0x03, 0x14, 0x00, 0xc5, 0x00,
+ 0x31, 0x40, 0x0c, 0x50, 0x03, 0x14, 0x10, 0xc5, 0x00, 0x31, 0x40, 0x0c,
+ 0x50, 0x03, 0x14, 0x00, 0xc5, 0x00, 0x31, 0x41, 0x0c, 0x50, 0x03, 0x10,
+ 0x00, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x43, 0x04, 0x60, 0xc1, 0x18, 0x30, 0x46, 0x0c, 0x11, 0x83, 0x04,
+ 0x60, 0xc1, 0x18, 0x30, 0x46, 0x0c, 0x01, 0x83, 0x04, 0x60, 0xc1, 0x18,
+ 0x30, 0x46, 0x0c, 0x11, 0x83, 0x04, 0x60, 0xc1, 0x18, 0x30, 0x46, 0x0c,
+ 0x11, 0x80, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x40, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00,
+ 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08,
+ 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x48, 0x44, 0x62, 0x11, 0x18, 0x84, 0x46, 0x21, 0x11, 0x88, 0x44,
+ 0x62, 0x11, 0x18, 0x84, 0x46, 0x21, 0x01, 0x88, 0x44, 0x62, 0x11, 0x18,
+ 0x84, 0x46, 0x21, 0x11, 0x88, 0x44, 0x62, 0x11, 0x18, 0x84, 0x46, 0x21,
+ 0x11, 0x80, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x40, 0x44, 0x50, 0x11, 0x14, 0x04, 0x45, 0x01, 0x11, 0x40, 0x44,
+ 0x50, 0x11, 0x14, 0x04, 0x45, 0x01, 0x01, 0x40, 0x44, 0x50, 0x11, 0x14,
+ 0x04, 0x45, 0x01, 0x11, 0x40, 0x44, 0x50, 0x10, 0x14, 0x04, 0x45, 0x01,
+ 0x11, 0x40, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x08, 0x20, 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, 0x01, 0x08, 0x20,
+ 0x42, 0x08, 0x10, 0x82, 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10,
+ 0x82, 0x04, 0x20, 0x81, 0x08, 0x20, 0x42, 0x08, 0x10, 0x80, 0x04, 0x20,
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0a, 0x01, 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28, 0x04, 0x0a, 0x01,
+ 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28, 0x04, 0x0a, 0x01, 0x02, 0x80, 0x40,
+ 0xa0, 0x10, 0x28, 0x04, 0x0a, 0x01, 0x02, 0x80, 0x40, 0xa0, 0x10, 0x28,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x45, 0x4d, 0x03, 0x53, 0x40, 0xd4, 0xd0, 0x35, 0x34, 0x0d, 0x4d, 0x03,
+ 0x53, 0x40, 0xd4, 0xd0, 0x35, 0x34, 0x0d, 0x4d, 0x03, 0x53, 0x40, 0xd4,
+ 0xd0, 0x35, 0x34, 0x0d, 0x4d, 0x03, 0x53, 0x40, 0xd4, 0xd0, 0x35, 0x34,
+ 0x0d, 0x40, 0x11, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0x48, 0x04, 0x72, 0x00, 0x1c, 0x80, 0x47, 0x20, 0x11, 0xc8, 0x04,
+ 0x72, 0x01, 0x1c, 0x80, 0x47, 0x20, 0x11, 0xc8, 0x04, 0x72, 0x01, 0x1c,
+ 0x80, 0x47, 0x20, 0x11, 0xc8, 0x04, 0x72, 0x01, 0x9c, 0x80, 0x47, 0x20,
+ 0x11, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x23, 0x18, 0x48, 0xc6, 0x12, 0x31, 0x84, 0x8c, 0x41, 0x23, 0x18,
+ 0x48, 0xc6, 0x12, 0x31, 0x84, 0x8c, 0x61, 0x23, 0x18, 0x48, 0xc6, 0x12,
+ 0x31, 0x84, 0x8c, 0x61, 0x23, 0x18, 0x48, 0xc4, 0x12, 0x31, 0x04, 0x8c,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff,
+ 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3,
+ 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff,
+ 0xfd, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff,
+ 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3,
+ 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff,
+ 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff,
+ 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3,
+ 0xff, 0xf4, 0xff, 0xfd, 0x3f, 0xff, 0x4f, 0xff, 0xd3, 0xff, 0xf4, 0xff,
+ 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3b, 0x7e, 0x4e, 0xdf, 0x93, 0xb7, 0xe4, 0xed, 0xf9, 0x3b, 0x7e,
+ 0x4e, 0xdf, 0x93, 0xb7, 0xe4, 0xed, 0xf9, 0x3b, 0x7e, 0x4e, 0xdf, 0x93,
+ 0xb7, 0xe4, 0xed, 0xf9, 0x3b, 0x7e, 0x4e, 0xde, 0x13, 0xb7, 0xe4, 0xec,
+ 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x02, 0x84, 0x00, 0xa1, 0x00, 0x28, 0x40, 0x0a, 0x10, 0x02, 0x84,
+ 0x00, 0xa1, 0x00, 0x28, 0x40, 0x0a, 0x10, 0x02, 0x84, 0x00, 0xa1, 0x00,
+ 0x28, 0x40, 0x0a, 0x10, 0x02, 0x84, 0x00, 0xa1, 0x00, 0x28, 0x40, 0x0a,
+ 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04,
+ 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00,
+ 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00,
+ 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x84, 0x00, 0x21, 0x00, 0x88, 0x40, 0x02, 0x10, 0x00, 0x84,
+ 0x00, 0x21, 0x00, 0x88, 0x40, 0x22, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00,
+ 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02,
+ 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04,
+ 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00,
+ 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00,
+ 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80,
+ 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00,
+ 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08,
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, 0x80,
+ 0x02, 0x20, 0x00, 0x88, 0x00, 0x22, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00,
+ 0x88, 0x00, 0x22, 0x00, 0x08, 0x80, 0x02, 0x20, 0x00, 0x88, 0x00, 0x22,
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00,
+ 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
+ 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20,
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x0a, 0x84, 0x02, 0xa1, 0x00, 0xa8, 0x40, 0x2a, 0x10, 0x0a, 0x84,
+ 0x02, 0xa1, 0x00, 0xa8, 0x40, 0x2a, 0x10, 0x0a, 0x84, 0x02, 0xa1, 0x00,
+ 0xa8, 0x40, 0x2a, 0x10, 0x0a, 0x84, 0x02, 0xa1, 0x00, 0xa8, 0x40, 0x2a,
+ 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04,
+ 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00,
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, 0x84,
+ 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00,
+ 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x07, 0x30, 0x01, 0xcc, 0x00, 0x73, 0x00, 0x1c, 0xc0, 0x07,
+ 0x30, 0x01, 0xcc, 0x00, 0x73, 0x00, 0x1c, 0xc0, 0x07, 0x30, 0x01, 0xcc,
+ 0x00, 0x73, 0x00, 0x1c, 0xc0, 0x07, 0x30, 0x01, 0xcc, 0x00, 0x73, 0x00,
+ 0x1c, 0xc0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, 0x84,
+ 0x00, 0x21, 0x00, 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00,
+ 0x08, 0x40, 0x02, 0x10, 0x00, 0x84, 0x00, 0x21, 0x00, 0x08, 0x40, 0x02,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00,
+ 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00,
+ 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80,
+ 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00,
+ 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x20, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+ 0x3c, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0f, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x02, 0x84, 0x04, 0xa1, 0xcd, 0x28, 0x41, 0x0a, 0x10, 0xc2, 0x84,
+ 0x00, 0xa1, 0x0a, 0x28, 0x40, 0x0a, 0x10, 0xc2, 0x04, 0x00, 0xa1, 0x02,
+ 0x28, 0x40, 0x0a, 0x10, 0x02, 0x84, 0x24, 0xa1, 0x09, 0x28, 0x40, 0x0a,
+ 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x05, 0x10, 0x01, 0x06, 0x00, 0x42, 0x00, 0x10, 0x80, 0x04,
+ 0x18, 0x01, 0x00, 0x00, 0x43, 0x00, 0x10, 0xc0, 0x44, 0x08, 0x01, 0x00,
+ 0x00, 0x40, 0x00, 0x10, 0x00, 0x04, 0x10, 0x01, 0x06, 0x80, 0x42, 0x00,
+ 0x10, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x08, 0xc6, 0x26, 0x21, 0x08, 0x08, 0x41, 0x42, 0x10, 0xc8, 0xc4,
+ 0x26, 0x31, 0x0a, 0x88, 0x43, 0x62, 0x10, 0x88, 0xc4, 0x06, 0x21, 0x02,
+ 0x88, 0x40, 0x62, 0x10, 0x00, 0x84, 0x26, 0x21, 0x08, 0x88, 0x40, 0x62,
+ 0x10, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x30, 0x04, 0x24, 0x01, 0xc7, 0x00, 0x41, 0x40, 0x10, 0xf0, 0x04,
+ 0x00, 0x01, 0x08, 0x00, 0x41, 0x40, 0x10, 0xf0, 0x04, 0x00, 0x01, 0x00,
+ 0x00, 0x40, 0x40, 0x10, 0x30, 0x04, 0x04, 0x01, 0x03, 0x00, 0x41, 0x40,
+ 0x10, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x24, 0x20, 0x00, 0x08, 0x20, 0x02, 0x00, 0x80, 0x02,
+ 0x20, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00,
+ 0x08, 0x20, 0x02, 0x00, 0x00, 0x80, 0x04, 0x20, 0x00, 0x04, 0x22, 0x02,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x02, 0x00, 0x10, 0x80, 0x44, 0x20, 0x10, 0x08, 0x00, 0x42, 0x41,
+ 0x10, 0x90, 0x00, 0x20, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x80, 0x04,
+ 0x20, 0x10, 0x08, 0x00, 0x02, 0x01, 0x10, 0x80, 0x00, 0x20, 0x11, 0x08,
+ 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x08, 0xc0, 0x2e, 0x20, 0x08, 0x88, 0x02, 0x22, 0x00, 0xa8, 0xc2,
+ 0x26, 0x30, 0x03, 0x88, 0x00, 0x22, 0x00, 0x28, 0xc0, 0x06, 0x20, 0x0b,
+ 0x88, 0x20, 0x22, 0x00, 0x08, 0x82, 0x2e, 0x20, 0x00, 0x88, 0x22, 0x22,
+ 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x18, 0x00, 0x0a, 0x00, 0x89, 0x80, 0x22, 0x20, 0x00, 0x88, 0x02,
+ 0x02, 0x00, 0x02, 0x80, 0x00, 0x60, 0x00, 0x08, 0x00, 0x02, 0x00, 0x02,
+ 0x80, 0x00, 0x60, 0x00, 0x18, 0x00, 0x2a, 0x00, 0x01, 0x80, 0x20, 0x20,
+ 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x2a, 0x84, 0x12, 0xa1, 0x82, 0xa8, 0x61, 0x6a, 0x10, 0xca, 0x84,
+ 0x3e, 0xa1, 0x04, 0xa8, 0x50, 0xaa, 0x10, 0x4a, 0x84, 0x0e, 0xa1, 0x00,
+ 0xa8, 0x60, 0xaa, 0x10, 0x2a, 0x84, 0x22, 0xa1, 0x0e, 0xa8, 0x60, 0x6a,
+ 0x10, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x04, 0x22, 0x81, 0x48, 0x80, 0x52, 0x20, 0x10, 0xc8, 0x04,
+ 0x36, 0x01, 0x0d, 0x80, 0x61, 0x20, 0x10, 0x88, 0x04, 0x06, 0x01, 0x01,
+ 0x80, 0x52, 0x20, 0x10, 0x08, 0x04, 0x32, 0x01, 0x0c, 0x80, 0x51, 0x20,
+ 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x84, 0x30, 0x31, 0x0c, 0x08, 0x43, 0x42, 0x10, 0xe0, 0x84,
+ 0x20, 0x31, 0x0c, 0x08, 0x52, 0x02, 0x10, 0xe0, 0x04, 0x00, 0x21, 0x00,
+ 0x08, 0x61, 0x02, 0x10, 0x00, 0x84, 0x30, 0x21, 0x08, 0x08, 0x62, 0x42,
+ 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x30, 0x04, 0x20, 0x01, 0x8e, 0x00, 0x63, 0x40, 0x1c, 0x50, 0x07,
+ 0x30, 0x01, 0xc0, 0x00, 0x73, 0x00, 0x10, 0xd0, 0x07, 0x30, 0x01, 0xcc,
+ 0x00, 0x53, 0x00, 0x1c, 0xf0, 0x07, 0x10, 0x01, 0xc2, 0x00, 0x51, 0x40,
+ 0x1c, 0xc0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x84, 0x08, 0x21, 0x08, 0x08, 0x41, 0x02, 0x10, 0x40, 0x86,
+ 0x04, 0x01, 0x04, 0x08, 0x40, 0x42, 0x10, 0x40, 0x84, 0x04, 0x21, 0x00,
+ 0x08, 0x40, 0x42, 0x10, 0x20, 0x86, 0x18, 0x21, 0x00, 0x04, 0x41, 0x02,
+ 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x01, 0x24, 0x00, 0x0e, 0x20, 0x02, 0xc8, 0x00, 0x82, 0x01,
+ 0x38, 0x90, 0x09, 0x20, 0x01, 0x08, 0x00, 0xc2, 0x00, 0x08, 0x80, 0x01,
+ 0x20, 0x02, 0x08, 0x00, 0x02, 0x01, 0x24, 0x80, 0x0e, 0x20, 0x02, 0xc8,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x82, 0x10, 0x30, 0x08, 0x08, 0x01, 0x42, 0x00, 0x70, 0x80,
+ 0x20, 0x30, 0x0c, 0x08, 0x02, 0x42, 0x00, 0xf0, 0xc0, 0x00, 0x20, 0x00,
+ 0x08, 0x01, 0x42, 0x00, 0x10, 0x82, 0x10, 0x20, 0x08, 0x08, 0x01, 0x42,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x80, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02,
+ 0x30, 0x00, 0x0e, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+ 0x3c, 0x30, 0x80, 0x80, 0x80, 0x00, 0x00, 0x10, 0x00, 0x10, 0xf0, 0x80,
+ 0x80, 0x80, 0x00, 0x00, 0x10, 0x00, 0x10, 0xf0, 0x80, 0x80, 0x80, 0x00,
+ 0x00, 0x10, 0x00, 0x10, 0xf0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x10, 0x00,
+ 0x10, 0xcf, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00,
+ 0x59, 0x80, 0x40, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40,
+ 0x09, 0x80, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x30, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x22, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22,
+ 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3e, 0x6f, 0xfe, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xfd, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3e, 0x6f, 0xbe, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x7f, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfb,
+ 0xff, 0xdf, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x37, 0x3f, 0x3d, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xef, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
+ 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xbf, 0xc0,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 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, 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, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+ 0x00, 0x20, 0x01, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x0c, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+ 0x00, 0x20, 0x01, 0x02, 0x02, 0x00, 0x00, 0x30, 0x00, 0x43, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x19, 0xaf, 0x30, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x03, 0x30, 0x00, 0x40, 0x0c, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x05, 0x30, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0xe1, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
diff --git a/kernel/drv/oss_envy24/oss_envy24.c b/kernel/drv/oss_envy24/oss_envy24.c
new file mode 100644
index 0000000..b3b82bd
--- /dev/null
+++ b/kernel/drv/oss_envy24/oss_envy24.c
@@ -0,0 +1,4043 @@
+/*
+ * Purpose: Driver for IC Ensemble ENVY24 based audio cards.
+ *
+ * The audio input and output devices implemented by this driver use additional
+ * layer of buffering for channel re-interleaving. The device itself uses
+ * 10/12 channel interleaved 32 bit format in hardware level. The
+ * re-interleaving engine splits these multi channel devices to several
+ * "stereo" devices.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_envy24_cfg.h"
+#include <ac97.h>
+#include <oss_pci.h>
+
+#include "envy24.h"
+
+extern int envy24_skipdevs;
+extern int envy24_force_mono;
+extern int envy24_gain_sliders;
+int envy24_virtualout = 0; /* This used to be an config option */
+
+extern int envy24_devmask;
+#define DMASK_ANALOGOUT 1
+#define DMASK_ANALOGIN 2
+#define DMASK_SPDIFOUT 4
+#define DMASK_SPDIFIN 8
+#define DMASK_MONITORIN 16
+#define DMASK_RAWDEVS 32
+
+extern envy24_auxdrv_t default_auxdrv;
+extern envy24_auxdrv_t ap2496_auxdrv;
+extern envy24_auxdrv_t d410_auxdrv;
+extern envy24_auxdrv_t d1010lt_auxdrv;
+extern envy24_auxdrv_t tdif_auxdrv;
+extern envy24_auxdrv_t ewx2496_auxdrv;
+extern envy24_auxdrv_t ews88d_auxdrv;
+extern envy24_auxdrv_t dmx6fire_auxdrv;
+
+static card_spec models[] = {
+ {0xd6301412, "M Audio Delta 1010", 8, 8,
+ MF_MAUDIO | MF_MIDI1 | MF_SPDIF | MF_WCLOCK | MF_MEEPROM},
+ {0xd6311412, "M Audio Delta DiO 2496", 2, 0,
+ MF_MAUDIO | MF_SPDIF | MF_SPDSELECT | MF_MEEPROM},
+ {0xd6321412, "M Audio Delta 66", 4, 4,
+ MF_MAUDIO | MF_SPDIF | MF_AKMCODEC | MF_MEEPROM},
+ {0xd6331412, "M Audio Delta 44", 4, 4,
+ MF_MAUDIO | MF_AKMCODEC | MF_MEEPROM},
+ {0xd6341412, "M Audio Audiophile 2496", 2, 2,
+ MF_AP | MF_SPDIF | MF_MIDI1 | MF_MEEPROM, &ap2496_auxdrv},
+ {0xd6381412, "M Audio Delta 410", 8, 2, MF_D410 | MF_SPDIF | MF_MEEPROM,
+ &d410_auxdrv},
+
+ /* Delta 1010 rev E is based on 1010LT instead of the original 1010 design */
+ {0xd63014ff, "M Audio Delta 1010 rev E", 8, 8,
+ MF_MIDI1 | MF_SPDIF | MF_MEEPROM | MF_WCLOCK, &d1010lt_auxdrv},
+
+ {0xd63b1412, "M Audio Delta 1010LT", 8, 8,
+ MF_MIDI1 | MF_SPDIF | MF_MEEPROM | MF_WCLOCK, &d1010lt_auxdrv},
+ {0xd6351412, "M Audio Delta TDIF", 8, 8, MF_SPDIF | MF_MEEPROM | MF_WCLOCK,
+ &tdif_auxdrv},
+ {0x1115153b, "Terratec EWS88MT", 8, 8,
+ MF_MIDI1 | MF_SPDIF | MF_EWS88 | MF_AC97},
+ {0x112b153b, "Terratec EWS88D", 8, 8,
+ MF_MIDI1 | MF_MIDI2 | MF_SPDIF | MF_AC97 | MF_WCLOCK, &ews88d_auxdrv},
+ {0x1130153b, "Terratec EWX 24/96", 2, 2, MF_SPDIF | MF_EWX2496,
+ &ewx2496_auxdrv},
+ {0x1138153b, "Terratec DMX6fire 24/96", 6, 6,
+ MF_MIDI1 | MF_MIDI2 | MF_SPDIF, &dmx6fire_auxdrv},
+ {0x17121412, "Generic Envy24 based card", 8, 8,
+ MF_SPDIF | MF_MIDI1 | MF_CONSUMER | MF_HOONTECH},
+ {0}
+};
+
+static struct speed_sel speed_tab[] = {
+ {
+ 8000, 0x06}
+ ,
+ {
+ 9600, 0x03}
+ ,
+ {
+ 11025, 0x0a}
+ ,
+ {
+ 12000, 0x02}
+ ,
+ {
+ 16000, 0x05}
+ ,
+ {
+ 22050, 0x09}
+ ,
+ {
+ 24000, 0x01}
+ ,
+ {
+ 32000, 0x04}
+ ,
+ {
+ 44100, 0x08}
+ ,
+ {
+ 48000, 0x00}
+ ,
+ /* {64000, 0x0f}, doesn't work */
+ {
+ 88200, 0x0b}
+ ,
+ {
+ 96000, 0x07}
+ ,
+ {
+ -1, 0x10}
+ ,
+};
+
+int
+envy24_read_cci (envy24_devc * devc, int pos)
+{
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x03);
+ return INB (devc->osdev, devc->ccs_base + 0x04);
+}
+
+void
+envy24_write_cci (envy24_devc * devc, int pos, int data)
+{
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x03);
+ OUTB (devc->osdev, data, devc->ccs_base + 0x04);
+}
+
+static int
+eeprom_read (envy24_devc * devc, int pos)
+{
+ int i, status;
+
+ for (i = 0; i < 0x10000; i++)
+ {
+ status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+
+ OUTB (devc->osdev, 0xa0, devc->ccs_base + 0x10); /* EEPROM read */
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x11); /* Offset */
+
+ for (i = 0; i < 2000; i++)
+ {
+ status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+
+ oss_udelay (1);
+ return INB (devc->osdev, devc->ccs_base + 0x12);
+}
+
+static int
+load_eeprom (envy24_devc * devc, int subid)
+{
+ int status, i, check;
+
+ status = INB (devc->osdev, devc->ccs_base + 0x13);
+
+ if (!(status & 0x80))
+ return 0; /* No EEPROM */
+
+ for (i = 0; i < 32; i++)
+ {
+ devc->eeprom[i] = eeprom_read (devc, i);
+ devc->eeprom[i] = eeprom_read (devc, i);
+ }
+ DDB (cmn_err (CE_CONT, "EEPROM="));
+ for (i = 0; i < 10; i++)
+ DDB (cmn_err (CE_CONT, "0x%02x, ", devc->eeprom[i]));
+ DDB (cmn_err (CE_CONT, "\n"));
+
+ check = 0;
+ for (i = 0; i < 4; i++)
+ {
+ check <<= 8;
+ check |= devc->eeprom[i];
+ }
+
+ if (check != subid)
+ cmn_err (CE_CONT,
+ "Envy24 WARNING: Possible EEPROM read error %08x != %08x\n",
+ check, subid);
+
+ return 1;
+}
+
+static void
+handle_playdev (envy24_devc * devc, envy24_portc * portc, int this_frag)
+{
+ int sample, nsamples, nbytes, ch;
+ dmap_t *dmap = audio_engines[portc->dev]->dmap_out;
+
+ if (!(portc->trigger_bits & PCM_ENABLE_OUTPUT) && devc->playback_started)
+ return;
+
+ nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */
+
+ nbytes = nsamples * portc->channels;
+
+ if (audio_engines[portc->dev]->dmap_out->flags & DMAP_POST)
+ {
+ if (portc->pcm_qlen > 0)
+ portc->pcm_qlen--;
+ }
+ else
+ {
+ if (portc->pcm_qlen < devc->writeahead)
+ portc->pcm_qlen++;
+ }
+
+ if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3))
+ nbytes *= 2;
+ else if (portc->
+ bits & (AFMT_S32_LE | AFMT_S32_BE | AFMT_S24_LE | AFMT_S24_BE))
+ nbytes *= 4;
+
+ if (nbytes != dmap->fragment_size)
+ return; /* Fragment size mismatch */
+
+ switch (portc->bits)
+ {
+ case AFMT_U8:
+ {
+ unsigned char *ip;
+ int *op;
+
+ ip = audio_engines[portc->dev]->dmap_out->dmabuf;
+ ip += (dmap_get_qhead (dmap) * dmap->fragment_size);
+ op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag);
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int *p = &op[sample * 10 + portc->chnum];
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ *p++ = (*ip++ ^ 0x80) << 24;
+ }
+ }
+ }
+ break;
+
+ case AFMT_AC3:
+ case AFMT_S16_LE:
+ {
+ short *ip;
+ int *op;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Envy24: Copy out %d, %d",
+ dmap_get_qhead (dmap) * dmap->fragment_size, nbytes);
+#endif
+
+ ip = (short *) (dmap->dmabuf +
+ (dmap_get_qhead (dmap) * dmap->fragment_size));
+ op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag);
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int *p = &op[sample * 10 + portc->chnum];
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ *p++ = *ip++ << 16;
+ }
+ }
+ }
+ break;
+
+ case AFMT_S16_BE:
+ {
+ short *ip;
+ int *op;
+
+ ip = (short *) (audio_engines[portc->dev]->dmap_out->dmabuf +
+ (dmap_get_qhead (dmap) * dmap->fragment_size));
+ op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag);
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int *p = &op[sample * 10 + portc->chnum];
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ short s = (short) (((*(unsigned short *) ip & 0xff) << 8) |
+ ((*(unsigned short *) ip & 0xff00) >>
+ 8));
+ ip++;
+ *p++ = s << 16;
+ }
+ }
+ }
+ break;
+
+ case AFMT_S24_LE:
+ {
+ int *ip;
+ int *op;
+
+ ip = (int *) (audio_engines[portc->dev]->dmap_out->dmabuf +
+ (dmap_get_qhead (dmap) * dmap->fragment_size));
+ op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag);
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int *p = &op[sample * 10 + portc->chnum];
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ *p++ = *ip++ << 8;
+ }
+ }
+ }
+ break;
+
+ case AFMT_S32_LE:
+ {
+ int *ip;
+ int *op;
+
+ ip = (int *) (audio_engines[portc->dev]->dmap_out->dmabuf +
+ (dmap_get_qhead (dmap) * dmap->fragment_size));
+ op = (int *) (devc->playbuf + devc->hw_pfragsize * this_frag);
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int *p = &op[sample * 10 + portc->chnum];
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ *p++ = *ip++;
+ }
+ }
+ }
+ break;
+ }
+
+ oss_audio_outputintr (portc->dev, 1);
+}
+
+#ifdef DO_RIAA
+static __inline__ int32_t
+_riaa_sat31 (register int32_t a, register int32_t b)
+{
+ register int64_t v = (((int64_t) a) * b) + (1 << 30);
+ return (int32_t) (v >> 31);
+}
+#endif
+
+static void
+handle_recdev (envy24_devc * devc, envy24_portc * portc)
+{
+ int sample, nsamples, nbytes, ch;
+ dmap_t *dmap = audio_engines[portc->dev]->dmap_in;
+
+ if (portc->trigger_bits == 0 && devc->recording_started)
+ return;
+
+ nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */
+
+ nbytes = nsamples * portc->channels;
+
+ if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3))
+ nbytes *= 2;
+ else if (portc->bits & (AFMT_S32_LE | AFMT_S24_LE))
+ nbytes *= 4;
+
+ if (nbytes != dmap->fragment_size)
+ {
+ return; /* Fragment size mismatch */
+ }
+
+ switch (portc->bits)
+ {
+ case AFMT_U8:
+ {
+ unsigned char *ip;
+ int *op;
+
+ ip = audio_engines[portc->dev]->dmap_in->dmabuf;
+ ip += (dmap_get_qtail (dmap) * dmap->fragment_size);
+ op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag);
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int *p = &op[sample * 12 + portc->chnum];
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ *ip++ = ((*p++) >> 24) ^ 0x80;
+ }
+ }
+ }
+ break;
+
+ case AFMT_S16_LE:
+#ifdef DO_RIAA
+ if (portc->riaa_filter)
+ {
+ /* RIAA filtered version */
+ short *ip;
+ int *op;
+
+ ip = (short *) (audio_engines[portc->dev]->dmap_in->dmabuf +
+ (dmap_get_qtail (dmap) * dmap->fragment_size));
+ op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag);
+
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ int *p = &op[portc->chnum + ch];
+ short *p2 = &ip[ch];
+ riaa_t *ff = &portc->riaa_parms[ch];
+
+ int32_t x1 = ff->x1, x2 = ff->x2, x3 = ff->x3,
+ y1 = ff->y1, y2 = ff->y2, y3 = ff->y3, x0, y0;
+
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int tmp = *p;
+ p += 12;
+
+ x0 = _riaa_sat31 (tmp, 0x4C30C30C);
+
+ y0 = _riaa_sat31 (x0, 0xF38FB92F) +
+ _riaa_sat31 (x1, 0xF2492994) +
+ _riaa_sat31 (x2, 0x1AB82385) +
+ _riaa_sat31 (x3, 0x023FB0F8) +
+ (_riaa_sat31 (y1, 0x574DB88C) << 1) +
+ _riaa_sat31 (y2, 0xF650F27D) +
+ _riaa_sat31 (y3, 0xDACB84B9);
+
+ x3 = x2;
+ x2 = x1;
+ x1 = x0;
+ y3 = y2;
+ y2 = y1;
+ y1 = y0;
+
+ tmp = -y0;
+
+ *p2 = tmp >> 16;
+ p2 += portc->channels;
+ }
+
+ ff->x1 = x1;
+ ff->x2 = x2;
+ ff->x3 = x3;
+ ff->y1 = y1;
+ ff->y2 = y2;
+ ff->y3 = y3;
+ }
+ /* RIAA filtered version */
+ }
+ else
+#endif
+ {
+ short *ip;
+ int *op;
+
+ ip = (short *) (audio_engines[portc->dev]->dmap_in->dmabuf +
+ (dmap_get_qtail (dmap) * dmap->fragment_size));
+ op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag);
+
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int *p = &op[sample * 12 + portc->chnum];
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ *ip++ = (*p++) >> 16;
+ }
+ }
+ }
+ break;
+
+ case AFMT_S32_LE:
+ {
+ int *ip;
+ int *op;
+
+ ip = (int *) (audio_engines[portc->dev]->dmap_in->dmabuf +
+ (dmap_get_qtail (dmap) * dmap->fragment_size));
+ op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag);
+
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int *p = &op[sample * 12 + portc->chnum];
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ *ip++ = *p++;
+ }
+ }
+ }
+ break;
+
+ case AFMT_S24_LE:
+ {
+ int *ip;
+ int *op;
+
+ ip = (int *) (audio_engines[portc->dev]->dmap_in->dmabuf +
+ (dmap_get_qtail (dmap) * dmap->fragment_size));
+ op = (int *) (devc->recbuf + devc->hw_rfragsize * devc->hw_recfrag);
+
+ VMEM_CHECK (ip, nsamples * sizeof (*ip));
+ VMEM_CHECK (op, nsamples * sizeof (*op));
+ for (sample = 0; sample < nsamples; sample++)
+ {
+ int *p = &op[sample * 12 + portc->chnum];
+
+ for (ch = 0; ch < portc->channels; ch++)
+ {
+ *ip++ = *p++ >> 8;
+ }
+ }
+ }
+ break;
+ }
+
+ oss_audio_inputintr (portc->dev, 0);
+}
+
+static void
+tank_playback_data (envy24_devc * devc)
+{
+ int i, nc = devc->nr_outdevs;
+ envy24_portc *portc;
+ unsigned char *p;
+
+ p = devc->playbuf + devc->hw_playfrag * devc->hw_pfragsize;
+ VMEM_CHECK (p, devc->hw_pfragsize);
+ memset (p, 0, devc->hw_pfragsize); /* Cleanup the fragment */
+
+ for (i = 0; i < nc; i++)
+ {
+ portc = &devc->play_portc[i];
+
+ if (!portc->open_mode) /* Not opened */
+ continue;
+ handle_playdev (devc, portc, devc->hw_playfrag);
+ }
+
+ devc->hw_playfrag = (devc->hw_playfrag + 1) % devc->hw_nfrags;
+}
+
+static void
+handle_recording (envy24_devc * devc)
+{
+ int i;
+ envy24_portc *portc;
+ /* oss_native_word flags; */
+
+ /*
+ * TODO: Fix mutexes and move the inputintr/outputintr calls outside the
+ * mutex block.
+ */
+ /* MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); */
+ for (i = 0; i < devc->nr_indevs; i++)
+ {
+ portc = &devc->rec_portc[i];
+
+ if (!portc->open_mode) /* Not opened */
+ continue;
+ handle_recdev (devc, portc);
+ }
+
+ devc->hw_recfrag = (devc->hw_recfrag + 1) % devc->hw_nfrags;
+ /* MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); */
+}
+
+extern int envy24d_get_buffer_pointer (int dev, dmap_t * dmap, int direction);
+
+static void
+mt_audio_intr (envy24_devc * devc)
+{
+ int status;
+
+#ifdef DO_TIMINGS
+ oss_timing_enter (DF_INTERRUPT);
+ oss_do_timing2 (DFLAG_PROFILE, "Envy24_audio_intr");
+#endif
+ status = INB (devc->osdev, devc->mt_base + 0x00);
+ if (devc->playback_started && (status & 0x01)) /* Playback interrupt */
+ {
+/* cmn_err(CE_CONT, "%d\n", GET_JIFFIES()); */
+ if (devc->direct_audio_opened & OPEN_WRITE)
+ {
+ envy24d_playintr (devc);
+ }
+ else
+ {
+ int ptr, qlen, i;
+
+ ptr = INW (devc->osdev, devc->mt_base + 0x14);
+ ptr = (devc->playbuffsize - ((ptr + 1) * 4)) / devc->hw_pfragsize;
+
+ /* Find the number of current fragments in the hardware level buffer */
+ qlen = 0;
+ i = devc->hw_playfrag;
+
+ while (qlen < 15 && i != ptr)
+ {
+ qlen++;
+ i = (i + 1) % devc->hw_nfrags;
+ }
+
+ if (qlen != devc->writeahead)
+ {
+ tank_playback_data (devc);
+ }
+
+ if (devc->hw_playfrag == ptr) /* Out of sync */
+ {
+ tank_playback_data (devc); /* Try to catch the hardware pointer */
+ }
+
+
+ tank_playback_data (devc);
+ }
+ }
+
+ if (devc->recording_started && (status & 0x02)) /* Record interrupt */
+ {
+ if (devc->direct_audio_opened & OPEN_READ)
+ envy24d_recintr (devc);
+ else
+ handle_recording (devc);
+ }
+
+ OUTB (devc->osdev, status, devc->mt_base + 0x00);
+#ifdef DO_TIMINGS
+ oss_timing_leave (DF_INTERRUPT);
+ oss_do_timing2 (DFLAG_PROFILE, "Envy24_audio_intr done");
+#endif
+}
+
+static int
+envy24intr (oss_device_t * osdev)
+{
+ int status;
+ envy24_devc *devc;
+
+ devc = osdev->devc;
+
+ status = INB (devc->osdev, devc->ccs_base + 0x02);
+ if (status == 0)
+ return 0;
+
+ if (status & 0x80) /* MIDI UART 1 */
+ if (devc->model_data->flags & MF_MIDI1)
+ uart401_irq (&devc->uart401devc1);
+
+ if (status & 0x20) /* MIDI UART 2 */
+ if (devc->model_data->flags & MF_MIDI2)
+ uart401_irq (&devc->uart401devc2);
+
+ if (status & 0x10)
+ {
+/*cmn_err(CE_CONT, "%d/%d.", GET_JIFFIES(), envy24d_get_buffer_pointer(11, audio_engines[11]->dmap_out, DMODE_OUTPUT)); */
+ mt_audio_intr (devc);
+ }
+
+ OUTB (devc->osdev, status, devc->ccs_base + 0x02); /* ACK */
+
+ return 1;
+}
+
+static void envy24_setup_pro_speed (envy24_devc * devc);
+static void envy24_setup_consumer_speed (envy24_devc * devc);
+
+void
+envy24_prepare_play_engine (envy24_devc * devc)
+{
+ int tmp, fragsize, buffsize;
+
+ if (devc->playback_prepared)
+ return;
+
+ /* Set S/PDIF sample rate indication */
+
+ if (devc->spdif_cbits[0] & 0x01)
+ envy24_setup_pro_speed (devc);
+ else
+ envy24_setup_consumer_speed (devc);
+
+ if (devc->model_data->flags & MF_SPDIF)
+ {
+ tmp = 0x80;
+
+ if (devc->ac3_mode)
+ tmp |= 0x40; /* Audio mode off */
+
+ switch (devc->speed)
+ {
+ case 48000:
+ tmp |= 0x01;
+ break;
+ case 44100:
+ tmp |= 0x02;
+ break;
+ case 32000:
+ tmp |= 0x03;
+ break;
+ }
+
+ if (devc->model_data->auxdrv->spdif_set)
+ devc->model_data->auxdrv->spdif_set (devc, tmp);
+
+ }
+
+ if (devc->model_data->auxdrv->set_rate)
+ devc->model_data->auxdrv->set_rate (devc);
+ else
+ {
+ tmp = devc->speedbits;
+ if (devc->syncsource != SYNC_INTERNAL)
+ {
+ tmp |= 0x10; /* S/PDIF input clock select */
+ if (devc->model_data->flags & MF_WCLOCK) /* Has world clock too */
+ {
+ int cmd = envy24_read_cci (devc, 0x20);
+ cmd |= 0x10; /* S/PDIF */
+ if (devc->syncsource == SYNC_WCLOCK)
+ cmd &= ~0x10; /* World clock */
+ envy24_write_cci (devc, 0x20, cmd);
+ }
+ }
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+ }
+
+ fragsize = devc->hw_pfragsize;
+ buffsize = devc->playbuffsize / 4 - 1;
+
+ PMEM_CHECK (devc->playbuf_phys, devc->playbuffsize);
+
+ OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Base */
+ OUTW (devc->osdev, buffsize, devc->mt_base + 0x14); /* Count */
+ OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Base */
+ OUTW (devc->osdev, buffsize, devc->mt_base + 0x14); /* Count */
+ OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Base */
+ OUTW (devc->osdev, fragsize / 4 - 1, devc->mt_base + 0x16); /* Interrupt rate */
+ OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Base */
+
+ devc->playback_prepared = 1;
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+}
+
+void
+envy24_launch_play_engine (envy24_devc * devc)
+{
+ /* Unmask playback interrupts */
+ OUTB (devc->osdev,
+ INB (devc->osdev, devc->mt_base + 0x00) & ~0x40,
+ devc->mt_base + 0x00);
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x00) & ~0x40,
+ devc->mt_base + 0x00);
+ /* Kick it */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) | 0x01,
+ devc->mt_base + 0x18);
+ devc->playback_started = 1;
+
+ if (devc->model_data->auxdrv->set_rate)
+ devc->model_data->auxdrv->set_rate (devc);
+}
+
+static void
+start_playback (envy24_devc * devc)
+{
+ devc->hw_playfrag = 0;
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Envy24: Start playback");
+#endif
+ tank_playback_data (devc);
+ tank_playback_data (devc);
+ if (devc->writeahead == 2)
+ tank_playback_data (devc);
+
+ envy24_prepare_play_engine (devc);
+ envy24_launch_play_engine (devc);
+}
+
+void
+envy24_stop_playback (envy24_devc * devc)
+{
+#ifdef DO_TIMINGS
+ oss_do_timing ("Envy24: Stop playback");
+#endif
+ memset (devc->playbuf, 0, devc->playbuffsize);
+ /*
+ * Give the engine time to eat some silent samples
+ * This makes the corresponding digital mixer inputs to drop to 0
+ * which decreases noise in the monitor outputs.
+ */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01,
+ devc->mt_base + 0x18);
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01,
+ devc->mt_base + 0x18);
+
+ /* Mask playback interrupts */
+ OUTB (devc->osdev,
+ INB (devc->osdev, devc->mt_base + 0x00) | 0x40, devc->mt_base + 0x00);
+ devc->playback_started = 0;
+ devc->playback_prepared = 0;
+}
+
+void
+envy24_start_recording (envy24_devc * devc)
+{
+ int tmp;
+
+ devc->hw_recfrag = 0;
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04,
+ devc->mt_base + 0x18);
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04,
+ devc->mt_base + 0x18);
+ oss_udelay (20);
+
+ if (devc->model_data->flags & MF_SPDIF)
+ {
+ tmp = 0x80;
+
+ switch (devc->speed)
+ {
+ case 48000:
+ tmp |= 0x01;
+ break;
+ case 44100:
+ tmp |= 0x02;
+ break;
+ case 32000:
+ tmp |= 0x03;
+ break;
+ }
+
+ if (devc->model_data->auxdrv->spdif_set)
+ devc->model_data->auxdrv->spdif_set (devc, tmp);
+
+ }
+
+ tmp = devc->speedbits;
+ if (devc->syncsource != SYNC_INTERNAL)
+ {
+ tmp |= 0x10; /* S/PDIF input clock select */
+ if (devc->model_data->flags & MF_WCLOCK) /* Has world clock too */
+ {
+ int cmd = envy24_read_cci (devc, 0x20);
+ cmd |= 0x10; /* S/PDIF */
+ if (devc->syncsource == SYNC_WCLOCK)
+ cmd &= ~0x10; /* World clock */
+ envy24_write_cci (devc, 0x20, cmd);
+ }
+ }
+
+ OUTB (devc->osdev, tmp, devc->mt_base + 0x01);
+
+ if (devc->model_data->auxdrv->set_rate)
+ devc->model_data->auxdrv->set_rate (devc);
+
+ PMEM_CHECK (devc->recbuf_phys, devc->recbuffsize);
+
+ OUTL (devc->osdev, devc->recbuf_phys, devc->mt_base + 0x20); /* Base */
+ oss_udelay (20);
+ OUTL (devc->osdev, devc->recbuf_phys, devc->mt_base + 0x20); /* Base */
+ oss_udelay (20);
+ OUTW (devc->osdev, devc->recbuffsize / 4 - 1, devc->mt_base + 0x24); /* Count */
+ OUTL (devc->osdev, devc->recbuf_phys, devc->mt_base + 0x20); /* Base */
+ oss_udelay (60);
+ OUTW (devc->osdev, devc->hw_rfragsize / 4 - 1, devc->mt_base + 0x26); /* Interrupt rate */
+
+ oss_udelay (60);
+}
+
+void
+envy24_launch_recording (envy24_devc * devc)
+{
+
+#if 1
+ /* Unmask recording interrupts */
+ OUTB (devc->osdev,
+ INB (devc->osdev, devc->mt_base + 0x00) & ~0x80,
+ devc->mt_base + 0x00);
+
+#endif
+ /* Kick it */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) | 0x04,
+ devc->mt_base + 0x18);
+ devc->recording_started = 1;
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+
+}
+
+void
+envy24_stop_recording (envy24_devc * devc)
+{
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04,
+ devc->mt_base + 0x18);
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04,
+ devc->mt_base + 0x18);
+
+ /* Mask recording interrupts */
+ OUTB (devc->osdev,
+ INB (devc->osdev, devc->mt_base + 0x00) | 0x80, devc->mt_base + 0x00);
+ devc->recording_started = 0;
+ memset (devc->recbuf, 0, devc->recbuffsize);
+}
+
+/*
+ * Audio entrypoint routines
+ */
+
+int
+envy24_audio_set_rate (int dev, int arg)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+#if 1
+ int i = 0, ix = -1, df, best = 0x7fffffff;
+ oss_native_word flags;
+
+ if (arg <= 0)
+ return devc->speed;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (devc->recording_started || devc->playback_started)
+ {
+ DDB (cmn_err (CE_CONT,
+ "Requested sampling rate(1) on device %d was %d, got %d\n",
+ dev, arg, devc->speed));
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->speed;
+ }
+
+ if ((devc->open_inputs + devc->open_outputs) > 1)
+ {
+ DDB (cmn_err (CE_CONT,
+ "Requested sampling rate(2) on device %d was %d, got %d\n",
+ dev, arg, devc->speed));
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->speed;
+ }
+
+ if (devc->ratelock)
+ {
+ DDB (cmn_err (CE_CONT,
+ "Requested sampling rate(3) on device %d was %d, got %d\n",
+ dev, arg, devc->speed));
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->speed;
+ }
+
+/* This is the only open device file so change the speed */
+
+ i = 0;
+
+ while (speed_tab[i].speed != -1)
+ {
+ df = arg - speed_tab[i].speed;
+ if (df < 0)
+ df = -df;
+
+ if (df < best)
+ {
+ best = df;
+ ix = i;
+ if (df == 0)
+ break;
+ }
+
+ i++;
+ }
+
+ if (ix == -1) /* No matching rate */
+ {
+ DDB (cmn_err (CE_CONT,
+ "Requested sampling rate(4) on device %d was %d, got %d\n",
+ dev, arg, devc->speed));
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->speed;
+ }
+
+ devc->speed = speed_tab[ix].speed;
+ devc->speedbits = speed_tab[ix].speedbits;
+#endif
+ if (devc->speed != arg)
+ {
+ DDB (cmn_err (CE_CONT,
+ "Requested sampling rate(5) on device %d was %d, got %d\n",
+ dev, arg, devc->speed));
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->speed;
+ }
+ DDB (cmn_err (CE_CONT, "Sampling rate set to %d\n", devc->speed));
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->speed;
+}
+
+static void
+update_fragments (envy24_portc * portc)
+{
+ int nsamples, nbytes, dev = portc->dev;
+ envy24_devc *devc = audio_engines[dev]->devc;
+
+ nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */
+
+ nbytes = nsamples * portc->channels;
+
+ if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3))
+ {
+ nbytes *= 2;
+ }
+ else if (portc->bits & (AFMT_S32_LE | AFMT_S24_LE))
+ nbytes *= 4;
+
+ audio_engines[dev]->min_block = nbytes;
+ audio_engines[dev]->max_block = nbytes;
+}
+
+static short
+envy24_audio_set_channels (int dev, short arg)
+{
+ envy24_portc *portc = audio_engines[dev]->portc;
+ envy24_devc *devc = audio_engines[dev]->devc;
+ int i, nc = devc->nr_play_channels;
+ oss_native_word flags;
+
+ if (envy24_virtualout)
+ nc = 10;
+
+ if (arg <= portc->channels)
+ return portc->channels;
+
+ /* Force mono->stereo conversion if in skip=2 mode */
+ if (devc->skipdevs == 2 && arg < 2)
+ arg = 2;
+
+ if (envy24_force_mono)
+ arg = 1;
+
+ if (portc->direction == DIR_INPUT)
+ {
+ if ((portc->chnum + arg) > devc->nr_rec_channels)
+ return portc->channels;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ for (i = portc->channels; i < arg; i++)
+ if (devc->rec_channel_mask & (1 << (portc->chnum + i)))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return portc->channels;
+ }
+ for (i = portc->channels; i < arg; i++)
+ devc->rec_channel_mask |= (1 << (portc->chnum + i));
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ }
+ else
+ {
+ if ((portc->chnum + arg) > nc)
+ return portc->channels;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ for (i = portc->channels; i < arg; i++)
+ if (devc->play_channel_mask & (1 << (portc->chnum + i)))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return portc->channels;
+ }
+ for (i = portc->channels; i < arg; i++)
+ devc->play_channel_mask |= (1 << (portc->chnum + i));
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ }
+
+ portc->channels = arg;
+ update_fragments (portc);
+
+ return portc->channels;
+}
+
+static unsigned int
+envy24_audio_set_format (int dev, unsigned int arg)
+{
+ envy24_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & audio_engines[dev]->oformat_mask))
+ return portc->bits = AFMT_S16_LE;
+
+ portc->bits = arg;
+
+ if (arg == AFMT_AC3)
+ {
+ envy24_audio_set_channels (dev, 2);
+ }
+
+ update_fragments (portc);
+
+ return portc->bits;
+}
+
+static int
+envy24_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+ envy24_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+ int rt;
+
+ if (arg == NULL)
+ return OSS_EINVAL;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_GET_RECSRC:
+ case SNDCTL_DSP_SET_RECSRC:
+ case SNDCTL_DSP_GET_PLAYTGT:
+ case SNDCTL_DSP_SET_PLAYTGT:
+ return *arg = 0;
+ break;
+
+ case SNDCTL_DSP_GET_RECSRC_NAMES:
+ return oss_encode_enum ((oss_mixer_enuminfo *) arg, portc->name, 0);
+ break;
+
+ case SNDCTL_DSP_GET_PLAYTGT_NAMES:
+ return oss_encode_enum ((oss_mixer_enuminfo *) arg, portc->name, 0);
+ break;
+
+ case SNDCTL_DSP_GET_CHNORDER:
+ *(oss_uint64_t *) arg = CHNORDER_UNDEF;
+ return 0;
+ }
+
+ if (devc->model_data->auxdrv->spdif_ioctl == NULL)
+ return OSS_EINVAL;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ rt = devc->model_data->auxdrv->spdif_ioctl (devc, dev, cmd, arg);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return rt;
+}
+
+static void envy24_audio_trigger (int dev, int state);
+
+static void
+envy24_audio_reset (int dev)
+{
+#ifdef DO_TIMINGS
+ oss_do_timing ("Envy24: Reset audio");
+#endif
+ envy24_audio_trigger (dev, 0);
+}
+
+#define WriteCsByte(devc, b, v) (devc)->spdif_cbits[b]=(v)
+#define ReadCsByte(devc, b) (devc)->spdif_cbits[b]
+
+static __inline__ void
+WriteCsField (envy24_devc * devc, unsigned char bByteNum,
+ unsigned short bMask, unsigned short bBits)
+{
+ /* Get current reg value. */
+ unsigned char bTemp = ReadCsByte (devc, bByteNum);
+
+ /* Clear field to be written. */
+ bTemp &= ~(bMask);
+
+ /* Set new values. */
+ WriteCsByte (devc, bByteNum, (unsigned char) (bTemp | (bBits & bMask)));
+}
+
+static void
+envy24_setup_pro_speed (envy24_devc * devc)
+{
+
+ switch (devc->speed)
+ {
+ case 32000:
+ WriteCsField (devc, 0, 0xc0, 0xc0);
+ break;
+
+ case 44100:
+ WriteCsField (devc, 0, 0xc0, 0x40);
+ break;
+
+ case 48000:
+ WriteCsField (devc, 0, 0xc0, 0x80);
+ break;
+
+ default:
+ WriteCsField (devc, 0, 0xc0, 0x00);
+ break;
+ }
+}
+
+static void
+setup_pro_mode (envy24_devc * devc)
+{
+ devc->spdif_cbits[0] |= 0x01; /* Pro mode */
+ devc->spdif_cbits[2] |= 0x2c; /* 24-bit data word */
+
+ envy24_setup_pro_speed (devc);
+}
+
+static void
+envy24_setup_consumer_speed (envy24_devc * devc)
+{
+
+ /*
+ * Set the sampling rate indication
+ */
+ if (devc->ac3_mode)
+ WriteCsField (devc, 0, 0x02, 0x02); /* 1:1 = 1 */
+ else
+ WriteCsField (devc, 0, 0x02, 0x00); /* 1:1 = 0 */
+
+ switch (devc->speed)
+ {
+ case 22050L:
+ WriteCsField (devc, 0, 0xC0, 0x00); /* 7:6 = 00 */
+ WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */
+ WriteCsField (devc, 4, 0x0F, 0x09); /* 3:0 = 1001 */
+ break;
+ case 32000L:
+ WriteCsField (devc, 0, 0xC0, 0xC0); /* 7:6 = 11 */
+ WriteCsField (devc, 3, 0x0F, 0x03); /* 3:0 = 0011 */
+ WriteCsField (devc, 4, 0x0F, 0x00); /* 3:0 = 0000 */
+ break;
+ case 44100L:
+ WriteCsField (devc, 0, 0xC0, 0x40); /* 7:6 = 01 */
+ WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */
+ WriteCsField (devc, 4, 0x0F, 0x00); /* 3:0 = 0000 */
+ break;
+ case 48000L:
+ WriteCsField (devc, 0, 0xC0, 0x80); /* 7:6 = 10 */
+ WriteCsField (devc, 3, 0x0F, 0x02); /* 3:0 = 0010 */
+ WriteCsField (devc, 4, 0x0F, 0x00); /* 3:0 = 0000 */
+ break;
+ case 88200L:
+ WriteCsField (devc, 0, 0xC0, 0x00); /* 7:6 = 00 */
+ WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */
+ WriteCsField (devc, 4, 0x0F, 0x05); /* 3:0 = 0101 */
+ break;
+ case 96000L:
+ WriteCsField (devc, 0, 0xC0, 0x00); /* 7:6 = 00 */
+ WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */
+ WriteCsField (devc, 4, 0x0F, 0x04); /* 3:0 = 0100 */
+ break;
+ default:
+ WriteCsField (devc, 0, 0xC0, 0x00); /* 7:6 = 00 */
+ WriteCsField (devc, 3, 0x0F, 0x00); /* 3:0 = 0000 */
+ WriteCsField (devc, 4, 0x0F, 0x00); /* 3:0 = 0000 */
+ break;
+ }
+}
+
+static void
+setup_consumer_mode (envy24_devc * devc)
+{
+ WriteCsByte (devc, 0, ReadCsByte (devc, 0) & ~(0x02)); /* Set audio mode */
+ WriteCsByte (devc, 0, ReadCsByte (devc, 0) & ~(0x38)); /* Set no emphasis */
+
+ WriteCsByte (devc, 0, ReadCsByte (devc, 0) & ~(0x04)); /* Set "original" */
+ WriteCsByte (devc, 1, ReadCsByte (devc, 1) | (0x80)); /* Set "original" */
+
+ envy24_setup_consumer_speed (devc);
+}
+
+static void
+setup_spdif_control (envy24_devc * devc)
+{
+/* unsigned char *cbits; */
+
+ memset (devc->spdif_cbits, 0, sizeof (devc->spdif_cbits));
+
+/* cbits = devc->spdif_cbits; */
+
+ if (devc->spdif_pro_mode)
+ {
+ setup_pro_mode (devc);
+ }
+ else
+ {
+ setup_consumer_mode (devc);
+ }
+}
+
+/*ARGSUSED*/
+static int
+envy24_audio_open (int dev, int mode, int open_flags)
+{
+ envy24_portc *portc = audio_engines[dev]->portc;
+ envy24_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ mode |= ADEV_NOVIRTUAL;
+
+ if (devc->playbuf == NULL || devc->recbuf == NULL)
+ {
+ cmn_err (CE_WARN, "No DMA buffer\n");
+ return OSS_ENOSPC;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode != 0 || devc->direct_audio_opened != 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (portc->direction == DIR_INPUT)
+ {
+ if (devc->rec_channel_mask & (1 << portc->chnum))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ devc->rec_channel_mask |= (1 << portc->chnum);
+ }
+ else
+ {
+ if (devc->play_channel_mask & (1 << portc->chnum))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ devc->play_channel_mask |= (1 << portc->chnum);
+ }
+
+ portc->open_mode = mode;
+ portc->channels = 1;
+ if (devc->skipdevs == 2)
+ portc->channels = 2;
+ portc->pcm_qlen = 0;
+ if (portc->direction == DIR_INPUT)
+ {
+ if (devc->open_inputs++ == 0 && devc->open_outputs == 0)
+ {
+ devc->speed = speed_tab[devc->pending_speed_sel].speed;
+ devc->speedbits = speed_tab[devc->pending_speed_sel].speedbits;
+ }
+ }
+ else
+ {
+ if (devc->open_inputs == 0 && devc->open_outputs++ == 0)
+ {
+ if (portc->flags & PORTC_SPDOUT)
+ {
+ setup_spdif_control (devc);
+ }
+
+ devc->speed = speed_tab[devc->pending_speed_sel].speed;
+ devc->speedbits = speed_tab[devc->pending_speed_sel].speedbits;
+ }
+ }
+#if 1
+ if (devc->use_src)
+ {
+ /* SRC stuff */
+ audio_engines[dev]->flags |= ADEV_FIXEDRATE;
+ audio_engines[dev]->fixed_rate = devc->speed;
+ audio_engines[dev]->min_rate = devc->speed;
+ audio_engines[dev]->max_rate = devc->speed;
+ }
+ else
+ {
+ audio_engines[dev]->flags &= ~ADEV_FIXEDRATE;
+ audio_engines[dev]->fixed_rate = 0;
+ audio_engines[dev]->min_rate = 8000;
+ audio_engines[dev]->max_rate = 96000;
+ }
+#endif
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+envy24_audio_close (int dev, int mode)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+ envy24_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ int i;
+
+ envy24_audio_reset (dev);
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->open_mode = 0;
+ if (portc->flags & PORTC_SPDOUT)
+ devc->ac3_mode = 0;
+ if (portc->direction == DIR_INPUT)
+ {
+ devc->open_inputs--;
+ for (i = 0; i < portc->channels; i++)
+ devc->rec_channel_mask &= ~(1 << (portc->chnum + i));
+ }
+ else
+ {
+ devc->open_outputs--;
+ for (i = 0; i < portc->channels; i++)
+ devc->play_channel_mask &= ~(1 << (portc->chnum + i));
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static void
+envy24_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+envy24_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+}
+
+static int
+envy24_sync_control (int dev, int event, int mode)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+ envy24_portc *portc = audio_engines[dev]->portc;
+
+ if (event == SYNC_PREPARE)
+ {
+ if (mode & PCM_ENABLE_OUTPUT)
+ {
+ if (!devc->playback_prepared)
+ devc->hw_playfrag = 0;
+ handle_playdev (devc, portc, devc->hw_playfrag);
+ handle_playdev (devc, portc, devc->hw_playfrag + 1);
+ if (devc->writeahead == 2)
+ handle_playdev (devc, portc, devc->hw_playfrag + 2);
+ envy24_prepare_play_engine (devc);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+
+ if (mode & PCM_ENABLE_INPUT)
+ {
+ if (devc->active_inputs == 0)
+ {
+ envy24_start_recording (devc);
+ }
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ return 0;
+ }
+
+ if (event == SYNC_TRIGGER)
+ {
+ if (mode & PCM_ENABLE_OUTPUT)
+ {
+ envy24_prepare_play_engine (devc); /* Just to make sure */
+ devc->hw_playfrag = 1 + devc->writeahead;
+ if (devc->active_outputs++ == 0)
+ envy24_launch_play_engine (devc);
+ }
+
+ if (mode & PCM_ENABLE_INPUT)
+ {
+ if (devc->active_inputs++ == 0)
+ {
+ devc->hw_recfrag = 0;
+ envy24_launch_recording (devc);
+ }
+ }
+ return 0;
+ }
+
+ return OSS_EIO;
+}
+
+static void
+envy24_audio_trigger (int dev, int state)
+{
+ int changed;
+ oss_native_word flags;
+
+ envy24_portc *portc = audio_engines[dev]->portc;
+ envy24_devc *devc = audio_engines[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ changed = state ^ portc->trigger_bits;
+
+ if (portc->direction == DIR_OUTPUT && (changed & PCM_ENABLE_OUTPUT))
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Envy24: Trigger start output");
+#endif
+ portc->trigger_bits = state;
+ if (devc->active_outputs++ == 0)
+ start_playback (devc);
+ }
+ else
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Envy24: Trigger stop output");
+#endif
+ portc->trigger_bits = state;
+ if (--devc->active_outputs == 0)
+ envy24_stop_playback (devc);
+ }
+ }
+
+ if (portc->direction == DIR_INPUT && (changed & PCM_ENABLE_INPUT))
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ portc->trigger_bits = state;
+ if (devc->active_inputs++ == 0)
+ {
+ envy24_start_recording (devc);
+ envy24_launch_recording (devc);
+ }
+ }
+ else
+ {
+ if (--devc->active_inputs == 0)
+ envy24_stop_recording (devc);
+ portc->trigger_bits = state;
+ }
+ }
+
+ portc->trigger_bits = state;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+envy24_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ int nsamples, nbytes;
+
+ envy24_portc *portc = audio_engines[dev]->portc;
+ envy24_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ if (audio_engines[dev]->flags & ADEV_NOINPUT)
+ return OSS_EACCES;
+
+ nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */
+
+ nbytes = nsamples * portc->channels;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+#ifdef DO_RIAA
+ memset (portc->riaa_parms, 0, sizeof (portc->riaa_parms));
+ if (portc->riaa_filter)
+ cmn_err (CE_CONT, "oss: RIAA filter activated for /dev/dsp%d\n", dev);
+#endif
+
+ if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3))
+ {
+ nbytes *= 2;
+ }
+ else if (portc->bits & (AFMT_S32_LE | AFMT_S24_LE))
+ nbytes *= 4;
+
+ if (nbytes != bsize)
+ {
+ dmap_p dmap = audio_engines[dev]->dmap_in;
+ dmap->fragment_size = bsize = nbytes;
+ dmap->bytes_in_use = dmap->fragment_size * dmap->nfrags;
+ if (dmap->bytes_in_use > dmap->buffsize)
+ {
+ dmap->nfrags = dmap->buffsize / dmap->fragment_size;
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+envy24_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ int nsamples, nbytes;
+ oss_native_word flags;
+
+ envy24_portc *portc = audio_engines[dev]->portc;
+ envy24_devc *devc = audio_engines[dev]->devc;
+
+ if (audio_engines[dev]->flags & ADEV_NOOUTPUT)
+ return OSS_EACCES;
+
+ nsamples = devc->hw_fragsamples; /* Number of 32 bit samples */
+
+ nbytes = nsamples * portc->channels;
+
+ if (portc->flags & PORTC_SPDOUT)
+ if (portc->bits == AFMT_AC3)
+ devc->ac3_mode = 1;
+
+ if (portc->bits & (AFMT_S16_LE | AFMT_S16_BE | AFMT_AC3))
+ {
+ nbytes *= 2;
+ }
+ else if (portc->bits & (AFMT_S32_LE | AFMT_S32_BE))
+ nbytes *= 4;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (nbytes != bsize)
+ {
+ dmap_p dmap = audio_engines[dev]->dmap_out;
+ cmn_err (CE_CONT, "Fragment size mismatch: hw=%d, sw=%d\n",
+ nbytes, bsize);
+ cmn_err (CE_NOTE,
+ "Application bug detected. Fix ioctl() calling order\n");
+
+ oss_audio_set_error (dev, E_PLAY,
+ OSSERR (1012, "Wrong ioctl call order"), 0);
+ /*
+ * Errordesc: The envy24 driver requires that number of channels, sample format and
+ * sampling rate are set before calling any ioctl call that may lock
+ * the fragment size prematurely. In such case the driver cannot change the
+ * fragment size to value that is suitable for the device.
+ *
+ * Please use the recommended ioctl call order defined in
+ * http://manuals.opensound.com/developer/callorder.html.
+ */
+ dmap->fragment_size = bsize = nbytes;
+ dmap->bytes_in_use = dmap->fragment_size * dmap->nfrags;
+ if (dmap->bytes_in_use > dmap->buffsize)
+ {
+ dmap->nfrags = dmap->buffsize / dmap->fragment_size;
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EIO;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+envy24_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+#if 0
+/*
+ * Ignore the direction parameter since it's missleading. Instead use the
+ * ADEV_NOINPUT/ADEV_NOOUTPUT flag.
+ */
+
+ if (audio_engines[dev]->flags & ADEV_NOINPUT)
+ direction = OPEN_WRITE;
+ else
+ direction = OPEN_READ;
+#endif
+
+ dmap->buffsize = devc->skipdevs * DEV_BUFSIZE;
+ dmap->dmabuf_phys = 0;
+ dmap->dmabuf = KERNEL_MALLOC (dmap->buffsize);
+
+ if (dmap->dmabuf == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate a DMA buffer\n");
+ return OSS_ENOSPC;
+ }
+ memset (dmap->dmabuf, 0, dmap->buffsize);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+envy24_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ if (dmap->dmabuf == NULL)
+ return 0;
+#if 1
+ KERNEL_FREE (dmap->dmabuf);
+#endif
+ dmap->dmabuf = NULL;
+ return 0;
+}
+
+static int
+envy24_check_input (int dev)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+
+ if (!devc->recording_started)
+ return 0;
+
+ cmn_err (CE_NOTE, "Input timed out.\n");
+ return OSS_EIO;
+}
+
+static int
+envy24_check_output (int dev)
+{
+ envy24_devc *devc = audio_engines[dev]->devc;
+
+ if (!devc->playback_started)
+ return 0;
+
+ cmn_err (CE_NOTE, "Output timed out\n");
+ return OSS_EIO;
+}
+
+static int
+envy24_local_qlen (int dev)
+{
+ envy24_portc *portc = audio_engines[dev]->portc;
+
+ return portc->pcm_qlen * audio_engines[dev]->dmap_out->fragment_size;
+}
+
+static const audiodrv_t envy24_audio_driver = {
+ envy24_audio_open,
+ envy24_audio_close,
+ envy24_audio_output_block,
+ envy24_audio_start_input,
+ envy24_audio_ioctl,
+ envy24_audio_prepare_for_input,
+ envy24_audio_prepare_for_output,
+ envy24_audio_reset,
+ envy24_local_qlen,
+ NULL,
+ NULL,
+ NULL,
+ envy24_audio_trigger,
+ envy24_audio_set_rate,
+ envy24_audio_set_format,
+ envy24_audio_set_channels,
+ NULL,
+ NULL,
+ envy24_check_input,
+ envy24_check_output,
+ envy24_alloc_buffer,
+ envy24_free_buffer,
+ NULL,
+ NULL,
+ NULL, /* envy24_get_buffer_pointer */
+ NULL, /* calibrate_speed */
+ envy24_sync_control
+};
+
+/*ARGSUSED*/
+static int
+envy24_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ extern int envy24_realencoder_hack;
+
+ if (!envy24_realencoder_hack)
+ {
+ if (cmd == SOUND_MIXER_READ_DEVMASK ||
+ cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC ||
+ cmd == SOUND_MIXER_READ_STEREODEVS)
+ return *arg = 0;
+ }
+
+ if (cmd == SOUND_MIXER_READ_DEVMASK ||
+ cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC ||
+ cmd == SOUND_MIXER_READ_STEREODEVS)
+ return *arg =
+ SOUND_MASK_LINE | SOUND_MASK_PCM | SOUND_MASK_MIC |
+ SOUND_MASK_VOLUME | SOUND_MASK_CD;
+
+ if (cmd == SOUND_MIXER_READ_VOLUME || cmd == SOUND_MIXER_READ_PCM ||
+ cmd == SOUND_MIXER_READ_LINE || cmd == SOUND_MIXER_READ_MIC ||
+ cmd == SOUND_MIXER_READ_CD || cmd == MIXER_READ (SOUND_MIXER_DIGITAL1))
+ return *arg = 100 | (100 << 8);
+ if (cmd == SOUND_MIXER_WRITE_VOLUME || cmd == SOUND_MIXER_WRITE_PCM ||
+ cmd == SOUND_MIXER_WRITE_LINE || cmd == SOUND_MIXER_READ_MIC ||
+ cmd == SOUND_MIXER_WRITE_CD ||
+ cmd == MIXER_WRITE (SOUND_MIXER_DIGITAL1))
+ return *arg = 100 | (100 << 8);
+ if (cmd == SOUND_MIXER_READ_CAPS)
+ return *arg = SOUND_CAP_EXCL_INPUT;
+ if (cmd == SOUND_MIXER_PRIVATE1)
+ return *arg = 0;
+ return OSS_EINVAL;
+}
+
+static int
+envy24_set_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ switch (ctrl)
+ {
+ case 1:
+ return devc->pending_speed_sel;
+ break;
+
+ case 2:
+ return devc->syncsource;
+ break;
+
+ case 3:
+ return devc->use_src;
+ break;
+
+ case 4:
+ {
+ int tmp = envy24_read_cci (devc, 0x20);
+ return !!(tmp & 0x10);
+ }
+ break;
+
+ case 5:
+ return devc->ratelock;
+ break;
+
+ case 6:
+ return devc->speed;
+ break;
+
+ case 7:
+ return devc->sync_locked =
+ devc->model_data->auxdrv->get_locked_status (devc);
+
+ default:
+ return OSS_EIO;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ switch (ctrl)
+ {
+ case 1:
+ if (value < 0 || value > 12)
+ return OSS_EIO;
+
+ if (value != devc->pending_speed_sel)
+ {
+ if (devc->open_inputs == 0 && devc->open_outputs == 0) /* IDDLE */
+ OUTB (devc->osdev, value, devc->mt_base + 0x01); /* Make the change now */
+ }
+
+ return devc->pending_speed_sel = value;
+ break;
+
+ case 2:
+ if (value < 0 || value > 2)
+ return OSS_EIO;
+ return devc->syncsource = value;
+ break;
+
+ case 3:
+ return devc->use_src = value;
+ break;
+
+ case 4:
+ {
+ int tmp = envy24_read_cci (devc, 0x20) & ~0x10;
+ if (value)
+ tmp |= 0x10; /* Optical */
+ envy24_write_cci (devc, 0x20, tmp);
+ return !!(tmp & 0x10);
+ }
+ break;
+
+ case 5:
+ return devc->ratelock = value;
+ break;
+
+ case 6:
+ return devc->speed;
+ break;
+
+ case 7:
+ return devc->sync_locked =
+ devc->model_data->auxdrv->get_locked_status (devc);
+ break;
+
+ default:
+ return OSS_EIO;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+read_mon (envy24_devc * devc, int ch, int is_right)
+{
+ int tmp;
+
+ if (ch >= 20)
+ return 0;
+
+ OUTB (devc->osdev, ch, devc->mt_base + 0x3a);
+ tmp = INW (devc->osdev, devc->mt_base + 0x38);
+
+ if (is_right)
+ tmp >>= 8;
+ tmp &= 0x7f;
+ if (tmp > 0x60) /* Mute? */
+ return 0;
+
+ tmp = (tmp * 15) / 10;
+ return 144 - tmp;
+}
+
+static int
+mon_scale (int v)
+{
+ if (v == 0)
+ return 0x7f; /* Mute */
+
+ v = 144 - v;
+
+ v = (10 * v) / 15;
+ if (v > 0x60)
+ v = 0x7f;
+ return v;
+}
+
+static void
+mon_set (envy24_devc * devc, int ch, int left, int right)
+{
+
+ left = mon_scale (left);
+ right = mon_scale (right);
+
+ OUTB (devc->osdev, 1, devc->mt_base + 0x3b); /* Volume change rate */
+ OUTB (devc->osdev, ch, devc->mt_base + 0x3a);
+ OUTW (devc->osdev, left | (right << 8), devc->mt_base + 0x38);
+}
+
+static int
+read_peak (envy24_devc * devc, int ch)
+{
+ int tmp;
+
+ if (ch >= 22)
+ return 0;
+
+ OUTB (devc->osdev, ch, devc->mt_base + 0x3e);
+ tmp = INB (devc->osdev, devc->mt_base + 0x3f);
+
+ return tmp;
+}
+
+/*ARGSUSED*/
+static int
+envy24_get_peak (int dev, int ctrl, unsigned int cmd, int value)
+{
+ static const unsigned char peak_cnv[256] = {
+ 0, 18, 29, 36, 42, 47, 51, 54, 57, 60, 62, 65, 67, 69, 71, 72,
+ 74, 75, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 89, 90,
+ 91, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 100, 101,
+ 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
+ 108,
+ 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 113, 113, 113, 114, 114,
+ 114,
+ 115, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119,
+ 119,
+ 119, 119, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 122, 122, 123,
+ 123,
+ 123, 123, 124, 124, 124, 124, 125, 125, 125, 125, 125, 126, 126, 126, 126,
+ 126,
+ 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 129, 129, 129, 129, 129,
+ 130,
+ 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132,
+ 132,
+ 132, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 135,
+ 135,
+ 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 137, 137, 137,
+ 137,
+ 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139,
+ 139,
+ 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141,
+ 141,
+ 141, 141, 141, 141, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143,
+ 143,
+ 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, 144, 144, 144,
+ 144,
+ };
+
+ envy24_devc *devc = mixer_devs[dev]->devc;
+
+ int i, orign, n = -1, left = 0, right = 0;
+
+ for (i = 0; i < 12 && n == -1; i++)
+ if (ctrl & (1 << i))
+ n = i;
+
+ if (n == -1)
+ return OSS_EINVAL;
+
+ orign = n;
+ if (ctrl & 0x80000000)
+ n += 10; /* Recording stream */
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ left = read_peak (devc, n);
+ if (ctrl & (1 << (orign + 1))) /* Stereo mode? */
+ right = read_peak (devc, n + 1);
+ else
+ right = left;
+
+ left = peak_cnv[left];
+ right = peak_cnv[right];
+ return left | (right << 8);
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+envy24_set_mon (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+
+ int i, orign, n = -1, left = 0, right = 0;
+
+ for (i = 0; i < 10 && n == -1; i++)
+ if (ctrl & (1 << i))
+ n = i;
+
+ if (n == -1)
+ return OSS_EINVAL;
+
+ orign = n;
+ if (ctrl & 0x80000000)
+ n += 10; /* Recording stream */
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ left = read_mon (devc, n, 0) * 10;
+ if (ctrl & (1 << (orign + 1))) /* Stereo mode? */
+ right = read_mon (devc, n + 1, 1) * 10;
+ else
+ right = read_mon (devc, n, 1) * 10;
+
+ return left | (right << 16);
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+ left = value & 0xffff;
+ right = (value >> 16) & 0xffff;
+
+ if (right > 1440)
+ right = 1440;
+ if (left > 1440)
+ left = 1440;
+
+ if (ctrl & (1 << (orign + 1))) /* Stereo mode? */
+ {
+ mon_set (devc, n, left / 10, 0);
+ mon_set (devc, n + 1, 0, right / 10);
+ }
+ else
+ {
+ mon_set (devc, n, left / 10, right / 10);
+ }
+ return left | (right << 16);
+ }
+ return OSS_EINVAL;
+}
+
+static int
+get_loopback (envy24_devc * devc, int ch)
+{
+ int tmp;
+
+ tmp = INL (devc->osdev, devc->mt_base + 0x34);
+ return (tmp >> (4 * ch)) & 0x07;
+}
+
+static int
+get_spdif_loopback (envy24_devc * devc, int ch)
+{
+ int tmp;
+
+ tmp = INL (devc->osdev, devc->mt_base + 0x34);
+ return (tmp >> ((4 * ch) + 3)) & 0x01;
+}
+
+static void
+set_loopback (envy24_devc * devc, int ch, int val)
+{
+ int tmp = INL (devc->osdev, devc->mt_base + 0x34);
+ tmp &= ~(0x07 << (4 * ch));
+ tmp |= (val & 0x07) << (4 * ch);
+ OUTL (devc->osdev, tmp, devc->mt_base + 0x34);
+}
+
+static void
+set_spdif_loopback (envy24_devc * devc, int ch, int val)
+{
+ int tmp = INL (devc->osdev, devc->mt_base + 0x34);
+ tmp &= ~(0x08 << (4 * ch));
+ tmp |= (val & 0x01) << ((4 * ch) + 3);
+ OUTL (devc->osdev, tmp, devc->mt_base + 0x34);
+}
+
+static int
+envy24_set_outrout (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int tmp, i;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ tmp = INW (devc->osdev, devc->mt_base + 0x30);
+
+ for (i = 0; i < 8; i++)
+ if (ctrl & (1 << i))
+ {
+ tmp = (tmp >> (2 * i)) & 0x03;
+ switch (tmp)
+ {
+ case 0: /* DMA */
+ return 0;
+ break;
+
+ case 1: /* Monitor */
+ return 1;
+ break;
+
+ case 2: /* Analog input loopback */
+ return 2 + get_loopback (devc, i);
+ break;
+
+ case 3: /* S/PDIF input loopback */
+ return 10 + get_spdif_loopback (devc, i);
+ break;
+ }
+ }
+
+ return OSS_EINVAL;
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+ tmp = INW (devc->osdev, devc->mt_base + 0x30);
+ for (i = 0; i < 8; i++)
+ if (ctrl & (1 << i))
+ {
+ int ch;
+ ch = i / 2;
+ if (i & 1)
+ ch += 4;
+
+ tmp &= ~(0x03 << (ch * 2)); /* Cleanup */
+
+ if (value == 0) /* DMA */
+ continue;
+
+ if (value == 1) /* Monitor */
+ {
+ tmp |= 1 << (ch * 2);
+ continue;
+ }
+
+ if (value < 10) /* Analog inputs */
+ {
+ tmp |= 2 << (ch * 2);
+ set_loopback (devc, i, value - 2);
+ continue;
+ }
+
+ tmp |= 3 << (ch * 2);
+ set_spdif_loopback (devc, i, value - 10);
+ }
+
+ OUTW (devc->osdev, tmp, devc->mt_base + 0x30);
+ return value;
+ }
+ return OSS_EINVAL;
+}
+
+static int
+envy24_set_stereo_outrout (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int tmp, i;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ tmp = INW (devc->osdev, devc->mt_base + 0x30);
+
+ for (i = 0; i < 8; i++)
+ if (ctrl & (1 << i))
+ {
+ int ch;
+ ch = i / 2;
+ if (i & 1)
+ ch += 4;
+ tmp = (tmp >> (2 * ch)) & 0x03;
+ switch (tmp)
+ {
+ case 0: /* DMA */
+ return 0;
+ break;
+
+ case 1: /* Monitor */
+ return 1;
+ break;
+
+ case 2: /* Analog input loopback */
+ return 2 + get_loopback (devc, i) / 2;
+ break;
+
+ case 3: /* S/PDIF input loopback */
+ return 6;
+ break;
+ }
+ }
+
+ return OSS_EINVAL;
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+ tmp = INW (devc->osdev, devc->mt_base + 0x30);
+ for (i = 0; i < 8; i++)
+ if (ctrl & (1 << i))
+ {
+ int ch;
+ ch = i / 2;
+ if (i & 1)
+ ch += 4;
+
+ tmp &= ~(0x03 << (ch * 2)); /* Cleanup */
+
+ if (value == 0) /* DMA */
+ {
+ continue;
+ }
+
+ if (value == 1) /* Monitor */
+ {
+ tmp |= 1 << (ch * 2);
+ continue;
+ }
+
+ if (value < 6) /* Analog inputs */
+ {
+ tmp |= 2 << (ch * 2);
+ set_loopback (devc, i, (value - 2) * 2 + (i & 1));
+ continue;
+ }
+
+ tmp |= 3 << (ch * 2); /* S/PDIF */
+ set_spdif_loopback (devc, i, (value - 10) + (i & 1));
+ continue;
+ }
+
+ OUTW (devc->osdev, tmp, devc->mt_base + 0x30);
+ return value;
+ }
+ return OSS_EINVAL;
+}
+
+static int
+read_spdif_stereo (envy24_devc * devc)
+{
+ int tmp;
+ tmp = INL (devc->osdev, devc->mt_base + 0x32);
+
+/*
+ * Look only at the left channel. Assume the same settings on right.
+ */
+
+ switch (tmp & 0x03)
+ {
+ case 0: /* From DMA */
+ return 0;
+ break;
+
+ case 1: /* From digital mixer */
+ return 1;
+ break;
+
+ case 2: /* Analog input # loopback */
+ return 2 + ((tmp >> 9) & 0x03);
+ break;
+
+ case 3: /* S/PDIF input loopback */
+ return 6;
+ break;
+ }
+
+ return 0;
+}
+
+static int
+read_spdif_mono (envy24_devc * devc, int ch)
+{
+ int tmp, v;
+ tmp = INL (devc->osdev, devc->mt_base + 0x32);
+
+ if (ch == 0) /* Left channel ? */
+ v = (tmp) & 0x03;
+ else
+ v = (tmp >> 2) & 0x03;
+
+ switch (v)
+ {
+ case 0: /* DMA */
+ return 0;
+ break;
+
+ case 1: /* Monitor */
+ return 1;
+ break;
+
+ case 2: /* Analog input */
+ if (ch == 0) /* Left or right */
+ v = (tmp >> 8) & 0x07;
+ else
+ v = (tmp >> 12) & 0x07;
+
+ return 2 + v;
+ break;
+
+ case 3:
+ if (ch == 0) /* Left or right */
+ v = (tmp >> 11) & 0x01;
+ else
+ v = (tmp >> 15) & 0x01;
+ return 10 + v;
+ break;
+
+ }
+
+ return 0;
+}
+
+static int
+write_spdif_mono (envy24_devc * devc, int ch, int val)
+{
+ int tmp = 0, v;
+ tmp = INW (devc->osdev, devc->mt_base + 0x32);
+
+ if (val == 0) /* DMA */
+ {
+ if (ch == 0) /* Left */
+ tmp &= ~0x0003;
+ else
+ tmp &= ~0x000c;
+ goto do_ne;
+ }
+
+ if (val == 1) /* Monitor */
+ {
+ if (ch == 0) /* Left */
+ {
+ tmp &= ~0x0003;
+ tmp |= 0x0001;
+ }
+ else
+ {
+ tmp &= ~0x000c;
+ tmp |= 0x0004;
+ }
+ goto do_ne;
+ }
+
+ if (val < 10) /* Analog inputs */
+ {
+ v = (val - 2) & 0x07;
+
+ if (ch == 0) /* Left */
+ {
+ tmp &= ~(0x0003 | (0x07 << 8));
+ tmp |= 0x02 | (v << 8);
+ }
+ else
+ {
+ tmp &= ~(0x000c | (0x07 << 12));
+ tmp |= 0x08 | (v << 12);
+ }
+ goto do_ne;
+ }
+
+ /* Else S/PDIF */
+
+ if (ch == 0) /* Left */
+ {
+ tmp &= ~(1 << 11);
+ tmp |= 0x0003;
+
+ if (val == 11)
+ tmp |= 1 << 11;
+ }
+ else
+ {
+ tmp &= ~(1 << 15);
+ tmp |= 0x000c;
+
+ if (val == 11)
+ tmp |= 1 << 15;
+ }
+
+do_ne:
+ OUTW (devc->osdev, tmp, devc->mt_base + 0x32);
+ return val;
+}
+
+static int
+write_spdif_stereo (envy24_devc * devc, int val)
+{
+ int tmp = 0, v;
+
+ if (val == 0) /* DMA */
+ {
+ tmp = 0x0000;
+ goto do_ne;
+ }
+
+ if (val == 1) /* Monitor */
+ {
+ tmp = 0x0005;
+ goto do_ne;
+ }
+
+ if (val < 6) /* Analog inputs */
+ {
+ tmp = 0x000a;
+
+ v = (val - 2) * 2;
+ tmp |= (v << 8);
+ tmp |= ((v + 1) << 12);
+ goto do_ne;
+ }
+
+ /* Else S/PDIF */
+
+ tmp = 0x800f;
+
+do_ne:
+ OUTW (devc->osdev, tmp, devc->mt_base + 0x32);
+ return val;
+}
+
+static int
+envy24_set_spdifrout (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (ctrl == 3)
+ return read_spdif_stereo (devc);
+ else
+ return read_spdif_mono (devc, ctrl - 1);
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+ if (ctrl == 3)
+ return write_spdif_stereo (devc, value);
+ else
+ return write_spdif_mono (devc, ctrl - 1, value);
+ }
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static int
+create_output_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, num, skip;
+ char tmp[64];
+
+ int nc = devc->nr_play_channels;
+
+ if (envy24_virtualout)
+ {
+ mask = 0;
+ nc = 10;
+ for (i = 0; i < nc; i++)
+ mask |= (1 << i);
+ }
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_OUTPUT")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ for (i = 0; i < nc; i += skip)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ sprintf (tmp, "@pcm%d", devc->play_portc[i / 2].dev);
+
+ num |= 1 << (i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_mon,
+ MIXT_STEREOSLIDER16,
+ tmp, 1440,
+ MIXF_MONVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE | MIXF_CENTIBEL)) <
+ 0)
+ return err;
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_get_peak,
+ MIXT_STEREOPEAK,
+ "-", 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+create_input_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->inportmask, group, err, num, skip;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_INPUT")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ for (i = 0; i < devc->nr_rec_channels && i < 10; i += skip)
+ {
+
+ num = (1 << i);
+ if (!(mask & num))
+ continue; /* Not present */
+
+ num |= 0x80000000; /* Input flag */
+
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDIN");
+ else
+ sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2);
+
+ num |= (1 << (i + 1));
+
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_mon,
+ MIXT_STEREOSLIDER16,
+ tmp, 1440,
+ MIXF_MONVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE | MIXF_CENTIBEL)) <
+ 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_get_peak,
+ MIXT_STEREOPEAK,
+ "-", 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return err;
+ }
+
+ num = (1 << 11);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_get_peak,
+ MIXT_STEREOPEAK,
+ "MONITOR", 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return err;
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+create_mon_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, num, skip;
+ char tmp[64];
+
+ int nc = devc->nr_play_channels;
+
+ if (envy24_virtualout)
+ {
+ mask = 0;
+ nc = 10;
+ for (i = 0; i < nc; i++)
+ mask |= (1 << i);
+ }
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_MON")) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ for (i = 0; i < nc; i += skip)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ num |= 1 << (i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_mon,
+ MIXT_STEREOSLIDER16,
+ tmp, 1440,
+ MIXF_MONVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE |
+ MIXF_CENTIBEL)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUTL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDOUTR");
+ else
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_mon,
+ MIXT_STEREOSLIDER16,
+ tmp, 1440,
+ MIXF_MONVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE |
+ MIXF_CENTIBEL)) < 0)
+ return err;
+ }
+ }
+
+ mask = devc->inportmask;
+ for (i = 0; i < devc->nr_rec_channels && i < 10; i += skip)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ num |= 0x80000000; /* Input flag */
+
+ if (devc->skipdevs == 2)
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDIN");
+ else
+ sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2);
+
+ num |= 1 << (i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_mon,
+ MIXT_STEREOSLIDER16,
+ tmp, 1440,
+ MIXF_MONVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE |
+ MIXF_CENTIBEL)) < 0)
+ return err;
+ }
+ else
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDINL");
+ else if (i == 9)
+ strcpy (tmp, "ENVY24_SPDINR");
+ else
+ sprintf (tmp, "ENVY24_IN%d", i + 1);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_mon,
+ MIXT_STEREOSLIDER16,
+ tmp, 1440,
+ MIXF_MONVOL |
+ MIXF_READABLE |
+ MIXF_WRITEABLE |
+ MIXF_CENTIBEL)) < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+create_peak_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, num, skip;
+ int nc = devc->nr_play_channels;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_PEAK")) < 0)
+ return group;
+
+ skip = 2;
+
+ for (i = 0; i < nc; i += skip)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDOUT");
+ else
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+
+ num |= 1 << (i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_get_peak,
+ MIXT_STEREOPEAK,
+ tmp, 144,
+ MIXF_READABLE | MIXF_DECIBEL)) <
+ 0)
+ return err;
+ }
+ }
+
+ mask = devc->inportmask;
+ for (i = 0; i < devc->nr_rec_channels; i += skip)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ num |= 0x80000000; /* Input flag */
+
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDIN");
+ else if (i == 10)
+ strcpy (tmp, "ENVY24_MAIN");
+ else
+ sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2);
+
+ num |= 1 << (i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_get_peak,
+ MIXT_STEREOPEAK,
+ tmp, 144,
+ MIXF_READABLE | MIXF_DECIBEL)) <
+ 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+void
+envy24_set_enum_mask (int dev, int ctl, oss_native_word mask)
+{
+ oss_mixext *ext;
+ int i;
+
+ ext = mixer_find_ext (dev, ctl);
+
+ if (ext == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot locate the mixer extension\n");
+ return;
+ }
+
+ memset (ext->enum_present, 0, sizeof (ext->enum_present));
+
+ for (i = 0; i < 32; i++)
+ if (mask & (1 << i))
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+}
+
+/*ARGSUSED*/
+static int
+create_rout_mixer (int dev, envy24_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, skip, num, chnum;
+ char tmp[64];
+
+ if ((group =
+ mixer_ext_create_group_flags (dev, 0, "ENVY24_ROUTE", MIXF_FLAT)) < 0)
+ return group;
+
+ skip = devc->skipdevs;
+ if (skip != 2)
+ skip = 1;
+
+ for (i = 0; i < 8; i += skip)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ if (devc->skipdevs == 2)
+ {
+ oss_native_word tmpmask = 0x00000001;
+ int j;
+
+ if (i < 2)
+ tmpmask |= 0x00000002;
+ for (j = 0; j < 8; j++)
+ if (mask & (1 << j))
+ tmpmask |= 1 << ((j / 2) + 2);
+ if (devc->model_data->flags & MF_SPDIF)
+ tmpmask |= 0x00000040;
+
+ sprintf (tmp, "ENVY24_OUT%d/%d", i + 1, i + 2);
+ chnum = i;
+ num = (1 << chnum) | (1 << (chnum + 1));
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_stereo_outrout,
+ MIXT_ENUM,
+ tmp, 7,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ envy24_set_enum_mask (dev, err, tmpmask);
+ }
+ else
+ {
+ oss_native_word tmpmask = 0x00000001;
+ int j;
+
+ sprintf (tmp, "ENVY24_OUT%d", i + 1);
+ chnum = i;
+ num = 1 << chnum;
+
+ if (i < 2)
+ tmpmask |= (1 << 1);
+ for (j = 0; j < 8; j++)
+ if (mask & (1 << j))
+ tmpmask |= 1 << (j + 2);
+ if (devc->model_data->flags & MF_SPDIF)
+ tmpmask |= (3 << 10);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_outrout,
+ MIXT_ENUM,
+ tmp, 12,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ envy24_set_enum_mask (dev, err, tmpmask);
+ }
+ }
+
+ mask = devc->inportmask;
+
+ if (devc->model_data->flags & MF_SPDIF)
+ {
+ if (devc->skipdevs == 2)
+ {
+ oss_native_word tmpmask = 0x00000043;
+ int j;
+ for (j = 0; j < 8; j++)
+ if (mask & (1 << j))
+ tmpmask |= (1 << ((j / 2) + 2));
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, envy24_set_spdifrout,
+ MIXT_ENUM,
+ "ENVY24_SPDIF", 7,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ envy24_set_enum_mask (dev, err, tmpmask);
+ }
+ else
+ {
+ oss_native_word tmpmask = 0x00000c03;
+ int j;
+ for (j = 0; j < 8; j++)
+ if (mask & (1 << j))
+ tmpmask |= (1 << (j + 2));
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, envy24_set_spdifrout,
+ MIXT_ENUM,
+ "ENVY24_SPDIFL", 12,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ envy24_set_enum_mask (dev, err, tmpmask);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, envy24_set_spdifrout,
+ MIXT_ENUM,
+ "ENVY24_SPDIFR", 12,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return err;
+ envy24_set_enum_mask (dev, err, tmpmask);
+ }
+ }
+
+#if 0
+ for (i = 0; i < devc->nr_rec_channels && i < 10; i += skip)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ num |= 0x80000000; /* Input flag */
+
+ if (devc->skipdevs == 2)
+ {
+ sprintf (tmp, "ENVY24_IN%d/%d", i + 1, i + 2);
+ num |= 1 << (i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_mon,
+ MIXT_STEREOSLIDER16,
+ tmp, 1440,
+ MIXF_READABLE |
+ MIXF_WRITEABLE |
+ MIXF_CENTIBEL)) < 0)
+ return err;
+ }
+ else
+ {
+ sprintf (tmp, "ENVY24_IN%d", i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24_set_mon,
+ MIXT_STEREOSLIDER16,
+ tmp, 1440,
+ MIXF_READABLE |
+ MIXF_WRITEABLE |
+ MIXF_CENTIBEL)) < 0)
+ return err;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+static int
+envy24_mix_init (int dev)
+{
+ envy24_devc *devc = mixer_devs[dev]->devc;
+ int group, err, ctl;
+ int n;
+
+ extern int envy24_mixerstyle;
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24")) < 0)
+ return group;
+
+ if (envy24_skipdevs == 2)
+ switch (envy24_mixerstyle)
+ {
+ case 2:
+ /* New style input and output mixer sections */
+ if ((err = create_output_mixer (dev, devc, group)) < 0)
+ return err;
+ if ((err = create_input_mixer (dev, devc, group)) < 0)
+ return err;
+ break;
+
+ default:
+ /* Traditional mixer (peak meters and montor gains separated) */
+ if ((err = create_peak_mixer (dev, devc, group)) < 0)
+ return err;
+ if ((err = create_mon_mixer (dev, devc, group)) < 0)
+ return err;
+ break;
+ }
+
+ if ((err = create_rout_mixer (dev, devc, group)) < 0)
+ return err;
+
+ if (devc->model_data->auxdrv->mixer_init)
+ if ((err = devc->model_data->auxdrv->mixer_init (devc, dev, group)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, envy24_set_control,
+ MIXT_ENUM,
+ "ENVY24_RATE", 12,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ mixer_ext_set_strings (dev, err,
+ "8000 9600 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000", 0);
+
+ if (devc->model_data->flags & (MF_SPDIF | MF_WCLOCK))
+ {
+ n = 2;
+ if (devc->model_data->flags & MF_WCLOCK)
+ n = 3;
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, envy24_set_control,
+ MIXT_ENUM,
+ "ENVY24_SYNC", n,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+ }
+
+ if (devc->model_data->flags & MF_SPDSELECT)
+ {
+ if ((err = mixer_ext_create_control (dev, group,
+ 4, envy24_set_control,
+ MIXT_ENUM,
+ "ENVY24_SPDIN", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+ }
+
+#if 0
+/* Always on */
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, envy24_set_control,
+ MIXT_ONOFF,
+ "ENVY24_SRC", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+#endif
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 5, envy24_set_control,
+ MIXT_ONOFF,
+ "ENVY24_RATELOCK", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ 6, envy24_set_control,
+ MIXT_VALUE,
+ "ENVY24_ACTRATE", 96000,
+ MIXF_READABLE)) < 0)
+ return ctl;
+ mixer_ext_set_description(dev, ctl, "Sample rate currently used by the device");
+
+#if 1
+ if (devc->model_data->auxdrv->get_locked_status)
+ {
+ devc->sync_locked = devc->model_data->auxdrv->get_locked_status (devc);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 7, envy24_set_control,
+ MIXT_ONOFF,
+ "ENVY24_LOCKED", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+ }
+#endif
+
+ if (devc->model_data->auxdrv->spdif_mixer_init)
+ if ((err =
+ devc->model_data->auxdrv->spdif_mixer_init (devc, dev, group)) < 0)
+ return err;
+ return 0;
+}
+
+static mixer_driver_t envy24_mixer_driver = {
+ envy24_mixer_ioctl
+};
+
+static int
+install_adev (envy24_devc * devc, char *name, int flags, int skip,
+ int portc_flags, char *port_id, char *devfile_name)
+{
+ int dev, i;
+ adev_p adev;
+ int fmts = 0, last;
+ extern int envy24_realencoder_hack;
+
+ if (portc_flags & PORTC_SPDOUT)
+ fmts |= AFMT_AC3;
+
+ if ((dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ name,
+ &envy24_audio_driver,
+ sizeof (audiodrv_t),
+ ADEV_AUTOMODE | ADEV_NOMMAP |
+ flags | ADEV_NOVIRTUAL,
+ fmts | AFMT_S16_LE | AFMT_S32_LE |
+ AFMT_S24_LE, devc, -1,
+ devfile_name)) < 0)
+ {
+ dev = -1;
+ return 0;
+ }
+ else
+ {
+ envy24_portc *portc;
+ adev = audio_engines[dev];
+
+ if (devc->first_dev == -1)
+ devc->first_dev = dev;
+ for (i = 0; speed_tab[i].speed != -1; i++)
+ adev->rates[adev->nrates++] = speed_tab[i].speed;
+
+ adev->vmix_flags = 0;
+
+ if (flags == DIR_OUTPUT)
+ {
+ last = 10;
+ audio_engines[dev]->port_number = devc->curr_outch;
+ audio_engines[dev]->min_rate = 8000;
+ audio_engines[dev]->max_rate = 96000;
+ portc = &devc->play_portc[devc->nr_outdevs++];
+ portc->chnum = devc->curr_outch;
+ strncpy (portc->name, port_id, sizeof (portc->name) - 1);
+ portc->name[sizeof (portc->name) - 1] = 0;
+ devc->curr_outch += skip;
+ if (portc_flags & PORTC_SPDOUT)
+ audio_engines[dev]->caps |= PCM_CAP_DIGITALOUT;
+ if (portc_flags & PORTC_SPDIN)
+ audio_engines[dev]->caps |= PCM_CAP_DIGITALIN;
+
+ }
+ else
+ {
+ last = 12;
+ portc = &devc->rec_portc[devc->nr_indevs++];
+ audio_engines[dev]->port_number = devc->curr_inch + 10;
+ portc->chnum = devc->curr_inch;
+ strncpy (portc->name, port_id, sizeof (portc->name) - 1);
+ portc->name[sizeof (portc->name) - 1] = 0;
+ devc->curr_inch += skip;
+#ifdef DO_RIAA
+ portc->riaa_filter = 0;
+#endif
+ }
+
+ portc->flags = portc_flags;
+ audio_engines[dev]->devc = devc;
+ audio_engines[dev]->portc = portc;
+ audio_engines[dev]->rate_source = devc->first_dev;
+
+ switch (skip)
+ {
+ case 1:
+ audio_engines[dev]->caps |= DSP_CH_MONO;
+ audio_engines[dev]->min_channels = 1;
+ audio_engines[dev]->max_channels =
+ (envy24_force_mono) ? 1 : last - portc->chnum;
+ break;
+
+ case 2:
+ audio_engines[dev]->caps |= DSP_CH_STEREO;
+ audio_engines[dev]->min_channels = 1;
+ audio_engines[dev]->max_channels = last - portc->chnum;
+ break;
+
+ default:
+ audio_engines[dev]->caps |= DSP_CH_MULTI;
+ audio_engines[dev]->min_channels = 1;
+ audio_engines[dev]->max_channels = last - portc->chnum;
+ }
+
+ audio_engines[dev]->mixer_dev = devc->mixer_dev;
+ portc->dev = dev;
+ portc->open_mode = 0;
+ portc->is_active = 0;
+ portc->direction = flags;
+ portc->trigger_bits = 0;
+
+ if (envy24_realencoder_hack && flags == DIR_INPUT
+ && devc->nr_indevs > 1)
+ if (oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "Dummy mixer",
+ &envy24_mixer_driver,
+ sizeof (mixer_driver_t), devc) >= 0)
+ {
+ mixer_devs[devc->mixer_dev]->priority = -1; /* Don't use as the default mixer */
+ }
+ }
+
+ return 1;
+}
+
+static int
+install_output_devices (envy24_devc * devc, int mask)
+{
+ char tmp[512], id[32];
+ int i, nc, portc_flags = 0;
+
+ char *lr = "", *kind;
+
+ nc = devc->nr_play_channels = MAX_ODEV;
+ devc->nr_rec_channels = MAX_IDEV;
+
+ if (devc->skipdevs < 1)
+ devc->skipdevs = 1;
+
+ for (i = 0; i < nc; i += devc->skipdevs)
+ {
+ char *devfile_name = "";
+
+ if (devc->skipdevs != 2)
+ lr = (i & 1) ? "R" : "L";
+ kind = "";
+
+ if (!(mask & (1 << devc->curr_outch)))
+ kind = "(virtual) ";
+
+ switch (devc->curr_outch)
+ {
+ case 8:
+ case 9:
+ portc_flags = PORTC_SPDOUT;
+ sprintf (tmp, "%s %sS/PDIF out %s", devc->model_data->product, kind,
+ lr);
+ sprintf (id, "SPDIF%s", lr);
+ devfile_name = "spdout";
+ break;
+
+ default:
+ if (devc->skipdevs > 1)
+ {
+ sprintf (tmp, "%s %sout%d/%d", devc->model_data->product, kind,
+ i + 1, i + devc->skipdevs);
+ sprintf (id, "OUT%d/%d", i + 1, i + devc->skipdevs);
+ }
+ else
+ {
+ sprintf (tmp, "%s %sout%d", devc->model_data->product, kind,
+ i + 1);
+ sprintf (id, "OUT%d", i + 1);
+ }
+ }
+
+ if (mask & (1 << devc->curr_outch))
+ install_adev (devc, tmp, ADEV_NOINPUT, devc->skipdevs, portc_flags,
+ id, devfile_name);
+ else
+ devc->curr_outch += devc->skipdevs;
+ }
+
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+install_virtual_output_devices (envy24_devc * devc, int mask)
+{
+#if 0
+ char tmp[512];
+ int i, nc;
+
+ char *lr = "";
+ nc = devc->nr_play_channels = MAX_ODEV;
+ devc->nr_rec_channels = MAX_IDEV;
+
+ if (envy24_virtualout)
+ {
+ nc = 10;
+ }
+
+ if (devc->skipdevs < 1)
+ devc->skipdevs = 1;
+
+ for (i = 0; i < nc; i += devc->skipdevs)
+ {
+
+ if (devc->skipdevs != 2)
+ lr = (i & 1) ? "R" : "L";
+
+ switch (devc->curr_outch)
+ {
+ case 8:
+ case 9:
+ sprintf (tmp, "%s virtual out %s", devc->model_data->product, lr);
+ break;
+
+ default:
+ if (devc->skipdevs > 1)
+ sprintf (tmp, "%s virtual out%d/%d", devc->model_data->product,
+ i + 1, i + devc->skipdevs);
+ else
+ sprintf (tmp, "%s virtual out%d", devc->model_data->product,
+ i + 1);
+ }
+
+ if (!(mask & (1 << devc->curr_outch))) /* Not done yet */
+ install_adev (devc, tmp, ADEV_NOINPUT, devc->skipdevs, 0, "virtual", ""); // TODO: Find better device file name
+ else
+ devc->curr_outch += devc->skipdevs;
+ }
+#endif
+ return 1;
+}
+
+static int
+install_input_devices (envy24_devc * devc, int mask)
+{
+ char tmp[512], id[32];
+ int i, portc_flags = 0;
+
+ char *lr = "";
+
+ devc->nr_play_channels = MAX_ODEV;
+ devc->nr_rec_channels = MAX_IDEV;
+
+ if (devc->skipdevs < 1)
+ devc->skipdevs = 1;
+
+ for (i = 0; i < devc->nr_rec_channels; i += devc->skipdevs)
+ {
+ char *devfile_name = "";
+
+ if (devc->skipdevs != 2)
+ lr = (i & 1) ? "R" : "L";
+
+ switch (devc->curr_inch)
+ {
+ case 8:
+ case 9:
+ portc_flags = PORTC_SPDIN;
+ sprintf (tmp, "%s S/PDIF in %s", devc->model_data->product, lr);
+ sprintf (id, "SPDIF%s", lr);
+ devfile_name = "spdin";
+ break;
+
+ case 10:
+ case 11:
+ sprintf (tmp, "%s input from mon. mixer %s",
+ devc->model_data->product, lr);
+ sprintf (id, "MON%s", lr);
+ devfile_name = "mon";
+ break;
+
+ default:
+ if (devc->skipdevs > 1)
+ {
+ sprintf (tmp, "%s in%d/%d", devc->model_data->product, i + 1,
+ i + devc->skipdevs);
+ sprintf (id, "IN%d/%d", i + 1, i + devc->skipdevs);
+ }
+ else
+ {
+ sprintf (tmp, "%s in%d", devc->model_data->product, i + 1);
+ sprintf (id, "IN%d", i + 1);
+ }
+ }
+
+ if (mask & (1 << devc->curr_inch))
+ install_adev (devc, tmp, ADEV_NOOUTPUT, devc->skipdevs, portc_flags,
+ id, devfile_name);
+ else
+ devc->curr_inch += devc->skipdevs;
+ }
+
+ OUTL (devc->osdev, 0x00224466, devc->mt_base + 0x34); /* 1 to 1 input routing */
+
+ return 1;
+}
+
+static int
+install_audio_devices (envy24_devc * devc)
+{
+ extern int envy24_swapdevs;
+ int maskout, maskin, i;
+#define setmask(m, b) m|=(1<<(b))
+
+ maskout = maskin = 0;
+
+ if (envy24_devmask == 0)
+ envy24_devmask = 65535;
+
+ if (envy24_devmask & DMASK_MONITORIN)
+ {
+ setmask (maskin, 10); /* Monitor input left */
+ setmask (maskin, 11); /* Monitor input right */
+ }
+
+ if (devc->model_data->flags & MF_SPDIF)
+ {
+ if (envy24_devmask & DMASK_SPDIFIN)
+ {
+ setmask (maskin, 8); /* S/PDIF left */
+ setmask (maskin, 9); /* S/PDIF right */
+ }
+
+ if (envy24_devmask & DMASK_SPDIFOUT)
+ {
+ setmask (maskout, 8); /* S/PDIF left */
+ setmask (maskout, 9); /* S/PDIF right */
+ }
+ if (devc->model_data->auxdrv->spdif_set)
+ devc->model_data->auxdrv->spdif_set (devc, 0x20);
+ }
+
+ if (envy24_devmask & DMASK_ANALOGOUT)
+ for (i = 0; i < devc->model_data->nr_outs; i++)
+ setmask (maskout, i);
+
+ if (envy24_devmask & DMASK_ANALOGIN)
+ for (i = 0; i < devc->model_data->nr_ins; i++)
+ setmask (maskin, i);
+
+ devc->inportmask = maskin;
+ devc->outportmask = maskout;
+
+ if (envy24_swapdevs)
+ {
+ install_input_devices (devc, maskin);
+ install_output_devices (devc, maskout);
+ install_virtual_output_devices (devc, maskout);
+ }
+ else
+ {
+ install_output_devices (devc, maskout);
+ install_input_devices (devc, maskin);
+ install_virtual_output_devices (devc, maskout);
+ }
+
+ for (i = 0; i < 10; i += devc->skipdevs)
+ {
+ int num = 1 << i;
+ if (devc->skipdevs == 2)
+ num |= 1 << (i + 1);
+
+ if (maskout & num)
+ envy24_set_mon (devc->mixer_dev, num, SNDCTL_MIX_WRITE,
+ 1340 | (1340 << 16));
+ if (maskin & num)
+ envy24_set_mon (devc->mixer_dev, 0x80000000 | num, SNDCTL_MIX_WRITE,
+ 1340 | (1340 << 16));
+ }
+
+ if (envy24_devmask & DMASK_RAWDEVS)
+ envy24d_install (devc);
+ return 1;
+}
+
+static int
+ac97_read (void *devc_, int reg)
+{
+ envy24_devc *devc = devc_;
+ int i, status;
+
+ OUTB (devc->osdev, reg, devc->ccs_base + 0x08);
+ OUTB (devc->osdev, reg, devc->ccs_base + 0x08);
+ OUTB (devc->osdev, reg, devc->ccs_base + 0x08);
+ OUTB (devc->osdev, 0x10, devc->ccs_base + 0x09);
+
+ for (i = 0; i < 1000; i++)
+ {
+ status = INB (devc->osdev, devc->ccs_base + 0x09);
+ if (!(status & 0x10))
+ {
+ status = INW (devc->osdev, devc->ccs_base + 0x0a);
+ return status;
+ }
+ }
+
+ return 0xffff;
+}
+
+static int
+ac97_writereg (void *devc_, int reg, int data)
+{
+ envy24_devc *devc = devc_;
+ int i, status;
+
+ OUTB (devc->osdev, reg, devc->ccs_base + 0x08);
+ OUTB (devc->osdev, reg, devc->ccs_base + 0x08);
+ OUTB (devc->osdev, reg, devc->ccs_base + 0x08);
+ OUTB (devc->osdev, 0x20, devc->ccs_base + 0x09);
+
+ for (i = 0; i < 1000; i++)
+ {
+ status = INB (devc->osdev, devc->ccs_base + 0x09);
+ if (!(status & 0x20))
+ {
+ OUTW (devc->osdev, data & 0xffff, devc->ccs_base + 0x0a);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+ac97_write (void *devc, int reg, int data)
+{
+ int ret;
+
+ ac97_writereg (devc, reg, data);
+ ac97_writereg (devc, reg, data);
+ ret = ac97_writereg (devc, reg, data);
+ return ret;
+}
+
+static void
+install_consumer_devices (envy24_devc * devc)
+{
+#if 1
+ int i, status;
+
+ OUTB (devc->osdev, 0x80, devc->ccs_base + 0x09); /* Cold reset mixer */
+ oss_udelay (200);
+ OUTB (devc->osdev, 0x00, devc->ccs_base + 0x09); /* Release reset */
+ oss_udelay (200);
+
+ for (i = 0; i < 1000; i++)
+ {
+ status = INB (devc->osdev, devc->ccs_base + 0x09);
+
+ if (status & 0x80)
+ break;
+
+ oss_udelay (1000);
+ }
+
+ if (i >= 1000)
+ {
+ }
+#endif
+
+ devc->consumer_mixer_dev =
+ ac97_install (&devc->ac97devc, "Envy24 consumer mixer", ac97_read,
+ ac97_write, devc, devc->osdev);
+
+ /* Route monitor output to consumer AC97 */
+ OUTB (devc->osdev, 0x01, devc->mt_base + 0x3c);
+
+ /* Set consumer volumes to full */
+ envy24_write_cci (devc, 3, 0);
+ envy24_write_cci (devc, 4, 0);
+}
+
+static int
+maudio_load_eeprom (envy24_devc * devc)
+{
+ int status;
+
+ status = INB (devc->osdev, devc->ccs_base + 0x13);
+
+ if (!(status & 0x80))
+ return 0; /* No EEPROM */
+
+ envy24_write_cci (devc, 0x22, devc->eeprom[0xc]); /* GPIO direction */
+ envy24_write_cci (devc, 0x21, devc->eeprom[0xa]); /* GPIO write mask */
+ envy24_write_cci (devc, 0x20, devc->eeprom[0xb]); /* GPIO data */
+
+ return 1;
+}
+
+
+static int
+envy24_init (envy24_devc * devc)
+{
+ extern int envy24_nfrags;
+ oss_native_word phaddr;
+ int err;
+
+ /* Disable all interrupts */
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x01);
+ OUTB (devc->osdev, 0xff, devc->mt_base + 0x00);
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, envy24intr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+
+ if (envy24_skipdevs < 1)
+ envy24_skipdevs = 1;
+ if (envy24_skipdevs > 2)
+ envy24_skipdevs = 2;
+
+ devc->skipdevs = envy24_skipdevs;
+
+ if (envy24_skipdevs != 1)
+ envy24_force_mono = 0;
+
+ if (devc->model_data->flags & MF_MIDI1)
+ {
+ char name[128];
+ oss_native_word flags;
+ sprintf (name, "%s #1", devc->model_data->product);
+
+ MUTEX_ENTER (devc->mutex, flags);
+ uart401_init (&devc->uart401devc1, devc->osdev, devc->ccs_base + 0x0c,
+ name);
+ MUTEX_EXIT (devc->mutex, flags);
+
+ /* Enable UART1 interrupts */
+ OUTB (devc->osdev,
+ INB (devc->osdev, devc->ccs_base + 0x01) & ~0x80,
+ devc->ccs_base + 0x01);
+ }
+
+ if (devc->model_data->flags & MF_MIDI2)
+ {
+ char name[128];
+ oss_native_word flags;
+ sprintf (name, "%s #2", devc->model_data->product);
+
+ MUTEX_ENTER (devc->mutex, flags);
+ uart401_init (&devc->uart401devc2, devc->osdev, devc->ccs_base + 0x1c,
+ name);
+ MUTEX_EXIT (devc->mutex, flags);
+ /* Enable UART2 interrupts */
+ OUTB (devc->osdev,
+ INB (devc->osdev, devc->ccs_base + 0x01) & ~0x20,
+ devc->ccs_base + 0x01);
+ }
+
+ devc->speedbits = 0;
+ devc->speed = 48000;
+ devc->pending_speed_sel = 9;
+
+ if (devc->model_data->flags & (MF_MEEPROM))
+ maudio_load_eeprom (devc);
+
+ if (devc->model_data->auxdrv->card_init)
+ devc->model_data->auxdrv->card_init (devc);
+ if (devc->model_data->auxdrv->spdif_init)
+ devc->model_data->auxdrv->spdif_init (devc);
+
+ if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ devc->model_data->product,
+ &envy24_mixer_driver,
+ sizeof (mixer_driver_t),
+ devc)) >= 0)
+ {
+ int n = 50;
+
+ if (devc->skipdevs == 1)
+ n += 30;
+ mixer_ext_set_init_fn (devc->mixer_dev, envy24_mix_init, n);
+ }
+
+ if (envy24_nfrags != 2 && envy24_nfrags != 4 && envy24_nfrags != 8 &&
+ envy24_nfrags != 16 && envy24_nfrags != 32 && envy24_nfrags != 64)
+ envy24_nfrags = 16;
+
+ devc->playbuffsize = HW_PLAYBUFFSIZE;
+ devc->recbuffsize = HW_RECBUFFSIZE;
+
+ devc->hw_nfrags = envy24_nfrags;
+ devc->hw_pfragsize = devc->playbuffsize / devc->hw_nfrags;
+ devc->hw_rfragsize = devc->recbuffsize / devc->hw_nfrags;
+ devc->hw_fragsamples = devc->hw_pfragsize / 40; /* # of 32 bit samples/fragment/channel */
+
+ if (devc->hw_pfragsize % 40)
+ cmn_err (CE_WARN, "Error! Bad per channel fragment size\n");
+ devc->hw_playfrag = 0;
+ devc->hw_recfrag = 0;
+
+ devc->playbuf =
+ CONTIG_MALLOC (devc->osdev, HW_ALLOCSIZE, MEMLIMIT_28BITS, &phaddr, devc->playbuf_dma_handle);
+ if (devc->playbuf == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate %d bytes of DMA buffer\n",
+ HW_ALLOCSIZE);
+ return 0;
+ }
+
+ devc->playbuf_phys = phaddr;
+ if ((devc->playbuf_phys + HW_ALLOCSIZE) >= (256 * 1024 * 1024))
+ {
+ cmn_err (CE_WARN, "Got DMA buffer beyond address 256M.\n");
+ cmn_err (CE_CONT, "Reboot and try again\n");
+ return 1;
+ }
+
+ OUTL (devc->osdev, devc->playbuf_phys, devc->mt_base + 0x10); /* Play base */
+
+ devc->recbuf =
+ CONTIG_MALLOC (devc->osdev, HW_ALLOCSIZE, MEMLIMIT_28BITS, &phaddr, devc->recbuf_dma_handle);
+ if (devc->recbuf == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate %d bytes of DMA buffer\n",
+ HW_ALLOCSIZE);
+ return 0;
+ }
+
+ devc->recbuf_phys = phaddr;
+ if ((devc->recbuf_phys + HW_ALLOCSIZE) >= (256 * 1024 * 1024))
+ {
+ cmn_err (CE_WARN, "Got DMA buffer beyond address 256M.\n");
+ cmn_err (CE_CONT, "Reboot and try again\n");
+ return 1;
+ }
+
+ OUTL (devc->osdev, devc->recbuf_phys, devc->mt_base + 0x20); /* Rec base */
+
+ devc->playback_started = 0;
+ devc->recording_started = 0;
+ devc->playback_prepared = 0;
+ devc->recording_prepared = 0;
+ devc->writeahead = 1;
+#ifdef __VXWORKS__
+ devc->ratelock = 0;
+#else
+ devc->ratelock = 1;
+#endif
+ memset (devc->playbuf, 0, HW_ALLOCSIZE);
+ memset (devc->recbuf, 0, HW_ALLOCSIZE);
+
+ install_audio_devices (devc);
+
+ if (devc->consumer_ac97_present || (devc->model_data->flags & MF_CONSUMER))
+ install_consumer_devices (devc);
+ /* Enable professional rec/play interrupts */
+ OUTB (devc->osdev,
+ INB (devc->osdev, devc->ccs_base + 0x01) & ~0x10,
+ devc->ccs_base + 0x01);
+
+ setup_spdif_control (devc);
+
+ if (devc->model_data->auxdrv->spdif_set)
+ devc->model_data->auxdrv->spdif_set (devc, 0x20);
+
+#if 1
+ /* Make sure everything is initialized */
+ envy24_prepare_play_engine (devc);
+ envy24_launch_play_engine (devc);
+ oss_udelay (10000);
+ envy24_stop_playback (devc);
+#endif
+
+#if 0
+ {
+ char line[200], *s = line;
+ *line = 0;
+
+ for (i = 0; i < 0x20; i++)
+ {
+ if (!(i % 16))
+ {
+ if (*line != 0)
+ cmn_err (CE_CONT, "%s\n", line);
+
+ s = line;
+ sprintf (s, "CCS%02x: ", i);
+ s = line + strlen (line);
+ }
+ sprintf (s, "%02x ", INB (devc->osdev, devc->ccs_base + i));
+ s = line + strlen (line);
+ }
+ *line = 0;
+
+ for (i = 0; i < 0x40; i++)
+ {
+ if (!(i % 16))
+ {
+ if (*line != 0)
+ cmn_err (CE_CONT, "%s\n", line);
+
+ s = line;
+ sprintf (s, "MT%02x: ", i);
+ s = line + strlen (line);
+ }
+ sprintf (s, "%02x ", INB (devc->osdev, devc->mt_base + i));
+ s = line + strlen (line);
+ }
+
+ cmn_err (CE_CONT, "%s\n", line);
+ }
+#endif
+
+ return 1;
+}
+
+int
+oss_envy24_attach (oss_device_t * osdev)
+{
+ envy24_devc *devc;
+ static int status;
+ unsigned char pci_irq_line;
+ unsigned short pci_command, vendor, device;
+ unsigned int subvendor;
+ unsigned int pci_ioaddr, pci_ioaddr3;
+ int i;
+
+ char *name = "Generic ENVY24";
+
+ DDB (cmn_err (CE_CONT, "Entered Envy24 probe routine\n"));
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != ICENSEMBLE_VENDOR_ID || device != ICENSEMBLE_ENVY24_ID)
+ return 0;
+
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+ DDB (cmn_err (CE_CONT, "Device found at I/O %x\n", pci_ioaddr));
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_3, &pci_ioaddr3);
+
+ devc->active_inputs = 0;
+ devc->active_outputs = 0;
+ devc->sync_locked = 1;
+ devc->first_dev = -1;
+
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, 0x2c, &subvendor);
+ devc->ccs_base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr) & ~0x3;
+ DDB (cmn_err (CE_CONT, "CCS base %x/%lx\n", pci_ioaddr, devc->ccs_base));
+
+ devc->mt_base = MAP_PCI_IOADDR (devc->osdev, 3, pci_ioaddr3) & ~0x3;
+ DDB (cmn_err (CE_CONT, "MT base %x/%lx\n", pci_ioaddr3, devc->mt_base));
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+
+ /* Reset the chip */
+ OUTB (devc->osdev, 0x81, devc->ccs_base + 0x00);
+ oss_udelay (200);
+ /* Release reset */
+ OUTB (devc->osdev, 0x01, devc->ccs_base + 0x00);
+ oss_udelay (200);
+
+ devc->nr_outdevs = devc->nr_indevs = 0;
+ devc->curr_outch = devc->curr_inch = 0;
+ devc->playbuffsize = 0;
+ devc->recbuffsize = 0;
+ devc->playbuf = devc->recbuf = NULL;
+
+ status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (status & 0x80) /* EEPROM present */
+ {
+ static char resol_tab[] = { 16, 18, 20, 24 };
+ unsigned char tmpbyte;
+
+ load_eeprom (devc, subvendor);
+
+ /* Fix bit 0x80 of EEPROM location 0x07. */
+ pci_read_config_byte (osdev, 0x61, &tmpbyte);
+ tmpbyte &= 0x80;
+ devc->eeprom[0x07] &= ~0x80;
+ devc->eeprom[0x07] |= tmpbyte;
+
+#if 1
+ devc->eeprom[0x07] |= 0x80;
+#endif
+
+ pci_write_config_byte (osdev, 0x60, devc->eeprom[0x06]);
+ pci_write_config_byte (osdev, 0x61, devc->eeprom[0x07]);
+ pci_write_config_byte (osdev, 0x62, devc->eeprom[0x08]);
+ pci_write_config_byte (osdev, 0x63, devc->eeprom[0x09]);
+
+#if 1
+ if (devc->eeprom[0x06] & 0x20)
+ DDB (cmn_err (CE_CONT, "Two MPU401 UARTs present.\n"));
+ if (devc->eeprom[0x06] & 0x10)
+ {
+ DDB (cmn_err (CE_CONT, "Consumer AC97 not present.\n"));
+ }
+ else
+ {
+ DDB (cmn_err (CE_CONT, "Consumer AC97 present.\n"));
+ }
+ DDB (cmn_err (CE_CONT, "%d stereo ADC(s) available\n",
+ ((devc->eeprom[0x06] >> 2) & 0x03) + 1));
+ DDB (cmn_err (CE_CONT, "%d stereo DAC(s) available\n",
+ ((devc->eeprom[0x06] >> 0) & 0x03) + 1));
+
+ DDB (cmn_err (CE_CONT, "MT converter type %s\n",
+ (devc->eeprom[0x07] & 0x80) ? "I2S" : "AC97"));
+
+ if (devc->eeprom[0x08] & 0x80)
+ {
+ DDB (cmn_err (CE_CONT, "Has I2S volume control and mute\n"));
+ }
+ else
+ {
+ DDB (cmn_err (CE_CONT, "No I2S volume control and mute\n"));
+ }
+ if (devc->eeprom[0x08] & 0x20)
+ DDB (cmn_err (CE_CONT, "Has 96kHz support\n"));
+
+ DDB (cmn_err (CE_CONT, "Converter resolution %d bits\n",
+ resol_tab[(devc->eeprom[0x08] >> 4) & 0x03]));
+
+ if (devc->eeprom[0x09] & 0x02)
+ DDB (cmn_err (CE_CONT, "Has S/PDIF in support\n"));
+ if (devc->eeprom[0x09] & 0x01)
+ DDB (cmn_err (CE_CONT, "Has S/PDIF out support\n"));
+
+#endif
+
+ if (subvendor == 0xd6301412) /* Delta 1010 */
+ if (devc->eeprom[0xc] == 0x7b) /* Looks like Delta 1010 rev E */
+ subvendor = 0xd63014ff; /* Delta 1010E */
+
+
+#if 1
+ if (!(devc->eeprom[0x07] & 0x80))
+ {
+ cmn_err (CE_WARN, "Cards with AC97 codecs are not supported\n");
+ return 0;
+ }
+#endif
+ }
+
+ i = 0;
+ while (models[i].svid != 0)
+ {
+ if (models[i].svid == subvendor)
+ {
+ name = models[i].product;
+ devc->model_data = &models[i];
+ if (devc->model_data->auxdrv == NULL)
+ devc->model_data->auxdrv = &default_auxdrv;
+ DDB (cmn_err (CE_CONT, "Card id '%s'\n", name));
+
+ break;
+ }
+
+ i++;
+ }
+
+ if (devc->model_data->flags & MF_AC97)
+ devc->consumer_ac97_present = 1;
+
+ if (models[i].svid == 0)
+ {
+ cmn_err (CE_NOTE, "Unknown device ID (%08x).\n", subvendor);
+ cmn_err (CE_NOTE, "This card is not supported (yet).\n");
+ return 0;
+ }
+
+ MUTEX_INIT (osdev, devc->mutex, MH_DRV);
+ oss_register_device (osdev, name);
+ devc->irq = pci_irq_line;
+ return envy24_init (devc); /* Detected */
+}
+
+
+int
+oss_envy24_detach (oss_device_t * osdev)
+{
+ envy24_devc *devc;
+
+ devc = osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ /* Disable all interrupts */
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x01);
+
+ /* Stop playback */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01,
+ devc->mt_base + 0x18);
+ oss_udelay (100);
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01,
+ devc->mt_base + 0x18);
+
+ /* Stop recording */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04,
+ devc->mt_base + 0x18);
+ oss_udelay (100);
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04,
+ devc->mt_base + 0x18);
+
+ if (devc->model_data->flags & MF_MIDI1)
+ uart401_disable (&devc->uart401devc1);
+ if (devc->model_data->flags & MF_MIDI2)
+ uart401_disable (&devc->uart401devc2);
+
+ oss_unregister_interrupts (osdev);
+ MUTEX_CLEANUP (devc->mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+ UNMAP_PCI_IOADDR (devc->osdev, 3);
+
+ if (devc->playbuf != NULL)
+ CONTIG_FREE (devc->osdev, devc->playbuf, HW_ALLOCSIZE, devc->playbuf_dma_handle);
+
+ if (devc->recbuf != NULL)
+ CONTIG_FREE (devc->osdev, devc->recbuf, HW_ALLOCSIZE, devc->recbuf_dma_handle);
+ devc->playbuf = devc->recbuf = NULL;
+
+ oss_unregister_device (osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_envy24/oss_envy24.man b/kernel/drv/oss_envy24/oss_envy24.man
new file mode 100644
index 0000000..d9943a9
--- /dev/null
+++ b/kernel/drv/oss_envy24/oss_envy24.man
@@ -0,0 +1,334 @@
+NAME
+oss_envy24 - ICE Envy24 audio device driver.
+
+DESCRIPTION
+Open Sound System driver for Envy24 based audio cards such as the
+M-Audio Delta Series, Terratec EWS88 Series, Hoontech DSP24.
+
+ ENVY24 device characteristics:
+
+o 8/16 bit playback/record
+o mono/stereo/4ch/5.1ch/7.1ch playback
+o mono/sterero recording
+o 8KHz to 192Khz sample rate.
+
+ ENVY24 AUDIO DEVICES
+
+ Audio devices:
+ 0: M Audio Delta 1010 out1/2
+ 1: M Audio Delta 1010 out3/4
+ 2: M Audio Delta 1010 out5/6
+ 3: M Audio Delta 1010 out7/8
+ 4: M Audio Delta 1010 S/PDIF out
+ 5: M Audio Delta 1010 in1/2
+ 6: M Audio Delta 1010 in3/4
+ 7: M Audio Delta 1010 in5/6
+ 8: M Audio Delta 1010 in7/8
+ 9: M Audio Delta 1010 S/PDIF in
+ 10: M Audio Delta 1010 input from mon. mixer
+ 11: M Audio Delta 1010 (all outputs)
+ 12: M Audio Delta 1010 (all inputs)
+
+ Synth devices:
+
+ Midi devices:
+ 0: M Audio Delta 1010
+
+ Timers:
+ 0: System clock
+
+ Mixers:
+ 0: M Audio Delta 1010
+
+
+The actual /dev/dsp# numbers may be different on your system. Check the right
+ones by looking at the output procuced by "ossinfo -a" command. With the
+above configuration you can use /dev/dsp0 to /dev/dsp4 for playback of stereo
+streams. If you play mono files the signal will be output only from the left
+channel. /dev/dsp0 to /dev/dsp3 are connected to the analog outputs while
+/dev/dsp4 is the S/PDIF output.
+
+The /dev/dsp5 to /dev/dsp10 device files can be used for recording. /dev/dsp5
+to /dev/dsp8 are the analog inputs. /dev/dsp11 and /dev/dsp12 are raw
+input/output device files. They will be described in detail in the "Raw I/O
+devices" section below.
+
+It's also possible to make OSS to create individual device files for every
+channel this creates twice as many device files than the default setting. To
+do this just append envy24_skipdevs=1 to the oss_envy24.conf file. This is useful
+only if you are working on mono rather than stereo signals. However please
+note that setting envy24_skipdevs=1 does _NOT_ lock the device files to one
+channel mode, the application can still set them to stereo or multi channel
+mode if it likes.
+
+It is possible to set all device files to mono only mode by setting
+envy24_skipdevs=1 and envy24_force_mono=1. However this mode disables stereo
+and multi channel usage for all devices so in general it should not be used.
+
+By default the driver will create output devices before the input ones. By
+setting envy24_swapdevs=1 in oss_envy24.conf you can ask OSS to create the device
+files in opposite order i.e. input device files before the output ones. This
+may be useful when using RealProducer.
+
+As a workaround to a bug in RealProducer you also need to create some dummy
+mixer devices by defining envy24_realencoder_hack=1 in oss_envy24.conf. Without
+these extra mixer devices RealProducer will not be able to access other than
+the first input device.
+
+
+ DEVICE MANAGEMENT
+
+By default OSS creates a large number of device files for each envy24 card.
+This may be a problem when multiple cards need to be used in the same system.
+Adding the envy24_devmask option to oss_envy24.conf should help
+in most cases because it removes the devices that are actually not needed in
+the system.
+
+The envy24_devmask number is the SUM of the following values:
+
+ 1: Create primary (analog/ADAT/TDIF) outputs.
+ 2: Create primary (analog/ADAT/TDIF) inputs.
+ 4: Create S/PDIF outputs.
+ 8: Create S/PDIF inputs.
+ 16: Create monitor input device.
+ 32: Create the raw input and output devices.
+
+For example envy24_devmask=12 (4+8) creates only the S/PDIF devices.
+To enable all possible (current or future) device files set envy24_devmask
+to 65535 (default).
+
+If possible make your application to open the right device file
+(/dev/dsp0 to /dev/dsp10) explicitly. It's also possible to use the
+default devicefile (/dev/dsp) since OSS now supports automatic device
+allocation (it opens the first available input or output devicefile
+depending on the open mode).
+
+The channel allocation mechanism between device files is very flexible.
+Even there is a device file for every stereo pair (or a mono channel)
+it's possible to use any of the device file to access multiple channels.
+For example an application can open /dev/dsp0 and set the number of
+channels to 10. In this way the application can play all 10 channels
+(or any number between 1 and 10) simultaneously (the samples will be
+interleaved).
+
+There is simple automatic syncstart feature when using multiple
+applications at the same time. Playback will not start before all
+currently open devices files have started the playback operation.
+The same mechanism works for recording (recording and playback
+operations are fully independent).
+
+The Envy24 driver supports 8, 16 and 24/32 bit sample formats.
+
+
+ SAMPLING RATE
+
+Envy24 based cards are multi channel devices and all the channels share the
+same sampling rate. For this reason the sampling rate is normally locked to the
+value selected using ossmix. However OSS supports some other methods for
+changing the sampling rate. There are four ways to change the sampling rate.
+
+ BASIC METHOD:
+
+Since all input and output channels of Envy24 work at the same sampling rate
+it's not possible for the applications to select the rate themselves. Instead
+the sampling rate is always locked to the currently selected rate. This rate
+selection can be changed using the ossmix program shipped with OSS.
+
+For example:
+
+ ossmix envy24.rate 48000
+
+sets the sampling rate to 48000 Hz (default). The possible alternatives are
+- 8000
+- 9600
+- 11025
+- 12000
+- 16000
+- 22050
+- 24000
+- 32000
+- 44100
+- 48000
+- 88200
+- 96000
+
+When using S/PDIF inputs/outputs only the sampling rates 32000, 44100, 48000, 88200 or 96000 should be used.
+
+ EXTERNAL SYNC
+It's possible to lock the sampling rate to the S/PDIF or world clock inputs
+by setting the envy24.sync setting in ossmix to SPDIF or WCLOCK. However
+the envy24.rate setting should be set manually to match the rate being used
+(there is no autodetection for that).
+
+ NONLOCKED METHOD
+It's also possible to turn the envy24.ratelock setting to OFF using ossmix.
+After that the first application that opens the device can change the sampling
+rate. However great care should be taken that this application gets the
+recording/playback process fully started before any of the other
+applications open their devices. Otherwise all devices will be locked to 8Khz.
+Also keep in mind that subsequent applications will be forced to use the
+sampling rate set by the first one.
+
+ SOFTWARE SRC
+OSS contains a very high quality software based sample rate converter.
+It can be enabled by setting envy24.src to ON using ossmix.
+
+After that OSS can do on-fly sample rate conversions between the actual
+"hardware" sampling rate and the sampling rates used by the applications. In
+this way every application may use different sampling rate. However there are
+some drawbacks in this method:
+
+o The hardware rate needs to be 44100, 48000 or 96000 Hz.
+o The software SRC algorithm consumes some CPU time (1% to 20% per audio
+channel depending on the CPU speed and sampling rates). For this reason this
+method may be useless in multi channel use with anything else but the fastest
+high end CPUs.
+o Only mono and stereo (1 or 2 channel) streams are supported.
+o The SRC algorithm does cause minor artifacts to the sound (SNR is around 60 dB).
+
+
+ RAW IO DEVICES
+
+These device files provide an alternative way to access Envy24 based devices.
+With these devices it's possible to bypass the dual buffering required by the
+"normal" input-output device files described above. This means that also the
+mmap() feature is available and that the latencies caused by dual buffering
+are gone. So these device files work much like "ordinary" soundcards. However
+due to multi channel professional nature of the Envy24 chip there are some very
+fundamental differences. This means that these device files can only be used
+with applications that are aware of them.
+
+The differences from normal audio device files are:
+
+1. The sample format will always be 32 bit msb aligned (AFMT_S32_LE). Trying to
+use any other sample format will cause unexpected results.
+2. Number of channels is fixed and cannot be changed. The output device has
+always 10 channels (0 to 7 are analog outputs and 8 to 9 are the digital
+outputs). This assignment will be used even with cards that don't support
+digital (or analog) outputs at all. If the actual hardware being used has
+less channels the unused ones will be discarded (however they will be fed to
+the on board monitor mixer).
+
+The input device is fixed to 12 channels. Channels 0 to 7 are analog inputs.
+Channels 8 to 9 are digital inputs. Channels 10 and 11 are for the result
+signal from the on board monitor mixer.
+
+
+ DIGITAL MONITOR MIXER
+
+All Envy24 based cards have a built in monitor mixer. It can be used to mix
+allinput and output signals together. The result can be recorded from the
+"input from mon mixer" device (device 10 in the /dev/sndstat example above).
+The monitor mix signal can also be routed to any of the outputs (including
+S/PDIF and the "consumer" AC97 output of Terratec EWS88MT/D and any other card
+that support s it).
+
+The settings in the gain.* group of ossmix are used to change the levels of all
+inputs and outputs in the digital monitor mixer. The possible values are
+between 0 (minimum) and 144 (maximum).
+
+OSS permits using all 10 possible output channels of the monitor mixer even
+with cards that have less physical outputs. These "virtual" outputs are only
+sent to the monitor mixer and their signal is only present in the monitor mixer
+output. To enable these "virtual" channels set the envy24_virtualout parameter
+to 1 in oss_envy24.conf. This option has no effect with Delta1010, EWS88MT and
+other cards that have 10 "real" outputs.
+
+
+ SYNC SOURCE
+
+On cards with S/PDIF and/or World Clock inputs it's possible to select the
+sync source using
+
+ ossmix envy24.sync
+
+The possible choices are:
+
+o INTERNAL: Use the internal sampling rate as defined by envy24.rate
+o SPDIF: Use the S/PDIF input as the clock source. The envy24.rate setting
+must be set manually to match the actual input sampling rate.
+o WCLOCK: Like SPDIF but uses the world clock input signal (Delta 1010 only).
+
+
+ OUTPUT ROUTINGS
+
+Output routing of output ports can be changed by changing the route.* settings
+using ossmix. The possible choices are:
+
+o DMA: Playback from the associated /dev/dsp# device.
+o MONITOR: Output of the digital mixer (only out1/2 and S/PDIF).
+o IN1/2 to IN9/10 or IN1 to IN10: Loopback from the analog inputs
+o SPDIFL or SPDIFR or SPDIF: Loopback from the S/PDIF input.
+
+
+ PEAK METERS
+
+Envy24 based cards have peak meters for the input and output ports of the
+digital monitor mixer. ossmix can show these values under the peak.* group
+(these settings are read only). The values are between 0 (minimum) and 255
+(maximum). At this moment the only applications that supports these peak meters
+are ossmix and ossxmix.
+
+
+ AUDIO LATENCY
+
+IDE disk and CD-ROM drives may cause some interrupt latency problems which
+may cause dropouts in recording/playback with Envy24 based cards. For this
+reason ensure that DMA is turned on for the disk drive.
+
+Another method to solve the dropout problems is making the fragment size used
+by the driver longer. This can be done by adding envy24_nfrags=N to the
+oss_envy24.conf file. By default N is 16. Values 2, 4 or 8 make the fragments
+longer which should cure the dropout problems. However this may cause
+latency problems with some applications. Values 32 and 64 decrease the
+latencies but may cause dropouts with IDE.
+
+
+OPTIONS
+
+o envy24_skipdevs: It's also possible to make OSS to create individual device
+files for every channel. This creates twice as many device files than the
+default setting.
+Values: 1, 0 Default: 0
+
+o envy24_swapdevs: By default the driver will create output devices before the
+input ones. You can force the input devices to be configured before output
+devices.
+Values: 1, 0 Default: 0
+
+o envy24_realencoder_hack: RealProducer wants to see a mixer device in
+/dev/mixer. This option allows you to define a dummy /dev/mixer mixer device.
+Envy24 Mixer device doesn't provide any consumer level soundcard compatibility
+so this dummy mixer fools RealProducer into thinking it's running on a consumer
+soundcard like SB Pro or SBLive.
+Values: 1, 0 Default: 0
+
+o envy24_gain_sliders: With some devices it's possible to change the gain
+controllers to be continuous sliders instead of just enumerated ones.
+Values: 1, 0 Default: 0
+
+o envy24_nfrags: To solve the dropout problems make the fragment size used by
+the driver longer. By default is 16. Values 2, 4 or 8 make the fragments longer
+which should cure the dropout problems. However this may cause latency problems
+with some applications. Values 32 and 64 decrease the latencies but may cause
+dropouts with IDE drives.
+Values: 2-64 Default: 16
+
+o envy24_virtualout: OSS permits using all 10 possible output channels of the
+monitor mixer even with cards that have less physical outputs. These "virtual"
+outputs are only sent to the monitor mixer and their signal is only present in
+the monitor mixer output. This has no effect for Delta1010 or Terratec EWS88MT.
+Values: 1, 0 Default: 0
+
+o envy24_force_mono: It is possible to set all device files to mono only mode
+by setting envy24_skipdevs=1 and envy24_force_mono=1. However this mode
+disables stereo and multi channel usage for all devices so in general it should
+not be used.
+Values: 1, 0 Default: 0
+
+FILES
+CONFIGFILEPATH/oss_envy24.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_envy24ht/.changelog b/kernel/drv/oss_envy24ht/.changelog
new file mode 100644
index 0000000..972605e
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/.changelog
@@ -0,0 +1 @@
+800802xx by Artem Antonov: Added support for ESI Juli@
diff --git a/kernel/drv/oss_envy24ht/.devices b/kernel/drv/oss_envy24ht/.devices
new file mode 100644
index 0000000..b90025d
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/.devices
@@ -0,0 +1,12 @@
+oss_envy24ht pci1412,1724 Generic ENVY24HT based sound card
+oss_envy24ht pcs1412,3630 M Audio Revolution 7.1
+oss_envy24ht pcs1412,3631 M Audio Revolution 5.1
+oss_envy24ht pcs1412,6321 M Audio Audiophile 192
+oss_envy24ht pcs153b,1145 Terratec Aureon 7.1 Space
+oss_envy24ht pcs153b,1147 Terratec Aureon 7.1 Sky
+oss_envy24ht pcs153b,1149 Terratec PHASE 28
+oss_envy24ht pcs153b,1153 Terratec Aureon 7.1 Universe
+oss_envy24ht pcs3031,4553 Ego Systems Juli@ *BETA*
+oss_envy24ht pcs4933,4553 Audiotrak Prodigy 7.1
+oss_envy24ht pcs3137,4154 Audiotrak Prodigy HD2
+oss_envy24ht pcs1412,2401 Audiotrak Prodigy HD2 Advance DE
diff --git a/kernel/drv/oss_envy24ht/.name b/kernel/drv/oss_envy24ht/.name
new file mode 100644
index 0000000..77fd7c1
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/.name
@@ -0,0 +1 @@
+VIA Envy24HT/PT (ICE1724) sound chipset
diff --git a/kernel/drv/oss_envy24ht/.params b/kernel/drv/oss_envy24ht/.params
new file mode 100644
index 0000000..4e6831b
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/.params
@@ -0,0 +1,5 @@
+int envy24ht_model = -1;
+/*
+ * Select the Model number if the card isn't autodetected
+ * Values: 0 = Envy24ht 1=Envy24PT/HT-s compatible -1=Autodetect Default: -1
+ */
diff --git a/kernel/drv/oss_envy24ht/envy24ht.h b/kernel/drv/oss_envy24ht/envy24ht.h
new file mode 100644
index 0000000..f11029b
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/envy24ht.h
@@ -0,0 +1,230 @@
+/*
+ * Purpose: Common definitions for envy24ht driver files
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "ac97.h"
+#include "midi_core.h"
+
+/*
+ * Various subvendor device ID's
+ */
+#define SSID_AUREON_SPACE 0x1145153b
+#define SSID_AUREON_SKY 0x1147153b
+#define SSID_AUREON_UNIVERSE 0x1153153b
+#define SSID_PHASE28 0x1149153b
+#define SSID_PRODIGY71 0x45534933
+#define SSID_PRODIGYHD2 0x41543137
+#define SSID_PRODIGYHD2_ADE 0x24011412
+#define SSID_JULIA 0x45533031
+#define SSID_AP192 0x36321412
+
+typedef struct
+{
+ unsigned int dwSubVendorID; /* PCI[2C-2F], in BIG ENDIAN format */
+ unsigned char bSize; /* size of EEPROM image in bytes */
+ unsigned char bVersion; /* version equal 1 for this structure. */
+ unsigned char bCodecConfig; /* PCI[60] */
+ unsigned char bACLinkConfig; /* PCI[61] */
+ unsigned char bI2SID; /* PCI[62] */
+ unsigned char bSpdifConfig; /* PCI[63] */
+ unsigned char bGPIOInitMask0; /* Corresponding bits need to be inited */
+ /* 0 means write bit and 1 means cannot write */
+ unsigned char bGPIOInitState0; /* Initial state of GPIO pins */
+ unsigned char bGPIODirection0; /* GPIO Direction State */
+ unsigned char bGPIOInitMask1;
+ unsigned char bGPIOInitState1;
+ unsigned char bGPIODirection1;
+ unsigned char bGPIOInitMask2;
+ unsigned char bGPIOInitState2;
+ unsigned char bGPIODirection2;
+ unsigned char bAC97RecSrc;
+ unsigned char bDACID[4]; /* I2S IDs for DACs [0 ~ 3] */
+ unsigned char bADCID[4]; /* I2S IDs for ADCs [0 ~ 3] */
+ unsigned char bDACID4; /* I2S ID for DAC#4 */
+ unsigned char Reserved[32];
+} eeprom_data_t;
+
+typedef struct envy24ht_auxdrv envy24ht_auxdrv_t;
+
+typedef struct
+{
+ unsigned int svid;
+ char *product;
+ int nr_outs, nr_ins; /* # of analog channels */
+ int flags;
+#define MF_MIDI 0x00000001 /* Has MIDI port */
+#define MF_192K 0x00000002 /* Supports 192kHz */
+#define MF_SPDIFIN 0x00000004 /* Has S/PDIF input */
+#define MF_SPDIFOUT 0x00000008 /* Has S/PDIF output */
+#define MF_ENVY24PT 0x00000010 /* Envy24PT chip (no EEPROM) */
+#define MF_NOAC97 0x00000020 /* Ignore AC97 codec */
+ const envy24ht_auxdrv_t *auxdrv;
+ unsigned char *eeprom_data;
+}
+card_spec;
+
+#define ICENSEMBLE_VENDOR_ID 0x1412
+#define ICENSEMBLE_ENVY24HT_ID 0x1724
+#define MAX_ENVY24HT_CARD 8
+
+#ifdef USE_LICENSING
+extern int options_data;
+#endif
+
+#define MAX_ODEV 5
+#define MAX_IDEV 2
+
+typedef struct
+{
+ int dev;
+ int open_mode;
+ int direction;
+ int fmt;
+ char *name;
+
+ int channels;
+ volatile int is_active;
+ volatile int trigger_bits;
+ oss_native_word base;
+ unsigned char mask;
+ int dev_flags;
+#define DF_MULTICH 0x00000001
+#define DF_SPDIF 0x00000002
+#define DF_AC3 0x00000004
+#define DF_DUPLEX 0x00000008
+ int chmask;
+ int used_chmask;
+
+ int state_bits;
+}
+envy24ht_portc;
+
+typedef struct
+{
+ int dta, clk;
+} oss_i2c_t;
+
+/*****************/
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+ const envy24ht_auxdrv_t *auxdrv;
+ int codec_type;
+#define CODEC_I2S 0
+#define CODEC_AC97 1
+ int mpu1_attached, mpu2_attached;
+ oss_native_word ccs_base, mt_base;
+ int irq;
+ card_spec *model_data;
+ unsigned int subvendor;
+ eeprom_data_t eeprom;
+ char channel_names[4][10];
+ unsigned short gpio_shadow_L;
+ unsigned char gpio_shadow_H;
+
+ oss_i2c_t i2c;
+/*
+ * MT mixer
+ */
+
+ int mixer_dev;
+ ac97_devc ac97devc;
+
+ int nr_outdevs, nr_indevs;
+ envy24ht_portc play_portc[MAX_ODEV];
+ envy24ht_portc rec_portc[MAX_IDEV];
+
+ int outportmask, inportmask;
+ int nr_play_channels, nr_rec_channels;
+ int first_dev;
+
+ int open_count;
+ int speed, pending_speed, pending_speed_sel, speedbits, configured_rate_sel;
+ int prev_speed; /* Strictly for use by low level modules */
+ int max_ratesel;
+ int syncsource;
+
+ int use_src;
+ int ratelock;
+ int external_sync;
+ int busy_play_channels;
+ int busy_rec_channels;
+
+ spdif_devc spdc;
+ int gains[6];
+ int monitor[5];
+ int recsrc;
+
+/*
+ * MIDI
+ */
+ int midi_opened;
+ int midi_attached;
+ oss_midi_inputbyte_t midi_input_intr;
+ oss_midi_outputintr_t midi_output_intr;
+ volatile unsigned char input_byte;
+ int midi_dev;
+
+/*
+ * Low level stuff
+ */
+ unsigned char dac1val[5], dac2val[11]; /* M Audio Revo 7.1 */
+ unsigned short m_AC97Volume[6]; /* Terratec Aureon */
+ unsigned char m_fAC97Mute[6]; /* Terratec Aureon */
+ int m_DigInSource; /* Aureon */
+ int m_LineInSource; /* Aureon */
+ int m_SPDIFSource; /* Aureon */
+ int m_ADCIndex; /* Aureon */
+ int m_f1724SPDIF; /* Aureon */
+ int m_SPDIFConfig; /* Aureon */
+ int m_Frontjack; /* Aureon */
+ unsigned char m_fDACMute[12]; /* Aureon */
+ unsigned char m_DACVolume[13]; /* Aureon & Juli@ */
+ unsigned short m_ADCVolume[8]; /* Aureon */
+ unsigned char m_ADCMux; /* Aureon */
+ unsigned char m_fSPDIFRecord; /* Aureon */
+ unsigned char m_AuxMux; /* Aureon */
+ unsigned int m_ClockSource; /* Aureon */
+ unsigned int m_Out0Source; /* Aureon */
+
+ int mute;
+ int reclevel;
+ timeout_id_t timeout_id; /* Juli@ */
+
+ unsigned char syncstart_mask;
+}
+envy24ht_devc;
+
+struct envy24ht_auxdrv
+{
+ void (*card_init) (envy24ht_devc * devc);
+ int (*mixer_init) (envy24ht_devc * devc, int dev, int group);
+ void (*set_rate) (envy24ht_devc * devc);
+ int (*get_locked_status) (envy24ht_devc * devc);
+ int (*spdif_mixer_init) (envy24ht_devc * devc, int dev, int group);
+ int (*private1) (envy24ht_devc * devc, int value);
+ int (*audio_ioctl) (envy24ht_devc * devc, envy24ht_portc * portc, unsigned int cmd,
+ ioctl_arg arg);
+ void (*card_uninit) (envy24ht_devc * devc);
+};
+
+struct speed_sel
+{
+ int speed, speedbits;
+};
+
+void envy24ht_write_cci (envy24ht_devc * devc, int pos, int data);
+int envy24ht_read_cci (envy24ht_devc * devc, int pos);
diff --git a/kernel/drv/oss_envy24ht/envy24ht_ac97.c b/kernel/drv/oss_envy24ht/envy24ht_ac97.c
new file mode 100644
index 0000000..46d2382
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/envy24ht_ac97.c
@@ -0,0 +1,137 @@
+/*
+ * Purpose: Low level routines for AC97 based Envy24HT boards (mainly Envy24-PT).
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_envy24ht_cfg.h"
+
+#include "spdif.h"
+#include "envy24ht.h"
+
+#define AKM_ADDRESS 0x10
+#if 0
+# define PRT_STATUS(v) outb(v&0xff, 0x378)
+#else
+# define PRT_STATUS(v)
+#endif
+
+#if 0
+static unsigned char
+i2c_read (envy24ht_devc * devc, unsigned char addr, unsigned char pos)
+{
+ int i;
+ unsigned char data;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x11); /* Offset */
+ OUTB (devc->osdev, addr << 1, devc->ccs_base + 0x10); /* Read address */
+
+ for (i = 0; i < 2000; i++)
+ {
+ unsigned char status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+
+ oss_udelay (1);
+ data = INB (devc->osdev, devc->ccs_base + 0x12);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return data;
+}
+
+static void
+i2c_write (envy24ht_devc * devc, unsigned char addr, unsigned char pos,
+ unsigned char data)
+{
+ int i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x11); /* Offset */
+ OUTB (devc->osdev, data, devc->ccs_base + 0x12); /* Data */
+ OUTB (devc->osdev, (addr << 1) | 1, devc->ccs_base + 0x10); /* Write address */
+
+ for (i = 0; i < 2000; i++)
+ {
+ unsigned char status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+#endif
+
+/*ARGSUSED*/
+static void
+init_cs8415a (envy24ht_devc * devc)
+{
+}
+
+/*ARGSUSED*/
+static void
+init_wm8728 (envy24ht_devc * devc)
+{
+
+#if 0
+ printk ("Regs=");
+ for (i = 0; i < 0x18; i++)
+ {
+ PRT_STATUS (2);
+ printk ("%02x ", i2c_read (devc, addr, i));
+ PRT_STATUS (0);
+ }
+ printk ("\n");
+#endif
+}
+
+static void
+ac97_card_init (envy24ht_devc * devc)
+{
+
+ PRT_STATUS (0);
+ PRT_STATUS (0x01);
+ PRT_STATUS (0);
+
+ OUTW (devc->osdev, 0x000f, devc->ccs_base + 0x14); /* GPIO */
+
+ oss_udelay (1000);
+
+ devc->recsrc = 0;
+ init_cs8415a (devc);
+ init_wm8728 (devc);
+}
+
+/*ARGSUSED*/
+static int
+ac97_mixer_init (envy24ht_devc * devc, int dev, int group)
+{
+ return 0;
+}
+
+#if 0
+static int
+ac97_private1 (envy24ht_devc * devc, int value)
+{
+ i2c_write (devc, AKM_ADDRESS, (value >> 8) & 0xff, value & 0xff);
+ return 0;
+}
+#endif
+
+envy24ht_auxdrv_t envy24ht_ac97_auxdrv = {
+ ac97_card_init,
+ ac97_mixer_init
+};
diff --git a/kernel/drv/oss_envy24ht/envy24ht_ap192.c b/kernel/drv/oss_envy24ht/envy24ht_ap192.c
new file mode 100644
index 0000000..9929c27
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/envy24ht_ap192.c
@@ -0,0 +1,617 @@
+/*
+ * Purpose: Low level routines for M Audio Audiophile 192
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_envy24ht_cfg.h"
+
+#include "spdif.h"
+#include "envy24ht.h"
+
+static char channel_names[4][10] = {
+ "main",
+ "unused1",
+ "unused2",
+ "unused3"
+};
+
+#define BIT(x) (1<<(x))
+#define BIT3 BIT(3)
+
+/*----- SPI bus for CODEC communication. */
+/* */
+#define SPI_CLK 1 /* Clock output to CODEC's, rising edge clocks data. */
+#define SPI_DIN 2 /* Data input from the CODEC. */
+#define SPI_DOUT 3 /* Data output to the CODEC. */
+#define SPI_CS0n (1<<4) /* Selects first chip. */
+#define SPI_CS1n (1<<5) /* Selects second chip. */
+
+#define SPI_CC_AK4358 0x02 /* C1:C0 for ak4358. */
+#define SPI_CC_AK4114 0x02 /* C1:C0 for ak4114. */
+#define WRITEMASK 0xffff
+/*----- Revolution defines. */
+/* */
+#define ap192_AK4114 (1) /* iDevice value for AK4114 DIR. */
+#define ap192_AK4358 (2) /* iDevice value for AK4358 D/A. */
+
+static unsigned int
+GpioReadAll (envy24ht_devc * devc)
+{
+ return INW (devc->osdev, devc->ccs_base + 0x14);
+}
+
+static void
+GPIOWriteAll (envy24ht_devc * devc, unsigned int data)
+{
+ OUTW (devc->osdev, 0xffff, devc->ccs_base + 0x18); /* GPIO direction */
+ OUTW (devc->osdev, 0x0000, devc->ccs_base + 0x16); /* GPIO write mask */
+
+ OUTW (devc->osdev, data, devc->ccs_base + 0x14);
+}
+
+static void
+GPIOWrite (envy24ht_devc * devc, int pos, int bit)
+{
+ int data = GpioReadAll (devc);
+
+ bit = (bit != 0);
+
+ data &= ~(1 << pos);
+ data |= (bit << pos);
+
+ GPIOWriteAll (devc, data);
+}
+
+void
+ap192_Assert_CS (envy24ht_devc * devc, int iDevice)
+/*
+*****************************************************************************
+* Assert chip select to specified GPIO-connected device.
+* iDevice: ap192_AK4114=DIG, ap192_AK4358=DAC.
+****************************************************************************/
+{
+ unsigned int dwGPIO; /* Current GPIO's. */
+ dwGPIO = GpioReadAll (devc); /* Read current GPIO's. */
+ dwGPIO |= (SPI_CS0n | SPI_CS1n); /* Reset CS bits. */
+ switch (iDevice) /* Select CS#. */
+ {
+ case ap192_AK4358:
+ dwGPIO &= ~SPI_CS0n;
+ break; /* DAC */
+ case ap192_AK4114:
+ dwGPIO &= ~SPI_CS1n;
+ break; /* DIG */
+ default:
+ break;
+ }
+ GPIOWriteAll (devc, dwGPIO); /* Write hardware. */
+}
+
+void
+ap192_DeAssert_CS (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* De-Assert all chip selects.
+****************************************************************************/
+{
+ unsigned int dwGPIO = GpioReadAll (devc); /* Current GPIO's. */
+ dwGPIO |= (SPI_CS0n | SPI_CS1n); /* Clear CS bits. */
+ GPIOWriteAll (devc, dwGPIO); /* Write back to hardware. */
+}
+
+/*#define _delay() oss_udelay(1) */
+#define _delay() {}
+
+void
+ap192_WriteSpiAddr (envy24ht_devc * devc, int iDevice, unsigned char bReg)
+/*
+*****************************************************************************
+* Write the address byte part of the SPI serial stream.
+* iDevice: ap192_AK4358=DAC, ap192_AK4114=DIG, etc.
+****************************************************************************/
+{
+ unsigned char bHdr;
+ unsigned char bNum;
+/* Built 8-bit packet header: C1,C0,R/W,A4,A3,A2,A1,A0. */
+/* */
+ switch (iDevice)
+ {
+ case ap192_AK4358:
+ bHdr = SPI_CC_AK4358 << 6;
+ break;
+ case ap192_AK4114:
+ bHdr = SPI_CC_AK4114 << 6;
+ break;
+ default:
+ bHdr = 0;
+ break;
+ }
+ bHdr = bHdr | 0x20 | (bReg & 0x1F); /* "write" + address. */
+/* Write header to SPI. */
+/* */
+ for (bNum = 0; bNum < 8; bNum++)
+ {
+ GPIOWrite (devc, SPI_CLK, 0); /* Drop clock low. */
+ _delay ();
+ GPIOWrite (devc, SPI_DOUT, 0x080 & bHdr); /* Write data bit. */
+ _delay ();
+ GPIOWrite (devc, SPI_CLK, 1); /* Raise clock. */
+ _delay ();
+ bHdr <<= 1; /* Next bit. */
+ }
+}
+
+void
+ap192_WriteSpiReg (envy24ht_devc * devc, int iDevice, unsigned char bReg,
+ unsigned char bData)
+/*
+*****************************************************************************
+* Writes one register in specified CHIP.
+* devc = PCI slot code of specific board.
+* iDevice: ap192_AK4358=DAC, ap192_AK4114=DIG, etc.
+****************************************************************************/
+{
+ unsigned char bNum;
+ GPIOWrite (devc, SPI_DOUT, 0); /* Init SPI signals. */
+ GPIOWrite (devc, SPI_CLK, 1); /* */
+/* Drop the chip select low. */
+/* Wait at least 150 nS. */
+/* */
+ ap192_Assert_CS (devc, iDevice);
+ _delay ();
+/* Write the address byte. */
+/* */
+ ap192_WriteSpiAddr (devc, iDevice, bReg);
+/* Write the data byte. */
+/* */
+ for (bNum = 0; bNum < 8; bNum++)
+ {
+ GPIOWrite (devc, SPI_CLK, 0); /* Drop clock low. */
+ _delay ();
+ GPIOWrite (devc, SPI_DOUT, 0x080 & bData); /* Write data bit. */
+ _delay ();
+ GPIOWrite (devc, SPI_CLK, 1); /* Raise clock. */
+ _delay ();
+ bData <<= 1; /* Next bit. */
+ }
+/* De-assert chip selects. */
+/* */
+ ap192_DeAssert_CS (devc);
+ _delay ();
+}
+
+
+#define GPIO_MUTEn 22 /* Converter mute signal. */
+void
+ap192_Mute (envy24ht_devc * devc, int bMute)
+/*
+*****************************************************************************
+* Mutes all outputs if bMute=TRUE.
+****************************************************************************/
+{
+ if (bMute)
+ {
+/* Soft-mute. Delay currently unspecified, try ½ second. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 1, 0x03);
+ _delay ();
+/* Switch mute transistors on. */
+ GPIOWrite (devc, GPIO_MUTEn, 0);
+ }
+ else
+ {
+/* Switch mute transistors off. Delay currently unspecified, try ½ second. */
+ GPIOWrite (devc, GPIO_MUTEn, 1);
+ _delay ();
+/* Release Soft-mute. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 1, 0x01);
+ }
+
+ devc->mute = bMute;
+}
+
+
+void
+ap192_Set_OutAttn (envy24ht_devc * devc, unsigned char bChan, int iAttn)
+/*
+*****************************************************************************
+* Sets the attenuation on one output channel.
+* bChan = Channel number (0..7).
+* Channel 0:1 = front, 2:3 = center/sub, 4:5 = rear, 6:7 = headphones.
+* Registers are 0x04, 05, 06, 07, 08, 09, 0B, 0C respectively
+* iAttn = Number of steps to attenuate CODEC.
+* Each step equals .5dB (-127..0)
+****************************************************************************/
+{
+ unsigned char bIndex;
+ unsigned char bAttn;
+ if (bChan > 7 || iAttn > 0 || iAttn < -127) /* parameter test */
+ {
+ cmn_err (CE_CONT, "Dnvalid data! %d=bChan, %d=iAttn", bChan, iAttn);
+ return;
+ }
+ if (bChan < 6)
+ bIndex = 0x04 + bChan; /* for registers 0x04..0x09 */
+ else
+ bIndex = 0x05 + bChan; /* for registers 0x0B..0x0C */
+ bAttn = (0x80 + (unsigned char) (iAttn + 127)); /* 7F is max volume. */
+/* MSB enables attenuation. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, bIndex, bAttn);
+}
+
+static void
+ap192_Set_48K_Mode (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* Sets Chip and Envy24 for 8kHz-48kHz sample rates.
+****************************************************************************/
+{
+/* ICE MCLK = 256x. */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 2) & ~BIT3,
+ devc->mt_base + 2);
+/* DFS=normal, RESET. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 2, 0x4E);
+/* DFS=normal, NORMAL OPERATION. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 2, 0x4F);
+
+ /* Set ADC modes */
+ GPIOWrite (devc, 8, 0); /* CKS0 = 0. MCLK = 256x */
+ GPIOWrite (devc, 9, 0); /* DFS0 = 0. */
+ GPIOWrite (devc, 10, 0); /* DFS1 = 0. Single speed mode. */
+
+ /* Reset ADC timing */
+ GPIOWrite (devc, 11, 0);
+ _delay ();
+ GPIOWrite (devc, 11, 1);
+}
+
+static void
+ap192_Set_96K_Mode (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* Sets CODEC and Envy24 for 60kHz-96kHz sample rates.
+****************************************************************************/
+{
+/* ICE MCLK = 256x. */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 2) & ~BIT3,
+ devc->mt_base + 2);
+/* DFS=double-speed, RESET. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 2, 0x5E);
+/* DFS=double-speed, NORMAL OPERATION. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 2, 0x5F);
+
+ /* Set ADC modes */
+ GPIOWrite (devc, 8, 0); /* CKS0 = 0. MCLK = 256x */
+ GPIOWrite (devc, 9, 1); /* DFS0 = 0. */
+ GPIOWrite (devc, 10, 0); /* DFS1 = 0. Single speed mode. */
+
+ /* Reset ADC timing */
+ GPIOWrite (devc, 11, 0);
+ _delay ();
+ GPIOWrite (devc, 11, 1);
+}
+
+static void
+ap192_Set_192K_Mode (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* Sets CODEC and Envy24 for 120kHz-192kHz sample rate.
+****************************************************************************/
+{
+/* ICE MCLK = 128x. */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 2) | BIT3,
+ devc->mt_base + 2);
+ _delay ();
+/*----- SET THE D/A. */
+/* DFS=quad-speed, RESET. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 2, 0x6E);
+ _delay ();
+/* DFS=quad-speed, NORMAL OPERATION. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 2, 0x6F);
+
+ /* SPDIF */
+ ap192_WriteSpiReg (devc, ap192_AK4114, 0x00, 0x0d);
+ ap192_WriteSpiReg (devc, ap192_AK4114, 0x00, 0x0f);
+
+ /* Set ADC modes */
+ GPIOWrite (devc, 8, 1); /* CKS0 = 0. MCLK = 256x */
+ GPIOWrite (devc, 9, 0); /* DFS0 = 0. */
+ GPIOWrite (devc, 10, 1); /* DFS1 = 0. Single speed mode. */
+
+ /* Reset ADC timing */
+ GPIOWrite (devc, 11, 0);
+ _delay ();
+ GPIOWrite (devc, 11, 1);
+}
+
+static int
+set_dac (envy24ht_devc * devc, int reg, int level)
+{
+ if (level < 0)
+ level = 0;
+ if (level > 0x7f)
+ level = 0x7f;
+
+ ap192_WriteSpiReg (devc, ap192_AK4358, reg, level | 0x80);
+
+ return level;
+}
+
+static void
+AK4358_Init (envy24ht_devc * devc)
+{
+/*===== AK4358 D/A initialization. Leave soft-muted. */
+/* */
+/* Power down, reset, normal mode. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 2, 0x00);
+/* Power up, reset, normal mode */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 2, 0x4E);
+/* Reset timing, Mode 3(I2S), disable auto clock detect, sharp roll off. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 0, 0x06);
+/* Soft mute, reset timing. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 1, 0x02);
+/* De-emphasis off. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 3, 0x01);
+/* Max volume on all 8 channels. */
+ set_dac (devc, 0x04, 0x7f);
+ set_dac (devc, 0x05, 0x7f);
+ set_dac (devc, 0x06, 0x7f);
+ set_dac (devc, 0x07, 0x7f);
+ set_dac (devc, 0x08, 0x7f);
+ set_dac (devc, 0x09, 0x7f);
+ set_dac (devc, 0x0b, 0x7f);
+ set_dac (devc, 0x0c, 0x7f);
+
+/* Datt mode 0, DZF non-invert, DCLK polarity 0, PCM mode, DCKS 512fs, TDM normal. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 0xA, 0x00);
+/* DZF control disabled. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 0xD, 0x00);
+ ap192_WriteSpiReg (devc, ap192_AK4358, 0xE, 0x00);
+ ap192_WriteSpiReg (devc, ap192_AK4358, 0xF, 0x00);
+/* Power up, normal operation. */
+ ap192_WriteSpiReg (devc, ap192_AK4358, 2, 0x4F);
+}
+
+static void
+ap192_set_rate (envy24ht_devc * devc)
+{
+ int tmp;
+
+ tmp = INB (devc->osdev, devc->mt_base + 0x02);
+ if (devc->speed <= 48000)
+ {
+ ap192_Set_48K_Mode (devc);
+ OUTB (devc->osdev, tmp & ~BIT (3), devc->mt_base + 0x02);
+ return;
+ }
+
+ if (devc->speed <= 96000)
+ {
+ ap192_Set_96K_Mode (devc);
+
+ return;
+ }
+
+ ap192_Set_192K_Mode (devc);
+ OUTB (devc->osdev, tmp | BIT (3), devc->mt_base + 0x02);
+}
+
+static int
+ap192_audio_ioctl (envy24ht_devc * devc, envy24ht_portc * portc, unsigned int cmd,
+ ioctl_arg arg)
+{
+ int left, right, value;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_GETPLAYVOL:
+ if (portc != &devc->play_portc[0])
+ return OSS_EINVAL;
+ left = (devc->gains[0] & 0xff) * 100 / 0x7f;
+ right = ((devc->gains[0] >> 8) & 0xff) * 100 / 0x7f;
+ return *arg = (left | (right << 8));
+ break;
+
+ case SNDCTL_DSP_SETPLAYVOL:
+ if (portc != &devc->play_portc[0])
+ return OSS_EINVAL;
+ value = *arg;
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ left = (left * 0x7f) / 100;
+ right = (right * 0x7f) / 100;
+ left = set_dac (devc, 0x04, left);
+ right = set_dac (devc, 0x05, right);
+ devc->gains[0] = left | (right << 8);
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+ return 0;
+ break;
+ }
+ return OSS_EINVAL;
+}
+
+static int
+ap192_set_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ switch (ctrl)
+ {
+ case 0:
+ return devc->mute;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ switch (ctrl)
+ {
+ case 0:
+ value = !!value;
+ ap192_Mute (devc, value);
+ return devc->mute;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+ap192_set_ak4358 (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (ctrl < 0 || ctrl > 4)
+ return OSS_EIO;
+
+ return devc->gains[ctrl];
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ int left, right;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ switch (ctrl)
+ {
+ case 0: /* PCM */
+ left = set_dac (devc, 0x04, left);
+ right = set_dac (devc, 0x05, right);
+ break;
+
+ case 1: /* Line IN */
+ /* Line IN monitor permits panning but we don't support it */
+ left = set_dac (devc, 0x06, left);
+ set_dac (devc, 0x07, 0);
+ set_dac (devc, 0x08, 0);
+ right = set_dac (devc, 0x09, right);
+ break;
+
+ case 2: /* S/PDIF */
+ left = set_dac (devc, 0x0b, left);
+ left = set_dac (devc, 0x0c, right);
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ value = left | (right << 8);
+ return devc->gains[ctrl] = value;
+ }
+
+ return OSS_EINVAL;
+}
+
+#if 0
+/*ARGSUSED*/
+static int
+set_mongain (envy24ht_devc * devc, int reg, int value)
+{
+ if (value < 0)
+ value = 0;
+ if (value > 79)
+ value = 79;
+
+ return value;
+}
+#endif
+
+/*ARGSUSED*/
+static int
+ap192_mixer_init (envy24ht_devc * devc, int dev, int g)
+{
+ int group = g;
+ int err;
+
+ if ((group = mixer_ext_create_group (dev, g, "VOL")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 0, ap192_set_control,
+ MIXT_ONOFF,
+ "ENVY24_MUTE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 0, ap192_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_PCM", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, ap192_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_IN", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, ap192_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_SPDIF", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+static void
+ap192_card_init (envy24ht_devc * devc)
+{
+
+ int i;
+
+#if 1
+ OUTW (devc->osdev, 0xffff, devc->ccs_base + 0x18); /* GPIO direction */
+ OUTW (devc->osdev, 0x0000, devc->ccs_base + 0x16); /* GPIO write mask */
+ OUTW (devc->osdev, 0xffff, devc->ccs_base + 0x14); /* Initial bit state */
+
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x1a); /* GPIO direction for bits 16:22 */
+ OUTB (devc->osdev, 0x00, devc->ccs_base + 0x1f); /* GPIO mask for bits 16:22 */
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x1e); /* GPIO data for bits 16:22 */
+#endif
+
+ memcpy (devc->channel_names, channel_names, sizeof (channel_names));
+ AK4358_Init (devc);
+ ap192_Set_48K_Mode (devc);
+
+ for (i = 0; i < 5; i++)
+ devc->gains[i] = 0x7f7f;
+
+ ap192_Mute (devc, 0);
+
+ GPIOWrite (devc, 5, 0); /* Select S/PDIF output mux */
+ GPIOWrite (devc, 5, 0); /* Select S/PDIF output mux */
+
+}
+
+envy24ht_auxdrv_t envy24ht_ap192_auxdrv = {
+ ap192_card_init,
+ ap192_mixer_init,
+ ap192_set_rate,
+ NULL,
+ NULL,
+ NULL, /* ap192_private1 */
+ ap192_audio_ioctl
+};
diff --git a/kernel/drv/oss_envy24ht/envy24ht_aureon.c b/kernel/drv/oss_envy24ht/envy24ht_aureon.c
new file mode 100644
index 0000000..98c8d72
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/envy24ht_aureon.c
@@ -0,0 +1,2536 @@
+/*
+ * Purpose: Low level routines for Terrate Aureon 7.1 family
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_envy24ht_cfg.h"
+
+#define IN
+#define OUT
+#define UCHAR unsigned char
+#define PUCHAR UCHAR*
+#define BYTE unsigned char
+#define PBYTE BYTE*
+#define BOOLEAN unsigned char
+#define ULONG unsigned int
+#define PULONG ULONG*
+#define USHORT unsigned short
+#define PUSHORT USHORT*
+
+#define WORD USHORT
+#define PWORD PUSHORT
+
+/*
+ * Default levels
+ */
+#define WM_OUT_DEFAULT 0x7F
+#define WM_OUT_MAX 0x7F
+#define WM_INP_DEFAULT 0x0C /* for 0dB */
+#define AC97_INP_DEFAULT 0x1f1f
+#define AC97_INP_MAX 0x1f
+
+#define REG_CCS 1
+#define REG_MT 2
+
+#define WM_MASTER_MODE_CNTRL 0
+
+/* List of the WKN CCS Control Registers. */
+#define WKN_CONTROL_REG 0x00
+#define WKN_INT_MASK_REG 0x01
+#define WKN_INT_STAT_REG 0x02
+#define WKN_DMA_INT 0x10
+#define WKN_UART_RECV 0x80
+#define WKN_UART_TRAN 0x20
+
+/* #define WKN_INDEX_REG 0x03 */
+
+#define WKN_SYS_CONFIG 0x04
+#define WKN_49MHZ 0x40
+#define WKN_ACLINK_CONFIG 0x05
+#define CODEC_AKM 0x80
+
+#define WKN_I2S_CONFIG 0x06
+#define WKN_SPDIF_CONFIG 0x07
+
+#define SPDIF_ENABLE_MASK 0x00010000
+
+/* #define WKN_AC97_INDEX 0x08 */
+/* #define WKN_AC97_CMDSTAT 0x09 */
+#define WKN_TX_QUE 0x0A
+#define WKN_RX_QUE 0x0B
+
+#define WKN_MIDI_PORT1_DATA_REG 0x0C
+#define WKN_MIDI_PORT1_CMD_REG 0x0D
+#define WKN_NMI_EXTSTAT_REG 0x0E
+
+#define WKN_I2C_DEVADDR 0x10
+#define WKN_I2C_AKM 0x20
+#define WKN_I2C_WRITE 0x01
+#define WKN_I2C_READ 0x00
+#define WKN_I2C_BYTEADDR 0x11
+#define WKN_I2C_DATA 0x12
+#define WKN_I2C_STATUS 0x13
+#define WKN_I2C_BUSY 0x01
+#define WKN_GPIO_DATA0 0x14
+#define WKN_GPIO_DATA1 0x15
+#define WKN_GPIO_DATA2 0x1E
+#define WKN_GPIO_WRT_MASK0 0x16
+#define WKN_GPIO_WRT_MASK1 0x17
+#define WKN_GPIO_WRT_MASK2 0x1F
+#define WKN_GPIO_DIR0 0x18
+#define WKN_GPIO_DIR1 0x19
+#define WKN_GPIO_DIR2 0x1A
+#define WKN_GPIO_DATA16 0x1E
+#define WKN_GPIO_WRT_MASK16 0x1F
+
+#define GPIO_DATA_ADR_MASK 0x000000FF
+#define GPIO_LD_DATA_H_MASK 0x00000100
+#define GPIO_LD_DATA_L_MASK 0x00000200
+#define GPIO_LD_ADR_MASK 0x00000400
+#define GPIO_GO_MASK 0x00000800
+#define GPIO_WM8770_CS_MASK 0x00001000
+#define GPIO_INT_REST_MASK 0x00002000
+#define GPIO_REMOTE_MASK 0x00004000
+#define GPIO_HEADPHONE_MASK 0x00004000
+#define GPIO_DIGITAL_SEL 0x00008000
+#define GPIO_AC97_RESET_MASK 0x00010000
+#define GPIO_SDA_TX_MASK 0x00020000
+#define GPIO_SDA_MASK 0x00040000
+#define GPIO_SCL_MASK 0x00080000
+#define GPIO_WM8770_RS_MASK 0x00100000
+#define GPIO_CS8415_CDTO_MASK 0x00200000
+#define GPIO_CS8415_CS_MASK 0x00400000
+
+#define WM_DAC1_VOL_CNTRL 0x00
+#define WM_DAC2_VOL_CNTRL 0x02
+#define WM_DAC3_VOL_CNTRL 0x04
+#define WM_DAC4_VOL_CNTRL 0x06
+#define WM_MASTER_VOL_CNTRL 0x08
+#define WM_POWER_CNTRL 0x18
+#define WM_ADC_GAIN_CNTRL 0x19
+#define WM_ADC_INPUT_MX 0x1B
+#define WM_OUT12_SELECT 0x1C
+#define WM_OUT34_SELECT 0x1D
+
+#define CS_CONTROL_1 0x01
+#define CS_CONTROL_2 0x02
+#define CS_CLK_SRC_CNTRL 0x04
+#define CS_SER_OUT_FORMAT 0x06
+
+#define MT_SAMPLE_RATE_REG 0x01
+#define MT_48KHZ 0x0
+#define MT_24KHZ 0x01
+#define MT_12KHZ 0x02
+#define MT_9p6KHZ 0x03
+#define MT_32KHZ 0x04
+#define MT_16KHZ 0x05
+#define MT_8KHZ 0x06
+#define MT_96KHZ 0x07
+#define MT_192KHZ 0x0E
+#define MT_64KHZ 0x0F
+#define MT_44p1KHZ 0x08
+#define MT_22p05KHZ 0x09
+#define MT_11p025KHZ 0x0A
+#define MT_88p2KHZ 0x0B
+#define MT_176p4KHZ 0x0C
+
+#define MT_DATA_FORMAT_REG 0x02
+#define MT_128X 0x08
+#define MT_INTR_MASK_REG 0x03
+
+#define SRC_PDMA 0x00
+#define SRC_PSDIN0_L 0x02
+#define SRC_PSDIN0_R 0x03
+#define SRC_SPDIN_L 0x06
+#define SRC_SPDIN_R 0x07
+#define SRC_MASK 0x07
+
+static const UCHAR gWMRegister[] = { WM_DAC1_VOL_CNTRL,
+ WM_DAC1_VOL_CNTRL + 1,
+ WM_DAC2_VOL_CNTRL,
+ WM_DAC2_VOL_CNTRL + 1,
+ WM_DAC3_VOL_CNTRL,
+ WM_DAC3_VOL_CNTRL + 1,
+ WM_DAC4_VOL_CNTRL,
+ WM_DAC4_VOL_CNTRL + 1,
+ WM_MASTER_VOL_CNTRL,
+ WM_MASTER_VOL_CNTRL + 1,
+ WM_ADC_GAIN_CNTRL,
+ WM_ADC_GAIN_CNTRL + 1
+};
+
+#define AC97_IDXREG_RESET 0x00
+#define AC97_IDXREG_STEREO_OUT 0x02
+#define AC97_IDXREG_MONO_OUT 0x06
+#define AC97_IDXREG_PCBEEP 0x0A
+#define AC97_IDXREG_PHONE 0x0C
+#define AC97_IDXREG_MIC_IN 0x0E
+#define AC97_IDXREG_LINE_IN 0x10
+#define AC97_IDXREG_CD_IN 0x12
+#define AC97_IDXREG_VIDEO_IN 0x14
+#define AC97_IDXREG_AUX_IN 0x16
+#define AC97_IDXREG_PCM_OUT 0x18
+#define AC97_IDXREG_RECORD_SELECT 0x1A
+#define AC97_IDXREG_RECORD_GAIN 0x1C
+#define AC97_IDXREG_GEN_PURPOSE 0x20
+#define AC97_IDXREG_POWER_DOWN 0x26
+#define AC97_IDXREG_TEST_CONTROL 0x5A
+#define AC97_IDXREG_VENDOR_RESV 0x7A
+#define AC97_IDXREG_VENDOR_ID1 0x7C
+#define AC97_IDXREG_VENDOR_ID2 0x7E
+/* AC97 register - AC97_IDXREG_RECORD_SELECT */
+#define AC97_REC_SELECT_MIC 0x0000
+#define AC97_REC_SELECT_LINEIN 0x0404
+#define AC97_REC_SELECT_ST_MIX 0x0505
+
+/*
+ * List of the Channel IDs
+ */
+#define CH_MASTER_LEFT ((OUT_MASTER<<16)|CH_LEFT)
+#define CH_MASTER_RIGHT ((OUT_MASTER<<16)|CH_RIGHT)
+#define CH_MASTER_BOTH ((OUT_MASTER<<16)|CH_BOTH)
+
+#define CH_OUT12_LEFT ((OUT_12<<16)|CH_LEFT)
+#define CH_OUT12_RIGHT ((OUT_12<<16)|CH_RIGHT)
+#define CH_OUT12_BOTH ((OUT_12<<16)|CH_BOTH)
+#define CH_OUT34_LEFT ((OUT_34<<16)|CH_LEFT)
+#define CH_OUT34_RIGHT ((OUT_34<<16)|CH_RIGHT)
+#define CH_OUT34_BOTH ((OUT_34<<16)|CH_BOTH)
+#define CH_OUT56_LEFT ((OUT_56<<16)|CH_LEFT)
+#define CH_OUT56_RIGHT ((OUT_56<<16)|CH_RIGHT)
+#define CH_OUT56_BOTH ((OUT_56<<16)|CH_BOTH)
+#define CH_OUT78_LEFT ((OUT_78<<16)|CH_LEFT)
+#define CH_OUT78_RIGHT ((OUT_78<<16)|CH_RIGHT)
+#define CH_OUT78_BOTH ((OUT_78<<16)|CH_BOTH)
+
+#define CH_IN12_LEFT ((IN_12<<16)|CH_LEFT)
+#define CH_IN12_RIGHT ((IN_12<<16)|CH_RIGHT)
+#define CH_IN12_BOTH ((IN_12<<16)|CH_BOTH)
+
+#define CH_FRONT_BOTH CH_OUT12_BOTH
+#define CH_REAR_BOTH CH_OUT34_BOTH
+#define CH_CENTER CH_OUT56_LEFT
+#define CH_LFE CH_OUT56_RIGHT
+#define CH_BS_BOTH CH_OUT78_BOTH
+
+#define MAX_VOLUME 0x7F
+#define MIN_VOLUME 0x00
+
+#define MAX_GAIN 0x1F
+
+#define MT_PLAY_REC_UNDOVR 0x01A
+#define MT_INTR_STATUS_REG 0x00
+#define MT_INTR_MASK_REG 0x03
+#define MT_SPDIF_REG 0x3C
+
+/* List of AC97 inputs */
+#define AC97_CD 0
+#define AC97_AUX 1
+#define AC97_LINE 2
+#define AC97_MIC 3
+#define AC97_PHONO 4
+#define AC97_LINE2 5
+#define AC97_COUNT 6 /* Must match devc->m_AC97Volume definition in envy24ht.h */
+
+/* Channel def */
+#define CH_LEFT 0x00000001
+#define CH_RIGHT 0x00000002
+#define CH_BOTH (CH_LEFT|CH_RIGHT)
+#define CH_NOP 0xFFFFFFFF
+
+/*
+ * List of inputs
+ */
+#define ADC_CD 0
+#define ADC_AUX 1
+#define ADC_LINE 2
+#define ADC_MIC 3
+#define ADC_PHONO 4
+#define ADC_WTL 5
+#define ADC_LINE_REAR 6
+#define ADC_STEREO_MIX 7
+#define ADC_COUNT 8 /* Must match the size of m_ADCVolume */
+
+/*
+ * List of Lines
+ */
+#define LINE_OUT_1L 0x00000000
+#define LINE_OUT_1R 0x00000001
+#define LINE_OUT_2L 0x00000002
+#define LINE_OUT_2R 0x00000003
+#define LINE_OUT_3L 0x00000004
+#define LINE_OUT_3R 0x00000005
+#define LINE_OUT_4L 0x00000006
+#define LINE_OUT_4R 0x00000007
+#define LINE_MASTER 0x00000008
+#define LINE_MASTER_ 0x00000009
+#define LINE_GAIN_L 0x0000000a
+#define LINE_GAIN_R 0x0000000b
+#define LINE_S_NUM 0x0000000c /* 12 - Should match devc->m_fDACMute size */
+
+/*
+ * List of Stereo Lines
+ */
+#define OUT_12 0x00000000
+#define OUT_34 0x00000001
+#define OUT_56 0x00000002
+#define OUT_78 0x00000003
+#define OUT_MASTER 0x00000004
+#define IN_12 0x00000005
+#define NUM_LINES 0x00000006
+
+/*
+ * SPDIF Out Source
+ */
+enum
+{
+ DIGOUT_DIG_IN = 0,
+ DIGOUT_ANA_IN,
+ DIGOUT_WAVE
+};
+/*
+ * Digital IN Source
+ */
+enum
+{
+ DIGIN_OPTICAL = 0,
+ DIGIN_COAX,
+ DIGIN_CD_IN
+};
+/*
+ * Out-0 Source
+ */
+enum
+{
+ SRC_DMA1 = 0,
+ SRC_PSDIN0,
+ SRC_SPDIN
+};
+
+/*
+ * Line IN Source (Aureon 7.1 Universe only)
+ */
+#define SRC_AUX 0
+#define SRC_WTL 1
+#define SRC_LINE_REAR 2
+#define SRC_GROUND 3
+
+/*
+ * Clock Source
+ */
+enum
+{
+ ICE_INTERNAL_CLOCK = 0,
+ ICE_SPDIF_CLOCK
+};
+/*
+ * Function of Frontjack
+ */
+enum
+{
+ FRONT_JACK_LINEIN = 0,
+ FRONT_JACK_HEADPHONE
+};
+
+enum MUX_TP_PIN
+{
+ CD_IN_MUX_TP_PIN = 1,
+ LINE_IN_MUX_TP_PIN,
+ AUX_IN_MUX_TP_PIN,
+ PHONO_IN_MUX_PIN,
+ LINE2_IN_MUX_PIN,
+ MIC_IN_MUX_TP_PIN,
+ DIG_IN_MUX_TP_PIN,
+ STEREO_MIX_MUX_TP_PIN
+};
+
+#define AUREON_REMOTE_CNTRL 0x32
+/* #define AUREON_REMOTE_ID 0x0016 */
+#define AUREON_REMOTE_ID 0x6B86
+#define AUREON_PCA_BASEBOARD 0x40
+
+#define MT_LOOPBK_CONTROL 0x02C
+#define MT_LOOPBK_CONTROL_DAC_REG 0x030
+#define MT_LOOPBK_CONTROL_SPDIF_OUT_REG 0x032
+
+#define WIDTH_BYTE 1
+#define WIDTH_WORD 2
+#define WIDTH_DWORD 4
+
+#define BITS_ON 0x10
+#define BITS_OFF 0x00
+#define TOGGLE_ON 0x20
+
+#define CRITSEC_ON 0x00000001
+
+#define WIDTH_MASK 0x0f
+
+#include "spdif.h"
+#include "envy24ht.h"
+
+/*! \fn =======================================================================
+ Function : WritePort
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : dwRegType ->
+ : dwIndex ->
+ : dwValue ->
+ : dwWidth ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void WritePort
+ (envy24ht_devc * devc,
+ IN ULONG dwRegType, IN ULONG dwIndex, IN ULONG dwValue, IN ULONG dwWidth)
+{
+ oss_native_word pPort = devc->ccs_base;
+
+ switch (dwRegType)
+ {
+ case REG_CCS:
+ pPort = devc->ccs_base;
+ break;
+
+ case REG_MT:
+ pPort = devc->mt_base;
+ break;
+ }
+
+ /* registers are addressible in byte, word or dword */
+ switch (dwWidth)
+ {
+ case WIDTH_BYTE:
+ OUTB (devc->osdev, dwValue, pPort + dwIndex);
+ break;
+ case WIDTH_WORD:
+ OUTW (devc->osdev, dwValue, pPort + dwIndex);
+
+ break;
+ case WIDTH_DWORD:
+ OUTL (devc->osdev, dwValue, pPort + dwIndex);
+ break;
+ }
+}
+
+
+/*! \fn =======================================================================
+ Function : ReadPort
+-------------------------------------------------------------------------------
+ Description :
+ Returns : ->
+ Parameters : IN ULONG dwWidth ->
+ IN ULONG dwWidth
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static ULONG ReadPort
+ (envy24ht_devc * devc,
+ IN ULONG dwRegType, IN ULONG dwIndex, IN ULONG dwWidth)
+{
+ oss_native_word pPort = devc->ccs_base;
+ ULONG dwData = 0;
+
+ switch (dwRegType)
+ {
+ case REG_CCS:
+ pPort = devc->ccs_base;
+ break;
+
+ case REG_MT:
+ pPort = devc->mt_base;
+ break;
+ }
+
+ /* all other registers are addressible in byte, word or dword */
+ switch (dwWidth)
+ {
+ case WIDTH_BYTE:
+ dwData = INB (devc->osdev, pPort + dwIndex);
+ break;
+ case WIDTH_WORD:
+ dwData = INW (devc->osdev, pPort + dwIndex);
+ break;
+ case WIDTH_DWORD:
+ dwData = INL (devc->osdev, pPort + dwIndex);
+ break;
+ }
+
+
+ return dwData;
+}
+
+/*! \fn =======================================================================
+ Function : ReadModifyWritePort
+-------------------------------------------------------------------------------
+ Description :
+ Returns : VOID ->
+ Parameters : wRegType ->
+ : dwMask ->
+ : dwControl ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void ReadModifyWritePort
+ (envy24ht_devc * devc,
+ IN ULONG dwRegType, IN ULONG dwIndex, IN ULONG dwMask, IN ULONG dwControl
+ /* dwControl: */
+ /* bit[3:0] : data width, 1 => byte, 2 => word, 4 => dword */
+ /* bit[4] : 1 => turn on bit(s); 0 => turn off bit(s) */
+ /* bit[5] : 1 => toggle bit(s) */
+ /* bit[6] : 1 => turn on Hw access critical section */
+ )
+{
+ ULONG dwValue;
+ ULONG dwWidth;
+ oss_native_word flags;
+
+ dwWidth = dwControl & WIDTH_MASK;
+
+ if (dwControl & CRITSEC_ON)
+ {
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ }
+
+ dwValue = ReadPort (devc, dwRegType, dwIndex, dwWidth);
+
+ /* see whether we should turn on or off the bit(s) */
+ if (dwControl & BITS_ON)
+ dwValue |= dwMask;
+ else
+ dwValue &= ~dwMask;
+
+ WritePort (devc, dwRegType, dwIndex, dwValue, dwWidth);
+
+ /* see if we need to toggle the bit(s) */
+ if (dwControl & TOGGLE_ON)
+ {
+ dwValue ^= dwMask;
+ WritePort (devc, dwRegType, dwIndex, dwValue, dwWidth);
+ }
+
+ if (dwControl & CRITSEC_ON)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ }
+
+}
+
+/*! \fn =======================================================================
+ Function : WriteGPIO
+-------------------------------------------------------------------------------
+ Description : Writes masked Data to GPIO Port
+ Parameters : IN ULONG Data ->
+ : IN ULONG Mask ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+WriteGPIO (envy24ht_devc * devc, IN ULONG Data, IN ULONG Mask)
+{
+ USHORT MaskL;
+ UCHAR MaskH;
+ USHORT DataL;
+ UCHAR DataH;
+
+ /* Do the masking. */
+ MaskL = (USHORT) Mask;
+ MaskH = (UCHAR) (Mask >> 16);
+ DataL = (USHORT) Data;
+ DataH = (UCHAR) (Data >> 16);
+ devc->gpio_shadow_L &= ~MaskL;
+ devc->gpio_shadow_H &= ~MaskH;
+ devc->gpio_shadow_L |= (MaskL & DataL);
+ devc->gpio_shadow_H |= (MaskH & DataH);
+
+ /* Write Data */
+ WritePort (devc, REG_CCS, WKN_GPIO_DATA0, devc->gpio_shadow_L, WIDTH_WORD);
+ WritePort (devc, REG_CCS, WKN_GPIO_DATA2, devc->gpio_shadow_H, WIDTH_BYTE);
+}
+
+/*! \fn =======================================================================
+ Function : SetSDADir
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : IN BOOLEAN fOut ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetSDADir (envy24ht_devc * devc, IN BOOLEAN fOut)
+{
+ if (fOut)
+ {
+ /* Set GPIO 18 direction to output */
+ WritePort (devc, REG_CCS, WKN_GPIO_DIR2, 0xDF, WIDTH_BYTE);
+ /* Turn IIC logic to SDA write */
+ WriteGPIO (devc, GPIO_SDA_TX_MASK, GPIO_SDA_TX_MASK);
+ }
+ else
+ {
+ WriteGPIO (devc, 0, GPIO_SDA_TX_MASK);
+ /* Direction "Read" for GPIO 18 (SDA) */
+ WritePort (devc, REG_CCS, WKN_GPIO_DIR2, 0xDB, WIDTH_BYTE);
+ }
+}
+
+/*! \fn =======================================================================
+ Function : SetSDA
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : BOOLEAN fSet
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetSDA (envy24ht_devc * devc, BOOLEAN fSet)
+{
+ /* Set GPIO 18 direction to output */
+ SetSDADir (devc, 1);
+ /* Write SDA */
+ WriteGPIO (devc, fSet ? GPIO_SDA_MASK : 0, GPIO_SDA_MASK);
+}
+
+/*! \fn =======================================================================
+ Function : GetSDA
+-------------------------------------------------------------------------------
+ Description :
+ Returns :
+UCHAR ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static UCHAR
+GetSDA (envy24ht_devc * devc)
+{
+ UCHAR ulData;
+
+ /* Turn IIC logic to SDA read */
+ SetSDADir (devc, 0);
+ ulData =
+ ((ReadPort (devc, REG_CCS, WKN_GPIO_DATA2, WIDTH_BYTE) & 0x04) == 0x04);
+ return ulData;
+}
+
+/*! \fn =======================================================================
+ Function : SetIIC
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN BOOLEAN fSDA ->
+ : IN BOOLEAN fCLK ->
+ : IN ULONG ulSleep ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void SetIIC
+ (envy24ht_devc * devc, IN BOOLEAN fSDA, IN BOOLEAN fCLK, IN ULONG ulSleep)
+{
+ SetSDA (devc, fSDA);
+ if (fCLK)
+ WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK);
+ else
+ WriteGPIO (devc, 0, GPIO_SCL_MASK);
+ if (ulSleep)
+ oss_udelay (ulSleep);
+}
+
+/*! \fn =======================================================================
+ Function : IICStart
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : ULONG ulSleep ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+IICStart (envy24ht_devc * devc, ULONG ulSleep)
+{
+ /* falling edge of SDA while SCL is HIGH */
+ SetIIC (devc, 1, 1, ulSleep);
+ SetIIC (devc, 0, 1, ulSleep);
+}
+
+/*! \fn =======================================================================
+ Function : IICStop
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : ULONG ulSleep ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+IICStop (envy24ht_devc * devc, ULONG ulSleep)
+{
+ /* rising edge of SDA while SCL is HIGH */
+ SetIIC (devc, 0, 1, ulSleep);
+ SetIIC (devc, 1, 1, ulSleep);
+ /* Reset Lines (No IIC requirement, but for prevent conflicts with SPI) */
+ /*SetIIC(0,0,ulSleep); */
+}
+
+/*! \fn =======================================================================
+ Function : IICSendByte
+-------------------------------------------------------------------------------
+ Description :
+ Returns : UCHAR ->
+ Parameters : CHAR bByte ->
+ : ULONG ulSleep ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static UCHAR IICSendByte
+ (envy24ht_devc * devc, IN UCHAR bByte, IN ULONG ulSleep)
+{
+ UCHAR bDataBit, bAck;
+ int i;
+ for (i = 7; i >= 0; i--) /* send byte (MSB first) */
+ {
+ bDataBit = (bByte >> i) & 0x01;
+
+ SetIIC (devc, bDataBit, 0, ulSleep);
+ SetIIC (devc, bDataBit, 1, ulSleep);
+ SetIIC (devc, bDataBit, 0, ulSleep);
+ } /* end for i */
+
+ SetIIC (devc, 1, 0, ulSleep);
+
+ /* This is neccesary for PLC */
+ SetSDADir (devc, 0);
+ /* Get acknowledge */
+ SetIIC (devc, 1, 1, ulSleep);
+ bAck = GetSDA (devc);
+ /*if (fAddress) */
+ /* SetIIC(devc, 1,0,ulSleep); */
+ /* else */
+ /* this is a start condition but never mind */
+ SetIIC (devc, 0, 0, ulSleep);
+ return (!bAck); /* bAck = 0 --> success */
+}
+
+#if 0
+/*! \fn =======================================================================
+ Function : IICReceiveByte
+-------------------------------------------------------------------------------
+ Description :
+ Returns : UCHAR ->
+ Parameters : CHAR fLastByte ->
+ : ULONG ulSleep ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static UCHAR IICReceiveByte
+ (envy24ht_devc * devc, UCHAR fLastByte, ULONG ulSleep)
+{
+ UCHAR bRead = 0;
+ int i;
+
+ for (i = 7; i >= 0; i--)
+ {
+ SetIIC (devc, 1, 0, ulSleep);
+ SetIIC (devc, 1, 1, ulSleep);
+ bRead <<= 1;
+ bRead += GetSDA (devc);
+ }
+
+ /* -> no acknowledge for last received byte */
+ SetIIC (devc, fLastByte, 0, ulSleep); /* SDA = HIGH for last byte */
+ SetIIC (devc, fLastByte, 1, ulSleep);
+ SetIIC (devc, fLastByte, 0, ulSleep); /* clock -> LOW */
+
+ return bRead;
+}
+#endif
+
+/*! \fn =======================================================================
+ Function : IICWriteBuffer
+-------------------------------------------------------------------------------
+ Description :
+ Returns : UCHAR ->
+ Parameters : CHAR bIicAddress ->
+ : PUCHAR pbByte ->
+ : USHORT nNoBytes ->
+ : ULONG ulSleep ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static UCHAR IICWriteBuffer
+ (envy24ht_devc * devc,
+ UCHAR bIicAddress, PUCHAR pbByte, USHORT nNoBytes, ULONG ulSleep)
+{
+ IICStart (devc, ulSleep);
+
+ /* send IIC address and data byte */
+ if (!IICSendByte (devc, bIicAddress, ulSleep))
+ goto FAILED;
+ /* send buffer */
+ do
+ {
+ if (!IICSendByte (devc, *pbByte, ulSleep))
+ goto FAILED; /* got no acknowledge */
+ pbByte++;
+ nNoBytes--;
+ }
+ while (nNoBytes);
+
+ IICStop (devc, ulSleep);
+ return 1;
+
+FAILED:
+ IICStop (devc, ulSleep);
+ return 0;
+}
+
+/*! \fn =======================================================================
+ Function : WriteCS8415
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN UCHAR Register ->
+ : IN UCHAR Value ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void WriteCS8415
+ (envy24ht_devc * devc, IN UCHAR Register, IN UCHAR Value)
+{
+ ULONG i;
+ BOOLEAN fData;
+ ULONG ulCmd;
+ ULONG ulCount;
+
+ /* m_pAdapter->HwEnter(); *//* TODO */
+
+ /* Clock low to prevent IIC Startcondition */
+ WriteGPIO (devc, 0, GPIO_SCL_MASK);
+
+ SetSDA (devc, 0);
+ /* Chip select (CS low) */
+ WriteGPIO (devc, 0, GPIO_CS8415_CS_MASK);
+
+ /* format buffer */
+ ulCmd = 0x200000 + /* chip address + R/W */
+ (((ULONG) Register) << 8) + /* register address */
+ Value; /* Value */
+ ulCmd <<= 8;
+ ulCount = 24; /* (AddressOnly) ? 16:24; */
+ for (i = 0; i < ulCount; i++)
+ {
+ fData = (ulCmd & 0x80000000) ? 1 : 0;
+ /* CCLK -> low */
+ WriteGPIO (devc, 0, GPIO_SCL_MASK);
+ oss_udelay (3);
+ /* CDTI -> Set data */
+ SetSDA (devc, fData);
+ oss_udelay (3);
+ /* CCLK -> high */
+ WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK);
+ ulCmd <<= 1;
+ }
+ WriteGPIO (devc, 0, GPIO_SCL_MASK); /* CCLK -> low */
+
+ /* Chip deselect (CS high) */
+ WriteGPIO (devc, GPIO_CS8415_CS_MASK, GPIO_CS8415_CS_MASK);
+ /* m_pAdapter->HwLeave(); *//* TODO */
+}
+
+#if 0
+/*! \fn =======================================================================
+ Function : ReadCS8415
+-------------------------------------------------------------------------------
+ Description :
+ Returns : UCHAR ->
+ Parameters : IN UCHAR Register ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+ /*ARGSUSED*/ static UCHAR
+ReadCS8415 (envy24ht_devc * devc, IN UCHAR Register)
+{
+ ULONG i;
+ BOOLEAN fData;
+ UCHAR cValue = 0;
+ USHORT wCmd;
+
+ /* m_pAdapter->HwEnter(); *//* TODO */
+
+ /* Clock low to prevent IIC Startcondition */
+ WriteGPIO (devc, 0, GPIO_SCL_MASK);
+
+ SetSDA (devc, 0);
+
+ /* Chip select (CS low) */
+ WriteGPIO (devc, 0, GPIO_CS8415_CS_MASK);
+ /* Set GPIO21 to read direction */
+ WritePort (devc, REG_CCS, WKN_GPIO_DIR2, 0xDF, WIDTH_BYTE);
+
+ wCmd = 0x2100; /* + *//* chip address + R/W */
+ /*(((USHORT)Register) << 8); *//* register address */
+ for (i = 0; i < 16; i++)
+ {
+ fData = (wCmd & 0x8000) ? 1 : 0;
+ /* CCLK -> low */
+ WriteGPIO (devc, 0, GPIO_SCL_MASK);
+ /* CDTI -> Set data */
+ SetSDA (devc, fData);
+ oss_udelay (3);
+ /* CCLK -> high */
+ WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK);
+ wCmd <<= 1;
+ if (i > 7)
+ {
+ /* Read CDTO */
+ cValue <<= 1;
+ cValue +=
+ ((ReadPort (devc, REG_CCS, WKN_GPIO_DATA2, WIDTH_BYTE) & 0x20) ==
+ 0x20);
+ }
+ }
+
+ WriteGPIO (devc, 0, GPIO_SCL_MASK); /* CCLK -> low */
+
+ /* Chip deselect (CS high) */
+ WriteGPIO (devc, GPIO_CS8415_CS_MASK, GPIO_CS8415_CS_MASK);
+
+ /* m_pAdapter->HwLeave(); *//* TODO */
+ return cValue;
+}
+#endif
+
+/*
+ * Definition of PCA I/Os
+ */
+typedef union tagPCA_CFG
+{
+ unsigned char cReg;
+ struct
+ {
+ unsigned char P00_SourceSel:2; /* LineIN Selector */
+ /* 00 -> Aux */
+ /* 01 -> Wavetable */
+ /* 11 -> LineIN Rear */
+ unsigned char P02_DigSel:1; /* DigitalIN Selector */
+ /* 0 -> Coax */
+ /* 1 -> Optical */
+
+ unsigned char P03_LineLED:1; /* LineLED */
+ /* 0 -> Off */
+ /* 1 -> On */
+ unsigned char P04_unused:4; /* unused */
+ } Bits;
+} PCA_CFG;
+
+/*! \fn =======================================================================
+ Function : WritePCA
+-------------------------------------------------------------------------------
+ Description :
+ Returns : NTSTATUS ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+WritePCA (envy24ht_devc * devc)
+{
+ PCA_CFG tCFG;
+ BYTE bByte[2];
+
+ tCFG.cReg = 0;
+
+ switch (devc->m_LineInSource)
+ {
+ case SRC_AUX:
+ tCFG.Bits.P00_SourceSel = 0;
+ break;
+ case SRC_WTL:
+ tCFG.Bits.P00_SourceSel = 1;
+ break;
+ case SRC_LINE_REAR:
+ tCFG.Bits.P00_SourceSel = 2;
+ break;
+ case SRC_GROUND:
+ tCFG.Bits.P00_SourceSel = 3;
+ break;
+
+ }
+
+ /* Switch LineLED when Line is selected for record */
+ if (devc->m_ADCIndex == ADC_LINE)
+ tCFG.Bits.P03_LineLED = 1;
+ if (devc->m_DigInSource == DIGIN_OPTICAL)
+ tCFG.Bits.P02_DigSel = 1;
+ /* Set all I/Os to Output */
+ bByte[0] = 3;
+ bByte[1] = 0;
+ IICWriteBuffer (devc, AUREON_PCA_BASEBOARD, bByte, 2, 30);
+ /* Write config */
+ bByte[0] = 0x01;
+ bByte[1] = tCFG.cReg;
+ IICWriteBuffer (devc, AUREON_PCA_BASEBOARD, bByte, 2, 30);
+}
+
+/*! \fn =======================================================================
+ Function : SetDigInSource
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : IN ULONG Source ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetDigInSource (envy24ht_devc * devc, IN ULONG Source)
+{
+ switch (Source)
+ {
+ case DIGIN_OPTICAL:
+ case DIGIN_COAX:
+ WriteCS8415 (devc, CS_CONTROL_2, 0x01);
+ break;
+ case DIGIN_CD_IN:
+ WriteCS8415 (devc, CS_CONTROL_2, 0x00);
+ break;
+ }
+ devc->m_DigInSource = Source;
+ WritePCA (devc);
+}
+
+/*! \fn =======================================================================
+ Function : SetOUT0Source
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : IN ULONG Source ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetOUT0Source (envy24ht_devc * devc, IN ULONG Source)
+{
+ ULONG ulShiftL, ulShiftR;
+ ULONG aulShiftL[] = { 0, 8, 11, 14, 17 };
+ ULONG aulShiftR[] = { 3, 20, 23, 26, 29 };
+ ULONG ulSourceL, ulSourceR;
+ int i;
+
+ /* No DigMonitor when Clock is internal */
+ if ((devc->m_ClockSource == ICE_INTERNAL_CLOCK) && (Source == SRC_SPDIN))
+ return;
+ for (i = 0; i < 5; i++)
+ {
+ ulShiftL = aulShiftL[i];
+ ulShiftR = aulShiftR[i];
+ switch (Source)
+ {
+ case SRC_DMA1:
+ ulSourceL = SRC_PDMA;
+ ulSourceR = SRC_PDMA;
+ break;
+ case SRC_PSDIN0:
+ ulSourceL = SRC_PSDIN0_L;
+ ulSourceR = SRC_PSDIN0_R;
+ break;
+ case SRC_SPDIN:
+ ulSourceL = SRC_SPDIN_L;
+ ulSourceR = SRC_SPDIN_R;
+ break;
+ default: /* Do nothing */
+ return;
+ }
+ /* First reset all relevant bits */
+ ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL,
+ SRC_MASK << ulShiftL, WIDTH_DWORD | BITS_OFF);
+ ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL,
+ SRC_MASK << ulShiftR, WIDTH_DWORD | BITS_OFF);
+ /* ..and set routing mask */
+ ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL,
+ ulSourceL << ulShiftL, WIDTH_DWORD | BITS_ON);
+ ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL,
+ ulSourceR << ulShiftR, WIDTH_DWORD | BITS_ON);
+ }
+ devc->m_Out0Source = Source;
+}
+static void SetADCMux (envy24ht_devc * devc, IN ULONG Value);
+
+/*! \fn =======================================================================
+ Function : SetLineSource
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN ULONG Source ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetLineSource (envy24ht_devc * devc, IN ULONG Source)
+{
+ switch (Source)
+ {
+ case SRC_AUX:
+ devc->m_AuxMux = 0x00;
+ break;
+ case SRC_WTL:
+ devc->m_AuxMux = 0x44;
+ break;
+ case SRC_LINE_REAR:
+ devc->m_AuxMux = 0x66;
+ break;
+
+ }
+ /* Update ADCMux */
+ SetADCMux (devc, devc->m_ADCMux);
+ devc->m_LineInSource = Source;
+ WritePCA (devc);
+}
+
+/*! \fn =======================================================================
+ Function : SetClockSource
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN ULONG ClockSource ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetClockSource (envy24ht_devc * devc, IN ULONG ClockSource)
+{
+
+ if (ClockSource == ICE_INTERNAL_CLOCK)
+ {
+ ReadModifyWritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, 0x10,
+ WIDTH_BYTE | BITS_OFF);
+ /* Disable DigMonitor to avoid noisy output */
+ if (devc->m_Out0Source == SRC_SPDIN)
+ SetOUT0Source (devc, SRC_DMA1);
+ }
+ else
+ {
+ ReadModifyWritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, 0x10,
+ WIDTH_BYTE | BITS_ON);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ }
+ devc->m_ClockSource = ClockSource;
+}
+
+/*! \fn =======================================================================
+ Function : ResetGPIO
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+ResetGPIO (envy24ht_devc * devc)
+{
+
+ /* Enable all lower GPIOs */
+ WritePort (devc, REG_CCS, WKN_GPIO_WRT_MASK0, 0x0, WIDTH_WORD);
+ /* Enable all upper GPIOs */
+ WritePort (devc, REG_CCS, WKN_GPIO_WRT_MASK2, 0x0, WIDTH_BYTE);
+ /* Set GPIO direction */
+ if (devc->subvendor == SSID_AUREON_UNIVERSE)
+ {
+ /* -> all output except GPIO_CS8415_CDTO_MASK */
+ /* and GPIO_REMOTE_MASK */
+ WritePort (devc, REG_CCS, WKN_GPIO_DIR0,
+ ~(GPIO_CS8415_CDTO_MASK | GPIO_REMOTE_MASK), WIDTH_DWORD);
+ }
+ else
+ {
+ /* All output except GPIO_CS8415_CDTO_MASK */
+ WritePort (devc, REG_CCS, WKN_GPIO_DIR0, ~GPIO_CS8415_CDTO_MASK,
+ WIDTH_DWORD);
+ }
+
+ oss_udelay (100);
+
+ /*----------------------------------------------------------------------------
+ Reset AC97 Interface
+ -----------------------------------------------------------------------------*/
+
+ WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
+ oss_udelay (3);
+ WriteGPIO (devc, 0, GPIO_AC97_RESET_MASK);
+ oss_udelay (3);
+ WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
+
+ /*----------------------------------------------------------------------------
+ Enable Remote-Control Interrupts
+ -----------------------------------------------------------------------------*/
+ WriteGPIO (devc, GPIO_INT_REST_MASK, GPIO_INT_REST_MASK);
+
+ /* Select optical input */
+ /* WriteGPIO(devc, GPIO_DIGITAL_SEL, 0); */
+}
+
+/*! \fn =======================================================================
+ Function : SetSPDIFConfig
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : IN ULONG Config ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetSPDIFConfig (envy24ht_devc * devc, IN ULONG Config)
+{
+ ReadModifyWritePort (devc, REG_CCS, WKN_SPDIF_CONFIG, 0x80,
+ WIDTH_BYTE | BITS_OFF);
+ if (Config & SPDIF_ENABLE_MASK)
+ {
+ devc->m_f1724SPDIF = 1;
+ }
+ else
+ {
+ devc->m_f1724SPDIF = 0;
+ }
+ /* Reset SPDIF Config */
+ ReadModifyWritePort (devc, REG_MT, MT_SPDIF_REG, 0x000F,
+ WIDTH_WORD | BITS_OFF);
+ /* Set new Config */
+ ReadModifyWritePort (devc, REG_MT, MT_SPDIF_REG, Config & 0xFFFF,
+ WIDTH_WORD | BITS_ON);
+ devc->m_SPDIFConfig = Config;
+ if (devc->m_f1724SPDIF)
+ ReadModifyWritePort (devc, REG_CCS, WKN_SPDIF_CONFIG, 0x80,
+ WIDTH_BYTE | BITS_ON);
+ /* Force saving of registers */
+ /* devc->m_pAdapter->SetDirty(); *//* TODO */
+}
+
+/*! \fn =======================================================================
+ Function : SetFrontjack
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN ULONG Frontjack ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetFrontjack (envy24ht_devc * devc, IN ULONG Frontjack)
+{
+
+ switch (Frontjack)
+ {
+ case FRONT_JACK_LINEIN:
+ WriteGPIO (devc, 0, GPIO_HEADPHONE_MASK);
+ break;
+ case FRONT_JACK_HEADPHONE:
+ WriteGPIO (devc, GPIO_HEADPHONE_MASK, GPIO_HEADPHONE_MASK);
+ break;
+ }
+ devc->m_Frontjack = Frontjack;
+ /* Force saving of registers */
+ /* devc->m_pAdapter->SetDirty(); *//* TODO */
+
+}
+
+/*! \fn =======================================================================
+ Function : Init1724
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+Init1724 (envy24ht_devc * devc)
+{
+ /* System Config: 4 DACs, one ADC & SPDIF, MPU enabled, 24,576Mhz crystal */
+ /* WritePort(REG_CCS, WKN_SYS_CONFIG, 0x2B, WIDTH_BYTE); */
+ /* CL_NOTE: New Setings */
+ /* System Config: 4 DACs, one ADC & SPDIF, MPU disabled, 24,576Mhz crystal */
+ WritePort (devc, REG_CCS, WKN_SYS_CONFIG, 0x0B, WIDTH_BYTE);
+
+ /* Config I2S Interface */
+ WritePort (devc, REG_CCS, WKN_ACLINK_CONFIG, 0x80, WIDTH_BYTE);
+ WritePort (devc, REG_CCS, WKN_I2S_CONFIG, 0xF9, WIDTH_BYTE);
+ WritePort (devc, REG_CCS, WKN_SPDIF_CONFIG, 0x83, WIDTH_BYTE);
+
+ /* Config Interrupt behaviour */
+ WritePort (devc, REG_MT, MT_PLAY_REC_UNDOVR, 0, WIDTH_BYTE);
+ WritePort (devc, REG_MT, MT_INTR_STATUS_REG, 0, WIDTH_BYTE);
+ WritePort (devc, REG_MT, MT_INTR_MASK_REG, 0xFF, WIDTH_BYTE);
+ WritePort (devc, REG_CCS, WKN_INT_STAT_REG, 0, WIDTH_BYTE);
+ WritePort (devc, REG_CCS, WKN_INT_MASK_REG, 0xFE, WIDTH_BYTE);
+
+ SetSPDIFConfig (devc, 0);
+ /* SetSDPIFSource(devc, DIGOUT_WAVE); */
+ SetDigInSource (devc, DIGIN_OPTICAL);
+ SetFrontjack (devc, FRONT_JACK_LINEIN);
+}
+
+/*! \fn =======================================================================
+ Function : WriteWM8770
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN UCHAR Register ->
+ : IN UCHAR Value ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+void
+WriteWM8770 (envy24ht_devc * devc, IN UCHAR Register, IN USHORT Value)
+{
+ int i;
+ BOOLEAN fData;
+ USHORT wCmd;
+/* KIRQL OldIrql; */
+
+ /* m_pAdapter->HwEnter(); */
+
+ /* KeAcquireSpinLock (&m_SPILock,&OldIrql); */
+
+
+ /* Clock low to prevent IIC Startcondition */
+ WriteGPIO (devc, 0, GPIO_SCL_MASK);
+
+ SetSDA (devc, 0);
+
+ /* Chip select (CS low) */
+ WriteGPIO (devc, 0, GPIO_WM8770_CS_MASK);
+
+ /* format buffer */
+ wCmd = (((USHORT) Register) << 9) + Value;
+
+
+ for (i = 0; i < 16; i++)
+ {
+ fData = (wCmd & 0x8000) ? 1 : 0;
+ /* CCLK -> low */
+ WriteGPIO (devc, 0, GPIO_SCL_MASK);
+ oss_udelay (3);
+ /* CDTI -> Set data */
+ SetSDA (devc, fData);
+ oss_udelay (3);
+ /* CCLK -> high */
+ WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK);
+ wCmd <<= 1;
+ }
+ WriteGPIO (devc, 0, GPIO_SCL_MASK); /* CCLK -> low */
+
+ /* Chip deselect */
+ WriteGPIO (devc, GPIO_WM8770_CS_MASK, GPIO_WM8770_CS_MASK);
+}
+
+/*! \fn =======================================================================
+ Function : SetVolReg
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN ULONG LineIdx ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetVolReg (envy24ht_devc * devc, IN ULONG LineIdx)
+{
+ int iVol, ChnlVol;
+
+ ChnlVol = devc->m_DACVolume[LineIdx];
+
+ /* See if we want to mute anything */
+ if (devc->m_fDACMute[LineIdx] || devc->m_fDACMute[LINE_MASTER])
+ {
+ WriteWM8770 (devc, gWMRegister[LineIdx], 0x100);
+ return;
+ }
+
+ /* Since master volume is virtualized, we add the attenuations for both */
+ /* master volume and channel volume to obtain the overall attenuation */
+
+ /* Get total attenuation */
+ iVol = ChnlVol + devc->m_DACVolume[LINE_MASTER] - MAX_VOLUME;
+ /* Check against bounds */
+ iVol = (iVol < MAX_VOLUME) ? iVol : MAX_VOLUME;
+ if (iVol < MIN_VOLUME)
+ iVol = MIN_VOLUME;
+ WriteWM8770 (devc, gWMRegister[LineIdx], iVol | 0x180);
+}
+
+
+/*! \fn =======================================================================
+ Function : SetMute
+-------------------------------------------------------------------------------
+ Description :
+ Returns : VOID ->
+ Parameters : IN ULONG ChannelID ->
+ : IN BOOLEAN Mute ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void SetDACMute
+ (envy24ht_devc * devc, IN ULONG ChannelID, IN BOOLEAN Mute)
+{
+ ULONG LineIndex;
+
+ /* Convert ChannelID to line index */
+ /* If it is for left channel, we will need to add one */
+ LineIndex = ChannelID >> 15;
+
+ /* See if this is for master volume */
+ if (LineIndex == LINE_MASTER)
+ {
+ /* if current setting is not the same as previous setting */
+ if (devc->m_fDACMute[LINE_MASTER] != Mute)
+ {
+ int i;
+
+ devc->m_fDACMute[LINE_MASTER] = Mute;
+
+ /* Need to do it for every single line (excluding Master and Gain) */
+ for (i = 0; i <= LINE_OUT_4R; i++)
+ {
+ SetVolReg (devc, i);
+ }
+ return;
+ }
+ }
+
+ /* See if this is for left channel */
+ if (ChannelID & CH_LEFT)
+ {
+ /* if current setting is not the same as previous setting */
+ if (devc->m_fDACMute[LineIndex] != Mute)
+ {
+ devc->m_fDACMute[LineIndex] = Mute;
+ if (LineIndex == LINE_GAIN_L)
+ {
+ WriteWM8770 (devc, gWMRegister[LINE_GAIN_L],
+ devc->
+ m_DACVolume[LINE_GAIN_L] | ((Mute) ? 0x20 : 0x00));
+ }
+ else
+ {
+ SetVolReg (devc, LineIndex);
+ }
+ }
+ }
+
+ /* See if this is for right channel */
+ if (ChannelID & CH_RIGHT)
+ {
+ LineIndex++;
+ /* if current setting is not the same as previous setting */
+ if (devc->m_fDACMute[LineIndex] != Mute)
+ {
+ devc->m_fDACMute[LineIndex] = Mute;
+ if (LineIndex == LINE_GAIN_R)
+ {
+ WriteWM8770 (devc, gWMRegister[LINE_GAIN_R],
+ devc->
+ m_DACVolume[LINE_GAIN_R] | ((Mute) ? 0x20 : 0x00));
+ }
+ else
+ {
+ SetVolReg (devc, LineIndex);
+ }
+ }
+ }
+ /* m_pAdapter->SetDirty(); *//* TODO */
+}
+
+
+
+/*=============================================================================
+ Function : SetVolume
+-------------------------------------------------------------------------------
+ Description :
+ Returns : VOID ->
+ Parameters : IN ICE_HW_PARAM* HwParm ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void SetDACVolume
+ (envy24ht_devc * devc, IN ULONG ChannelID, IN UCHAR Volume)
+{
+ ULONG LineIndex;
+ WORD LeftRight;
+ BOOLEAN VolChnged = 0;
+
+ /* Convert ChannelID to line index */
+ LineIndex = ChannelID >> 15;
+ /* Get the left/right side */
+ LeftRight = (WORD) (ChannelID & 0xffff);
+
+ /* Check if left volume is changed */
+ if (LeftRight & CH_LEFT)
+ {
+ if (devc->m_DACVolume[LineIndex] != Volume)
+ {
+ devc->m_DACVolume[LineIndex] = Volume;
+ VolChnged = 1;
+ }
+ }
+
+ /* Check if right volume is changed */
+ if (LeftRight & CH_RIGHT)
+ {
+ if (devc->m_DACVolume[LineIndex + 1] != Volume)
+ {
+ devc->m_DACVolume[LineIndex + 1] = Volume;
+ VolChnged = 1;
+ }
+ }
+
+ /* If any volume is changed, need to touch hardware */
+ if (VolChnged)
+ {
+ /* check if this is for input gain */
+ if ((ChannelID >> 16) == IN_12)
+ {
+ USHORT WMValue = (USHORT) Volume;
+#ifdef NULL_DB
+ WMValue = 0x0C;
+#endif
+ if (LeftRight & CH_LEFT)
+ WriteWM8770 (devc, gWMRegister[LineIndex], WMValue);
+ if (LeftRight & CH_RIGHT)
+ WriteWM8770 (devc, gWMRegister[LineIndex + 1], WMValue);
+ }
+ else
+ /* Yap, now check if this is for master volume */
+ if ((ChannelID >> 16) == OUT_MASTER)
+ {
+ int i;
+ /* Need to do it for every single line (excluding Master and Gain) */
+ for (i = 0; i <= LINE_OUT_4R; i++)
+ {
+ SetVolReg (devc, i);
+ }
+ }
+ else
+ {
+ if (LeftRight & CH_LEFT)
+ SetVolReg (devc, LineIndex);
+ if (LeftRight & CH_RIGHT)
+ SetVolReg (devc, LineIndex + 1);
+ }
+ }
+ /* m_pAdapter->SetDirty(); TODO */
+}
+
+
+/*! \fn =======================================================================
+ Function : GetVolume
+-------------------------------------------------------------------------------
+ Description :
+ Returns : UCHAR ->
+ Parameters : IN ULONG ChannelID ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static UCHAR
+GetDACVolume (envy24ht_devc * devc, IN ULONG ChannelID)
+{
+ UCHAR Value;
+ USHORT LeftRight;
+ ULONG LineIndex;
+
+ /* Convert ChannelID to line index */
+ LineIndex = ChannelID >> 15;
+ /* Get the left/right side */
+ LeftRight = (USHORT) (ChannelID & 0xffff);
+
+ if (LeftRight == CH_LEFT)
+ {
+ Value = devc->m_DACVolume[LineIndex];
+ }
+ else
+ {
+ Value = devc->m_DACVolume[LineIndex + 1];
+ }
+ return Value;
+}
+
+
+#if 0
+/*! \fn =======================================================================
+ Function : GetMute
+-------------------------------------------------------------------------------
+ Description :
+ Returns : BOOLEAN ->
+ Parameters : IN ULONG ChannelID ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static BOOLEAN
+GetDACMute (envy24ht_devc * devc, IN ULONG ChannelID)
+{
+ BOOLEAN Value;
+ USHORT LeftRight;
+ ULONG LineIndex;
+
+ /* Convert ChannelID to line index */
+ LineIndex = ChannelID >> 15;
+ /* Get the left/right side */
+ LeftRight = (USHORT) (ChannelID & 0xffff);
+
+ if (LeftRight == CH_LEFT)
+ {
+ Value = devc->m_fDACMute[LineIndex];
+ }
+ else
+ {
+ Value = devc->m_fDACMute[LineIndex + 1];
+ }
+ return Value;
+}
+#endif
+
+/*! \fn =======================================================================
+ Function : SetADCGain
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN ULONG Index ->
+ : IN ULONG Value ->
+ : IN ULONG Channel ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void SetADCGain
+ (envy24ht_devc * devc, IN ULONG Index, IN USHORT Value, IN ULONG Channel)
+{
+ UCHAR WMReg = 0x19;
+ USHORT WMValue;
+
+ /* Set only selected Line */
+ if (Index != devc->m_ADCIndex)
+ return;
+
+ switch (Channel)
+ {
+ case CH_LEFT:
+ devc->m_ADCVolume[Index] =
+ (Value << 8) | (devc->m_ADCVolume[Index] & 0x00FF);
+ break;
+ case CH_BOTH:
+ devc->m_ADCVolume[Index] = (Value << 8) | Value;
+ break;
+ case CH_NOP:
+ /* Hold Value */
+ break;
+ case CH_RIGHT:
+ default:
+ devc->m_ADCVolume[Index] = Value | (devc->m_ADCVolume[Index] & 0xFF00);
+
+ }
+ WMValue =
+ ((devc->m_ADCVolume[Index] & 0x00FF) <
+ 0x1F) ? (devc->m_ADCVolume[Index] & 0x00FF) : 0x1F;
+#ifdef NULL_DB
+ WMValue = 0x0C;
+#endif
+ WriteWM8770 (devc, WMReg, WMValue);
+ WMValue = (((devc->m_ADCVolume[Index] >> 8) & 0x00FF) < 0x1F) ?
+ ((devc->m_ADCVolume[Index] >> 8) & 0x00FF) : 0x1F;
+#ifdef NULL_DB
+ WMValue = 0x0C;
+#endif
+ WriteWM8770 (devc, WMReg + 1, WMValue);
+ /* Force saving of registers */
+ /* devc->m_pAdapter->SetDirty(); TODO */
+}
+
+#if 0
+/*! \fn =======================================================================
+ Function : GetADCGain
+-------------------------------------------------------------------------------
+ Description :
+ Returns : UCHAR ->
+ Parameters : IN ULONG Index ->
+ : IN ULONG Channel ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static UCHAR GetADCGain
+ (envy24ht_devc * devc, IN ULONG Index, IN ULONG Channel)
+{
+ UCHAR Value;
+
+ if (Channel == CH_LEFT)
+ {
+ Value = (UCHAR) ((devc->m_ADCVolume[Index] >> 8) & 0xFF);
+ }
+ else
+ {
+ Value = (UCHAR) (devc->m_ADCVolume[Index] & 0xFF);
+ }
+ return Value;
+}
+#endif
+
+/*! \fn =======================================================================
+ Function : SetADCMux
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN Value ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetADCMux (envy24ht_devc * devc, IN ULONG Value)
+{
+ UCHAR MuxVal = 0;
+ BOOLEAN fAU;
+
+ /* Store to shadow register */
+ devc->m_ADCMux = Value;
+ devc->m_fSPDIFRecord = 0;
+ fAU = (devc->subvendor == SSID_AUREON_UNIVERSE);
+ switch (Value)
+ {
+ case CD_IN_MUX_TP_PIN:
+ devc->m_ADCIndex = ADC_CD;
+ MuxVal = (fAU) ? 0x11 : 0x00;
+ break;
+ case LINE_IN_MUX_TP_PIN:
+ devc->m_ADCIndex = ADC_LINE;
+ MuxVal = (fAU) ? 0x33 : 0x22;
+ break;
+ case AUX_IN_MUX_TP_PIN:
+ devc->m_ADCIndex = ADC_AUX;
+ MuxVal = (fAU) ? devc->m_AuxMux : 0x11;
+ break;
+ case MIC_IN_MUX_TP_PIN:
+ devc->m_ADCIndex = ADC_MIC;
+ MuxVal = (fAU) ? 0x55 : 0x33;
+ break;
+ case DIG_IN_MUX_TP_PIN:
+ /* Use SPDIF DMA channel */
+ devc->m_fSPDIFRecord = 1;
+ break;
+ case PHONO_IN_MUX_PIN:
+ devc->m_ADCIndex = ADC_PHONO;
+ MuxVal = 0x22;
+ break;
+ case STEREO_MIX_MUX_TP_PIN:
+ devc->m_ADCIndex = ADC_STEREO_MIX;
+ MuxVal = (fAU) ? 0x77 : 0x44;
+ break;
+
+ default:
+ devc->m_ADCIndex = ADC_LINE;
+ MuxVal = 0x22;
+
+ }
+ WriteWM8770 (devc, WM_ADC_INPUT_MX, (UCHAR) MuxVal);
+ /* Reset GAIN */
+ SetADCGain (devc, devc->m_ADCIndex, 0, CH_NOP);
+ /* Update PCA config */
+ WritePCA (devc);
+ /* Force saving of registers */
+ /*devc->m_pAdapter->SetDirty(); TODO */
+}
+
+/*! \fn =======================================================================
+ Function : InitWM8770
+-------------------------------------------------------------------------------
+ Description :
+-------------------------------------------------------------------------------
+ Notes : Call before Registry Read
+=============================================================================*/
+static void
+InitWM8770 (envy24ht_devc * devc)
+{
+ /*----------------------------------------------------------------------------
+ Reset WM8770
+ -----------------------------------------------------------------------------*/
+ /* Set SPI Mode */
+ WriteGPIO (devc, 0, GPIO_WM8770_RS_MASK);
+ oss_udelay (3);
+ WriteGPIO (devc, GPIO_WM8770_CS_MASK, GPIO_WM8770_CS_MASK);
+ oss_udelay (3);
+ WriteGPIO (devc, GPIO_WM8770_RS_MASK, GPIO_WM8770_RS_MASK);
+ oss_udelay (100);
+
+ /*----------------------------------------------------------------------------
+ Set defaults
+ -----------------------------------------------------------------------------*/
+
+ /* Output defaults */
+ SetDACVolume (devc, CH_MASTER_BOTH, WM_OUT_DEFAULT);
+ SetDACVolume (devc, CH_FRONT_BOTH, WM_OUT_DEFAULT);
+ SetDACVolume (devc, CH_REAR_BOTH, WM_OUT_DEFAULT);
+ SetDACVolume (devc, CH_CENTER, WM_OUT_DEFAULT);
+ SetDACVolume (devc, CH_LFE, WM_OUT_DEFAULT);
+ SetDACVolume (devc, CH_BS_BOTH, WM_OUT_DEFAULT);
+ SetDACMute (devc, CH_MASTER_BOTH, 0);
+ SetDACMute (devc, CH_FRONT_BOTH, 0);
+ SetDACMute (devc, CH_REAR_BOTH, 0);
+ SetDACMute (devc, CH_CENTER, 0);
+ SetDACMute (devc, CH_LFE, 0);
+ SetDACMute (devc, CH_BS_BOTH, 0);
+ /* Input */
+ SetADCGain (devc, ADC_CD, WM_INP_DEFAULT, CH_BOTH);
+ SetADCGain (devc, ADC_AUX, WM_INP_DEFAULT, CH_BOTH);
+ SetADCGain (devc, ADC_LINE, WM_INP_DEFAULT, CH_BOTH);
+ SetADCGain (devc, ADC_MIC, WM_INP_DEFAULT, CH_BOTH);
+ /* Mux */
+ SetADCMux (devc, STEREO_MIX_MUX_TP_PIN);
+
+ /* At least Power DAC & ADC */
+ WriteWM8770 (devc, WM_POWER_CNTRL, 0x0000);
+ /* Power ADC Input Mux */
+ WriteWM8770 (devc, WM_ADC_INPUT_MX, 0x0000);
+ /* Enable Aux-Output */
+
+ if (devc->subvendor == SSID_PHASE28)
+ {
+ WriteWM8770 (devc, WM_OUT12_SELECT, 0x0009);
+ WriteWM8770 (devc, WM_OUT34_SELECT, 0x0009);
+ }
+ else
+ {
+ WriteWM8770 (devc, WM_OUT12_SELECT, 0x000b);
+ WriteWM8770 (devc, WM_OUT34_SELECT, 0x0009);
+ }
+ /* Init Master Mode Register */
+ WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x0012);
+
+}
+
+/*! \fn =======================================================================
+ Function : InitCS8415
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+-------------------------------------------------------------------------------
+ Notes : Has to be called after InitWM8770 since RST must be "high"
+=============================================================================*/
+static void
+InitCS8415 (envy24ht_devc * devc)
+{
+
+ /* Init Remote-Controller */
+ if (devc->subvendor == SSID_AUREON_UNIVERSE)
+ {
+ UCHAR bByte[2];
+ bByte[0] = (UCHAR) ((AUREON_REMOTE_ID >> 8) & 0xFF);
+ bByte[1] = (UCHAR) AUREON_REMOTE_ID;
+ IICWriteBuffer (devc, AUREON_REMOTE_CNTRL, bByte, 2, 200);
+ }
+ /*----------------------------------------------------------------------------
+ Reset CS8415
+ -----------------------------------------------------------------------------*/
+ /* Set SPI Mode */
+ WriteGPIO (devc, GPIO_CS8415_CS_MASK, GPIO_CS8415_CS_MASK);
+ oss_udelay (3);
+ WriteGPIO (devc, 0, GPIO_CS8415_CS_MASK);
+ oss_udelay (100);
+
+ /* Set defaults */
+ WriteCS8415 (devc, CS_CONTROL_1, 0x80);
+ /* SPDIF mux to RXP1 */
+ WriteCS8415 (devc, CS_CONTROL_2, 0x01);
+ WriteCS8415 (devc, CS_CLK_SRC_CNTRL, 0x41);
+ WriteCS8415 (devc, CS_SER_OUT_FORMAT, 0x05);
+
+ /* all other register remain to their defaults */
+
+}
+
+#define GPIO_WAIT 10
+
+/*! \fn =======================================================================
+ Function : WriteAC97Codec
+-------------------------------------------------------------------------------
+ Description : Writes to TT-AC97 Interface
+ Parameters : IN ULONG Register ->
+ : IN ULONG Data ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void WriteAC97Codec
+ (envy24ht_devc * devc, IN ULONG Register, IN ULONG Data)
+{
+ UCHAR TTData;
+
+#ifdef TTTT
+ /* CL_TEST */
+ /* Reset AC97 */
+ WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
+ oss_udelay (3);
+ WriteGPIO (devc, 0, GPIO_AC97_RESET_MASK);
+ oss_udelay (3);
+ WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
+ oss_udelay (3);
+ /* Unmute Master */
+ WriteAC97Codec (devc, 0x02, 0x00);
+#endif
+
+ /* m_pAdapter->HwEnter(); TODO */
+
+ oss_udelay (GPIO_WAIT);
+
+ /* Reset all LD Pins and GO Pin */
+ WriteGPIO (devc, 0,
+ GPIO_LD_DATA_H_MASK | GPIO_LD_DATA_L_MASK | GPIO_LD_ADR_MASK |
+ GPIO_GO_MASK);
+
+
+ /* apply address to TT-AC97 Interface */
+ WriteGPIO (devc, Register, GPIO_DATA_ADR_MASK);
+
+ /* Set "Load Address" Pin */
+ oss_udelay (GPIO_WAIT);
+ WriteGPIO (devc, GPIO_LD_ADR_MASK, GPIO_LD_ADR_MASK);
+
+ /* Reset "Load Address" Pin */
+ oss_udelay (GPIO_WAIT);
+ WriteGPIO (devc, 0, GPIO_LD_ADR_MASK);
+
+ /* apply data low to TT-AC97 Interface */
+ oss_udelay (GPIO_WAIT);
+ TTData = (UCHAR) (Data & 0x000000FF);
+ WriteGPIO (devc, TTData, GPIO_DATA_ADR_MASK);
+
+ /* Set "Load Data low" Pin */
+ oss_udelay (GPIO_WAIT);
+ WriteGPIO (devc, GPIO_LD_DATA_L_MASK, GPIO_LD_DATA_L_MASK);
+
+ /* Reset "Load Data low" Pin */
+ oss_udelay (GPIO_WAIT);
+ WriteGPIO (devc, 0, GPIO_LD_DATA_L_MASK);
+
+ /* apply data high to TT-AC97 Interface */
+ oss_udelay (GPIO_WAIT);
+ TTData = (UCHAR) ((Data >> 8) & 0x000000FF);
+ WriteGPIO (devc, TTData, GPIO_DATA_ADR_MASK);
+
+ /* Set "Load Data high" Pin */
+ oss_udelay (GPIO_WAIT);
+ WriteGPIO (devc, GPIO_LD_DATA_H_MASK, GPIO_LD_DATA_H_MASK);
+
+ /* Reset "Load Data high" Pin */
+ oss_udelay (GPIO_WAIT);
+ WriteGPIO (devc, 0, GPIO_LD_DATA_H_MASK);
+
+ /* Set and immediately reset "GO" Pin */
+ oss_udelay (GPIO_WAIT);
+ WriteGPIO (devc, GPIO_GO_MASK, GPIO_GO_MASK);
+ WriteGPIO (devc, 0, GPIO_GO_MASK);
+ /* m_pAdapter->HwLeave(); *//* TODO */
+
+}
+
+/*! \fn =======================================================================
+ Function : SetAC97Volume
+-------------------------------------------------------------------------------
+ Description :
+ Parameters : IN ULONG Index ->
+ : IN UHSORT Value ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void SetAC97Volume
+ (envy24ht_devc * devc, IN ULONG Index, IN USHORT left, IN USHORT right)
+{
+ int AC97Reg = 0, value;
+
+ devc->m_AC97Volume[Index] = left | (right << 8);
+
+ left = AC97_INP_MAX - left;
+ right = AC97_INP_MAX - right;
+
+ value = (left << 8) | right;
+
+ switch (devc->subvendor)
+ {
+ case SSID_AUREON_SKY:
+ case SSID_PRODIGY71:
+ case SSID_AUREON_SPACE:
+ switch (Index)
+ {
+ case AC97_MIC:
+ AC97Reg = AC97_IDXREG_MIC_IN;
+ break;
+ case AC97_LINE:
+ AC97Reg = AC97_IDXREG_LINE_IN;
+ break;
+ case AC97_CD:
+ AC97Reg = AC97_IDXREG_CD_IN;
+ break;
+ case AC97_AUX:
+ AC97Reg = AC97_IDXREG_AUX_IN;
+ break;
+ default:
+ cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index);
+ return;
+ }
+ break;
+ case SSID_AUREON_UNIVERSE:
+ switch (Index)
+ {
+ case AC97_MIC:
+ AC97Reg = AC97_IDXREG_MIC_IN;
+ break;
+ case AC97_LINE:
+ AC97Reg = AC97_IDXREG_LINE_IN;
+ break;
+ case AC97_CD:
+ AC97Reg = AC97_IDXREG_AUX_IN;
+ break;
+ case AC97_PHONO:
+ AC97Reg = AC97_IDXREG_CD_IN;
+ break;
+ case AC97_AUX:
+ case AC97_LINE2:
+ AC97Reg = AC97_IDXREG_VIDEO_IN;
+ break;
+ default:
+ cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index);
+ return;
+
+ }
+ break;
+ }
+ if (!devc->m_fAC97Mute[Index])
+ {
+ WriteAC97Codec (devc, AC97Reg, value);
+ }
+ /* Force saving of registers */
+ /* m_pAdapter->SetDirty(); TODO */
+}
+
+
+/*! \fn =======================================================================
+ Function : GetAC97Volume
+-------------------------------------------------------------------------------
+ Description :
+ Returns : UCHAR ->
+ Parameters : IN ULONG Index ->
+ : IN ULONG Channel ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static USHORT
+GetAC97Volume (envy24ht_devc * devc, IN ULONG Index)
+{
+ return devc->m_AC97Volume[Index];
+}
+
+/*! \fn =======================================================================
+ Function : SetAC97Mute
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+ Parameters : IN ULONG Index ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetAC97Mute (envy24ht_devc * devc, IN ULONG Index, BOOLEAN OnOff)
+{
+ UCHAR AC97Reg = 0;
+ devc->m_fAC97Mute[Index] = OnOff;
+ switch (devc->subvendor)
+ {
+ case SSID_AUREON_SKY:
+ case SSID_PRODIGY71:
+ case SSID_AUREON_SPACE:
+ switch (Index)
+ {
+ case AC97_MIC:
+ AC97Reg = AC97_IDXREG_MIC_IN;
+ break;
+ case AC97_LINE:
+ AC97Reg = AC97_IDXREG_LINE_IN;
+ break;
+ case AC97_CD:
+ AC97Reg = AC97_IDXREG_CD_IN;
+ break;
+ case AC97_AUX:
+ AC97Reg = AC97_IDXREG_AUX_IN;
+ break;
+ default:
+ cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index);
+ return;
+ }
+ break;
+ case SSID_AUREON_UNIVERSE:
+ switch (Index)
+ {
+ case AC97_MIC:
+ AC97Reg = AC97_IDXREG_MIC_IN;
+ break;
+ case AC97_LINE:
+ AC97Reg = AC97_IDXREG_LINE_IN;
+ break;
+ case AC97_CD:
+ AC97Reg = AC97_IDXREG_AUX_IN;
+ break;
+ case AC97_PHONO:
+ AC97Reg = AC97_IDXREG_CD_IN;
+ break;
+ case AC97_AUX:
+ case AC97_LINE2:
+ AC97Reg = AC97_IDXREG_VIDEO_IN;
+ break;
+ default:
+ cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index);
+ return;
+ }
+ break;
+ }
+#ifdef AC97_MUTE
+ WriteAC97Codec (devc, AC97Reg, 0x8000);
+#else
+ WriteAC97Codec (devc, AC97Reg,
+ (OnOff) ? 0x8000 : devc->m_AC97Volume[Index]);
+#endif
+
+ /* Force saving of registers */
+ /* m_pAdapter->SetDirty(); *//* TODO */
+}
+
+/*! \fn =======================================================================
+ Function : InitAC97
+-------------------------------------------------------------------------------
+ Description :
+ Returns : void ->
+-------------------------------------------------------------------------------
+ Notes : Call before Registry Read
+=============================================================================*/
+static void
+InitAC97 (envy24ht_devc * devc)
+{
+ /* Reset AC97 */
+ oss_udelay (30);
+ WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
+ oss_udelay (3);
+ WriteGPIO (devc, 0, GPIO_AC97_RESET_MASK);
+ oss_udelay (3);
+ WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
+ oss_udelay (3);
+
+ /* Unmute Master */
+ WriteAC97Codec (devc, 0x02, 0x00);
+
+ /*----------------------------------------------------------------------------
+ Set defaults
+ -----------------------------------------------------------------------------*/
+ /* Volume */
+ SetAC97Volume (devc, AC97_MIC, AC97_INP_DEFAULT, AC97_INP_DEFAULT);
+ SetAC97Volume (devc, AC97_LINE, AC97_INP_DEFAULT, AC97_INP_DEFAULT);
+ SetAC97Volume (devc, AC97_AUX, AC97_INP_DEFAULT, AC97_INP_DEFAULT);
+ SetAC97Volume (devc, AC97_CD, AC97_INP_DEFAULT, AC97_INP_DEFAULT);
+ /* Mute */
+ SetAC97Mute (devc, AC97_MIC, 0);
+ SetAC97Mute (devc, AC97_LINE, 0);
+ SetAC97Mute (devc, AC97_AUX, 0);
+ SetAC97Mute (devc, AC97_CD, 0);
+}
+
+/*! \fn =======================================================================
+ Function : SetSampleRate
+-------------------------------------------------------------------------------
+ Description :
+ Returns : NTSTATUS ->
+ Parameters : IN ULONG SampleRate ->
+-------------------------------------------------------------------------------
+ Notes :
+=============================================================================*/
+static void
+SetSampleRate (envy24ht_devc * devc, IN ULONG SampleRate)
+{
+ WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x0012);
+
+ switch (SampleRate)
+ {
+ case 48000:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_48KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ /* WRITE_PORT_UCHAR(WKNMTBase + MT_DATA_FORMAT_REG,(~MT_128X)&READ_PORT_UCHAR(WKNMTBase + MT_DATA_FORMAT_REG)); */
+ break;
+ case 24000:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_24KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 12000:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_12KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 9600:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_9p6KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 32000:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_32KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 16000:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_16KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 8000:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_8KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 96000:
+ WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A);
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_96KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 192000:
+ WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A);
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_192KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_ON);
+ break;
+ case 64000:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_64KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 44100:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_44p1KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 22050:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_22p05KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 11025:
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_11p025KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 88200:
+ WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A);
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_88p2KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ case 176400:
+ WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A);
+ WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_176p4KHZ, WIDTH_BYTE);
+ ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X,
+ WIDTH_BYTE | BITS_OFF);
+ break;
+ default:
+ break;
+
+ }
+}
+
+static void
+aureon_card_init (envy24ht_devc * devc)
+{
+
+/* Do not change the order of the following lines */
+ Init1724 (devc);
+ ResetGPIO (devc);
+
+ if (devc->subvendor != SSID_PHASE28)
+ InitAC97 (devc);
+ InitWM8770 (devc);
+ InitCS8415 (devc);
+/* Do not change the order of the above lines */
+
+ SetSPDIFConfig (devc, 0);
+ /* SetSDPIFSource(devc, DIGOUT_WAVE); */
+ SetDigInSource (devc, DIGIN_COAX);
+ SetFrontjack (devc, FRONT_JACK_HEADPHONE);
+ SetLineSource (devc, SRC_LINE_REAR);
+ SetClockSource (devc, ICE_INTERNAL_CLOCK);
+
+}
+
+static void
+aureon_set_rate (envy24ht_devc * devc)
+{
+ SetSampleRate (devc, devc->speed);
+}
+
+static int
+aureon_set_ctl (int dev, int ctl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ switch (ctl)
+ {
+ case 1:
+ return devc->m_LineInSource;
+ case 3:
+ return devc->m_DigInSource;
+ case 4:
+ return devc->m_Frontjack;
+ }
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctl)
+ {
+ case 1:
+ SetLineSource (devc, value);
+ return devc->m_LineInSource;
+ case 3:
+ SetDigInSource (devc, value);
+ return devc->m_DigInSource;
+ case 4:
+ SetFrontjack (devc, value);
+ return devc->m_Frontjack;
+ }
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+aureon_set_vol (int dev, int ChannelID, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->devc;
+ ULONG LineIndex;
+ WORD LeftRight;
+ int left, right;
+
+ /* Convert ChannelID to line index */
+ LineIndex = ChannelID >> 15;
+ /* Get the left/right side */
+ LeftRight = (WORD) (ChannelID & 0xffff);
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ left = right = 0;
+ if (LeftRight & CH_LEFT)
+ left = GetDACVolume (devc, (LineIndex << 15) | CH_LEFT);
+ if (LeftRight & CH_RIGHT)
+ right = GetDACVolume (devc, (LineIndex << 15) | CH_RIGHT);
+
+ if (left == 0)
+ left = right;
+ else if (right == 0)
+ right = left;
+
+ return left | (right << 8);
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ left = (value & 0xff);
+ right = ((value >> 8) & 0xff);
+
+ if (LeftRight != CH_BOTH)
+ right = left;
+
+ if (LeftRight & CH_LEFT)
+ SetDACVolume (devc, (LineIndex << 15) | CH_LEFT, left);
+
+ if (LeftRight & CH_RIGHT)
+ SetDACVolume (devc, (LineIndex << 15) | CH_RIGHT, right);
+
+ return left | (right << 8);
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+aureon_set_ac97 (int dev, int Index, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->devc;
+ int left, right;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return GetAC97Volume (devc, Index);
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ left = (value & 0xff);
+ right = ((value >> 8) & 0xff);
+
+ SetAC97Volume (devc, Index, left, right);
+
+ return left | (right << 8);
+ }
+
+ return OSS_EINVAL;
+}
+
+ /*ARGSUSED*/ static int
+aureon_mixer_init_common (envy24ht_devc * devc, int dev, int root)
+{
+ int ctl, group;
+
+ if ((group = mixer_ext_create_group (dev, root, "VOL")) < 0)
+ return group;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ CH_MASTER_BOTH,
+ aureon_set_vol,
+ MIXT_STEREOSLIDER, "MASTER",
+ WM_OUT_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ CH_FRONT_BOTH,
+ aureon_set_vol,
+ MIXT_STEREOSLIDER, "FRONT", WM_OUT_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ CH_REAR_BOTH,
+ aureon_set_vol,
+ MIXT_STEREOSLIDER, "SURROUND",
+ WM_OUT_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ CH_CENTER,
+ aureon_set_vol,
+ MIXT_MONOSLIDER, "CENTER", WM_OUT_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ CH_LFE,
+ aureon_set_vol,
+ MIXT_MONOSLIDER, "LFE", WM_OUT_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ CH_BS_BOTH,
+ aureon_set_vol,
+ MIXT_STEREOSLIDER, "REAR", WM_OUT_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((group =
+ mixer_ext_create_group_flags (dev, root, "TERRATEC", MIXF_FLAT)) < 0)
+ return group;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ 1,
+ aureon_set_ctl,
+ MIXT_ENUM, "LINESRC", 4,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "AUX WTL REAR GROUND", 0);
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ 3,
+ aureon_set_ctl,
+ MIXT_ENUM, "DIGIN", 3,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "OPTICAL COAX CD", 0);
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+aureon_mixer_init_universe (envy24ht_devc * devc, int dev, int group)
+{
+ int ctl;
+
+ if ((group = mixer_ext_create_group (dev, group, "ENVY24_UNIVERSE")) < 0)
+ return group;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ 4,
+ aureon_set_ctl,
+ MIXT_ENUM, "FRONTJACK", 3,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "LINEIN HEADPH", 0);
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+aureon_mixer_init_ac97 (envy24ht_devc * devc, int dev, int group)
+{
+ int ctl;
+
+ if ((group = mixer_ext_create_group (dev, group, "ENVY24_AC97")) < 0)
+ return group;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ AC97_MIC,
+ aureon_set_ac97,
+ MIXT_STEREOSLIDER, "MIC", AC97_INP_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ AC97_LINE,
+ aureon_set_ac97,
+ MIXT_STEREOSLIDER, "LINE",
+ AC97_INP_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ AC97_CD,
+ aureon_set_ac97,
+ MIXT_STEREOSLIDER, "CD", AC97_INP_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ AC97_PHONO,
+ aureon_set_ac97,
+ MIXT_STEREOSLIDER, "PHONO",
+ AC97_INP_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, group,
+ AC97_AUX,
+ aureon_set_ac97,
+ MIXT_STEREOSLIDER, "AUX", AC97_INP_MAX,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ return 0;
+}
+
+static int
+aureon_mixer_init (envy24ht_devc * devc, int dev, int root)
+{
+ aureon_mixer_init_common (devc, dev, root);
+
+ if (devc->subvendor == SSID_AUREON_UNIVERSE)
+ aureon_mixer_init_universe (devc, dev, root);
+
+ if (devc->subvendor != SSID_PHASE28)
+ aureon_mixer_init_ac97 (devc, dev, root);
+ return 0;
+}
+
+envy24ht_auxdrv_t envy24ht_aureon_auxdrv = {
+ aureon_card_init,
+ aureon_mixer_init,
+ aureon_set_rate,
+ NULL,
+ NULL,
+ NULL, /* aureon_private1 */
+};
diff --git a/kernel/drv/oss_envy24ht/envy24ht_julia.c b/kernel/drv/oss_envy24ht/envy24ht_julia.c
new file mode 100644
index 0000000..544dd08
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/envy24ht_julia.c
@@ -0,0 +1,547 @@
+/*
+ * Purpose: Low level routines for the ESI (Egosys) Juli@ card
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_envy24ht_cfg.h"
+
+#include "spdif.h"
+#include "envy24ht.h"
+
+#define AK4358_ADDRESS 0x11
+#define AK4114_ADDRESS 0x10
+
+static unsigned char
+i2c_read (envy24ht_devc * devc, unsigned char addr, unsigned char pos)
+{
+ int i;
+ unsigned char data;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x11); /* Offset */
+ OUTB (devc->osdev, addr << 1, devc->ccs_base + 0x10); /* Read address */
+
+ for (i = 0; i < 2000; i++)
+ {
+ unsigned char status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+
+ oss_udelay (1);
+ data = INB (devc->osdev, devc->ccs_base + 0x12);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return data;
+}
+
+static void
+i2c_write (envy24ht_devc * devc, unsigned char addr, unsigned char pos,
+ unsigned char data)
+{
+ int i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ for (i = 0; i < 2000; i++)
+ {
+ unsigned char status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x11); /* Offset */
+ OUTB (devc->osdev, data, devc->ccs_base + 0x12); /* Data */
+ OUTB (devc->osdev, (addr << 1) | 1, devc->ccs_base + 0x10); /* Write address */
+
+ for (i = 0; i < 2000; i++)
+ {
+ unsigned char status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ if ((addr == AK4358_ADDRESS) && (pos <= 0x0c))
+ devc->m_DACVolume[pos] = data;
+}
+
+static void
+GPIOWrite (envy24ht_devc * devc, int pos, int bit)
+{
+ int data = INW (devc->osdev, devc->ccs_base + 0x14);
+
+ bit = (bit != 0);
+
+ data &= ~(1 << pos);
+ data |= (bit << pos);
+
+ OUTW (devc->osdev, data, devc->ccs_base + 0x14);
+}
+
+static int
+set_dac (envy24ht_devc * devc, int reg, int level)
+{
+ if (level < 0)
+ level = 0;
+ if (level > 0x7f)
+ level = 0x7f;
+
+ i2c_write (devc, AK4358_ADDRESS, reg, level | 0x80);
+
+ return level;
+}
+
+static struct {
+ int rate, spdifin, clks;
+} rate_sel[] = {
+ {32000, 0x30, 0x08},
+ {44100, 0x00, 0x09},
+ {48000, 0x20, 0x0A},
+ {88200, 0x80, 0x05},
+ {96000, 0xA0, 0x06},
+ {176400, 0xC0, 0x01},
+ {192000, 0xE0, 0x02},
+ {16000, -1, 0x0C},
+ {22050, -1, 0x0D},
+ {24000, -1, 0x0E},
+ {64000, -1, 0x04},
+ {128000, -1, 0x00},
+ {-1, -1, -1}
+};
+
+static void
+julia_set_deemph (envy24ht_devc * devc, int mode)
+{
+ int deemph = 0x01; /* OFF */
+
+ if (mode == 0)
+ i2c_write (devc, AK4358_ADDRESS, 0x03, deemph);
+ else {
+
+ if (devc->speed == 44100)
+ deemph = 0x00;
+ else if (devc->speed == 48000)
+ deemph = 0x02;
+ else if (devc->speed == 32000)
+ deemph = 0x03;
+
+ i2c_write (devc, AK4358_ADDRESS, 0x03, deemph);
+ }
+}
+
+static void
+julia_Monitor (envy24ht_devc * devc, int bMonitor, int num)
+{
+ switch (num)
+ {
+ case 0: /* MUTE */
+ if (bMonitor)
+ {
+ i2c_write (devc, AK4358_ADDRESS, 1, 0x03);
+ GPIOWrite (devc, 15, 1);
+ } else {
+ i2c_write (devc, AK4358_ADDRESS, 1, 0x01);
+ GPIOWrite (devc, 15, 0);
+ }
+ break;
+
+ case 1: /* LINEIN */
+ if (bMonitor)
+ GPIOWrite (devc, 13, 1);
+ else
+ GPIOWrite (devc, 13, 0);
+ break;
+
+ case 2: /* SPDIFOUT */
+ if (bMonitor)
+ GPIOWrite (devc, 11, 1);
+ else
+ GPIOWrite (devc, 11, 0);
+ break;
+ case 3: /* SPDIFIN */
+ if (bMonitor)
+ GPIOWrite (devc, 12, 1);
+ else
+ GPIOWrite (devc, 12, 0);
+ break;
+ case 4: /* De-emphasis */
+ julia_set_deemph (devc, bMonitor);
+ break;
+ }
+ devc->monitor[num] = bMonitor;
+}
+
+static void
+ak4114_init (envy24ht_devc * devc)
+{
+ /*
+ * AK4114 S/PDIF interface initialization
+ */
+ i2c_write (devc, AK4114_ADDRESS, 0x00, 0x0f);
+ i2c_write (devc, AK4114_ADDRESS, 0x01, 0x70);
+ i2c_write (devc, AK4114_ADDRESS, 0x02, 0x80);
+ i2c_write (devc, AK4114_ADDRESS, 0x03, 0x49);
+ i2c_write (devc, AK4114_ADDRESS, 0x04, 0x00);
+ i2c_write (devc, AK4114_ADDRESS, 0x05, 0x00);
+
+ i2c_write (devc, AK4114_ADDRESS, 0x0d, 0x41);
+ i2c_write (devc, AK4114_ADDRESS, 0x0e, 0x02);
+ i2c_write (devc, AK4114_ADDRESS, 0x0f, 0x2c);
+ i2c_write (devc, AK4114_ADDRESS, 0x10, 0x00);
+ i2c_write (devc, AK4114_ADDRESS, 0x11, 0x00);
+}
+
+static void
+julia_set_rate (envy24ht_devc * devc)
+{
+ int i, data;
+ int adc = 0x00;
+
+ if (devc->speed <= 48000)
+ devc->m_DACVolume[2] = 0x4f; /* DFS=normal-speed */
+ else if (devc->speed <= 96000)
+ {
+ adc = 0x04;
+ devc->m_DACVolume[2] = 0x5f; /* DFS=double-speed */
+ }
+ else
+ {
+ adc = 0x03;
+ devc->m_DACVolume[2] = 0x6f; /* DFS=quad-speed */
+ }
+
+ data = INW (devc->osdev, devc->ccs_base + 0x14);
+ data &= ~0x70f;
+ data |= adc << 8;
+
+ for (i = 0; rate_sel[i].rate; i++)
+ if (rate_sel[i].rate == devc->speed)
+ data |= rate_sel[i].clks;
+
+ OUTW (devc->osdev, data, devc->ccs_base + 0x14);
+
+ OUTB (devc->osdev, 0x80, devc->mt_base + 0x05); /* RESET */
+ OUTB (devc->osdev, 0x00, devc->mt_base + 0x05);
+
+ if (devc->speed == 8000)
+ OUTB (devc->osdev, 0x06, devc->mt_base + 0x01);
+ else if (devc->speed == 9600)
+ OUTB (devc->osdev, 0x03, devc->mt_base + 0x01);
+ else if (devc->speed == 11025)
+ OUTB (devc->osdev, 0x0a, devc->mt_base + 0x01);
+ else if (devc->speed == 12000)
+ OUTB (devc->osdev, 0x02, devc->mt_base + 0x01);
+ else
+ OUTB (devc->osdev, 0x10, devc->mt_base + 0x01);
+
+ /* Restore ak4358 regs and set DFS */
+ for (i = 0; i <= 0x0c; i++)
+ i2c_write (devc, AK4358_ADDRESS, i, devc->m_DACVolume[i]);
+ /* Restore ak4114 */
+ ak4114_init (devc);
+ if (devc->monitor[4] == 1)
+ julia_set_deemph (devc, 1);
+}
+
+static void
+julia_sync_ak4114 (void *arg)
+{
+ envy24ht_devc *devc = arg;
+ int i;
+ int spdifin = i2c_read (devc, AK4114_ADDRESS, 7);
+
+ for (i = 0; rate_sel[i].rate; i++)
+ if (rate_sel[i].spdifin == spdifin)
+ {
+ if (devc->speed != rate_sel[i].rate)
+ {
+ devc->speed = rate_sel[i].rate;
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+ julia_set_rate (devc);
+ }
+ break;
+ }
+
+ if (devc->syncsource == 1)
+ devc->timeout_id = timeout (julia_sync_ak4114, devc, OSS_HZ);
+}
+
+static int
+julia_set_syncsource (envy24ht_devc * devc, int value)
+{
+ if (value == 1)
+ {
+ GPIOWrite (devc, 4, 0);
+ devc->timeout_id = timeout (julia_sync_ak4114, devc, OSS_HZ);
+ } else {
+ if (devc->timeout_id != 0)
+ untimeout (devc->timeout_id);
+ devc->timeout_id = 0;
+
+ GPIOWrite (devc, 4, 1);
+
+ if (devc->speed != devc->pending_speed)
+ {
+ devc->speed = devc->pending_speed;
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+ julia_set_rate (devc);
+ }
+ }
+
+ return 0;
+}
+
+static int
+julia_audio_ioctl (envy24ht_devc * devc, envy24ht_portc * portc, unsigned int cmd,
+ ioctl_arg arg)
+{
+ int left, right, value;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_GETPLAYVOL:
+ if (portc != &devc->play_portc[0])
+ return OSS_EINVAL;
+ left = (devc->gains[0] & 0xff) * 100 / 0x7f;
+ right = ((devc->gains[0] >> 8) & 0xff) * 100 / 0x7f;
+ return *arg = (left | (right << 8));
+ break;
+
+ case SNDCTL_DSP_SETPLAYVOL:
+ if (portc != &devc->play_portc[0])
+ return OSS_EINVAL;
+ value = *arg;
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ left = (left * 0x7f) / 100;
+ right = (right * 0x7f) / 100;
+ left = set_dac (devc, 0x04, left);
+ right = set_dac (devc, 0x05, right);
+ devc->gains[0] = left | (right << 8);
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+ return 0;
+ break;
+ }
+ return OSS_EINVAL;
+}
+
+static int
+julia_set_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (ctrl < 0 || ctrl > 4)
+ return OSS_EINVAL;
+
+ return devc->monitor[ctrl];
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ if (ctrl < 0 || ctrl > 4)
+ return OSS_EINVAL;
+
+ value = !!value;
+ julia_Monitor (devc, value, ctrl);
+ return devc->monitor[ctrl];
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+julia_set_ak4358 (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (ctrl < 0 || ctrl > 4)
+ return OSS_EIO;
+
+ return devc->gains[ctrl];
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ int left, right;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ switch (ctrl)
+ {
+ case 0: /* PCM */
+ left = set_dac (devc, 0x04, left);
+ right = set_dac (devc, 0x05, right);
+ break;
+ case 1: /* LINEIN */
+ left = set_dac (devc, 0x06, left);
+ right = set_dac (devc, 0x07, right);
+ break;
+ case 2: /* SPDIFOUT */
+ left = set_dac (devc, 0x08, left);
+ right = set_dac (devc, 0x09, right);
+ break;
+ case 3: /* SPDIFIN */
+ left = set_dac (devc, 0x0B, left);
+ right = set_dac (devc, 0x0C, right);
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ value = left | (right << 8);
+ return devc->gains[ctrl] = value;
+ }
+
+ return OSS_EINVAL;
+}
+
+ /*ARGSUSED*/ static int
+julia_mixer_init (envy24ht_devc * devc, int dev, int g)
+{
+ int group = g;
+ int err, monitor;
+
+ if ((group = mixer_ext_create_group (dev, g, "VOL")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 0, julia_set_control,
+ MIXT_ONOFF,
+ "ENVY24_MUTE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 0, julia_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_PCM", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, julia_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_LINEIN", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, julia_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_SPDIFOUT", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, julia_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_SPDIFIN", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((monitor = mixer_ext_create_group (dev, g, "MONITOR")) < 0)
+ return monitor;
+
+ if ((err = mixer_ext_create_control (dev, monitor,
+ 1, julia_set_control,
+ MIXT_ONOFF,
+ "ENVY24_LINEIN", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, monitor,
+ 2, julia_set_control,
+ MIXT_ONOFF,
+ "ENVY24_SPDIFOUT", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, monitor,
+ 3, julia_set_control,
+ MIXT_ONOFF,
+ "ENVY24_SPDIFIN", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, monitor,
+ 4, julia_set_control,
+ MIXT_ENUM,
+ "ENVY24_DEEMPH", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ mixer_ext_set_strings (dev, err, "OFF 50/15usec", 0);
+
+ return 0;
+}
+
+static void
+julia_card_init (envy24ht_devc * devc)
+{
+ ak4114_init (devc);
+/*
+ * AK4358 DAC initialization
+ */
+ i2c_write (devc, AK4358_ADDRESS, 2, 0x00);
+ i2c_write (devc, AK4358_ADDRESS, 2, 0x4E);
+ i2c_write (devc, AK4358_ADDRESS, 0, 0x06);
+ i2c_write (devc, AK4358_ADDRESS, 1, 0x02);
+ i2c_write (devc, AK4358_ADDRESS, 3, 0x01);
+
+ set_dac (devc, 0x04, 0x7f);
+ set_dac (devc, 0x05, 0x7f);
+ set_dac (devc, 0x06, 0x7f);
+ set_dac (devc, 0x07, 0x7f);
+ set_dac (devc, 0x08, 0x7f);
+ set_dac (devc, 0x09, 0x7f);
+ set_dac (devc, 0x0b, 0x7f);
+ set_dac (devc, 0x0c, 0x7f);
+
+ i2c_write (devc, AK4358_ADDRESS, 0xA, 0x00);
+ i2c_write (devc, AK4358_ADDRESS, 0xD, 0x00);
+ i2c_write (devc, AK4358_ADDRESS, 0xE, 0x00);
+ i2c_write (devc, AK4358_ADDRESS, 0xF, 0x00);
+ i2c_write (devc, AK4358_ADDRESS, 2, 0x4F);
+
+ julia_Monitor (devc, 0, 0); /* Unmute */
+}
+
+static void
+julia_card_uninit (envy24ht_devc * devc)
+{
+ if (devc->timeout_id != 0)
+ untimeout (devc->timeout_id);
+}
+
+envy24ht_auxdrv_t envy24ht_julia_auxdrv = {
+ julia_card_init,
+ julia_mixer_init,
+ julia_set_rate,
+ NULL,
+ NULL,
+ julia_set_syncsource,
+ julia_audio_ioctl,
+ julia_card_uninit
+};
diff --git a/kernel/drv/oss_envy24ht/envy24ht_revo51.c b/kernel/drv/oss_envy24ht/envy24ht_revo51.c
new file mode 100644
index 0000000..e84cb6a
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/envy24ht_revo51.c
@@ -0,0 +1,938 @@
+/*
+ * Purpose: Low level routines for M Audio Revolution 5.1
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_envy24ht_cfg.h"
+
+#include "spdif.h"
+#include "envy24ht.h"
+
+static char channel_names[4][10] = {
+ "front",
+ "c/l",
+ "surround",
+ "headph"
+};
+
+#define BIT(x) (1<<(x))
+#define BIT3 BIT(3)
+
+/*----- SPI bus for CODEC communication. */
+/* */
+#define SPI_CLK 1 /* Clock output to CODEC's, rising edge clocks data. */
+#define SPI_DOUT 3 /* Data output to the CODEC. */
+#define SPI_CS0n (1<<4) /* Selects first chip. */
+#define SPI_CS1n (1<<5) /* Selects second chip. */
+#define SPI_CC_AK4358 0x02 /* C1:C0 for ak4358. */
+#define SPI_CC_AK5365 0x02 /* C1:C0 for ak5365. */
+#define WRITEMASK 0xffff
+/*----- Revolution defines. */
+/* */
+#define REVO51_AK5365 (1) /* iDevice value for AK5365 A/D. */
+#define REVO51_AK4358 (2) /* iDevice value for AK4358 D/A. */
+
+static unsigned int
+GpioReadAll (envy24ht_devc * devc)
+{
+ return INW (devc->osdev, devc->ccs_base + 0x14);
+}
+
+static void
+GpioWriteAll (envy24ht_devc * devc, unsigned int data)
+{
+ OUTW (devc->osdev, 0xffff, devc->ccs_base + 0x18); /* GPIO direction */
+ OUTW (devc->osdev, 0x0000, devc->ccs_base + 0x16); /* GPIO write mask */
+
+ OUTW (devc->osdev, data, devc->ccs_base + 0x14);
+}
+
+static void
+GpioWrite (envy24ht_devc * devc, int pos, int bit)
+{
+ int data = GpioReadAll (devc);
+
+ bit = (bit != 0);
+
+ data &= ~(1 << pos);
+ data |= (bit << pos);
+
+ GpioWriteAll (devc, data);
+}
+
+void
+REVO51_Assert_CS (envy24ht_devc * devc, int iDevice)
+/*
+*****************************************************************************
+* Assert chip select to specified GPIO-connected device.
+* iDevice: REVO51_AK5365=ADC, REVO51_AK4358=DAC.
+****************************************************************************/
+{
+ unsigned int dwGPIO; /* Current GPIO's. */
+ dwGPIO = GpioReadAll (devc); /* Read current GPIO's. */
+ dwGPIO |= (SPI_CS0n | SPI_CS1n); /* Reset CS bits. */
+ switch (iDevice) /* Select CS#. */
+ {
+ case REVO51_AK4358:
+ dwGPIO &= ~SPI_CS0n;
+ break; /* DAC */
+ case REVO51_AK5365:
+ dwGPIO &= ~SPI_CS1n;
+ break; /* ADC */
+ default:
+ break;
+ }
+ GpioWriteAll (devc, dwGPIO); /* Write hardware. */
+}
+
+void
+REVO51_DeAssert_CS (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* De-Assert all chip selects.
+****************************************************************************/
+{
+ unsigned int dwGPIO = GpioReadAll (devc); /* Current GPIO's. */
+ dwGPIO |= (SPI_CS0n | SPI_CS1n); /* Clear CS bits. */
+ GpioWriteAll (devc, dwGPIO); /* Write back to hardware. */
+}
+
+/*#define _delay() oss_udelay(1) */
+#define _delay() {}
+
+void
+REVO51_WriteSpiAddr (envy24ht_devc * devc, int iDevice, unsigned char bReg)
+/*
+*****************************************************************************
+* Write the address byte part of the SPI serial stream.
+* iDevice: REVO51_AK4358=DAC, REVO51_AK5365=ADC, etc.
+****************************************************************************/
+{
+ unsigned char bHdr;
+ unsigned char bNum;
+/* Built 8-bit packet header: C1,C0,R/W,A4,A3,A2,A1,A0. */
+/* */
+ switch (iDevice)
+ {
+ case REVO51_AK4358:
+ bHdr = SPI_CC_AK4358 << 6;
+ break;
+ case REVO51_AK5365:
+ bHdr = SPI_CC_AK5365 << 6;
+ break;
+ default:
+ bHdr = 0;
+ break;
+ }
+ bHdr = bHdr | 0x20 | (bReg & 0x1F); /* "write" + address. */
+/* Write header to SPI. */
+/* */
+ for (bNum = 0; bNum < 8; bNum++)
+ {
+ GpioWrite (devc, SPI_CLK, 0); /* Drop clock low. */
+ _delay ();
+ GpioWrite (devc, SPI_DOUT, 0x080 & bHdr); /* Write data bit. */
+ _delay ();
+ GpioWrite (devc, SPI_CLK, 1); /* Raise clock. */
+ _delay ();
+ bHdr <<= 1; /* Next bit. */
+ }
+}
+
+void
+REVO51_WriteSpiReg (envy24ht_devc * devc, int iDevice, unsigned char bReg,
+ unsigned char bData)
+/*
+*****************************************************************************
+* Writes one register in specified CHIP.
+* devc = PCI slot code of specific board.
+* iDevice: REVO51_AK4358=DAC, REVO51_AK5365=ADC, etc.
+****************************************************************************/
+{
+ unsigned char bNum;
+ GpioWrite (devc, SPI_DOUT, 0); /* Init SPI signals. */
+ GpioWrite (devc, SPI_CLK, 1); /* */
+/* Drop the chip select low. */
+/* Wait at least 150 nS. */
+/* */
+ REVO51_Assert_CS (devc, iDevice);
+ _delay ();
+/* Write the address byte. */
+/* */
+ REVO51_WriteSpiAddr (devc, iDevice, bReg);
+/* Write the data byte. */
+/* */
+ for (bNum = 0; bNum < 8; bNum++)
+ {
+ GpioWrite (devc, SPI_CLK, 0); /* Drop clock low. */
+ _delay ();
+ GpioWrite (devc, SPI_DOUT, 0x080 & bData); /* Write data bit. */
+ _delay ();
+ GpioWrite (devc, SPI_CLK, 1); /* Raise clock. */
+ _delay ();
+ bData <<= 1; /* Next bit. */
+ }
+/* De-assert chip selects. */
+/* */
+ REVO51_DeAssert_CS (devc);
+ _delay ();
+}
+
+
+#define GPIO_MUTEn 22 /* Converter mute signal. */
+void
+REVO51_Mute (envy24ht_devc * devc, int bMute)
+/*
+*****************************************************************************
+* Mutes all outputs if bMute=1.
+****************************************************************************/
+{
+ if (bMute)
+ {
+/* Soft-mute. Delay currently unspecified, try ½ second. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 1, 0x03);
+ _delay ();
+/* Switch mute transistors on. */
+ GpioWrite (devc, GPIO_MUTEn, 0);
+ }
+ else
+ {
+/* Switch mute transistors off. Delay currently unspecified, try ½ second. */
+ GpioWrite (devc, GPIO_MUTEn, 1);
+ _delay ();
+/* Release Soft-mute. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 1, 0x01);
+ }
+
+ devc->mute = bMute;
+}
+
+
+void
+REVO51_Set_OutAttn (envy24ht_devc * devc, unsigned char bChan, int iAttn)
+/*
+*****************************************************************************
+* Sets the attenuation on one output channel.
+* bChan = Channel number (0..7).
+* Channel 0:1 = front, 2:3 = center/sub, 4:5 = rear, 6:7 = headphones.
+* Registers are 0x04, 05, 06, 07, 08, 09, 0B, 0C respectively
+* iAttn = Number of steps to attenuate CODEC.
+* Each step equals .5dB (-127..0)
+****************************************************************************/
+{
+ unsigned char bIndex;
+ unsigned char bAttn;
+ if (bChan > 7 || iAttn > 0 || iAttn < -127) /* parameter test */
+ {
+ cmn_err (CE_CONT, "\ninvalid data! %d=bChan, %d=iAttn", bChan, iAttn);
+ return;
+ }
+ if (bChan < 6)
+ bIndex = 0x04 + bChan; /* for registers 0x04..0x09 */
+ else
+ bIndex = 0x05 + bChan; /* for registers 0x0B..0x0C */
+ bAttn = (0x80 + (unsigned char) (iAttn + 127)); /* 7F is max volume. */
+/* MSB enables attenuation. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, bIndex, bAttn);
+}
+
+static void
+ADC_Set_Chan (envy24ht_devc * devc, int iChan)
+/***************************************************************************
+* Makes input selection for ADC.
+* 0=mic, 1=line, 2=aux
+****************************************************************************/
+{
+/*Check param */
+ if (2 < iChan)
+#define GPIO_SDA 6 /* SDA pin */
+ cmn_err (CE_CONT, "\nInvalid Input channel parameter");
+ else
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 1, (unsigned char) iChan);
+}
+
+#define GPIO_SCL 7 /* SCL pin */
+static void
+start_bit (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* Send I2C Start Bit.
+****************************************************************************/
+{
+ GpioWrite (devc, GPIO_SDA, 1); /* Make sure DATA high. */
+ _delay ();
+ GpioWrite (devc, GPIO_SCL, 1); /* Set clock high. */
+ _delay ();
+ GpioWrite (devc, GPIO_SDA, 0); /* Falling edge indicates start bit. */
+ _delay ();
+ GpioWrite (devc, GPIO_SCL, 0); /* Start clock train. */
+}
+
+static void
+byte_out (envy24ht_devc * devc, unsigned char b8)
+/*
+*****************************************************************************
+* Send current 8 input bits in B8. Msb is first written.
+****************************************************************************/
+{
+ int bnum; /* bit number */
+ for (bnum = 7; bnum >= 0; bnum--)
+ {
+ GpioWrite (devc, GPIO_SDA, b8 & 0x80); /* Set bit. */
+ _delay (); /* */
+ GpioWrite (devc, GPIO_SCL, 1); /* Set clock high. */
+ _delay (); /* */
+ GpioWrite (devc, GPIO_SCL, 0); /* Return clock low. */
+ b8 = b8 << 1; /* Next position. */
+ }
+/* No ACK, but we need to clock a false "9th" bit. */
+ _delay (); /* */
+ GpioWrite (devc, GPIO_SCL, 1); /* Set clock high. */
+ _delay (); /* */
+ GpioWrite (devc, GPIO_SCL, 0); /* Return clock low. */
+}
+
+static void
+stop_bit (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* Send I2C Stop Bit.
+****************************************************************************/
+{
+ GpioWrite (devc, GPIO_SDA, 0); /* Make sure data is low. */
+ _delay ();
+ GpioWrite (devc, GPIO_SCL, 1); /* Set clock high. */
+ _delay ();
+ GpioWrite (devc, GPIO_SDA, 1); /* Rising edge indicates stop bit. */
+}
+static void
+PT2258S_Write_Data (envy24ht_devc * devc, int cnt, unsigned char *aData)
+/*
+************************************************************************ *****
+* Write an array of bytes (aData) to address VADDR in PT2258S.
+* Assumes I2C Bus is inactive, i.e., SCL=1,SDA=1 and both are outputs.
+* This routine waits for the byte to complete writing.
+************************************************************************ ****/
+{
+ int i;
+ start_bit (devc); /* Send start bit. */
+ byte_out (devc, (unsigned char) 0x80); /* Set address to write data to. */
+ for (i = 0; i < cnt; i++)
+ byte_out (devc, aData[i]); /* Write data to address. */
+ stop_bit (devc); /* Stop bit ends operation. */
+}
+static void
+PT2258S_Write_Byte (envy24ht_devc * devc, unsigned char vdata)
+/*
+*****************************************************************************
+* Write a byte VDATA to address VADDR in PT2258S.
+* Assumes I2C Bus is inactive, i.e., SCL=1,SDA=1 and both are outputs.
+* This routine waits for the byte to complete writing.
+****************************************************************************/
+{
+ start_bit (devc); /* Send start bit. */
+ byte_out (devc, (unsigned char) 0x80); /* Set address to write data to. */
+ byte_out (devc, vdata); /* Write data to address. */
+ stop_bit (devc); /* Stop bit ends operation. */
+}
+
+static void
+PT2258S_Set_Attn (envy24ht_devc * devc, unsigned char bChan, int iAttn)
+/*
+************************************************************************ *****
+* Set the attenuation of a specific channel.
+* bChan = 0..5.
+* iAttn = 0..-79.
+************************************************************************ ****/
+{
+ static unsigned char bXlat[] = { 0x90, 0x50, 0x10, 0x30, 0x70, 0xB0 };
+ unsigned char aAttn[2];
+ aAttn[1] = (-iAttn) % 10; /* 1's digit */
+ aAttn[0] = (-iAttn) / 10; /* 10's digit */
+/* Check parameters. */
+ if ((bChan > 5) || (iAttn < (-79) || iAttn > 0))
+ {
+ cmn_err (CE_CONT, "\nPT2258S_Set_Attn() parameter out of range!");
+ return;
+ }
+/* Always set 10's digit, then 1's. */
+ aAttn[0] += bXlat[bChan] - 0x10;
+ aAttn[1] += bXlat[bChan];
+ PT2258S_Write_Data (devc, 2, aAttn);
+}
+static void
+PT2258S_Mute (envy24ht_devc * devc, int bMute)
+/*
+*****************************************************************************
+* Mute all 6 outputs of the monitoring volume control.
+* Unmuting returns volume to previous levels.
+****************************************************************************/
+{
+ if (bMute)
+ PT2258S_Write_Byte (devc, (unsigned char) 0xF9);
+ else
+ PT2258S_Write_Byte (devc, (unsigned char) 0xF8);
+}
+
+
+static void
+REVO51_Set_48K_Mode (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* Sets Chip and Envy24 for 8kHz-48kHz sample rates.
+****************************************************************************/
+{
+/* ICE MCLK = 256x. */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 2) & ~BIT3,
+ devc->mt_base + 2);
+/* DFS=normal, RESET. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 2, 0x4E);
+/* DFS=normal, NORMAL OPERATION. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 2, 0x4F);
+}
+
+static void
+REVO51_Set_96K_Mode (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* Sets CODEC and Envy24 for 60kHz-96kHz sample rates.
+****************************************************************************/
+{
+/* ICE MCLK = 256x. */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 2) & ~BIT3,
+ devc->mt_base + 2);
+/* DFS=double-speed, RESET. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 2, 0x5E);
+/* DFS=double-speed, NORMAL OPERATION. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 2, 0x5F);
+}
+
+static void
+REVO51_Set_192K_Mode (envy24ht_devc * devc)
+/*
+*****************************************************************************
+* Sets CODEC and Envy24 for 120kHz-192kHz sample rate.
+****************************************************************************/
+{
+/* ICE MCLK = 128x. */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 2) | BIT3,
+ devc->mt_base + 2);
+ _delay ();
+/*----- SET THE D/A. */
+/* DFS=quad-speed, RESET. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 2, 0x6E);
+ _delay ();
+/* DFS=quad-speed, NORMAL OPERATION. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 2, 0x6F);
+/*------ POWER DOWN THE A/D -- doesn't support 192K. */
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 0, 0x00);
+}
+
+static int
+set_dac (envy24ht_devc * devc, int reg, int level)
+{
+ if (level < 0)
+ level = 0;
+ if (level > 0x7f)
+ level = 0x7f;
+
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, reg, level | 0x80);
+
+ return level;
+}
+
+static void
+AK4358_Init (envy24ht_devc * devc)
+{
+/*===== AK4358 D/A initialization. Leave soft-muted. */
+/* */
+/* Power down, reset, normal mode. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 2, 0x00);
+/* Power up, reset, normal mode */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 2, 0x4E);
+/* Reset timing, Mode 3(I2S), disable auto clock detect, sharp roll off. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 0, 0x06);
+/* Soft mute, reset timing. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 1, 0x02);
+/* De-emphasis off. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 3, 0x01);
+/* Max volume on all 8 channels. */
+ set_dac (devc, 0x04, 0x7f);
+ set_dac (devc, 0x05, 0x7f);
+ set_dac (devc, 0x06, 0x7f);
+ set_dac (devc, 0x07, 0x7f);
+ set_dac (devc, 0x08, 0x7f);
+ set_dac (devc, 0x09, 0x7f);
+ set_dac (devc, 0x0b, 0x7f);
+ set_dac (devc, 0x0c, 0x7f);
+
+/* Datt mode 0, DZF non-invert, DCLK polarity 0, PCM mode, DCKS 512fs, TDM normal. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 0xA, 0x00);
+/* DZF control disabled. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 0xD, 0x00);
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 0xE, 0x00);
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 0xF, 0x00);
+/* Power up, normal operation. */
+ REVO51_WriteSpiReg (devc, REVO51_AK4358, 2, 0x4F);
+}
+
+static void
+PT2258_init (envy24ht_devc * devc)
+{
+/*===== PT2258 initialization. */
+/* */
+/* Initializes and clears register . */
+ PT2258S_Write_Byte (devc, (unsigned char) 0xC0);
+/*Example of 2-line command controlling all channels. */
+/*This sets all channels to max volume. */
+/*PT2258S_Write_Byte(devc, (unsigned char)0xE0); */
+/*PT2258S_Write_Byte(devc, (unsigned char)0xD0); */
+/* set volumes */
+ PT2258S_Set_Attn (devc, 0, 0);
+ PT2258S_Set_Attn (devc, 1, 0);
+ PT2258S_Set_Attn (devc, 2, 0);
+ PT2258S_Set_Attn (devc, 3, 0);
+ PT2258S_Set_Attn (devc, 4, 0);
+ PT2258S_Set_Attn (devc, 5, 0);
+/*mute, true or false */
+ PT2258S_Mute (devc, 0);
+}
+
+static void
+REVO51_set_recsrc (envy24ht_devc * devc, int src)
+{
+ devc->recsrc = src;
+
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 1, src);
+}
+
+static void
+AK5365_Init (envy24ht_devc * devc)
+{
+/*===== AK5365 2-ch A/D initialization. Leave soft-muted. */
+/* */
+/* Power down. */
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 0, 0x00);
+/* Set input to (LINE IN). */
+ REVO51_set_recsrc (devc, 0);
+/* Clock freq 256fs, I2S mode, mute off. */
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 2, 0x08);
+/* ALC settings (ALC is disabled, so rewrite default values). */
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 3, 0x2B);
+/* Neutral analog and digital gain. */
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 4, 0x7F);
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 5, 0x7F);
+/* ALC settings (ALC is disabled, so rewrite default values). */
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 6, 0x28);
+/* ALC settings (ALC is disabled, so rewrite default values). */
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 7, 0x89);
+/* Power up. */
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 0, 0x01);
+}
+
+static void
+revo51_set_rate (envy24ht_devc * devc)
+{
+ int tmp;
+
+ tmp = INB (devc->osdev, devc->mt_base + 0x02);
+ if (devc->speed <= 48000)
+ {
+ REVO51_Set_48K_Mode (devc);
+ OUTB (devc->osdev, tmp & ~BIT (3), devc->mt_base + 0x02);
+ return;
+ }
+
+ if (devc->speed <= 96000)
+ {
+ REVO51_Set_96K_Mode (devc);
+
+ return;
+ }
+
+ REVO51_Set_192K_Mode (devc);
+ OUTB (devc->osdev, tmp | BIT (3), devc->mt_base + 0x02);
+}
+
+static int
+revo51_audio_ioctl (envy24ht_devc * devc, envy24ht_portc * portc, unsigned int cmd,
+ ioctl_arg arg)
+{
+ int value;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_GET_RECSRC_NAMES:
+ return oss_encode_enum ((oss_mixer_enuminfo *) arg, "mic line aux", 0);
+ break;
+
+ case SNDCTL_DSP_GET_RECSRC:
+ return *arg = devc->recsrc;
+ break;
+
+ case SNDCTL_DSP_SET_RECSRC:
+ value = *arg;
+ if (value < 0 || value > 2)
+ return OSS_EINVAL;
+ REVO51_set_recsrc (devc, value);
+ return *arg = devc->recsrc;
+ break;
+
+ case SNDCTL_DSP_GET_PLAYTGT:
+ case SNDCTL_DSP_SET_PLAYTGT:
+ return *arg = 0;
+ break;
+
+ case SNDCTL_DSP_GET_PLAYTGT_NAMES:
+ return oss_encode_enum ((oss_mixer_enuminfo *) arg, portc->name, 0);
+ break;
+
+
+ default:
+ return OSS_EINVAL;
+ }
+}
+
+static int
+set_reclevel (envy24ht_devc * devc, int value)
+{
+ int left, right;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ if (left > 0x98)
+ left = 0x98;
+ if (right > 0x98)
+ right = 0x98;
+
+ value = left | (right << 8);
+
+ devc->reclevel = value;
+
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 4, left);
+ REVO51_WriteSpiReg (devc, REVO51_AK5365, 5, right);
+
+ return value;
+}
+
+static int
+revo51_set_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ switch (ctrl)
+ {
+ case 0:
+ return devc->mute;
+
+ case 1:
+ return devc->recsrc;
+
+ case 2:
+ return devc->reclevel;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ switch (ctrl)
+ {
+ case 0:
+ value = !!value;
+ REVO51_Mute (devc, value);
+ return devc->mute;
+
+ case 1:
+ if (value < 0 || value > 2)
+ return devc->recsrc;
+ REVO51_set_recsrc (devc, value);
+ return devc->recsrc;
+
+ case 2:
+ return set_reclevel (devc, value);
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+revo51_set_ak4358 (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (ctrl < 0 || ctrl > 4)
+ return OSS_EIO;
+
+ return devc->gains[ctrl];
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ int left, right;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ switch (ctrl)
+ {
+ case 0: /* Front */
+ left = set_dac (devc, 0x04, left);
+ right = set_dac (devc, 0x05, right);
+ break;
+
+ case 1: /* Center */
+ left = set_dac (devc, 0x06, left);
+ right = left;
+ break;
+
+ case 2: /* LFE */
+ left = set_dac (devc, 0x07, left);
+ right = left;
+ break;
+
+ case 3: /* Surround */
+ left = set_dac (devc, 0x08, left);
+ left = set_dac (devc, 0x09, right);
+ break;
+
+ case 4: /* Headphones */
+ left = set_dac (devc, 0x0b, left);
+ left = set_dac (devc, 0x0c, right);
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ value = left | (right << 8);
+ return devc->gains[ctrl] = value;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+set_mongain (envy24ht_devc * devc, int reg, int value)
+{
+ if (value < 0)
+ value = 0;
+ if (value > 79)
+ value = 79;
+
+ PT2258S_Set_Attn (devc, reg, value - 79);
+ return value;
+}
+
+static int
+revo51_set_monitor (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (ctrl < 0 || ctrl > 3)
+ return OSS_EIO;
+
+ return devc->monitor[ctrl];
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ int left, right;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ switch (ctrl)
+ {
+ case 0: /* Mic */
+ left = set_mongain (devc, 0, left);
+ right = set_mongain (devc, 1, right);
+ break;
+
+ case 1: /* Line */
+ left = set_mongain (devc, 2, left);
+ right = set_mongain (devc, 3, right);
+ break;
+
+ case 2: /* Aux */
+ left = set_mongain (devc, 4, left);
+ right = set_mongain (devc, 5, right);
+ break;
+
+ case 3: /* Mute */
+ value = !!value;
+ PT2258S_Mute (devc, value);
+ return devc->monitor[3] = value;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ value = left | (right << 8);
+ return devc->monitor[ctrl] = value;
+ }
+
+ return OSS_EINVAL;
+}
+
+ /*ARGSUSED*/ static int
+revo51_mixer_init (envy24ht_devc * devc, int dev, int g)
+{
+ int group = 0;
+ int err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 0, revo51_set_control,
+ MIXT_ONOFF,
+ "ENVY24_MUTE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 0, revo51_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_FRONT", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, revo51_set_ak4358,
+ MIXT_SLIDER,
+ "ENVY24_CENTER", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, revo51_set_ak4358,
+ MIXT_SLIDER,
+ "ENVY24_LFE", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, revo51_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_SURROUND", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 4, revo51_set_ak4358,
+ MIXT_STEREOSLIDER,
+ "ENVY24_HEADPH", 0x7f,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, revo51_set_control,
+ MIXT_STEREOSLIDER,
+ "ENVY24_REC", 0x98,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, revo51_set_control,
+ MIXT_ENUM,
+ "ENVY24_RECSRC", 3,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ mixer_ext_set_strings (dev, err, "mic line aux", 0);
+
+ if ((group = mixer_ext_create_group (dev, g, "MONITOR")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, revo51_set_monitor,
+ MIXT_ONOFF,
+ "MON_MUTE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 0, revo51_set_monitor,
+ MIXT_STEREOSLIDER,
+ "ENVY24_MIC", 79,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, revo51_set_monitor,
+ MIXT_STEREOSLIDER,
+ "ENVY24_LINE", 79,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, revo51_set_monitor,
+ MIXT_STEREOSLIDER,
+ "ENVY24_AUX", 79,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+static void
+revo51_card_init (envy24ht_devc * devc)
+{
+
+ int i;
+
+#if 1
+ OUTW (devc->osdev, 0xffff, devc->ccs_base + 0x18); /* GPIO direction */
+ OUTW (devc->osdev, 0x0000, devc->ccs_base + 0x16); /* GPIO write mask */
+ OUTW (devc->osdev, 0xffff, devc->ccs_base + 0x14); /* Initial bit state */
+
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x1a); /* GPIO direction for bits 16:22 */
+ OUTB (devc->osdev, 0x00, devc->ccs_base + 0x1f); /* GPIO mask for bits 16:22 */
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x1e); /* GPIO data for bits 16:22 */
+#endif
+
+ memcpy (devc->channel_names, channel_names, sizeof (channel_names));
+ AK4358_Init (devc);
+ AK5365_Init (devc);
+ PT2258_init (devc);
+ ADC_Set_Chan (devc, 0); /* TODO */
+ REVO51_Set_48K_Mode (devc);
+
+ for (i = 0; i < 5; i++)
+ devc->gains[i] = 0x7f7f;
+ for (i = 0; i < 3; i++)
+ devc->monitor[i] = 79 | (79 << 8);
+ devc->monitor[3] = 0; /* Unmuted */
+
+ set_reclevel (devc, 0x7f7f); /* +0 dB */
+
+ REVO51_Mute (devc, 0);
+}
+
+envy24ht_auxdrv_t envy24ht_revo51_auxdrv = {
+ revo51_card_init,
+ revo51_mixer_init,
+ revo51_set_rate,
+ NULL,
+ NULL,
+ NULL, /* revo51_private1 */
+ revo51_audio_ioctl
+};
diff --git a/kernel/drv/oss_envy24ht/envy24ht_revo71.c b/kernel/drv/oss_envy24ht/envy24ht_revo71.c
new file mode 100644
index 0000000..fd3a9bb
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/envy24ht_revo71.c
@@ -0,0 +1,338 @@
+/*
+ * Purpose: Low level routines for M Audio Revolution 7.1
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_envy24ht_cfg.h"
+
+#include "spdif.h"
+#include "envy24ht.h"
+
+#define BIT(x) (1<<(x))
+
+#define CCLK (1<<1)
+#define CDIN (1<<2) /* Currently not connected */
+#define CDTI (1<<3)
+#define CSDIG (1<<4)
+#define CSN1 (1<<5)
+#define CSN2 (1<<6)
+
+#define WRITEMASK (CSN1|CSN2|CDTI|CCLK)
+
+#define DAC1 0x01 /* 2ch Front DAC (AK4381) */
+#define DAC2 0x03 /* 6ch Surround DAC (AK4355) */
+
+
+static void
+writereg (envy24ht_devc * devc, int csn, int chip, unsigned char reg,
+ unsigned char val)
+{
+ int i;
+ unsigned short v, tmp;
+
+ tmp = INW (devc->osdev, devc->ccs_base + 0x14) & ~(csn | CCLK | CDTI);
+ OUTW (devc->osdev, tmp, devc->ccs_base + 0x14);
+
+ reg = (reg & 0x1f) | 0x20 | (chip << 6); /* Chip address (variable), write */
+ /* Address bits */
+
+ for (i = 7; i >= 0; i--)
+ {
+ v = (reg & (1 << i)) ? CDTI : 0;
+ OUTW (devc->osdev, v | tmp, devc->ccs_base + 0x14); /* Tack */
+ OUTW (devc->osdev, v | CCLK | tmp, devc->ccs_base + 0x14); /* Tick */
+ }
+
+ /* Data bits */
+
+ for (i = 7; i >= 0; i--)
+ {
+ v = (val & (1 << i)) ? CDTI : 0;
+ OUTW (devc->osdev, v | tmp, devc->ccs_base + 0x14); /* Tack */
+ OUTW (devc->osdev, v | CCLK | tmp, devc->ccs_base + 0x14); /* Tick */
+ }
+
+ OUTW (devc->osdev, v | tmp, devc->ccs_base + 0x14); /* Tack */
+ OUTW (devc->osdev, tmp | csn | CDTI | CCLK, devc->ccs_base + 0x14); /* Release */
+
+}
+
+static void
+writedac1 (envy24ht_devc * devc, unsigned char reg, unsigned char data)
+{
+ writereg (devc, CSN1, DAC1, reg, data);
+ devc->dac1val[reg] = data;
+}
+
+static void
+writedac2 (envy24ht_devc * devc, unsigned char reg, unsigned char data)
+{
+ writereg (devc, CSN2, DAC2, reg, data);
+ devc->dac2val[reg] = data;
+}
+
+static void
+revo71_mute (envy24ht_devc * devc, int mute)
+{
+ if (mute)
+ {
+ writedac1 (devc, 1, devc->dac1val[1] | BIT (0));
+ writedac2 (devc, 1, devc->dac2val[1] | BIT (1));
+ oss_udelay (1000);
+/* OUTB (devc->osdev, INB (devc->osdev, devc->ccs_base + 0x1e) & ~BIT(22-16), */
+/* devc->ccs_base + 0x1e); */
+ }
+ else
+ {
+/* OUTB (devc->osdev, INB (devc->osdev, devc->ccs_base + 0x1e) | ~BIT(22-16), */
+/* devc->ccs_base + 0x1e); */
+ oss_udelay (1000);
+ writedac1 (devc, 1, devc->dac1val[1] & ~BIT (0));
+ writedac2 (devc, 1, devc->dac2val[1] & ~BIT (1));
+ }
+}
+
+static void
+revo71_card_init (envy24ht_devc * devc)
+{
+ int i;
+
+ OUTL (devc->osdev, WRITEMASK | 0x400000, devc->ccs_base + 0x18); /* GPIO direction */
+ OUTW (devc->osdev, ~WRITEMASK, devc->ccs_base + 0x16); /* GPIO write mask */
+ OUTB (devc->osdev, 0x40, devc->ccs_base + 0x1f);
+ OUTW (devc->osdev, WRITEMASK, devc->ccs_base + 0x14); /* Initial bit state */
+
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x1a); /* GPIO direction for bits 16:22 */
+ OUTB (devc->osdev, 0x00, devc->ccs_base + 0x1f); /* GPIO mask for bits 16:22 */
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x1e); /* GPIO data for bits 16:22 */
+
+#if 0
+ for (i = 0; i < 7; i++)
+ {
+ OUTW (devc->osdev, 1 << i, devc->ccs_base + 0x14); /* Test bit */
+ OUTW (devc->osdev, 0, devc->ccs_base + 0x14); /* Test bit */
+ }
+#endif
+
+ OUTW (devc->osdev, WRITEMASK, devc->ccs_base + 0x14); /* Initial bit state */
+ oss_udelay (10);
+
+ revo71_mute (devc, 1);
+/*
+ * Init front DAC (AK4381)
+ */
+ writedac1 (devc, 0x00, 0x0c);
+ writedac1 (devc, 0x01, 0x03);
+ writedac1 (devc, 0x02, 0x00);
+
+ writedac1 (devc, 0x03, 0xff); /* Initial volume */
+ writedac1 (devc, 0x04, 0xff); /* Initial volume */
+
+ writedac1 (devc, 0x00, 0x0f);
+/*
+ * Init surround DAC (AK4355)
+ */
+ writedac2 (devc, 0x01, 0x02);
+ writedac2 (devc, 0x00, 0x06);
+ oss_udelay (10);
+ writedac2 (devc, 0x02, 0x0e);
+ writedac2 (devc, 0x03, 0x01);
+
+ for (i = 4; i < 10; i++)
+ writedac2 (devc, i, 0xff); /* Initial volumes */
+ writedac2 (devc, 0x0a, 0x00);
+
+ writedac2 (devc, 0x01, 0x01);
+ revo71_mute (devc, 0);
+}
+
+static void
+revo71_set_rate (envy24ht_devc * devc)
+{
+ int rate = devc->speed, i;
+ unsigned char tmp;
+
+ if (devc->speed == devc->prev_speed)
+ return;
+ devc->prev_speed = devc->speed;
+
+ revo71_mute (devc, 1);
+
+ /* Pulse the PRST# signal to reset converters */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x05) | 0x80,
+ devc->mt_base + 0x05);
+ oss_udelay (5000);
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x05) & ~0x80,
+ devc->mt_base + 0x05);
+ oss_udelay (5000);
+
+ tmp = 0x03;
+ if (rate <= 48000)
+ tmp |= 0x00;
+ else
+ {
+ if (rate <= 96000)
+ tmp |= 0x04;
+ else
+ tmp |= 0x08;
+ }
+
+ /* Front DAC */
+
+ writedac1 (devc, 0, 0x0c);
+ writedac1 (devc, 1, tmp);
+ writedac1 (devc, 2, 0x00);
+ writedac1 (devc, 3, devc->dac1val[3]);
+ writedac1 (devc, 4, devc->dac1val[4]);
+ writedac1 (devc, 0, 0x0f);
+
+ /* Surround DAC */
+ writedac2 (devc, 1, 0x02);
+ writedac2 (devc, 0, 0x06);
+
+ tmp = 0x0e;
+
+ if (devc->speed > 60000)
+ {
+ if (devc->speed > 120000)
+ tmp |= 0x20;
+ else
+ tmp |= 0x10;
+ }
+ writedac2 (devc, 2, tmp);
+ writedac2 (devc, 3, 0x01);
+
+ for (i = 4; i < 10; i++)
+ writedac2 (devc, i, devc->dac2val[i]);
+
+ writedac2 (devc, 0xa, 0x00);
+ writedac2 (devc, 1, 0x03);
+
+ revo71_mute (devc, 0);
+}
+
+static int
+revo71_set_akm (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (ctrl < 0 || ctrl > 4)
+ return OSS_EIO;
+
+ return devc->gains[ctrl];
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ int left, right;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ switch (ctrl)
+ {
+ case 0: /* Front */
+ writedac1 (devc, 0x03, left);
+ writedac1 (devc, 0x04, right);
+ break;
+
+ case 1: /* Rear */
+ writedac2 (devc, 0x06, left);
+ writedac2 (devc, 0x07, right);
+ break;
+
+ case 2: /* Center */
+ writedac2 (devc, 0x04, left);
+ right = left;
+ break;
+
+ case 3: /* LFE */
+ writedac2 (devc, 0x05, left);
+ right = left;
+ break;
+
+ case 4: /* Surround */
+ writedac2 (devc, 0x08, left);
+ writedac2 (devc, 0x09, right);
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ value = left | (right << 8);
+ return devc->gains[ctrl] = value;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+revo71_mixer_init (envy24ht_devc * devc, int dev, int group)
+{
+ int i, err;
+
+ for (i = 0; i < 6; i++)
+ devc->gains[i] = 0xffff;
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24HT_GAIN")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 0, revo71_set_akm,
+ MIXT_STEREOSLIDER,
+ "GAIN_FRONT", 255,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, revo71_set_akm,
+ MIXT_STEREOSLIDER,
+ "GAIN_REAR", 255,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, revo71_set_akm,
+ MIXT_MONOSLIDER,
+ "GAIN_CENTER", 255,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, revo71_set_akm,
+ MIXT_MONOSLIDER,
+ "GAIN_LFE", 255,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 4, revo71_set_akm,
+ MIXT_STEREOSLIDER,
+ "GAIN_surround", 255,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+envy24ht_auxdrv_t envy24ht_revo71_auxdrv = {
+ revo71_card_init,
+ revo71_mixer_init,
+ revo71_set_rate,
+ NULL,
+ NULL,
+ NULL, /* revo71_private1 */
+};
diff --git a/kernel/drv/oss_envy24ht/envy24ht_via.c.save b/kernel/drv/oss_envy24ht/envy24ht_via.c.save
new file mode 100644
index 0000000..49d4199
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/envy24ht_via.c.save
@@ -0,0 +1,324 @@
+/*
+ * Purpose: Low level routines for VIA's Envy24HT reference board (AKM codec)
+ *
+ * Notice:
+ *
+ * This driver is currently disabled because no known real world device
+ * is based on this design. To enable this driver againa just rename it to
+ * envy24ht_via.c and edit the models[] table in envy24ht.c.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_envy24ht_cfg.h"
+
+#include "spdif.h"
+#include "envy24ht.h"
+
+#define AKM_ADDRESS 0x10
+
+static unsigned char
+i2c_read (envy24ht_devc * devc, unsigned char addr, unsigned char pos)
+{
+ int i;
+ unsigned char data;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x11); /* Offset */
+ OUTB (devc->osdev, addr << 1, devc->ccs_base + 0x10); /* Read address */
+
+ for (i = 0; i < 2000; i++)
+ {
+ unsigned char status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+
+ oss_udelay (1);
+ data = INB (devc->osdev, devc->ccs_base + 0x12);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return data;
+}
+
+static void
+i2c_write (envy24ht_devc * devc, unsigned char addr, unsigned char pos,
+ unsigned char data)
+{
+ int i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x11); /* Offset */
+ OUTB (devc->osdev, data, devc->ccs_base + 0x12); /* Data */
+ OUTB (devc->osdev, (addr << 1) | 1, devc->ccs_base + 0x10); /* Write address */
+
+ for (i = 0; i < 2000; i++)
+ {
+ unsigned char status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+
+static void
+viaref_card_init (envy24ht_devc * devc)
+{
+ int addr = AKM_ADDRESS;
+
+ if (devc->codec_type != CODEC_I2S)
+ return;
+
+ OUTW (devc->osdev, 0x000f, devc->ccs_base + 0x14); /* GPIO */
+
+ oss_udelay (1000);
+
+ i2c_write (devc, addr, 0, 0x00);
+ i2c_write (devc, addr, 0, 0x0f);
+ i2c_write (devc, addr, 1, 0x00);
+ i2c_write (devc, addr, 2, 0x01);
+ i2c_write (devc, addr, 5, 0x07);
+ i2c_write (devc, addr, 6, 0x00);
+ i2c_write (devc, addr, 7, 0x00);
+
+ i2c_write (devc, addr, 6, 0x00);
+ i2c_write (devc, addr, 7, 0x00);
+ i2c_write (devc, addr, 8, 0x00);
+ i2c_write (devc, addr, 9, 0x00);
+ i2c_write (devc, addr, 10, 0x00);
+ i2c_write (devc, addr, 11, 0x00);
+
+ devc->recsrc = 0;
+
+#if 0
+ cmn_err(CE_CONT, "Regs=");
+ for (i = 0; i < 0x18; i++)
+ {
+ cmn_err(CE_CONT, "%02x ", i2c_read (devc, addr, i));
+ }
+ cmn_err(CE_CONT, "\n");
+#endif
+}
+
+static int
+viaref_set_akm (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+ int left, right, val;
+ unsigned char tmp, tmp2, old, old2;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ switch (ctrl)
+ {
+ /* Output gain controls */
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ return devc->gains[ctrl];
+
+ case 10: /* Loopback enable */
+ return !!(i2c_read (devc, AKM_ADDRESS, 0x01) & 0x30);
+
+ case 11: /* codec.recsrc (ANALOG OPTICAL COAX CD AUX) */
+ return devc->recsrc;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ oss_native_word flags;
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ val = left | (right << 8);
+
+ switch (ctrl)
+ {
+ case 0:
+ left = 0xff - left;
+ right = 0xff - right;
+ i2c_write (devc, AKM_ADDRESS, 0x06, left);
+ i2c_write (devc, AKM_ADDRESS, 0x07, right);
+ return devc->gains[ctrl] = val;
+
+ case 1:
+ left = 0xff - left;
+ right = 0xff - right;
+ i2c_write (devc, AKM_ADDRESS, 0x08, left);
+ i2c_write (devc, AKM_ADDRESS, 0x09, right);
+ return devc->gains[ctrl] = val;
+
+ case 2:
+ val = left | (left << 8);
+ left = 0xff - left;
+ i2c_write (devc, AKM_ADDRESS, 0x0a, left);
+ return devc->gains[ctrl] = val;
+
+ case 3:
+ val = left | (left << 8);
+ left = 0xff - left;
+ i2c_write (devc, AKM_ADDRESS, 0x0b, left);
+ return devc->gains[ctrl] = val;
+
+ case 10: /* Loopback enable */
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ old = tmp = i2c_read (devc, AKM_ADDRESS, 0x01);
+ value = !!value;
+ if (value)
+ tmp |= 0x10;
+ else
+ tmp &= ~0x30;
+
+ if (tmp != old)
+ {
+ i2c_write (devc, AKM_ADDRESS, 0x01, tmp);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return value;
+
+ case 11: /* codec.recsrc (ANALOG OPTICAL COAX CD AUX) */
+ if (value < 0 || value > 4)
+ return devc->recsrc;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ old = tmp = i2c_read (devc, AKM_ADDRESS, 0x01);
+ old2 = tmp2 = i2c_read (devc, AKM_ADDRESS, 0x02);
+
+ tmp &= ~0x0c;
+ tmp2 &= ~0x03;
+
+ switch (value)
+ {
+ case 0: /* Analog */
+ tmp2 |= 0x01;
+ break;
+
+ case 1: /* Optical (RX2) */
+ tmp |= 0x04;
+ tmp2 |= 0x00;
+ break;
+
+ case 2: /* Coax (RX1) */
+ tmp |= 0x00;
+ tmp2 |= 0x00;
+ break;
+
+ case 3: /* CD digital input (RX3) */
+ tmp |= 0x08;
+ tmp2 |= 0x00;
+ break;
+
+ case 4: /* Unused digital input (RX4) */
+ tmp |= 0x08;
+ tmp2 |= 0x00;
+ break;
+ }
+
+ if (tmp != old)
+ i2c_write (devc, AKM_ADDRESS, 0x01, tmp);
+ if (tmp2 != old2)
+ i2c_write (devc, AKM_ADDRESS, 0x02, tmp2);
+
+ devc->recsrc = value;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->recsrc;
+ break;
+
+ }
+ return OSS_EIO;
+ }
+
+ return OSS_EIO;
+}
+
+static int
+viaref_mixer_init (envy24ht_devc * devc, int dev, int group)
+{
+ int i, err;
+ if (devc->codec_type != CODEC_I2S)
+ return 0;
+
+ for (i = 0; i < 4; i++)
+ devc->gains[i] = 0xffff;
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24HT_GAIN")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 0, viaref_set_akm,
+ MIXT_STEREOSLIDER,
+ "GAIN_FRONT", 255,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, viaref_set_akm,
+ MIXT_STEREOSLIDER,
+ "GAIN_REAR", 255,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, viaref_set_akm,
+ MIXT_MONOSLIDER,
+ "GAIN_CENTER", 255,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, viaref_set_akm,
+ MIXT_MONOSLIDER,
+ "GAIN_LFE", 255,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24HT_CODEC")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 11, viaref_set_akm,
+ MIXT_ENUM,
+ "CODEC_RECSRC", 5,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 10, viaref_set_akm,
+ MIXT_ONOFF,
+ "CODEC_LOOPBACK", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+#if 0
+static int
+viaref_private1 (envy24ht_devc * devc, int value)
+{
+ i2c_write (devc, AKM_ADDRESS, (value >> 8) & 0xff, value & 0xff);
+ return 0;
+}
+#endif
+
+envy24ht_auxdrv_t envy24ht_viaref_auxdrv = {
+ viaref_card_init,
+ viaref_mixer_init
+};
diff --git a/kernel/drv/oss_envy24ht/oss_envy24ht.c b/kernel/drv/oss_envy24ht/oss_envy24ht.c
new file mode 100644
index 0000000..11fb75b
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/oss_envy24ht.c
@@ -0,0 +1,2411 @@
+/*
+ * Purpose: VIA ENVY24HT chipset driver.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_envy24ht_cfg.h"
+#include <oss_pci.h>
+
+#define SUPPORTED_FORMAT AFMT_S32_LE
+
+#include <spdif.h>
+#include "envy24ht.h"
+
+/* extern envy24ht_auxdrv_t envy24ht_viaref_auxdrv; */
+extern envy24ht_auxdrv_t envy24ht_ac97_auxdrv;
+extern envy24ht_auxdrv_t envy24ht_revo51_auxdrv;
+extern envy24ht_auxdrv_t envy24ht_revo71_auxdrv;
+extern envy24ht_auxdrv_t envy24ht_aureon_auxdrv;
+extern envy24ht_auxdrv_t envy24ht_julia_auxdrv;
+extern envy24ht_auxdrv_t envy24ht_ap192_auxdrv;
+
+#define OUTCH_NAMES "front c/l side rear"
+static char channel_names[4][10] = {
+ "front",
+ "c/l",
+ "side",
+ "rear"
+};
+
+static card_spec models[] = {
+ {0x17241412, "Generic Envy24PT motherboard audio", 6, 2,
+ MF_SPDIFOUT | MF_ENVY24PT, &envy24ht_ac97_auxdrv},
+ {0xf641270f, "Chaintech ZNF3-150", 6, 2,
+ MF_SPDIFOUT | MF_ENVY24PT, &envy24ht_ac97_auxdrv},
+ {0x2723270f, "Chaintech 9CJS", 6, 2,
+ MF_SPDIFOUT | MF_ENVY24PT, &envy24ht_ac97_auxdrv},
+ {0x50361297, "Shuttle SN25P", 6, 2,
+ MF_SPDIFOUT | MF_ENVY24PT, &envy24ht_ac97_auxdrv},
+ {0x020010b0, "Gainward Hollywood Envy24HT-S", 6, 2,
+ MF_SPDIFOUT | MF_ENVY24PT, &envy24ht_ac97_auxdrv},
+ {0x36311412, "M Audio Revolution 5.1", 6, 2,
+ MF_SPDIFOUT | MF_192K, &envy24ht_revo51_auxdrv},
+ {0x36301412, "M Audio Revolution 7.1", 8, 2,
+ MF_SPDIFOUT | MF_192K, &envy24ht_revo71_auxdrv},
+ {SSID_AUREON_SPACE, "Terratec Aureon 7.1 Space", 8, 2,
+ MF_SPDIFOUT | MF_192K | MF_NOAC97, &envy24ht_aureon_auxdrv},
+ {SSID_AUREON_UNIVERSE, "Terratec Aureon 7.1 Universe", 8, 2,
+ MF_SPDIFOUT | MF_192K | MF_NOAC97, &envy24ht_aureon_auxdrv},
+ {SSID_AUREON_SKY, "Terratec Aureon 7.1 Sky", 8, 2,
+ MF_SPDIFOUT | MF_192K | MF_NOAC97, &envy24ht_aureon_auxdrv},
+ {SSID_PRODIGY71, "Audiotrak Prodigy 7.1", 8, 2,
+ MF_SPDIFOUT | MF_192K | MF_NOAC97, &envy24ht_aureon_auxdrv},
+ {SSID_JULIA, "Ego Systems Juli@", 2, 2,
+ MF_SPDIFOUT | MF_SPDIFIN | MF_192K | MF_NOAC97 | MF_MIDI,
+ &envy24ht_julia_auxdrv},
+ {SSID_PHASE28, "Terratec PHASE 28", 8, 2,
+ MF_SPDIFOUT | MF_192K | MF_NOAC97 | MF_MIDI, &envy24ht_aureon_auxdrv},
+ {SSID_AP192, "M-Audio Audiophile 192", 2, 2,
+ MF_SPDIFOUT | MF_SPDIFIN | MF_192K | MF_NOAC97 | MF_MIDI,
+ &envy24ht_ap192_auxdrv},
+ {0x24031412, "VIA Vinyl Tremor Audio", 6, 2,
+ MF_SPDIFOUT | MF_ENVY24PT, &envy24ht_ac97_auxdrv},
+ /* XXX Do a separate auxdrv, to adjust for Envy24HT-S and other differences. */
+ {SSID_PRODIGYHD2, "Audiotrak Prodigy HD2", 2, 2,
+ MF_SPDIFOUT | MF_192K | MF_NOAC97, &envy24ht_ap192_auxdrv},
+ {SSID_PRODIGYHD2_ADE, "Audiotrak Prodigy HD2 Advance DE", 2, 2,
+ MF_SPDIFOUT | MF_192K | MF_NOAC97, &envy24ht_ap192_auxdrv},
+ /* {0x17241412, "VIA Envy24HT reference design", 6, 2, */
+ /* MF_SPDIFOUT | MF_MIDI, &envy24ht_viaref_auxdrv}, */
+ {0}
+};
+
+static struct speed_sel speed_tab[] = {
+ {
+ 8000, 0x06}
+ ,
+ {
+ 9600, 0x03}
+ ,
+ {
+ 11025, 0x0a}
+ ,
+ {
+ 12000, 0x02}
+ ,
+ {
+ 16000, 0x05}
+ ,
+ {
+ 22050, 0x09}
+ ,
+ {
+ 24000, 0x01}
+ ,
+ {
+ 32000, 0x04}
+ ,
+ {
+ 44100, 0x08}
+ ,
+ {
+ 48000, 0x00}
+ ,
+ {
+ 64000, 0x0f}
+ ,
+ {
+ 88200, 0x0b}
+ ,
+ {
+ 96000, 0x07}
+ ,
+ {
+ 176400, 0x0c}
+ ,
+ {
+ 192000, 0x0e}
+ ,
+ {-1, 0x10}
+ ,
+};
+
+static const envy24ht_auxdrv_t dummy_auxdrv = { NULL };
+
+static int
+ac97_read (void *devc_, int wAddr)
+{
+ envy24ht_devc *devc = devc_;
+ oss_native_word flags;
+ int n = 0, dat;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ while (n++ < 10000 && INB (devc->osdev, devc->mt_base + 0x05) & 0x30);
+ OUTB (devc->osdev, wAddr, devc->mt_base + 0x04);
+ OUTB (devc->osdev, 0x10, devc->mt_base + 0x05); /* Codec read */
+
+ n = 0;
+ while (n++ < 10000 && INB (devc->osdev, devc->mt_base + 0x05) & 0x10);
+ dat = INW (devc->osdev, devc->mt_base + 0x06);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return dat;
+}
+
+static int
+ac97_write (void *devc_, int wAddr, int wData)
+{
+ envy24ht_devc *devc = devc_;
+ oss_native_word flags;
+ int n = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ while (n++ < 10000 && INB (devc->osdev, devc->mt_base + 0x05) & 0x30);
+
+ OUTB (devc->osdev, wAddr, devc->mt_base + 0x04);
+ OUTW (devc->osdev, wData, devc->mt_base + 0x06);
+ OUTB (devc->osdev, 0x20, devc->mt_base + 0x05); /* Codec write */
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return 0;
+}
+
+static __inline__ int
+input_avail (envy24ht_devc * devc)
+{
+ unsigned char status;
+
+ status = INB (devc->osdev, devc->ccs_base + 0x0b);
+ return status & 0x1f; /* Number of bytes in RX queue */
+}
+
+static __inline__ int
+output_ready (envy24ht_devc * devc)
+{
+ unsigned char status;
+
+ status = INB (devc->osdev, devc->ccs_base + 0x0a);
+ return (31 - (status & 0x1f)) > 0; /* Number of free bytes in TX queue */
+}
+
+static __inline__ void
+midi_cmd (envy24ht_devc * devc, unsigned char cmd)
+{
+ OUTB (devc->osdev, cmd, devc->ccs_base + 0x0d);
+}
+
+static __inline__ int
+midi_read (envy24ht_devc * devc)
+{
+ return INB (devc->osdev, devc->ccs_base + 0x0c);
+}
+
+static __inline__ void
+midi_write (envy24ht_devc * devc, unsigned char byte)
+{
+ OUTB (devc->osdev, byte, devc->ccs_base + 0x0c);
+}
+
+static void reset_midi (envy24ht_devc * devc);
+static void enter_uart_mode (envy24ht_devc * devc);
+
+static void
+midi_input_loop (envy24ht_devc * devc)
+{
+ int n = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ while (input_avail (devc) && n++ < 33)
+ {
+ unsigned char c = midi_read (devc);
+
+ devc->input_byte = c;
+ if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr (devc->midi_dev, c);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+midiintr (envy24ht_devc * devc)
+{
+ int status;
+
+ status = INB (devc->osdev, devc->ccs_base + 0x02);
+ if (status & 0x80)
+ midi_input_loop (devc);
+ if ((status & 0x20))
+ {
+ OUTB (devc->osdev, INB (devc->osdev, devc->ccs_base + 0x01) | 0x20,
+ devc->ccs_base + 0x01);
+
+#if 0
+ if (devc->midi_output_intr)
+ devc->midi_output_intr (devc->midi_dev);
+#endif
+ }
+}
+
+/*ARGSUSED*/
+static int
+midi_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf, oss_midi_outputintr_t outputintr)
+{
+ envy24ht_devc *devc = (envy24ht_devc *) midi_devs[dev]->devc;
+ int n = 0, tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (devc->midi_opened & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ devc->midi_opened |= mode;
+
+ if (mode & OPEN_READ)
+ {
+ while (n++ < 33 && input_avail (devc))
+ midi_read (devc);
+
+ devc->midi_input_intr = inputbyte;
+ devc->midi_output_intr = outputintr;
+ }
+ enter_uart_mode (devc);
+ tmp = INB (devc->osdev, devc->ccs_base + 0x01);
+ if (mode & OPEN_READ)
+ tmp &= ~0x80;
+ OUTB (devc->osdev, tmp, devc->ccs_base + 0x01);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+midi_close (int dev, int mode)
+{
+ envy24ht_devc *devc = (envy24ht_devc *) midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ reset_midi (devc);
+ enter_uart_mode (devc);
+ reset_midi (devc);
+ OUTB (devc->osdev, INB (devc->osdev, devc->ccs_base + 0x01) | 0xa0,
+ devc->ccs_base + 0x01);
+ devc->midi_opened &= ~mode;
+ devc->midi_input_intr = NULL;
+ devc->midi_output_intr = NULL;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static int
+midi_out (int dev, unsigned char midi_byte)
+{
+ envy24ht_devc *devc = (envy24ht_devc *) midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (!output_ready (devc))
+ {
+ OUTB (devc->osdev, INB (devc->osdev, devc->ccs_base + 0x01) & ~0x20,
+ devc->ccs_base + 0x01);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+
+ midi_write (devc, midi_byte);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t envy24ht_midi_driver = {
+ midi_open,
+ midi_close,
+ midi_ioctl,
+ midi_out
+};
+
+static void
+enter_uart_mode (envy24ht_devc * devc)
+{
+ devc->input_byte = 0;
+ midi_cmd (devc, 1);
+}
+
+void
+attach_midi (envy24ht_devc * devc)
+{
+ char name[128];
+ enter_uart_mode (devc);
+
+ sprintf (name, "%s input", devc->model_data->product);
+ devc->midi_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "ENVY24HT", name, &envy24ht_midi_driver, sizeof (midi_driver_t),
+ MFLAG_INPUT, devc, devc->osdev);
+ sprintf (name, "%s output", devc->model_data->product);
+ devc->midi_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "ENVY24HT", name, &envy24ht_midi_driver, sizeof (midi_driver_t),
+ MFLAG_OUTPUT, devc, devc->osdev);
+ devc->midi_opened = 0;
+ devc->midi_attached = 1;
+}
+
+static void
+reset_midi (envy24ht_devc * devc)
+{
+ /*
+ * Send the RESET command. Try again if no success at the first time.
+ */
+
+ midi_cmd (devc, 0);
+}
+
+void
+unload_midi (envy24ht_devc * devc)
+{
+ if (devc->midi_attached)
+ reset_midi (devc);
+ devc->midi_attached = 0;
+}
+
+static int
+envy24htintr (oss_device_t * osdev)
+{
+ envy24ht_devc *devc = osdev->devc;
+ int port, status, mt_status, serviced = 0;
+
+ status = INB (devc->osdev, devc->ccs_base + 0x02);
+ if (status != 0)
+ serviced = 1;
+
+ if (status & 0xa0)
+ midiintr (devc);
+
+/*
+ * Handle audio interrupts
+ */
+ mt_status = INB (devc->osdev, devc->mt_base + 0x00);
+
+ if (mt_status & 0x08) /* FIFO underrun/overrun */
+ {
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x1A),
+ devc->mt_base + 0x1A);
+ serviced = 1;
+ }
+
+ if ((status & 0x10) || mt_status != 0)
+ {
+
+ for (port = 0; port < devc->nr_outdevs; port++)
+ {
+ envy24ht_portc *portc = &devc->play_portc[port];
+
+ if (mt_status & portc->mask)
+ {
+ oss_audio_outputintr (portc->dev, 1);
+ }
+ }
+
+ for (port = 0; port < devc->nr_indevs; port++)
+ {
+ envy24ht_portc *portc = &devc->rec_portc[port];
+
+ if (mt_status & portc->mask)
+ {
+ oss_audio_inputintr (portc->dev, 0);
+ }
+ }
+ }
+ OUTB (devc->osdev, mt_status, devc->mt_base + 0x00);
+ OUTB (devc->osdev, status, devc->ccs_base + 0x02);
+
+ return serviced;
+}
+
+/*ARGSUSED*/
+static int
+envy24ht_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static mixer_driver_t envy24ht_mixer_driver = {
+ envy24ht_mixer_ioctl
+};
+
+static int
+envy24ht_set_route (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+ unsigned int tmp;
+ oss_native_word flags;
+
+ if (ctrl < 0 || ctrl > 8)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ tmp = INL (devc->osdev, devc->mt_base + 0x2c);
+
+ switch (ctrl)
+ {
+ case 0:
+ tmp >>= 8;
+ break;
+ case 2:
+ tmp >>= 11;
+ break;
+ case 4:
+ tmp >>= 14;
+ break;
+ case 6:
+ tmp >>= 17;
+ break;
+ }
+
+ tmp = (tmp & 0x03) >> 1;
+
+ if (tmp == 3)
+ return 2;
+ return tmp;
+ }
+ else if (cmd == SNDCTL_MIX_WRITE)
+ {
+ int left_shift = 0, right_shift = 0;
+
+ static const unsigned char cnv_tab[3] = { 0x00, 0x02, 0x06 };
+ if (value < 0 || value > 2)
+ return OSS_EINVAL;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ tmp = INL (devc->osdev, devc->mt_base + 0x2c);
+
+ switch (ctrl)
+ {
+ case 0:
+ left_shift = 8;
+ right_shift = 20;
+ break;
+ case 2:
+ left_shift = 11;
+ right_shift = 23;
+ break;
+ case 4:
+ left_shift = 14;
+ right_shift = 26;
+ break;
+ case 6:
+ left_shift = 17;
+ right_shift = 29;
+ break;
+ case 8:
+ left_shift = 0;
+ right_shift = 3;
+ break;
+ }
+
+ tmp &= ~(0x7 << left_shift);
+ tmp &= ~(0x7 << right_shift);
+ tmp |= cnv_tab[value] << left_shift;
+ if (ctrl != 8)
+ tmp |= (cnv_tab[value] + 1) << right_shift;
+ else
+ tmp |= cnv_tab[value] << right_shift;
+
+ OUTL (devc->osdev, tmp, devc->mt_base + 0x2c);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return value;
+ }
+ return OSS_EINVAL;
+}
+
+static int
+read_peak (envy24ht_devc * devc, int ch)
+{
+ int tmp;
+
+ if (ch >= 22)
+ return 0;
+
+ OUTB (devc->osdev, ch, devc->mt_base + 0x3e);
+ tmp = INB (devc->osdev, devc->mt_base + 0x3f);
+
+ return tmp;
+}
+
+/*ARGSUSED*/
+static int
+envy24ht_get_peak (int dev, int ctrl, unsigned int cmd, int value)
+{
+ static const unsigned char peak_cnv[256] = {
+ 0, 18, 29, 36, 42, 47, 51, 54, 57, 60, 62, 65, 67, 69, 71, 72,
+ 74, 75, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 89, 90,
+ 91, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 100, 101,
+ 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
+ 108,
+ 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 113, 113, 113, 114, 114,
+ 114,
+ 115, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119,
+ 119,
+ 119, 119, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 122, 122, 123,
+ 123,
+ 123, 123, 124, 124, 124, 124, 125, 125, 125, 125, 125, 126, 126, 126, 126,
+ 126,
+ 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 129, 129, 129, 129, 129,
+ 130,
+ 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132,
+ 132,
+ 132, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 135,
+ 135,
+ 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 137, 137, 137,
+ 137,
+ 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139,
+ 139,
+ 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141,
+ 141,
+ 141, 141, 141, 141, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143,
+ 143,
+ 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, 144, 144, 144,
+ 144,
+ };
+
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+
+ int i, orign, n = -1, left = 0, right = 0;
+
+ for (i = 0; i < 12 && n == -1; i++)
+ if (ctrl & (1 << i))
+ n = i;
+
+ if (n == -1)
+ return OSS_EINVAL;
+
+ orign = n;
+ if (ctrl & 0x80000000)
+ n += 10; /* Recording stream */
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ left = read_peak (devc, n);
+ if (ctrl & (1 << (orign + 1))) /* Stereo mode? */
+ right = read_peak (devc, n + 1);
+ else
+ right = left;
+
+ left = peak_cnv[left];
+ right = peak_cnv[right];
+ return left | (right << 8);
+ }
+
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static int
+create_peak_mixer (int dev, envy24ht_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, err, num, skip;
+ int nc = devc->nr_play_channels;
+ char tmp[64];
+
+ if ((group = mixer_ext_create_group (dev, 0, "ENVY24_PEAK")) < 0)
+ return group;
+
+ skip = 2;
+
+ for (i = 0; i < nc; i += skip)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDIFOUT");
+ else
+ sprintf (tmp, devc->channel_names[i / 2], i + 1, i + 2);
+
+ num |= 1 << (i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24ht_get_peak,
+ MIXT_STEREOPEAK,
+ tmp, 144,
+ MIXF_READABLE | MIXF_DECIBEL)) <
+ 0)
+ return err;
+ }
+ }
+
+ mask = devc->inportmask;
+ for (i = 0; i < devc->nr_rec_channels; i += skip)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ num |= 0x80000000; /* Input flag */
+
+ {
+ if (i == 8)
+ strcpy (tmp, "ENVY24_SPDIFIN");
+ else
+ strcpy (tmp, "ENVY24_IN");
+
+ num |= 1 << (i + 1);
+ if ((err = mixer_ext_create_control (dev, group,
+ num, envy24ht_get_peak,
+ MIXT_STEREOPEAK,
+ tmp, 144,
+ MIXF_READABLE | MIXF_DECIBEL)) <
+ 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+create_rout_mixer (int dev, envy24ht_devc * devc, int root)
+{
+ int i, mask = devc->outportmask, group, ret, num;
+ char *name;
+
+ if ((group =
+ mixer_ext_create_group_flags (dev, 0, "ENVY24_ROUTE", MIXF_FLAT)) < 0)
+ return group;
+
+ for (i = 0; i < 8; i += 2)
+ {
+
+ num = 1 << i;
+ if (!(mask & num))
+ continue; /* Not present */
+
+ name = devc->channel_names[i / 2];
+
+ if ((ret = mixer_ext_create_control (dev, group,
+ i,
+ envy24ht_set_route,
+ MIXT_ENUM, name, 3,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return ret;
+ mixer_ext_set_strings (dev, ret, "DMA ANALOGIN DIGITALIN", 0);
+ }
+
+ if (devc->model_data == NULL)
+ {
+ cmn_err (CE_CONT, "Internal error: No model data\n");
+ return 0;
+ }
+
+ mask = devc->inportmask;
+
+ if (devc->model_data->flags & MF_SPDIFOUT)
+ {
+ if ((ret = mixer_ext_create_control (dev, group,
+ 8, envy24ht_set_route,
+ MIXT_ENUM,
+ "ENVY24_SPDIFOUT", 3,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * S/PDIF lowlevel driver
+ */
+/*ARGSUSED*/
+static int
+default_reprogram_device (void *_devc, void *_portc,
+ oss_digital_control * ctl, unsigned int mask)
+{
+ unsigned char c;
+ unsigned short cbits = 0;
+ envy24ht_devc *devc = _devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ cbits |= (ctl->rate_bits & 0x0f) << 12; /* Sample rate */
+
+ if (ctl->out_vbit == VBIT_ON)
+ cbits |= 0x8000; /* Turn on the V bit */
+
+ cbits |= ctl->cbitout[0] & 0x07; /* Consumer/pro, audio/data, copyright */
+ cbits |= (!!(ctl->cbitout[1] & 0x80)) << 11; /* Generation level */
+ cbits |= (ctl->cbitout[1] & 0x7f) << 4; /* Category code */
+ cbits |= (ctl->emphasis_type & 1) << 3; /* Pre-emphasis */
+
+ if (cbits != INW (devc->osdev, devc->mt_base + 0x3c))
+ {
+ c = INB (devc->osdev, devc->ccs_base + 0x07);
+ OUTB (devc->osdev, c & ~0x80, devc->ccs_base + 0x07); /* Disable S/PDIF transmitter */
+ OUTW (devc->osdev, cbits, devc->mt_base + 0x3c);
+ OUTB (devc->osdev, c | 0x80, devc->ccs_base + 0x07); /* (Re)enable S/PDIF transmitter */
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+spdif_driver_t default_spdif_driver = {
+/* reprogram_device: */ default_reprogram_device,
+};
+
+
+static void
+setup_sample_rate (envy24ht_devc * devc)
+{
+ unsigned char bits;
+ int change = 0;
+
+ devc->speedbits = bits = speed_tab[devc->pending_speed_sel].speedbits;
+ if (devc->speed != speed_tab[devc->pending_speed_sel].speed)
+ change = 1;
+ devc->speed = devc->pending_speed =
+ speed_tab[devc->pending_speed_sel].speed;
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+
+ if (change)
+ {
+ oss_spdif_setrate (&devc->spdc, devc->speed);
+
+ if (devc->model_data->svid == SSID_JULIA)
+ goto JULIA;
+
+ if (devc->syncsource != 0) /* External sync */
+ bits |= 0x10;
+
+ if (devc->speed > 120000)
+ {
+ OUTB (devc->osdev, 0x08, devc->mt_base + 0x02); /* 128x I2S setup */
+ }
+ else
+ {
+ OUTB (devc->osdev, 0x00, devc->mt_base + 0x02); /* 256x I2S setup */
+ }
+
+ OUTB (devc->osdev, bits & 0x0f, devc->mt_base + 0x01); /* Sampling rate */
+JULIA:
+ if (devc->auxdrv->set_rate)
+ devc->auxdrv->set_rate (devc);
+ }
+}
+
+static int
+envy24ht_set_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+ oss_native_word flags;
+
+ if (cmd == SNDCTL_MIX_READ)
+ switch (ctrl)
+ {
+ case 1:
+ return devc->pending_speed_sel;
+ break;
+
+ case 2:
+ return devc->syncsource;
+ break;
+
+ case 3:
+ return devc->use_src;
+ break;
+
+ case 5:
+ return devc->ratelock;
+ break;
+
+ case 6:
+ return devc->speed;
+ break;
+
+ case 7:
+ return 1;
+
+ default:
+ return OSS_EIO;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ switch (ctrl)
+ {
+ case 1:
+ if (value < 0 || value > devc->max_ratesel)
+ return OSS_EIO;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (devc->configured_rate_sel != value)
+ {
+ devc->configured_rate_sel = value;
+ if (devc->open_count < 1)
+ {
+ devc->pending_speed_sel = devc->configured_rate_sel;
+ setup_sample_rate (devc);
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->configured_rate_sel;
+ break;
+
+ case 2:
+ if (value < 0 || value > 2)
+ return OSS_EIO;
+ devc->syncsource = value;
+ if (devc->model_data->svid == SSID_JULIA)
+ devc->auxdrv->private1 (devc, value);
+ return devc->syncsource;
+ break;
+
+ case 3:
+ devc->use_src = !!value;
+ return devc->use_src;
+ break;
+
+ case 5:
+ return devc->ratelock = !!value;
+ break;
+
+ case 6:
+ return devc->speed;
+ break;
+
+ case 7:
+ return 1;
+ break;
+
+ default:
+ return OSS_EIO;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+envy24ht_mix_init (int dev)
+{
+ envy24ht_devc *devc = mixer_devs[dev]->hw_devc;
+ int group, err, n;
+
+ if ((group =
+ mixer_ext_create_group_flags (dev, 0, "ENVY24", MIXF_FLAT)) < 0)
+ return group;
+
+ if ((err = create_peak_mixer (dev, devc, group)) < 0)
+ return err;
+
+ if ((err = create_rout_mixer (dev, devc, group)) < 0)
+ return err;
+
+ n = devc->max_ratesel + 1;
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, envy24ht_set_control,
+ MIXT_ENUM,
+ "ENVY24_RATE", n,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ mixer_ext_set_strings (dev, err,
+ "8000 9600 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 176400 192000", 0);
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, envy24ht_set_control,
+ MIXT_ENUM,
+ "ENVY24_SYNC", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, envy24ht_set_control,
+ MIXT_ONOFF,
+ "ENVY24_SRC", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 5, envy24ht_set_control,
+ MIXT_ONOFF,
+ "ENVY24_RATELOCK", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 6, envy24ht_set_control,
+ MIXT_VALUE,
+ "ENVY24_ACTRATE", 192000,
+ MIXF_READABLE)) < 0)
+ return err;
+
+ if (devc->auxdrv->mixer_init)
+ if ((err = devc->auxdrv->mixer_init (devc, dev, 0)) < 0)
+ return err;
+
+ if ((err = oss_spdif_mix_init (&devc->spdc)) < 0)
+ return err;
+
+ return 0;
+}
+
+static int
+eeprom_read (envy24ht_devc * devc, int pos)
+{
+ int i, status;
+
+ for (i = 0; i < 0x10000; i++)
+ {
+ status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+
+ OUTB (devc->osdev, pos, devc->ccs_base + 0x11); /* Offset */
+ OUTB (devc->osdev, 0xa0, devc->ccs_base + 0x10); /* EEPROM read */
+
+ for (i = 0; i < 0x10000; i++)
+ {
+ status = INB (devc->osdev, devc->ccs_base + 0x13);
+ if (!(status & 1))
+ break;
+
+ }
+
+ oss_udelay (1);
+ return INB (devc->osdev, devc->ccs_base + 0x12);
+}
+
+static void
+envy24pt_init (envy24ht_devc * devc)
+{
+ int gpio;
+
+ gpio = INW (devc->osdev, devc->ccs_base + 0x14);
+ gpio |= INB (devc->osdev, devc->ccs_base + 0x1e) << 16;
+
+#if 0
+#define GPBIT(nn) !!(1<<nn)
+ cmn_err (CE_CONT, "GPIO=%06x\n", gpio);
+ cmn_err (CE_CONT, "With SPDIF_IN 'optical' connector: %d\n", GPBIT (1));
+ cmn_err (CE_CONT, "With SPDIF_IN 'coaxial' connector: %d\n", GPBIT (2));
+
+ cmn_err (CE_CONT, "AC97 with stereo DAC for 7.1: %d\n", !GPBIT (8));
+ cmn_err (CE_CONT, "Extra ADC/DAC connected to S/PDIF pins: %d\n",
+ GPBIT (9));
+ cmn_err (CE_CONT, "S/PDIF connected to RDMA1: %d\n", !GPBIT (10));
+ cmn_err (CE_CONT, "Smart 5.1 function supported: %d\n", GPBIT (11));
+ cmn_err (CE_CONT, "De-POP function supported: %d\n", !GPBIT (12));
+ cmn_err (CE_CONT, "PDMA4 DAC: 0=cs4321 1=WM8728: %d\n", GPBIT (13));
+#endif
+
+ OUTB (devc->osdev, 0x00, devc->ccs_base + 0x04); /* System configuration */
+ OUTB (devc->osdev, 0x02, devc->ccs_base + 0x05); /* AC-link configuration */
+ OUTB (devc->osdev, 0x00, devc->ccs_base + 0x06); /* I2S configuration */
+ OUTB (devc->osdev, 0x83, devc->ccs_base + 0x07); /* S/PDIF configuration */
+
+ /* TODO: GPIO initialization */
+}
+
+static void
+julia_eeprom_init (envy24ht_devc * devc)
+{
+ OUTB (devc->osdev, 0x39, devc->ccs_base + 0x04); /* System configuration */
+ OUTB (devc->osdev, 0x80, devc->ccs_base + 0x05); /* AC-link configuration */
+ OUTB (devc->osdev, 0x78, devc->ccs_base + 0x06); /* I2S configuration */
+ OUTB (devc->osdev, 0xc3, devc->ccs_base + 0x07); /* S/PDIF configuration */
+
+ OUTW (devc->osdev, 0xffff, devc->ccs_base + 0x18); /* GPIO direction */
+ OUTW (devc->osdev, 0x0000, devc->ccs_base + 0x16); /* GPIO write mask */
+ OUTW (devc->osdev, 0x801A, devc->ccs_base + 0x14); /* Initital bit state */
+}
+
+static int
+init_eeprom_v2 (envy24ht_devc * devc)
+{
+ unsigned char *eeprom = (unsigned char *) &devc->eeprom;
+
+ OUTB (devc->osdev, eeprom[6], devc->ccs_base + 0x04);
+ OUTB (devc->osdev, eeprom[7], devc->ccs_base + 0x05);
+ OUTB (devc->osdev, eeprom[8], devc->ccs_base + 0x06);
+ OUTB (devc->osdev, eeprom[9], devc->ccs_base + 0x07);
+
+ OUTB (devc->osdev, eeprom[10], devc->ccs_base + 0x18);
+ OUTB (devc->osdev, eeprom[11], devc->ccs_base + 0x19);
+ OUTB (devc->osdev, eeprom[12], devc->ccs_base + 0x1a);
+
+ OUTB (devc->osdev, eeprom[13], devc->ccs_base + 0x16);
+ OUTB (devc->osdev, eeprom[14], devc->ccs_base + 0x17);
+ OUTB (devc->osdev, eeprom[15], devc->ccs_base + 0x1f);
+
+ OUTB (devc->osdev, eeprom[16], devc->ccs_base + 0x14);
+ OUTB (devc->osdev, eeprom[17], devc->ccs_base + 0x15);
+ OUTB (devc->osdev, eeprom[18], devc->ccs_base + 0x1e);
+ return 1;
+}
+
+static int
+load_eeprom (envy24ht_devc * devc)
+{
+ int status, i, check;
+ unsigned char *eeprom = (unsigned char *) &devc->eeprom, c;
+ static const char resolutions[4] = { 16, 18, 20, 24 };
+
+ c = 0;
+
+ status = INB (devc->osdev, devc->ccs_base + 0x13);
+
+ if (!(status & 0x80))
+ return 0; /* No EEPROM */
+
+ devc->eeprom.bSize = sizeof (devc->eeprom); /* Guess the size */
+
+ for (i = 0; i < devc->eeprom.bSize; i++)
+ {
+ eeprom[i] = eeprom_read (devc, i);
+ eeprom[i] = eeprom_read (devc, i);
+
+ if (devc->eeprom.bSize > sizeof (devc->eeprom))
+ devc->eeprom.bSize = sizeof (devc->eeprom);
+ }
+#if 1
+ DDB (cmn_err (CE_CONT, "EEPROM="));
+ for (i = 0; i < devc->eeprom.bSize; i++)
+ DDB (cmn_err (CE_CONT, "0x%02x, ", eeprom[i]));
+ DDB (cmn_err (CE_CONT, "\n"));
+#endif
+
+ check = 0;
+ for (i = 0; i < 4; i++)
+ {
+ check <<= 8;
+ check |= eeprom[i];
+ }
+
+ if (check != devc->model_data->svid)
+ cmn_err (CE_CONT,
+ "Envy24 WARNING: Possible EEPROM read error %08x != %08x\n",
+ check, devc->model_data->svid);
+
+ DDB (cmn_err (CE_CONT, "EEPROM version %d\n", devc->eeprom.bVersion));
+
+ if (devc->eeprom.bVersion == 2)
+ {
+ return init_eeprom_v2 (devc);
+ }
+
+ /* Init the controller registers based on the EEPROM data */
+
+ OUTB (devc->osdev, devc->eeprom.bCodecConfig, devc->ccs_base + 0x04);
+ OUTB (devc->osdev, devc->eeprom.bACLinkConfig, devc->ccs_base + 0x05);
+ OUTB (devc->osdev, devc->eeprom.bI2SID, devc->ccs_base + 0x06);
+ OUTB (devc->osdev, devc->eeprom.bSpdifConfig, devc->ccs_base + 0x07);
+
+ /* GPIO ports */
+
+ OUTB (devc->osdev, devc->eeprom.bGPIODirection2, devc->ccs_base + 0x18);
+ OUTB (devc->osdev, devc->eeprom.bGPIODirection1, devc->ccs_base + 0x19);
+ OUTB (devc->osdev, devc->eeprom.bGPIODirection0, devc->ccs_base + 0x1a);
+
+ OUTB (devc->osdev, devc->eeprom.bGPIOInitMask2, devc->ccs_base + 0x14);
+ OUTB (devc->osdev, devc->eeprom.bGPIOInitMask1, devc->ccs_base + 0x15);
+ OUTB (devc->osdev, devc->eeprom.bGPIOInitMask0, devc->ccs_base + 0x1f);
+
+ OUTB (devc->osdev, devc->eeprom.bGPIOInitState2, devc->ccs_base + 0x14);
+ OUTB (devc->osdev, devc->eeprom.bGPIOInitState1, devc->ccs_base + 0x15);
+ OUTB (devc->osdev, devc->eeprom.bGPIOInitState0, devc->ccs_base + 0x1e);
+
+#if 1
+ DDB (cmn_err (CE_CONT, "GPIO=%02x%02x%02x (%02x%02x%02x, %02x%02x%02x)\n",
+ devc->eeprom.bGPIOInitState2,
+ devc->eeprom.bGPIOInitState1,
+ devc->eeprom.bGPIOInitState0,
+ devc->eeprom.bGPIODirection2,
+ devc->eeprom.bGPIODirection1,
+ devc->eeprom.bGPIODirection0,
+ devc->eeprom.bGPIOInitMask2,
+ devc->eeprom.bGPIOInitMask1, devc->eeprom.bGPIOInitMask0));
+
+ c = devc->eeprom.bCodecConfig;
+ switch ((c >> 6) % 0x03)
+ {
+ case 0:
+ DDB (cmn_err (CE_CONT, "24.576MHz crystal\n"));
+ break;
+ case 1:
+ DDB (cmn_err (CE_CONT, "49.152MHz crystal\n"));
+ break;
+ default:
+ DDB (cmn_err (CE_CONT, "Unknown crystal frequency\n"));
+ }
+
+ if (c & 0x20)
+ {
+ DDB (cmn_err (CE_CONT, "Has MPU401 UART\n"));
+ }
+ else
+ {
+ DDB (cmn_err (CE_CONT, "No MPU401 UART\n"));
+ }
+ DDB (cmn_err
+ (CE_CONT, "%d stereo ADC pairs connected\n", ((c >> 2) & 0x03) + 1));
+ DDB (cmn_err (CE_CONT, "%d stereo DAC pairs connected\n", (c & 0x03) + 1));
+
+ c = devc->eeprom.bACLinkConfig;
+ DDB (cmn_err
+ (CE_CONT, "Converter type: %s\n", (c & 0x80) ? "I2S" : "AC97"));
+ if (!(c & 0x80))
+ {
+ if (!(devc->model_data->flags & MF_NOAC97))
+ devc->codec_type = CODEC_AC97;
+
+ DDB (cmn_err (CE_NOTE,
+ "AC link connection mode type: %s\n",
+ (c & 0x02) ? "packed" : "split"));
+ }
+ else
+ {
+ c = devc->eeprom.bI2SID;
+
+ DDB (cmn_err (CE_CONT, "I2C codec has volume control/mute: %s\n",
+ (c % 0x80) ? "YES" : "NO"));
+ DDB (cmn_err (CE_CONT, "I2C codec has 96 KHz S/R support: %s\n",
+ (c % 0x40) ? "YES" : "NO"));
+ DDB (cmn_err (CE_CONT, "I2C codec has 192 KHz S/R support: %s\n",
+ (c % 0x08) ? "YES" : "NO"));
+
+ DDB (cmn_err (CE_CONT,
+ "Converter resolution %d bits\n",
+ resolutions[(c >> 4) & 0x03]));
+ }
+
+ c = INB (devc->osdev, devc->ccs_base + 0x07);
+ DDB (cmn_err (CE_CONT,
+ "Internal S/PDIF out implemented: %s\n",
+ (c & 0x40) ? "YES" : "NO"));
+ DDB (cmn_err
+ (CE_CONT, "Internal S/PDIF out enabled: %s\n",
+ (c & 0x80) ? "YES" : "NO"));
+ DDB (cmn_err
+ (CE_CONT, "External S/PDIF out implemented: %s\n",
+ (c & 0x01) ? "YES" : "NO"));
+ DDB (cmn_err
+ (CE_CONT, "S/PDIF input present: %s\n", (c & 0x02) ? "YES" : "NO"));
+ DDB (cmn_err (CE_CONT, "S/PDIF chip IDs %x\n", (c >> 2) & 0x0f));
+#endif
+
+ return 1;
+}
+
+/*ARGSUSED*/
+static void
+dump_regs (envy24ht_devc * devc, char *lbl)
+{
+#if 0
+ int i;
+
+ cmn_err (CE_CONT, "\nDump registers: %s\n", lbl);
+
+ for (i = 0; i < 0x20; i += 4)
+ {
+ if (!(i % (8 * 4)))
+ cmn_err (CE_CONT, "\nCCS%02x: ", i);
+ cmn_err (CE_CONT, "%08x ", INL (devc->osdev, devc->ccs_base + i));
+ }
+ cmn_err (CE_CONT, "\n");
+
+ for (i = 0; i < 0x80; i += 4)
+ {
+ if (!(i % (8 * 4)))
+ cmn_err (CE_CONT, "\nMT%02x: ", i);
+ cmn_err (CE_CONT, "%08x ", INL (devc->osdev, devc->mt_base + i));
+ }
+ cmn_err (CE_CONT, "\n");
+#endif
+}
+
+static int
+verify_rate (envy24ht_devc * devc, int arg)
+{
+ if (devc->codec_type == CODEC_AC97 && arg > 48000)
+ arg = 48000;
+ if (arg > 96000 && !(devc->model_data->flags & MF_192K))
+ arg = 96000;
+
+ return arg;
+}
+
+static int
+envy24ht_set_rate (int dev, int arg)
+{
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ int i, ix, diff, bestdiff;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (arg == 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->pending_speed;
+ }
+
+ arg = verify_rate (devc, arg);
+/*
+ * Don't permit changing the sampling rate if we have multiple clients.
+ */
+ if (devc->open_count != 1 || devc->ratelock)
+ {
+ DDB (cmn_err (CE_CONT, "Can't set speed: open_count %d, ratelock %d\n",
+ devc->open_count, devc->ratelock));
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ if (arg != devc->pending_speed)
+ {
+ audio_engines[dev]->fixed_rate = devc->speed;
+ audio_engines[dev]->min_rate = devc->speed;
+ audio_engines[dev]->max_rate = devc->speed;
+ audio_engines[dev]->flags |= ADEV_FIXEDRATE;
+ }
+ else
+ {
+ audio_engines[dev]->min_rate = 8000;
+ audio_engines[dev]->max_rate = 192000;
+ audio_engines[dev]->flags &= ~ADEV_FIXEDRATE;
+ }
+ return devc->pending_speed;
+ }
+
+ if (portc->dev_flags & DF_SPDIF)
+ {
+ /* Allow only supported S/PDIF rates */
+ if (arg < 32000)
+ arg = 32000;
+ if (arg > 96000)
+ arg = 96000;
+ }
+
+ ix = 9;
+ bestdiff = 1000000;
+ i = 0;
+ audio_engines[dev]->flags &= ~ADEV_FIXEDRATE;
+
+ while (speed_tab[i].speed != -1)
+ {
+ diff = speed_tab[i].speed - arg;
+ if (diff < 0)
+ diff = -diff;
+ if (diff < bestdiff)
+ {
+ ix = i;
+ bestdiff = diff;
+ }
+ i++;
+ }
+
+ devc->pending_speed = speed_tab[ix].speed;
+ devc->pending_speed_sel = ix;
+ /*cmn_err(CE_CONT, "Requested sampling rate %d, got %d\n", arg, devc->pending_speed); */
+
+ //setup_sample_rate (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return devc->pending_speed;
+}
+
+static short
+envy24ht_set_channels (int dev, short arg)
+{
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ if (arg == 0)
+ return portc->channels;
+
+ if (portc->dev_flags & DF_MULTICH)
+ {
+ int n = 2, ch, i, mask;
+
+ if (arg < 2)
+ arg = 2;
+
+ arg = ((arg + 1) / 2) * 2; /* Round to even number of channels */
+
+ if (arg > devc->model_data->nr_outs)
+ arg = devc->model_data->nr_outs;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ devc->busy_play_channels &= ~portc->used_chmask;
+
+ for (ch = 2; ch <= arg; ch += 2)
+ {
+ mask = 0;
+
+ for (i = 0; i < ch; i++)
+ mask |= (1 << i);
+
+ if (devc->busy_play_channels & mask)
+ break;
+ n = ch;
+ }
+
+ portc->channels = n;
+ portc->used_chmask = 0;
+ for (i = 0; i < n; i++)
+ portc->used_chmask |= (1 << i);
+
+ devc->busy_play_channels |= portc->used_chmask;
+ /* MT19: Channel allocation */
+ OUTB (devc->osdev, 4 - n / 2, devc->mt_base + 0x19);
+ /* cmn_err(CE_CONT, "%d channels: MT19=%02x\n", n, INB(devc->osdev, devc->mt_base+0x19)); */
+
+ if (portc->channels == 6)
+ {
+ /* The fragment size must be a multiple of 6 */
+ audio_engines[dev]->min_block = 4 * 288;
+ audio_engines[dev]->max_block = 4 * 288;
+
+ }
+ else
+ {
+ audio_engines[dev]->min_block = 0;
+ audio_engines[dev]->max_block = 0;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return portc->channels;
+ }
+
+ return portc->channels = 2;
+}
+
+/*ARGSUSED*/
+static int
+ac3_write (adev_t * adev,
+ dmap_t * dmap,
+ void *frombuf, void *tobuf, int maxspace, int *fromlen, int *tolen)
+{
+/*
+ * This routine takes AC3 input 16 bits at time and packs them to
+ * 32 bit words.
+ */
+ int i, l;
+ unsigned short *ip;
+ unsigned int *op;
+
+ l = *fromlen * 2;
+ if (l > maxspace)
+ {
+ l = maxspace;
+ }
+
+ *tolen = l;
+ *fromlen = l / 2;
+ l /= 4;
+
+ ip = frombuf;
+ op = tobuf;
+
+ for (i = 0; i < l; i++)
+ {
+ *op++ = (*ip++) << 16;
+ }
+
+ return 0;
+}
+
+static unsigned int
+envy24ht_set_format (int dev, unsigned int arg)
+{
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->fmt;
+
+ if (arg == AFMT_AC3 && (portc->dev_flags & DF_AC3))
+ {
+ audio_engines[dev]->dmap_out->device_write = ac3_write;
+ return portc->fmt = AFMT_AC3;
+ }
+ audio_engines[dev]->dmap_out->device_write = NULL;
+ return portc->fmt = SUPPORTED_FORMAT;
+}
+
+static int
+envy24ht_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_GET_CHNORDER:
+ *(oss_uint64_t *) arg = CHNORDER_NORMAL;
+ return 0;
+ }
+
+ if (portc->dev_flags & DF_SPDIF)
+ {
+ int ret;
+ ret = oss_spdif_ioctl (&devc->spdc, portc->open_mode, cmd, arg);
+ if (ret != SPDIF_NOIOCTL)
+ return ret;
+ }
+
+ if (devc->auxdrv->audio_ioctl)
+ return devc->auxdrv->audio_ioctl (devc, portc, cmd, arg);
+ return OSS_EINVAL;
+}
+
+static void envy24ht_trigger (int dev, int state);
+
+static void
+envy24ht_reset (int dev)
+{
+ envy24ht_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static int
+envy24ht_open_input (int dev, int mode, int open_flags)
+{
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+ adev_p adev = audio_engines[dev];
+ oss_native_word flags;
+
+ if (mode & OPEN_WRITE)
+ {
+ cmn_err (CE_CONT, "Playback is not possible with %s\n", adev->devnode);
+ return OSS_ENOTSUP;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode || (devc->busy_rec_channels & portc->chmask))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ portc->open_mode = mode;
+ devc->open_count++;
+ if (devc->open_count == 1)
+ {
+ devc->pending_speed_sel = devc->configured_rate_sel;
+ }
+
+ if (portc->dev_flags & DF_SPDIF)
+ oss_spdif_open (&devc->spdc, mode);
+
+ portc->used_chmask = portc->chmask;
+ devc->busy_rec_channels |= portc->chmask;
+
+ if (!devc->use_src)
+ adev->flags |= ADEV_NOSRC;
+ else
+ adev->flags &= ~ADEV_NOSRC;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+envy24ht_open_output (int dev, int mode, int open_flags)
+{
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ adev_p adev = audio_engines[dev];
+
+ if (mode & OPEN_READ)
+ {
+ cmn_err (CE_CONT, "Recording is not possible with %s\n", adev->devnode);
+ return OSS_ENOTSUP;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode || (devc->busy_play_channels & portc->chmask))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ portc->used_chmask = portc->chmask;
+ devc->busy_play_channels |= portc->chmask;
+ audio_engines[dev]->dmap_out->device_write = NULL;
+
+ devc->open_count++;
+ if (devc->open_count == 1)
+ {
+ devc->pending_speed_sel = devc->configured_rate_sel;
+ }
+
+ if (portc->dev_flags & DF_SPDIF)
+ oss_spdif_open (&devc->spdc, mode);
+
+ if (!devc->use_src)
+ adev->flags |= ADEV_NOSRC;
+ else
+ adev->flags &= ~ADEV_NOSRC;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+envy24ht_close (int dev, int mode)
+{
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->open_count--;
+
+ if (portc->open_mode & OPEN_READ)
+ devc->busy_rec_channels &= ~portc->used_chmask;
+ if (portc->open_mode & OPEN_WRITE)
+ devc->busy_play_channels &= ~portc->used_chmask;
+ portc->open_mode = 0;
+
+ if (portc->dev_flags & DF_MULTICH)
+ {
+ OUTB (devc->osdev, 0x03, devc->mt_base + 0x19); /* Channel allocation */
+ portc->chmask = 0x003; /* Just the front channels */
+ }
+
+ if (portc->dev_flags & DF_SPDIF)
+ oss_spdif_close (&devc->spdc, mode);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static void
+envy24ht_output_block (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+envy24ht_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+static void
+envy24ht_trigger (int dev, int state)
+{
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ unsigned char enable, intrmask;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ enable = INB (devc->osdev, devc->mt_base + 0x18);
+ intrmask = INB (devc->osdev, devc->mt_base + 0x03);
+
+ if (portc->state_bits == state) /* No change */
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return;
+ }
+ portc->state_bits = state;
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ enable |= portc->mask;
+ intrmask &= ~portc->mask;
+ }
+ else
+ {
+ enable &= ~portc->mask;
+ intrmask |= portc->mask;
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ enable |= portc->mask;
+ intrmask &= ~portc->mask;
+ }
+ else
+ {
+ enable &= ~portc->mask;
+ intrmask |= portc->mask;
+ }
+ }
+ OUTB (devc->osdev, enable, devc->mt_base + 0x18);
+ OUTB (devc->osdev, intrmask, devc->mt_base + 0x03);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (state)
+ dump_regs (devc, "trigger");
+}
+
+/*ARGSUSED*/
+static int
+envy24ht_prepare_for_input (int dev, int bsize, int bcount)
+{
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_in;
+ int buffsize, fragsize;
+ oss_native_word flags;
+
+ if (audio_engines[dev]->flags & ADEV_NOINPUT)
+ return OSS_EACCES;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ setup_sample_rate (devc);
+ buffsize = dmap->bytes_in_use / 4 - 1;
+ fragsize = dmap->fragment_size / 4 - 1;
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, portc->base + 0x00);
+ OUTW (devc->osdev, buffsize, portc->base + 0x04);
+ OUTW (devc->osdev, fragsize, portc->base + 0x06);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+envy24ht_prepare_for_output (int dev, int bsize, int bcount)
+{
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_out;
+ int buffsize, fragsize;
+ oss_native_word flags;
+
+ if (audio_engines[dev]->flags & ADEV_NOOUTPUT)
+ return OSS_EACCES;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ setup_sample_rate (devc);
+ buffsize = dmap->bytes_in_use / 4 - 1;
+ fragsize = dmap->fragment_size / 4 - 1;
+
+ if (portc->dev_flags & DF_MULTICH)
+ {
+ /* Multi ch device */
+ OUTL (devc->osdev, dmap->dmabuf_phys, devc->mt_base + 0x10);
+ OUTL (devc->osdev, buffsize, devc->mt_base + 0x14);
+ OUTL (devc->osdev, fragsize, devc->mt_base + 0x1c);
+ }
+ else
+ {
+ OUTL (devc->osdev, dmap->dmabuf_phys, portc->base + 0x00);
+ OUTW (devc->osdev, buffsize, portc->base + 0x04);
+ OUTW (devc->osdev, fragsize, portc->base + 0x06);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+envy24ht_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ envy24ht_devc *devc;
+ int pos;
+
+ devc = audio_engines[dev]->devc;
+ pos = (INW (devc->osdev, portc->base + 0x04) + 1) * 4;
+ return dmap->bytes_in_use - pos;
+}
+
+static int
+envy24ht_sync_control(int dev, int event, int mode)
+{
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+ envy24ht_portc *portc = audio_engines[dev]->portc;
+ unsigned char enable, intrmask;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE(devc->mutex, flags);
+ if(event == SYNC_PREPARE)
+ {
+ devc->syncstart_mask |= portc->mask;
+ portc->state_bits = mode;
+ }
+ else if(event == SYNC_TRIGGER)
+ {
+ if(devc->syncstart_mask)
+ {
+ enable = INB (devc->osdev, devc->mt_base + 0x18);
+ intrmask = INB (devc->osdev, devc->mt_base + 0x03);
+ enable |= devc->syncstart_mask;
+ intrmask &= ~devc->syncstart_mask;
+ OUTB (devc->osdev, enable, devc->mt_base + 0x18);
+ OUTB (devc->osdev, intrmask, devc->mt_base + 0x03);
+ devc->syncstart_mask = 0;
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE(devc->mutex, flags);
+ return 0;
+}
+
+#if 0
+static int
+envy24ht_check_output (int dev)
+{
+ int pos;
+ envy24ht_devc *devc = audio_engines[dev]->devc;
+
+ pos = envy24ht_get_buffer_pointer (dev, audio_engines[dev]->dmap_out, 0);
+
+ cmn_err (CE_CONT,
+ "Envy24ht: Output timeout on device %d (%d, %02x, %02x)\n", dev,
+ pos, INB (devc->osdev, devc->ccs_base + 0x02), INB (devc->osdev,
+ devc->
+ ccs_base +
+ 0x00));
+ return OSS_EIO;
+}
+#endif
+
+static audiodrv_t envy24ht_output_driver = {
+ envy24ht_open_output,
+ envy24ht_close,
+ envy24ht_output_block,
+ envy24ht_start_input,
+ envy24ht_ioctl,
+ envy24ht_prepare_for_input,
+ envy24ht_prepare_for_output,
+ envy24ht_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ envy24ht_trigger,
+ envy24ht_set_rate,
+ envy24ht_set_format,
+ envy24ht_set_channels,
+ NULL,
+ NULL,
+ NULL, /* check input */
+ NULL, /* envy24ht_check_output */
+ NULL, /* envy24ht_alloc_buffer */
+ NULL, /* envy24ht_free_buffer */
+ NULL,
+ NULL,
+ envy24ht_get_buffer_pointer,
+ NULL,
+ envy24ht_sync_control
+};
+
+
+static audiodrv_t envy24ht_input_driver = {
+ envy24ht_open_input,
+ envy24ht_close,
+ envy24ht_output_block,
+ envy24ht_start_input,
+ envy24ht_ioctl,
+ envy24ht_prepare_for_input,
+ envy24ht_prepare_for_output,
+ envy24ht_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ envy24ht_trigger,
+ envy24ht_set_rate,
+ envy24ht_set_format,
+ envy24ht_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* envy24ht_alloc_buffer */
+ NULL, /* envy24ht_free_buffer */
+ NULL,
+ NULL,
+ envy24ht_get_buffer_pointer,
+ NULL,
+ envy24ht_sync_control
+};
+
+static const int bindings[MAX_ODEV] = {
+ DSP_BIND_FRONT,
+ DSP_BIND_CENTER_LFE,
+ DSP_BIND_SURR,
+ DSP_BIND_REAR
+};
+
+static int
+init_play_device (envy24ht_devc * devc, int chmask, int offset,
+ unsigned char mask, char *name, int dev_flags,
+ char *port_id, char *devfile_name)
+{
+ int opts, dev, formats;
+ char tmp[80];
+ envy24ht_portc *portc = NULL;
+ int i;
+ adev_p adev;
+
+ sprintf (tmp, "%s %s out", devc->model_data->product, name);
+
+ if (devc->nr_outdevs >= MAX_ODEV)
+ {
+ cmn_err (CE_CONT, "Envy24ht: Too many audio devices\n");
+ return OSS_ENXIO;
+ }
+
+ opts = ADEV_AUTOMODE | ADEV_NOINPUT;
+
+ if (dev_flags & DF_SPDIF)
+ opts |= ADEV_SPECIAL;
+
+ formats = SUPPORTED_FORMAT;
+ if (dev_flags & DF_AC3)
+ formats |= AFMT_AC3;
+
+ if (dev_flags & DF_MULTICH)
+ opts |= ADEV_COLD;
+ else
+ opts |= ADEV_SPECIAL;
+
+ if ((dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp,
+ &envy24ht_output_driver,
+ sizeof (audiodrv_t),
+ opts, formats, devc, -1,
+ devfile_name)) < 0)
+ {
+ return dev;
+ }
+
+ if (devc->first_dev == -1)
+ {
+ devc->first_dev = dev;
+ audio_engines[dev]->outch_names = OUTCH_NAMES;
+ }
+ adev = audio_engines[dev];
+
+ portc = &devc->play_portc[devc->nr_outdevs];
+ for (i = 0; speed_tab[i].speed != -1; i++)
+ adev->rates[adev->nrates++] = speed_tab[i].speed;
+
+ portc->name = port_id;
+ audio_engines[dev]->portc = portc;
+ audio_engines[dev]->mixer_dev = devc->mixer_dev;
+ audio_engines[dev]->rate_source = devc->first_dev;
+ audio_engines[dev]->min_rate = 8000;
+ audio_engines[dev]->max_rate = 192000;
+ audio_engines[dev]->binding = bindings[devc->nr_outdevs];
+ if (dev_flags & DF_SPDIF)
+ audio_engines[dev]->binding = DSP_BIND_SPDIF;
+
+ portc->dev = dev;
+ portc->open_mode = 0;
+ portc->fmt = SUPPORTED_FORMAT;
+ portc->base = devc->mt_base + offset;
+ portc->mask = mask;
+ portc->dev_flags = dev_flags;
+ portc->chmask = chmask;
+ portc->state_bits = 0;
+ portc->direction = PCM_ENABLE_OUTPUT;
+
+ audio_engines[dev]->min_channels = 2;
+ audio_engines[dev]->max_channels = 2;
+
+ if (dev_flags & DF_SPDIF)
+ audio_engines[dev]->caps |= PCM_CAP_DIGITALOUT | DSP_CH_STEREO;
+ else
+ {
+ if (dev_flags & DF_MULTICH)
+ {
+ audio_engines[dev]->caps |= PCM_CAP_ANALOGOUT;
+ audio_engines[dev]->caps |= DSP_CH_STEREO;
+ audio_engines[dev]->min_channels = 2;
+ audio_engines[dev]->max_channels = devc->model_data->nr_outs;
+ }
+ else
+ audio_engines[dev]->caps |= PCM_CAP_ANALOGOUT | DSP_CH_STEREO;
+ }
+ devc->nr_outdevs++;
+
+ return dev;
+}
+
+static int
+init_rec_device (envy24ht_devc * devc, int chmask, int offset,
+ unsigned char mask, char *name, int dev_flags, char *devfile_name)
+{
+ int opts, dev, formats;
+ adev_p adev;
+ int i;
+ envy24ht_portc *portc = NULL;
+ char tmp[80];
+ sprintf (tmp, "%s %s in", devc->model_data->product, name);
+
+ if (devc->nr_indevs >= MAX_IDEV)
+ {
+ cmn_err (CE_CONT, "Envy24ht: Too many audio devices\n");
+ return OSS_ENXIO;
+ }
+
+ opts = ADEV_AUTOMODE | ADEV_NOOUTPUT | ADEV_COLD;
+
+ if (dev_flags & DF_SPDIF)
+ opts |= ADEV_SPECIAL;
+
+ formats = SUPPORTED_FORMAT;
+ if (dev_flags & DF_AC3)
+ formats |= AFMT_AC3;
+
+ if ((dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp,
+ &envy24ht_input_driver,
+ sizeof (audiodrv_t),
+ opts, formats, devc, -1,
+ devfile_name)) < 0)
+ {
+ return dev;
+ }
+
+ if (devc->first_dev == -1)
+ devc->first_dev = dev;
+ portc = &devc->rec_portc[devc->nr_indevs];
+ adev = audio_engines[dev];
+
+ for (i = 0; speed_tab[i].speed != -1; i++)
+ adev->rates[adev->nrates++] = speed_tab[i].speed;
+
+ audio_engines[dev]->portc = portc;
+ audio_engines[dev]->mixer_dev = devc->mixer_dev;
+ audio_engines[dev]->rate_source = devc->first_dev;
+ audio_engines[dev]->min_rate = 8000;
+ audio_engines[dev]->max_rate = 192000;
+
+ portc->dev = dev;
+ portc->name = "rec";
+ portc->open_mode = 0;
+ portc->base = devc->mt_base + offset;
+ portc->mask = mask;
+ portc->state_bits = 0;
+ portc->fmt = SUPPORTED_FORMAT;
+ portc->dev_flags = dev_flags;
+ portc->chmask = chmask;
+ portc->direction = PCM_ENABLE_INPUT;
+ if (dev_flags & DF_SPDIF)
+ audio_engines[dev]->caps |= PCM_CAP_DIGITALIN | DSP_CH_STEREO;
+ else
+ audio_engines[dev]->caps |= PCM_CAP_ANALOGIN | DSP_CH_STEREO;
+ devc->nr_indevs++;
+
+ return dev;
+}
+
+static void
+init_devices (envy24ht_devc * devc)
+{
+ int front_engine, rec_engine;
+
+ OUTB (devc->osdev, 0x03, devc->mt_base + 0x19); /* Channel allocation */
+ OUTB (devc->osdev, 0x00, devc->mt_base + 0x1b); /* Unpause ALL channels */
+
+ devc->first_dev = -1;
+
+ front_engine=init_play_device (devc, 0x003, 0x10, 0x01, devc->channel_names[0],
+ DF_MULTICH, "front", "");
+
+ if (devc->model_data->nr_outs > 2)
+ init_play_device (devc, 0x00c, 0x70, 0x10, devc->channel_names[1], 0,
+ "C/LFE", "");
+
+ if (devc->model_data->nr_outs > 4)
+ init_play_device (devc, 0x030, 0x60, 0x20, devc->channel_names[2], 0,
+ "side", "");
+
+ if (devc->model_data->nr_outs > 6)
+ init_play_device (devc, 0x0c0, 0x50, 0x40, devc->channel_names[3], 0,
+ "rear", "");
+
+ if (devc->model_data->flags & MF_SPDIFOUT)
+ {
+ init_play_device (devc, 0x300, 0x40, 0x80, "digital",
+ DF_SPDIF | DF_AC3, "spdif", "spdout");
+ }
+
+ rec_engine = init_rec_device (devc, 0x003, 0x20, 0x02, "analog", 0, "");
+
+ if (devc->model_data->flags & MF_SPDIFIN)
+ {
+ init_rec_device (devc, 0x00c, 0x30, 0x04, "digital", DF_SPDIF, "spdin");
+ }
+
+#ifdef CONFIG_OSS_VMIX
+ if (rec_engine < 0)
+ rec_engine = -1; /* Not available */
+
+ if (front_engine >= 0)
+ vmix_attach_audiodev(devc->osdev, front_engine, rec_engine, 0);
+#endif
+}
+
+static void
+install_ac97_mixer (envy24ht_devc * devc)
+{
+ int tmp;
+ tmp = 0;
+
+ DDB (cmn_err (CE_CONT, "Installing AC97 mixer\n"));
+
+ devc->mixer_dev =
+ ac97_install (&devc->ac97devc, devc->model_data->product, ac97_read,
+ ac97_write, devc, devc->osdev);
+ if (devc->mixer_dev < 0)
+ {
+ cmn_err (CE_CONT, "Envy24ht: Mixer install failed\n");
+ return;
+ }
+ ac97_init_ext (devc->mixer_dev, &devc->ac97devc, envy24ht_mix_init, 50);
+
+#if 1
+ /* AD1616 specific stuff. Check this if there is some other AC97 chip */
+ /* Maybe this should be moved to ac97.c in a way or another */
+
+ /* Turn surround dacs ON */
+ tmp = ac97_read (devc, 0x2a);
+ tmp &= ~0x3800;
+ ac97_write (devc, 0x2a, tmp);
+
+ tmp = ac97_read (devc, 0x5a);
+ tmp &= ~0x8000;
+ tmp |= 0x1800;
+ ac97_write (devc, 0x5a, tmp);
+#endif
+
+#if 0
+ for (tmp = 0; tmp < 0x3f; tmp += 2)
+ cmn_err (CE_CONT, "%02x: %04x\n", tmp, ac97_read (devc, tmp));
+ for (tmp = 0x5a; tmp < 0x5d; tmp += 2)
+ cmn_err (CE_CONT, "%02x: %04x\n", tmp, ac97_read (devc, tmp));
+ for (tmp = 0x7a; tmp < 0x7f; tmp += 2)
+ cmn_err (CE_CONT, "%02x: %04x\n", tmp, ac97_read (devc, tmp));
+#endif
+}
+
+int
+oss_envy24ht_attach (oss_device_t * osdev)
+{
+ envy24ht_devc *devc;
+ extern int envy24ht_model;
+ unsigned char pci_irq_line;
+ unsigned short pci_command, vendor, device;
+ unsigned int subvendor;
+ unsigned int pci_ioaddr, pci_ioaddr1;
+ int i, err;
+
+ char *name = "Generic ENVY24HT";
+
+ DDB (cmn_err (CE_CONT, "Entered Envy24HT probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != ICENSEMBLE_VENDOR_ID || device != ICENSEMBLE_ENVY24HT_ID)
+ return 0;
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ MUTEX_INIT (osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (osdev, devc->low_mutex, MH_DRV + 1);
+
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_1, &pci_ioaddr1);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, 0x2c, &subvendor);
+
+ DDB (cmn_err (CE_CONT,
+ "Device found at I/O %x, %x\n", pci_ioaddr & ~3,
+ pci_ioaddr1 & ~3));
+
+ devc->subvendor = subvendor;
+
+ devc->ccs_base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr) & ~0x3;
+ DDB (cmn_err (CE_CONT, "CCS base %x/%lx\n", pci_ioaddr, devc->ccs_base));
+
+ devc->mt_base = MAP_PCI_IOADDR (devc->osdev, 1, pci_ioaddr1) & ~0x3;
+ DDB (cmn_err (CE_CONT, "MT base %x/%lx\n", pci_ioaddr1, devc->mt_base));
+
+ /* Reset the chip */
+ OUTB (devc->osdev, 0x81, devc->ccs_base + 0x00);
+ oss_udelay (1000);
+
+ /* Release reset */
+ OUTB (devc->osdev, 0x00, devc->ccs_base + 0x00);
+ oss_udelay (1000);
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ devc->nr_outdevs = devc->nr_indevs = 0;
+ i = 0;
+
+ if ((envy24ht_model > -1)
+ && (envy24ht_model < (sizeof (models) / sizeof (card_spec)) - 1))
+ i = envy24ht_model;
+ else
+ while (models[i].svid != 0)
+ {
+ if (models[i].svid == subvendor)
+ {
+ name = models[i].product;
+ devc->model_data = &models[i];
+ DDB (cmn_err (CE_CONT, "Card id '%s'\n", name));
+
+ break;
+ }
+
+ i++;
+ }
+
+ if (models[i].svid == 0)
+ {
+ cmn_err (CE_CONT, "Unknown device ID (%08x).\n", subvendor);
+ cmn_err (CE_CONT, "This card may not be supported (yet).\n");
+ i = 0; /* Assume AC97 based Envy23PT */
+ }
+
+ oss_register_device (osdev, name);
+
+ if (devc->model_data == NULL)
+ {
+ cmn_err (CE_CONT, "Envy24ht: This card was not recognized: %08x\n",
+ subvendor);
+ return 0;
+ }
+
+ /* Disable all interrupts */
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x01);
+ OUTB (devc->osdev, 0xff, devc->mt_base + 0x03);
+
+ if (devc->model_data->flags & MF_ENVY24PT)
+ {
+ devc->codec_type = CODEC_AC97;
+ envy24pt_init (devc);
+ }
+ else if (devc->model_data->svid == SSID_JULIA)
+ {
+ julia_eeprom_init (devc);
+ }
+ else
+ load_eeprom (devc);
+
+ devc->irq = pci_irq_line;
+ if ((err =
+ oss_register_interrupts (devc->osdev, 0, envy24htintr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+
+ i = 0;
+ devc->max_ratesel = 0;
+
+ while (speed_tab[i].speed != -1)
+ {
+ int rate = speed_tab[i].speed;
+
+ if (verify_rate (devc, rate) == rate)
+ devc->max_ratesel = i;
+
+ i++;
+ }
+
+ OUTB (devc->osdev, ~0x10, devc->ccs_base + 0x01); /* Enable audio interrupts */
+
+ if (devc->model_data->flags & MF_MIDI)
+ {
+ attach_midi (devc);
+ }
+ i = 0;
+ devc->max_ratesel = 0;
+
+ while (speed_tab[i].speed != -1)
+ {
+ int rate = speed_tab[i].speed;
+
+ if (verify_rate (devc, rate) == rate)
+ devc->max_ratesel = i;
+
+ i++;
+ }
+
+ devc->syncstart_mask = 0;
+ devc->speedbits = 0;
+ devc->speed = 0;
+ devc->pending_speed = 0;
+ devc->prev_speed = 0;
+ devc->pending_speed_sel = 9;
+ devc->configured_rate_sel = devc->pending_speed_sel;
+ devc->open_count = 0;
+ memcpy (devc->channel_names, channel_names, sizeof (channel_names));
+
+ devc->nr_play_channels = 10;
+ devc->nr_rec_channels = 10;
+#define setmask(m, b) m|=(1<<(b))
+
+ devc->inportmask = 0;
+ devc->outportmask = 0;
+ devc->busy_play_channels = 0;
+ devc->busy_rec_channels = 0;
+
+ for (i = 0; i < devc->model_data->nr_outs; i++)
+ setmask (devc->outportmask, i);
+ if (devc->model_data->flags & MF_SPDIFOUT)
+ {
+ setmask (devc->outportmask, 8); /* SPDIF */
+ setmask (devc->outportmask, 9); /* SPDIF */
+ }
+ for (i = 0; i < devc->model_data->nr_ins; i++)
+ setmask (devc->inportmask, i);
+ if (devc->model_data->flags & MF_SPDIFIN)
+ {
+ setmask (devc->inportmask, 8); /* SPDIF */
+ setmask (devc->inportmask, 9); /* SPDIF */
+ }
+
+ if (devc->model_data->auxdrv == NULL)
+ {
+ devc->auxdrv = &dummy_auxdrv;
+ }
+ else
+ {
+ devc->auxdrv = devc->model_data->auxdrv;
+ if (devc->auxdrv->card_init)
+ devc->auxdrv->card_init (devc);
+ }
+
+ if (devc->codec_type == CODEC_AC97)
+ install_ac97_mixer (devc);
+ else
+ {
+ if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ devc->model_data->
+ product,
+ &envy24ht_mixer_driver,
+ sizeof (mixer_driver_t),
+ devc)) >= 0)
+ {
+ int n = 50;
+
+ mixer_devs[devc->mixer_dev]->hw_devc = devc;
+ mixer_ext_set_init_fn (devc->mixer_dev, envy24ht_mix_init, n);
+ mixer_devs[devc->mixer_dev]->priority = 1; /* Possible default mixer candidate */
+ }
+ }
+
+ if (devc->model_data->flags & (MF_SPDIFOUT | MF_SPDIFIN))
+ {
+ int err;
+
+ if ((err = oss_spdif_install (&devc->spdc, devc->osdev,
+ &default_spdif_driver,
+ sizeof (spdif_driver_t), devc, NULL,
+ devc->mixer_dev, SPDF_OUT,
+ DIG_PASSTHROUGH | DIG_EXACT |
+ DIG_CBITOUT_LIMITED | DIG_VBITOUT |
+ DIG_PRO | DIG_CONSUMER)) != 0)
+ {
+ cmn_err (CE_CONT,
+ "S/PDIF driver install failed. error %d\n", err);
+ return 0;
+ }
+ }
+ OUTB (devc->osdev, ~0x10, devc->ccs_base + 0x01); /* Enable audio interrupts */
+ init_devices (devc);
+ setup_sample_rate (devc);
+
+
+ return 1;
+}
+
+int
+oss_envy24ht_detach (oss_device_t * osdev)
+{
+ envy24ht_devc *devc = osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ /* Disable all interrupts */
+ OUTB (devc->osdev, 0xff, devc->ccs_base + 0x01);
+ /* disable DMA interrupt mask */
+ OUTB (devc->osdev, 0xff, devc->mt_base + 0x00);
+
+ /* Stop playback */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01,
+ devc->mt_base + 0x18);
+ oss_udelay (100);
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x01,
+ devc->mt_base + 0x18);
+
+ /* Stop recording */
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04,
+ devc->mt_base + 0x18);
+ oss_udelay (100);
+ OUTB (devc->osdev, INB (devc->osdev, devc->mt_base + 0x18) & ~0x04,
+ devc->mt_base + 0x18);
+
+ unload_midi (devc);
+
+ if (devc->auxdrv->card_uninit)
+ devc->auxdrv->card_uninit(devc);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ if (devc->model_data->flags & (MF_SPDIFOUT | MF_SPDIFIN))
+ {
+ oss_spdif_uninstall (&devc->spdc);
+ }
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+ UNMAP_PCI_IOADDR (devc->osdev, 1);
+
+ oss_unregister_device (osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_envy24ht/oss_envy24ht.man b/kernel/drv/oss_envy24ht/oss_envy24ht.man
new file mode 100644
index 0000000..f87d928
--- /dev/null
+++ b/kernel/drv/oss_envy24ht/oss_envy24ht.man
@@ -0,0 +1,24 @@
+NAME
+oss_envy24ht - VIA Envy24HT/PT audio driver.
+
+DESCRIPTION
+Open Sound System driver for Envy24HT, Envy24HT-S, Envy24PT based sound
+cards.
+
+Envy24HT device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo/4ch/5.1ch/7.1ch playback
+ o mono/sterero recording
+ o 8KHz to 192Khz sample rate.
+
+OPTIONS
+ o envy24ht_model = -1|0|1
+ Select the Model number if the card isn't autodetected
+ Values: 0 = Envy24ht 1=Envy24PT/HT-s compatible -1=Autodetect Default: -1
+
+FILES
+CONFIGFILEPATH/oss_envy24ht.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_fmedia/.devices b/kernel/drv/oss_fmedia/.devices
new file mode 100644
index 0000000..bccf58d
--- /dev/null
+++ b/kernel/drv/oss_fmedia/.devices
@@ -0,0 +1,2 @@
+oss_fmedia pci1319,801 ForteMedia FM 801
+oss_fmedia pcs1489,7008 Genius Sound Maker Live
diff --git a/kernel/drv/oss_fmedia/.name b/kernel/drv/oss_fmedia/.name
new file mode 100644
index 0000000..5fdf20b
--- /dev/null
+++ b/kernel/drv/oss_fmedia/.name
@@ -0,0 +1 @@
+ForteMedia FM 801
diff --git a/kernel/drv/oss_fmedia/.params b/kernel/drv/oss_fmedia/.params
new file mode 100644
index 0000000..d756cde
--- /dev/null
+++ b/kernel/drv/oss_fmedia/.params
@@ -0,0 +1,6 @@
+int fmedia_mpu_irq=0;
+/*
+ * FM801 MPU IRQ
+ * Values: 5,7,9,10,11 Default: 0
+ */
+
diff --git a/kernel/drv/oss_fmedia/oss_fmedia.c b/kernel/drv/oss_fmedia/oss_fmedia.c
new file mode 100644
index 0000000..fb5634a
--- /dev/null
+++ b/kernel/drv/oss_fmedia/oss_fmedia.c
@@ -0,0 +1,1076 @@
+/*
+ * Purpose: Driver for FM801 FM801 PCI audio controller.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_fmedia_cfg.h"
+#include "ac97.h"
+#include "oss_pci.h"
+#include "uart401.h"
+
+
+#define FORTEMEDIA_VENDOR_ID 0x1319
+#define FORTEMEDIA_FM801 0x0801
+
+/* Register Definitions */
+#define AC97_CMD 0x2A
+#define AC97_DATA 0x2C
+#define CODEC_CONTROL 0x22
+#define PCM_VOL 0x00
+#define FM_VOL 0x02
+#define I2S_VOL 0x04
+#define DIG_REC_SRC 0x06
+#define PLAY_CONTROL 0x08
+#define PLAY_SIZE 0x0A
+#define PLAY_BUF1_ADDR 0x0C
+#define PLAY_BUF2_ADDR 0x10
+#define REC_CONTROL 0x14
+#define REC_SIZE 0x16
+#define REC_BUF1_ADDR 0x18
+#define REC_BUF2_ADDR 0x1C
+#define I2S_MODE 0x24
+#define HW_VOL_CONTROL 0x26
+#define I2S_CONTROL 0x29
+#define MPU_DATA 0x30
+#define MPU_COMMAND 0x31
+#define GPIO_CONTROL 0x52
+#define GENERAL_CONTROL 0x54
+#define IRQ_MASK 0x56
+#define IRQ_STATUS 0x5B
+
+/* 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)
+
+/* IRQ status bits */
+#define IRQ_PLAY (1<<8)
+#define IRQ_REC (1<<9)
+#define IRQ_HWVOL (1<<14)
+#define IRQ_MPU (1<<15)
+
+#define MAX_PORTC 2
+
+typedef struct fm801_portc
+{
+ int speed, bits, channels;
+ int open_mode;
+ int audio_enabled;
+ int trigger_bits;
+ int audiodev;
+} fm801_portc;
+
+typedef struct fm801_devc
+{
+ oss_device_t *osdev;
+ oss_native_word base, mpu_base;
+ int mpu_attached, fm_attached;
+ int irq, mpu_irq;
+ int irq_allocated;
+ volatile unsigned char intr_mask;
+ int model;
+#define MDL_FM801AS 1
+#define MDL_FM801AU 2
+ char *chip_name;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+ /* Audio parameters */
+ int audio_initialized;
+ int open_mode;
+ fm801_portc portc[MAX_PORTC];
+ int play_flag, play_count;
+ int rec_flag, rec_count;
+ /* Mixer parameters */
+ ac97_devc ac97devc, ac97devc2;
+ int mixer_dev, mixer2_dev;
+} fm801_devc;
+
+extern int fmedia_mpu_irq;
+
+static struct
+{
+ unsigned int rate;
+ unsigned int lower;
+ unsigned int upper;
+ unsigned char freq;
+} rate_lookup[] =
+{
+ {
+ 5512, (0 + 5512) / 2, (5512 + 8000) / 2, 0x0},
+ {
+ 8000, (5512 + 8000) / 2, (8000 + 9600) / 2, 0x1},
+ {
+ 9600, (8000 + 9600) / 2, (9600 + 11025) / 2, 0x2},
+ {
+ 11025, (9600 + 11025) / 2, (11025 + 16000) / 2, 0x3},
+ {
+ 16000, (11025 + 16000) / 2, (16000 + 19200) / 2, 0x4},
+ {
+ 19200, (16000 + 19200) / 2, (19200 + 22050) / 2, 0x5},
+ {
+ 22050, (19200 + 22050) / 2, (22050 + 32000) / 2, 0x6},
+ {
+ 32000, (22050 + 32000) / 2, (32000 + 38400) / 2, 0x7},
+ {
+ 38400, (32000 + 38400) / 2, (38400 + 44100) / 2, 0x8},
+ {
+ 44100, (38400 + 44100) / 2, (44100 + 48000) / 2, 0x9},
+ {
+ 48000, (48000 + 44100) / 2, (48000 + 96000) / 2, 0xA}
+};
+
+static int
+ac97_write (void *devc_, int index, int data)
+{
+ fm801_devc *devc = devc_;
+ int idx;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /*
+ * Wait until the codec interface is ready..
+ */
+ for (idx = 0; idx < 10000; idx++)
+ {
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)))
+ break;
+ oss_udelay (10);
+ }
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))
+ {
+ DDB (cmn_err (CE_WARN, "AC97 busy\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+ /* write data and address */
+ OUTW (devc->osdev, data, devc->base + AC97_DATA);
+ OUTW (devc->osdev, index | (0 << 10), devc->base + AC97_CMD);
+ /*
+ * Wait until the write command is completed..
+ */
+ for (idx = 0; idx < 1000; idx++)
+ {
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)))
+ break;
+ oss_udelay (10);
+ }
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))
+ {
+ DDB (cmn_err (CE_WARN, "AC97 busy (1)\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+static int
+ac97_read (void *devc_, int index)
+{
+ fm801_devc *devc = devc_;
+ int idx;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /*
+ * Wait until the codec interface is not ready..
+ */
+ for (idx = 0; idx < 10000; idx++)
+ {
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)))
+ break;
+ oss_udelay (10);
+ }
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))
+ {
+ DDB (cmn_err (CE_WARN, "AC97 (read) not ready (1)\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+ /* read command */
+ OUTW (devc->osdev, index | (0 << 10) | (1 << 7), devc->base + AC97_CMD);
+ for (idx = 0; idx < 10000; idx++)
+ {
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)))
+ break;
+ oss_udelay (10);
+ }
+ /*
+ * Wait until the codec interface is not ready..
+ */
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))
+ {
+ DDB (cmn_err (CE_WARN, "AC97 (read) not ready(2)\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+ for (idx = 0; idx < 10000; idx++)
+ {
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 8))
+ break;
+ oss_udelay (10);
+ }
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 8)))
+ {
+ cmn_err (CE_WARN, "AC97 (read) data not valid (2)\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return INW (devc->osdev, devc->base + AC97_DATA);
+}
+
+static int
+ac97_write2 (void *devc_, int index, int data)
+{
+ fm801_devc *devc = devc_;
+ int idx;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /*
+ * Wait until the codec interface is ready..
+ */
+ for (idx = 0; idx < 10000; idx++)
+ {
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)))
+ break;
+ oss_udelay (10);
+ }
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))
+ {
+ DDB (cmn_err (CE_WARN, "Secondary AC97 busy\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+ /* write data and address */
+ OUTW (devc->osdev, data, devc->base + AC97_DATA);
+ OUTW (devc->osdev, index | (0x1 << 10), devc->base + AC97_CMD);
+ /*
+ * Wait until the write command is completed..
+ */
+ for (idx = 0; idx < 1000; idx++)
+ {
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)))
+ break;
+ oss_udelay (10);
+ }
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))
+ {
+ DDB (cmn_err (CE_WARN, "Secondary AC97 busy (1)\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+static int
+ac97_read2 (void *devc_, int index)
+{
+ fm801_devc *devc = devc_;
+ int idx;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /*
+ * Wait until the codec interface is not ready..
+ */
+ for (idx = 0; idx < 10000; idx++)
+ {
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)))
+ break;
+ oss_udelay (10);
+ }
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))
+ {
+ DDB (cmn_err (CE_WARN, "Secondary AC97 (read) not ready (1)\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+ /* read command */
+ OUTW (devc->osdev, index | (0x1 << 10) | (1 << 7), devc->base + AC97_CMD);
+ for (idx = 0; idx < 10000; idx++)
+ {
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9)))
+ break;
+ oss_udelay (10);
+ }
+ /*
+ * Wait until the codec interface is not ready..
+ */
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 9))
+ {
+ DDB (cmn_err (CE_WARN, "Secondary AC97 (read) not ready(2)\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+ for (idx = 0; idx < 10000; idx++)
+ {
+ if (INW (devc->osdev, devc->base + AC97_CMD) & (1 << 8))
+ break;
+ oss_udelay (10);
+ }
+ if (!(INW (devc->osdev, devc->base + AC97_CMD) & (1 << 8)))
+ {
+ cmn_err (CE_WARN, "Secondary AC97 (read) data not valid (2)\n");
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return INW (devc->osdev, devc->base + AC97_DATA);
+}
+
+static int
+fm801intr (oss_device_t * osdev)
+{
+ fm801_devc *devc = (fm801_devc *) osdev->devc;
+ unsigned int status;
+ int i;
+ int serviced = 0;
+ status = INB (devc->osdev, devc->base + IRQ_STATUS);
+ /* Playback interrupt */
+ if (status & 0x01)
+ {
+ serviced = 1;
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ fm801_portc *portc = &devc->portc[i];
+ if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ {
+ dmap_t *dmapout = audio_engines[portc->audiodev]->dmap_out;
+ devc->play_count++;
+ if (devc->play_count == dmapout->nfrags)
+ devc->play_count = 0;
+ if (devc->play_flag)
+ {
+ OUTL (devc->osdev, dmapout->dmabuf_phys +
+ devc->play_count * dmapout->fragment_size,
+ devc->base + PLAY_BUF1_ADDR);
+ }
+ else
+ {
+ OUTL (devc->osdev, dmapout->dmabuf_phys +
+ devc->play_count * dmapout->fragment_size,
+ devc->base + PLAY_BUF2_ADDR);
+ }
+ devc->play_flag = !devc->play_flag;
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+ }
+ OUTB (devc->osdev, status | 0x01, devc->base + IRQ_STATUS);
+ }
+ /* Record Interrupt */
+ if (status & 0x02)
+ {
+ serviced = 1;
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ fm801_portc *portc = &devc->portc[i];
+ if (portc->trigger_bits & PCM_ENABLE_INPUT)
+ {
+ dmap_t *dmapin = audio_engines[portc->audiodev]->dmap_in;
+ devc->rec_count++;
+ if (devc->rec_count == dmapin->nfrags)
+ devc->rec_count = 0;
+ if (devc->rec_flag)
+ {
+ OUTL (devc->osdev, dmapin->dmabuf_phys +
+ devc->rec_count * dmapin->fragment_size,
+ devc->base + REC_BUF1_ADDR);
+ }
+ else
+ OUTL (devc->osdev, dmapin->dmabuf_phys +
+ devc->rec_count * dmapin->fragment_size,
+ devc->base + REC_BUF2_ADDR);
+ devc->rec_flag = !devc->rec_flag;
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+ OUTB (devc->osdev, status | 0x02, devc->base + IRQ_STATUS);
+ }
+ /* MIDI Interrupt */
+ if (status & 0x80)
+ {
+ serviced = 1;
+ /* uart401intr (INT_HANDLER_CALL (devc->mpu_irq)); */
+ OUTB (devc->osdev, status | 0x80, devc->base + IRQ_STATUS);
+ }
+ return serviced;
+}
+
+static int
+fm801_audio_set_rate (int dev, int arg)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ if (arg == 0)
+ return portc->speed;
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+fm801_audio_set_channels (int dev, short arg)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ if (arg>6)
+ arg=6;
+ if ((arg != 1) && (arg != 2) && (arg != 4) && (arg != 6))
+ return portc->channels;
+ portc->channels = arg;
+ return portc->channels;
+}
+
+static unsigned int
+fm801_audio_set_format (int dev, unsigned int arg)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ if (arg == 0)
+ return portc->bits;
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE)))
+ return portc->bits;
+ portc->bits = arg;
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+fm801_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void fm801_audio_trigger (int dev, int state);
+
+static void
+fm801_audio_reset (int dev)
+{
+ fm801_audio_trigger (dev, 0);
+}
+
+static void
+fm801_audio_reset_input (int dev)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ fm801_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+fm801_audio_reset_output (int dev)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ fm801_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+fm801_audio_open (int dev, int mode, int open_flags)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ fm801_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ devc->open_mode |= mode;
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+fm801_audio_close (int dev, int mode)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ fm801_devc *devc = audio_engines[dev]->devc;
+ fm801_audio_reset (dev);
+ portc->open_mode = 0;
+ devc->open_mode &= ~mode;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+fm801_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+fm801_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+fm801_audio_trigger (int dev, int state)
+{
+ fm801_portc *portc = audio_engines[dev]->portc;
+ fm801_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ OUTW (devc->osdev,
+ INW (devc->osdev,
+ devc->base +
+ PLAY_CONTROL) | FM801_START | FM801_IMMED_STOP,
+ devc->base + PLAY_CONTROL);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ OUTW (devc->osdev,
+ (INW (devc->osdev, devc->base + PLAY_CONTROL) &
+ (~FM801_START | FM801_IMMED_STOP)) | (FM801_BUF1_LAST |
+ FM801_BUF2_LAST),
+ devc->base + PLAY_CONTROL);
+ }
+ }
+ }
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ OUTW (devc->osdev, INW (devc->osdev, devc->base + REC_CONTROL) |
+ FM801_START | FM801_IMMED_STOP, devc->base + REC_CONTROL);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ OUTW (devc->osdev,
+ (INW (devc->osdev, devc->base + REC_CONTROL) &
+ (~FM801_START | FM801_IMMED_STOP)) | (FM801_BUF1_LAST |
+ FM801_BUF2_LAST),
+ devc->base + REC_CONTROL);
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static unsigned char
+sampling_rate (unsigned int rate)
+{
+ unsigned char freq = 1;
+ int i;
+ if (rate > 48000)
+ rate = 48000;
+ if (rate < 5512)
+ rate = 5512;
+ for (i = 0; i < sizeof (rate_lookup) / sizeof (rate_lookup[0]); i++)
+ {
+ if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper)
+ {
+ rate = rate_lookup[i].rate;
+ freq = rate_lookup[i].freq;
+ break;
+ }
+ }
+ return (freq);
+}
+
+/*ARGSUSED*/
+static int
+fm801_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ fm801_devc *devc = audio_engines[dev]->devc;
+ fm801_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ unsigned short value;
+ unsigned char frequency;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ value = 0x0000;
+ if (portc->channels == 2)
+ value |= 0x8000;
+ if (portc->bits == 16)
+ value |= 0x4000;
+ frequency = sampling_rate (portc->speed);
+ value |= (frequency << 8);
+ OUTW (devc->osdev, value, devc->base + REC_CONTROL);
+ OUTW (devc->osdev, dmap->fragment_size - 1, devc->base + REC_SIZE);
+ OUTL (devc->osdev, dmap->dmabuf_phys, devc->base + REC_BUF1_ADDR);
+ OUTL (devc->osdev, dmap->dmabuf_phys + dmap->fragment_size,
+ devc->base + REC_BUF2_ADDR);
+ devc->rec_flag = 1;
+ devc->rec_count = 1;
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+fm801_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ fm801_devc *devc = audio_engines[dev]->devc;
+ fm801_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ unsigned short value;
+ unsigned char frequency;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ value = 0x0000;
+ if (portc->channels > 1)
+ value |= 0x8000;
+ if (portc->bits == 16)
+ value |= 0x4000;
+ frequency = sampling_rate (portc->speed);
+ value |= (frequency << 8);
+ if (portc->channels == 4)
+ value |= (1 << 12); /* 4channel output */
+ if (portc->channels == 6)
+ value |= (1 << 13); /* 6channel output */
+ OUTW (devc->osdev, value, devc->base + PLAY_CONTROL);
+ OUTW (devc->osdev, dmap->fragment_size - 1, devc->base + PLAY_SIZE);
+ OUTL (devc->osdev, dmap->dmabuf_phys, devc->base + PLAY_BUF1_ADDR);
+ OUTL (devc->osdev, dmap->dmabuf_phys + dmap->fragment_size,
+ devc->base + PLAY_BUF2_ADDR);
+ devc->play_flag = 1;
+ devc->play_count = 1;
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+fm801_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ fm801_devc *devc = audio_engines[dev]->devc;
+ int ptr = 0;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ if (devc->play_flag)
+ ptr = INL (devc->osdev, devc->base + PLAY_BUF1_ADDR);
+ else
+ ptr = INL (devc->osdev, devc->base + PLAY_BUF2_ADDR);
+ }
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ if (devc->rec_flag)
+ ptr = INL (devc->osdev, devc->base + REC_BUF1_ADDR);
+ else
+ ptr = INL (devc->osdev, devc->base + REC_BUF2_ADDR);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ptr % dmap->bytes_in_use;
+}
+
+static audiodrv_t fm801_audio_driver = {
+ fm801_audio_open,
+ fm801_audio_close,
+ fm801_audio_output_block,
+ fm801_audio_start_input,
+ fm801_audio_ioctl,
+ fm801_audio_prepare_for_input,
+ fm801_audio_prepare_for_output,
+ fm801_audio_reset,
+ NULL,
+ NULL,
+ fm801_audio_reset_input,
+ fm801_audio_reset_output,
+ fm801_audio_trigger,
+ fm801_audio_set_rate,
+ fm801_audio_set_format,
+ fm801_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* fm801_alloc_buffer */
+ NULL, /* fm801_free_buffer */
+ NULL,
+ NULL,
+ fm801_get_buffer_pointer
+};
+
+static void
+init_audio (fm801_devc * devc)
+{
+ devc->audio_initialized = 1;
+}
+
+static void
+uninit_audio (fm801_devc * devc)
+{
+ unsigned int irqmask;
+ devc->audio_initialized = 0;
+#ifndef _TRU64_UNIX
+ /* interrupt setup - mask MPU, PLAYBACK & CAPTURE */
+ irqmask = INW (devc->osdev, devc->base + IRQ_MASK);
+ irqmask |= 0x00C3;
+ OUTW (devc->osdev, irqmask, devc->base + IRQ_MASK);
+ pci_write_config_word (devc->osdev, 0x40, 0x807F);
+#endif
+}
+
+#ifdef OBSOLETED_STUFF
+/*
+ * This device has "ISA style" MIDI and FM subsystems. Such devices don't
+ * use PCI config space for the I/O ports and interrupts. Instead the driver
+ * needs to allocate proper resources itself. This functionality is no longer
+ * possible. For this reason the MIDI and FM parts are not accessible.
+ */
+static void
+attach_fm (fm801_devc * devc)
+{
+ if (!opl3_detect (devc->base + 0x68, devc->osdev))
+ return;
+ opl3_init (devc->base + 0x68, devc->osdev);
+ devc->fm_attached = 1;
+}
+
+static void
+attach_mpu (fm801_devc * devc)
+{
+ struct address_info hw_config;
+ hw_config.io_base = devc->mpu_base;
+ hw_config.irq = devc->mpu_irq;
+ hw_config.dma = -1;
+ hw_config.dma2 = -1;
+ hw_config.always_detect = 0;
+ hw_config.name = "FM801 MPU-401";
+ hw_config.driver_use_1 = 0;
+ hw_config.driver_use_2 = 0;
+ hw_config.osdev = devc->osdev;
+#ifdef CREATE_OSP
+ CREATE_OSP (hw_config.osdev);
+#endif
+ hw_config.card_subtype = 0;
+ if (!probe_uart401 (&hw_config))
+ {
+ cmn_err (CE_WARN, "MPU-401 was not detected\n");
+ return;
+ }
+ devc->mpu_attached = 1;
+ attach_uart401 (&hw_config);
+}
+
+static void
+unload_mpu (fm801_devc * devc)
+{
+ struct address_info hw_config;
+ hw_config.io_base = -devc->mpu_base;
+ hw_config.irq = devc->mpu_irq;
+ hw_config.dma = -1;
+ hw_config.dma2 = -1;
+ hw_config.always_detect = 0;
+ hw_config.name = "FM801 MPU-401";
+ hw_config.driver_use_1 = 0;
+ hw_config.driver_use_2 = 0;
+ hw_config.osdev = devc->osdev;
+#ifdef CREATE_OSP
+ CREATE_OSP (hw_config.osdev);
+#endif
+ hw_config.card_subtype = 0;
+ devc->mpu_attached = 0;
+ unload_uart401 (&hw_config);
+}
+#endif
+
+static int
+init_fm801 (fm801_devc * devc)
+{
+ int my_mixer, my_mixer2;
+ int legacy;
+ int irqmask;
+ int adev;
+ int first_dev = 0;
+ int i;
+
+ devc->mpu_attached = devc->fm_attached = 0;
+
+ legacy = 0;
+
+#if !defined(__hpux) && !defined(sparc) && !defined(_TRU64)
+ /* Enable Legacy FM, MPU and Joystick ports */
+ legacy = 0x001E;
+ switch (fmedia_mpu_irq)
+ {
+ case 5:
+ legacy |= 0x0000;
+ break;
+ case 7:
+ legacy |= 0x0800;
+ break;
+ case 9:
+ legacy |= 0x1000;
+ break;
+ case 10:
+ legacy |= 0x1800;
+ break;
+ case 11:
+ legacy |= 0x2000;
+ break;
+ }
+#endif
+
+ pci_write_config_word (devc->osdev, 0x40, legacy);
+
+ /* codec cold reset + AC'97 warm reset */
+ OUTW (devc->osdev, (1 << 5) | (1 << 6), devc->base + CODEC_CONTROL);
+ oss_udelay (10);
+ OUTW (devc->osdev, 0, devc->base + CODEC_CONTROL);
+
+ if (devc->model == MDL_FM801AU)
+ {
+ OUTW (devc->osdev, (1 << 7), devc->base + CODEC_CONTROL);
+ oss_udelay (10);
+ }
+
+ /* init volume */
+ OUTW (devc->osdev, 0x0808, devc->base + PCM_VOL);
+ OUTW (devc->osdev, 0x0808, devc->base + FM_VOL);
+ OUTW (devc->osdev, 0x0808, devc->base + I2S_VOL);
+ /* interrupt setup - unmask MPU, PLAYBACK & CAPTURE */
+ irqmask = INW (devc->osdev, devc->base + IRQ_MASK);
+ irqmask &= ~0x0083;
+ OUTW (devc->osdev, irqmask, devc->base + IRQ_MASK);
+ OUTW (devc->osdev, 0x280C, devc->base + GENERAL_CONTROL);
+ OUTW (devc->osdev, 0x0, devc->base + I2S_MODE);
+#if !defined(__hpux) && !defined(sparc) && !defined(_TRU64_UNIX)
+ /* interrupt clear */
+ /*
+ * TODO: Check this. Unaligned I/O access causes a crash onder non-x86
+ */
+ OUTW (devc->osdev, IRQ_PLAY | IRQ_REC | IRQ_MPU, devc->base + IRQ_STATUS);
+#endif
+ /*
+ * Enable BusMasterMode and IOSpace Access
+ */
+#ifdef OBSOLETED_STUFF
+ attach_fm (devc);
+ attach_mpu (devc);
+#endif
+ my_mixer = ac97_install (&devc->ac97devc, "FM801 AC97 Mixer",
+ ac97_read, ac97_write, devc, devc->osdev);
+
+ if (my_mixer >= 0)
+ {
+ devc->mixer_dev = my_mixer;
+ if (devc->model == MDL_FM801AU)
+ {
+ my_mixer2 = ac97_install (&devc->ac97devc2, "FM801 AC97 Secondary",
+ ac97_read2, ac97_write2, devc,
+ devc->osdev);
+ if (my_mixer2 >= 0)
+ devc->mixer2_dev = my_mixer2;
+ }
+ }
+ else
+ return 0;
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ char tmp_name[100];
+ fm801_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE;
+ if (i == 0)
+ {
+ strcpy (tmp_name, devc->chip_name);
+ caps |= ADEV_DUPLEX;
+ }
+ else
+ {
+ strcpy (tmp_name, devc->chip_name);
+ caps |= ADEV_DUPLEX | ADEV_SHADOW;
+ }
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &fm801_audio_driver,
+ sizeof (audiodrv_t),
+ caps,
+ AFMT_U8 | AFMT_S16_LE, devc, -1)) < 0)
+ {
+ adev = -1;
+ return 1;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ audio_engines[adev]->min_channels = 2;
+ audio_engines[adev]->max_channels = 6;
+ portc->open_mode = 0;
+ portc->audiodev = adev;
+ portc->audio_enabled = 0;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+ init_audio (devc);
+ }
+ return 1;
+}
+
+int
+oss_fmedia_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ int err;
+ fm801_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered FM801 FM801 probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != FORTEMEDIA_VENDOR_ID || device != FORTEMEDIA_FM801)
+ return 0;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+ DDB (cmn_err (CE_WARN, "FM801 I/O base %04x\n", pci_ioaddr));
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d). Can't continue\n",
+ pci_irq_line);
+ return 0;
+ }
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+
+ /* Remove I/O space marker in bit 0. */
+ devc->base &= ~3;
+ devc->mpu_irq = fmedia_mpu_irq;
+ devc->mpu_base = devc->base + 0x30;
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ switch (pci_revision)
+ {
+ case 0xb1:
+ devc->model = MDL_FM801AS;
+ devc->chip_name = "ForteMedia FM801-AS";
+ break;
+ case 0xb2:
+ devc->model = MDL_FM801AU;
+ devc->chip_name = "ForteMedia FM801-AU";
+ break;
+ }
+
+ oss_register_device (osdev, devc->chip_name);
+ if ((err = oss_register_interrupts (osdev, 0, fm801intr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Error installing interrupt handler: %x\n", err);
+ return 0;
+ }
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ return init_fm801 (devc); /* Detected */
+}
+
+int
+oss_fmedia_detach (oss_device_t * osdev)
+{
+ fm801_devc *devc = (fm801_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ if (devc->audio_initialized)
+ {
+ uninit_audio (devc);
+ }
+
+ devc->audio_initialized = 0;
+
+#ifdef OBSOLETED_STUFF
+ if (devc->mpu_attached)
+ {
+ unload_mpu (devc);
+ devc->mpu_attached = 0;
+ }
+#endif
+
+ oss_unregister_interrupts (devc->osdev);
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_fmedia/oss_fmedia.man b/kernel/drv/oss_fmedia/oss_fmedia.man
new file mode 100644
index 0000000..58ed235
--- /dev/null
+++ b/kernel/drv/oss_fmedia/oss_fmedia.man
@@ -0,0 +1,23 @@
+NAME
+oss_fmedia - Forte Media FM801 driver.
+
+DESCRIPTION
+Open Sound System driver for Forte Media FM801/FM801-AU audio controllers.
+
+FM801 device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo/4ch/5.1ch playback
+ o mono/sterero recording
+ o 8KHz to 48Khz sample rate.
+
+OPTIONS
+o fmedia_mpu_irq=<xx>
+Set the IRQ for the UART401 MPU. Refer to device conf file (see below) for
+valid IRQs.
+
+FILES
+CONFIGFILEPATH/oss_fmedia.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_geode/.config b/kernel/drv/oss_geode/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_geode/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_geode/.devices b/kernel/drv/oss_geode/.devices
new file mode 100644
index 0000000..fce8dd2
--- /dev/null
+++ b/kernel/drv/oss_geode/.devices
@@ -0,0 +1,3 @@
+oss_geode pci100b,503 National Semiconductor Geode SC1200
+oss_geode pci1078,103 National Semiconductor Geode CS5530
+oss_geode pci1022,2093 AMD Geode CS5536
diff --git a/kernel/drv/oss_geode/.name b/kernel/drv/oss_geode/.name
new file mode 100644
index 0000000..02c7b76
--- /dev/null
+++ b/kernel/drv/oss_geode/.name
@@ -0,0 +1 @@
+National Semiconductor Geode SC1200/CS5530/CS5536
diff --git a/kernel/drv/oss_geode/oss_geode.c b/kernel/drv/oss_geode/oss_geode.c
new file mode 100644
index 0000000..284aba3
--- /dev/null
+++ b/kernel/drv/oss_geode/oss_geode.c
@@ -0,0 +1,852 @@
+/*
+ * Purpose: Driver for the NS/Cyrix/AMD Geode AC97 audio controller
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_geode_cfg.h"
+#include "oss_pci.h"
+#include "ac97.h"
+
+#define CYRIX_VENDOR_ID 0x1078
+#define CYRIX_GEODE 0x0103
+#define AMD_VENDOR_ID 0x1022
+#define AMD_CS5536_ID 0x2093
+#define NATIONAL_VENDOR_ID 0x100b
+#define NATIONAL_SC1200 0x0503
+
+#define CS_READL(devc,addr) INL((devc)->osdev, (unsigned int)((devc)->physaddr) + (addr))
+#define CS_READW(devc,addr) INW((devc)->osdev, (unsigned int)((devc)->physaddr) + (addr))
+#define CS_READB(devc,addr) INB((devc)->osdev, (unsigned int)((devc)->physaddr) + (addr))
+#define CS_WRITEL(devc,addr,val) OUTL((devc)->osdev, (val), (unsigned int)((devc)->physaddr) + (addr))
+#define CS_WRITEB(devc,addr,val) OUTB((devc)->osdev, (val), (unsigned int)((devc)->physaddr) + (addr))
+
+#define MAX_PORTC 2
+
+typedef struct
+{
+ unsigned int ptr;
+ unsigned int size;
+#define PRD_EOT 0x80000000
+#define PRD_EOP 0x40000000
+#define PRD_JMP 0x20000000
+}
+PRD_rec;
+
+typedef struct
+{
+ int open_mode;
+ int speed;
+ int bits;
+ int channels;
+ int trigger_bits;
+ int audio_enabled;
+ int audiodev;
+}
+geode_portc;
+
+typedef struct
+{
+ oss_device_t *osdev;
+ int physaddr;
+ void *linaddr;
+ int irq;
+ char *chip_name;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ int mixer_dev;
+ ac97_devc ac97devc;
+
+ geode_portc portc[MAX_PORTC];
+ int open_mode;
+
+ PRD_rec *prdin, *prdout;
+ unsigned long prdin_phys, prdout_phys;
+ oss_dma_handle_t prdin_dma_handle, prdout_dma_handle;
+
+ unsigned int chip;
+}
+geode_devc;
+
+static int
+geodeintr_5530 (oss_device_t * osdev)
+{
+
+ geode_devc *devc = osdev->devc;
+ geode_portc *portc;
+ int i, n, irqstat;
+ int serviced = 0;
+ unsigned int pos;
+ int ptr;
+
+ irqstat = CS_READW (devc, 0x12);
+ if (irqstat & 3) /* either gpio or gpio wakeup */
+ {
+ CS_READL (devc, 0x00);
+ serviced = 1;
+ }
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT) && (irqstat & 4))
+ {
+ dmap_t *dmap;
+ dmap = audio_engines[portc->audiodev]->dmap_out;
+ CS_READB (devc, 0x21); /* ack interrupt */
+ pos = CS_READL (devc, 0x24);
+ pos = (pos - devc->prdout_phys) / 8;
+ ptr = pos;
+ ptr--;
+
+ if (ptr < 0)
+ ptr = 0;
+ ptr %= dmap->nfrags;
+
+ n = 0;
+ while (ptr != dmap_get_qhead (dmap) && n++ < dmap->nfrags)
+ oss_audio_outputintr (portc->audiodev, 0);
+ serviced = 1;
+ }
+
+
+ if ((portc->trigger_bits & PCM_ENABLE_INPUT) && (irqstat & 8))
+ {
+ dmap_t *dmap;
+
+ dmap = audio_engines[portc->audiodev]->dmap_in;
+
+ pos = CS_READL (devc, 0x2c);
+ pos = (pos - devc->prdin_phys) / 8;
+ ptr = pos;
+ ptr--;
+
+ if (ptr < 0)
+ ptr = 0;
+ ptr %= dmap->nfrags;
+
+ n = 0;
+ while (ptr != dmap_get_qtail (dmap) && n++ < dmap->nfrags)
+ oss_audio_inputintr (portc->audiodev, 0);
+
+ serviced = 1;
+ }
+ }
+ return serviced;
+}
+
+static int
+geodeintr_5536 (oss_device_t * osdev)
+{
+
+ geode_devc *devc = osdev->devc;
+ geode_portc *portc;
+ int i;
+ int serviced = 0;
+ int irqstat;
+
+ irqstat = CS_READW (devc, 0x12);
+
+ if (irqstat & 3) /* either gpio or gpio wakeup */
+ {
+ CS_READL (devc, 0x00);
+ serviced = 1;
+ }
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT) && (irqstat & 4))
+ if (CS_READB (devc, 0x21) & 1)
+ {
+ oss_audio_outputintr (portc->audiodev, 0);
+ serviced = 1;
+
+ }
+
+
+ if ((portc->trigger_bits & PCM_ENABLE_INPUT) && (irqstat & 8))
+ if (CS_READB (devc, 0x29) & 1)
+ {
+ oss_audio_inputintr (portc->audiodev, 0);
+ serviced = 1;
+ }
+ }
+ return serviced;
+}
+
+static int
+codec_valid_data (geode_devc * devc, int command, unsigned int *data)
+{
+ int y;
+ for (y = 0; y < 1000; y++)
+ {
+ *data = CS_READL (devc, 0x08);
+
+ if ((*data & 0x7F000000) != (command & 0x7F000000))
+ continue;
+ if (devc->chip == AMD_CS5536_ID)
+ {
+ if ((*data & 0x00020000) == 0x00020000)
+ return 1;
+ }
+ else
+ {
+ if ((*data & 0x00030000) == 0x00030000)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
+ac97_read (void *devc_, int wAddr)
+{
+ geode_devc *devc = devc_;
+ int i;
+ unsigned int x, y;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ for (i = 0; i < 10000; i++)
+ if (!(CS_READL (devc, 0x0c) & 0x10000))
+ break;
+
+ for (i = 0; i < 10000; i++)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ x = (wAddr << 24) | 0x80000000;
+ if (devc->chip == AMD_CS5536_ID)
+ x = x | 0x10000; /* this chip also need the NEW flag set */
+ CS_WRITEL (devc, 0x0c, x);
+
+ if (codec_valid_data (devc, x, &y))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return y & 0xffff;
+ }
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+}
+
+static int
+ac97_write (void *devc_, int wAddr, int wData)
+{
+ geode_devc *devc = devc_;
+ unsigned int tmp, i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ tmp = (wAddr << 24) | wData;
+ if (devc->chip == AMD_CS5536_ID)
+ tmp = (tmp | 0x10000) & ~0x80000000;
+ CS_WRITEL (devc, 0x0c, tmp);
+
+ /* wait for codec to be ready */
+ for (i = 0; i <= 10000; i++)
+ if (!(CS_READL (devc, 0x0c) & 0x10000))
+ break;
+
+ if (i >= 10000)
+ {
+ cmn_err (CE_WARN, "AC97 write timeout\n");
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return 0;
+}
+
+static int
+geode_audio_set_rate (int dev, int arg)
+{
+ geode_portc *portc = audio_engines[dev]->portc;
+ if (arg == 0)
+ return portc->speed;
+
+ if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
+ arg = 48000;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 8000)
+ arg = 8000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+geode_audio_set_channels (int dev, short arg)
+{
+ geode_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->channels;
+
+ if (audio_engines[dev]->flags & ADEV_STEREOONLY)
+ arg = 2;
+
+ if ((arg != 1) && (arg != 2))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+geode_audio_set_format (int dev, unsigned int arg)
+{
+ geode_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (audio_engines[dev]->flags & ADEV_16BITONLY)
+ arg = 16;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE)))
+ return portc->bits;
+ portc->bits = arg;
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+geode_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void geode_audio_trigger (int dev, int state);
+
+static void
+geode_audio_reset (int dev)
+{
+ geode_audio_trigger (dev, 0);
+}
+
+static void
+geode_audio_reset_input (int dev)
+{
+ geode_portc *portc = audio_engines[dev]->portc;
+ geode_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+geode_audio_reset_output (int dev)
+{
+ geode_portc *portc = audio_engines[dev]->portc;
+ geode_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+geode_audio_open (int dev, int mode, int open_flags)
+{
+ geode_portc *portc = audio_engines[dev]->portc;
+ geode_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode |= mode;
+
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+geode_audio_close (int dev, int mode)
+{
+ geode_portc *portc = audio_engines[dev]->portc;
+ geode_devc *devc = audio_engines[dev]->devc;
+
+ geode_audio_reset (dev);
+ portc->open_mode = 0;
+ devc->open_mode &= ~mode;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+geode_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ geode_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+geode_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ geode_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+geode_audio_trigger (int dev, int state)
+{
+ geode_devc *devc = audio_engines[dev]->devc;
+ geode_portc *portc = audio_engines[dev]->portc;
+ int i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ CS_WRITEB (devc, 0x20, 0x01);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ CS_WRITEB (devc, 0x20, 0x00);
+ for (i = 0; i < 512; i++)
+ {
+ devc->prdout[i].size = PRD_EOT; /* Stop */
+ }
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ CS_WRITEB (devc, 0x28, 0x09);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+ CS_WRITEB (devc, 0x28, 0x00);
+ for (i = 0; i < 512; i++)
+ {
+ devc->prdin[i].size = PRD_EOT; /* Stop */
+ }
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+geode_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ geode_devc *devc = audio_engines[dev]->devc;
+ geode_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ int i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ ac97_recrate (&devc->ac97devc, portc->speed);
+
+
+ /* clear out the prd table */
+ memset (devc->prdin, 0, 512 * sizeof (PRD_rec));
+
+ /* Initialize PRD entries */
+ for (i = 0; i < dmap->nfrags; i++)
+ {
+ devc->prdin[i].ptr = dmap->dmabuf_phys + (i * dmap->fragment_size);
+ devc->prdin[i].size = dmap->fragment_size | PRD_EOP;
+ }
+
+ /* Initialize the JMP entry back to the beginning */
+ devc->prdin[dmap->nfrags].ptr = devc->prdin_phys;
+ devc->prdin[dmap->nfrags].size = PRD_JMP | PRD_EOP;
+
+ CS_WRITEL (devc, 0x2c, devc->prdin_phys);
+
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+geode_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ geode_devc *devc = audio_engines[dev]->devc;
+ geode_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ int i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ ac97_playrate (&devc->ac97devc, portc->speed);
+
+ /* clear out the PRD table */
+ memset (devc->prdout, 0, 512 * sizeof (PRD_rec));
+
+
+ /* Initialize PRD entries */
+ for (i = 0; i < dmap->nfrags; i++)
+ {
+ devc->prdout[i].ptr = dmap->dmabuf_phys + (i * dmap->fragment_size);
+ devc->prdout[i].size = dmap->fragment_size | PRD_EOP;
+ }
+
+ /* Initialize the JMP entry back to the beginning */
+ devc->prdout[dmap->nfrags].ptr = devc->prdout_phys;
+ devc->prdout[dmap->nfrags].size = PRD_JMP | PRD_EOP;
+
+ CS_WRITEL (devc, 0x24, devc->prdout_phys);
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static int
+geode_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ geode_devc *devc = audio_engines[dev]->devc;
+ int ptr = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ if (devc->chip == AMD_CS5536_ID)
+ ptr = CS_READL (devc, 0x60);
+ else
+ ptr = CS_READL (devc, 0x24);
+ }
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ if (devc->chip == AMD_CS5536_ID)
+ ptr = CS_READL (devc, 0x64);
+ else
+ ptr = CS_READL (devc, 0x2c);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ptr - dmap->dmabuf_phys;
+}
+
+static const audiodrv_t geode_audio_driver = {
+ geode_audio_open,
+ geode_audio_close,
+ geode_audio_output_block,
+ geode_audio_start_input,
+ geode_audio_ioctl,
+ geode_audio_prepare_for_input,
+ geode_audio_prepare_for_output,
+ geode_audio_reset,
+ NULL,
+ NULL,
+ geode_audio_reset_input,
+ geode_audio_reset_output,
+ geode_audio_trigger,
+ geode_audio_set_rate,
+ geode_audio_set_format,
+ geode_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* geode_alloc_buffer */
+ NULL, /* geode_free_buffer */
+ NULL,
+ NULL,
+ geode_get_buffer_pointer
+};
+
+static int
+init_geode (geode_devc * devc)
+{
+ int i, caps, opts;
+ int first_dev = 0;
+ oss_native_word phaddr;
+
+ /* Allocate the buffers for the prdin/prdout tables */
+ devc->prdin =
+ (PRD_rec *) CONTIG_MALLOC (devc->osdev, 512 * sizeof (PRD_rec),
+ MEMLIMIT_32BITS, &phaddr, devc->prdin_dma_handle);
+ if (devc->prdin == NULL)
+ {
+ cmn_err (CE_WARN, "Can't allocate memory for PRD input tables\n");
+ return 0;
+ }
+
+ devc->prdin_phys = phaddr;
+
+ devc->prdout =
+ (PRD_rec *) CONTIG_MALLOC (devc->osdev, 512 * sizeof (PRD_rec),
+ MEMLIMIT_32BITS, &phaddr, devc->prdout_dma_handle);
+ if (devc->prdout == NULL)
+ {
+ cmn_err (CE_WARN, "Can't allocate memory for PRD output tables\n");
+ return 0;
+ }
+
+ devc->prdout_phys = phaddr;
+
+ if (devc->chip != AMD_CS5536_ID)
+ {
+ /* VSA2 IRQ config method */
+ OUTW (devc->osdev, 0xFC53, 0xAC1C);
+ OUTW (devc->osdev, 0x108, 0xAC1C);
+ OUTW (devc->osdev, devc->irq, 0xAC1E);
+
+ /* VSA1 IRQ config method */
+ OUTL (devc->osdev, 0x800090D0, 0x0CF8);
+ OUTL (devc->osdev, (devc->irq << 16) | 0xA00A, 0x0CFC);
+ oss_udelay (10000);
+ }
+ /* Now configure the OSS devices */
+
+ devc->mixer_dev =
+ ac97_install (&devc->ac97devc, "AC97 Mixer", ac97_read, ac97_write, devc,
+ devc->osdev);
+
+ if (devc->mixer_dev < 0)
+ return 0;
+
+ if (devc->chip == AMD_CS5536_ID)
+ {
+ /* remove controls that are backed by devices unsupported by the
+ chip, like s/pdif (cs5536 databook, page 89) */
+ ac97_remove_control (&devc->ac97devc,
+ SOUND_MASK_VIDEO | SOUND_MASK_MONO | SOUND_MASK_CD | SOUND_MASK_PHONE,
+ 0);
+ }
+
+ opts = ADEV_AUTOMODE | ADEV_STEREOONLY | ADEV_16BITONLY;
+
+ if (!ac97_varrate (&devc->ac97devc))
+ {
+ opts |= ADEV_FIXEDRATE;
+ }
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ int adev;
+ geode_portc *portc = &devc->portc[i];
+ char tmp_name[100];
+
+ if (i == 0)
+ {
+ if (devc->chip == AMD_CS5536_ID)
+ sprintf (tmp_name, "%s", "Geode CS5536");
+ else
+ sprintf (tmp_name, "%s", "Geode CS5530");
+
+ caps = opts | ADEV_DUPLEX;
+ }
+ else
+ {
+ if (devc->chip == AMD_CS5536_ID)
+ sprintf (tmp_name, "%s", "Geode CS5536 (playback)");
+ else
+ sprintf (tmp_name, "%s", "Geode CS5530 (playback");
+
+ caps = opts | ADEV_DUPLEX | ADEV_SHADOW;
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &geode_audio_driver,
+ sizeof (audiodrv_t),
+ caps, AFMT_S16_LE, devc, -1)) < 0)
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->mixer_dev = devc->mixer_dev;
+ audio_engines[adev]->min_rate = 8000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ portc->open_mode = 0;
+ portc->audiodev = adev;
+ portc->audio_enabled = 0;
+ if (caps & ADEV_FIXEDRATE)
+ {
+ audio_engines[adev]->fixed_rate = 48000;
+ audio_engines[adev]->min_rate = 48000;
+ }
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+
+ }
+ return 1;
+}
+
+int
+oss_geode_attach (oss_device_t * osdev)
+{
+ unsigned char pci_revision, pci_irq_line /*, pci_latency */ ;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ int err;
+ geode_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered Geode probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+ if (vendor != CYRIX_VENDOR_ID || device != CYRIX_GEODE)
+ if (vendor != NATIONAL_VENDOR_ID || device != NATIONAL_SC1200)
+ if (vendor != AMD_VENDOR_ID || device != AMD_CS5536_ID)
+ return 0;
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &pci_ioaddr);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "BAR0 not initialized by BIOS\n");
+ return 0;
+ }
+
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->physaddr = pci_ioaddr & ~1UL;
+ devc->irq = pci_irq_line;
+ devc->chip = device;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+ if (devc->chip == AMD_CS5536_ID)
+ {
+ devc->chip_name = "AMD CS5536 AC97 Controller";
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, geodeintr_5536, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+ }
+ else
+ {
+ devc->chip_name = "Geode/NS5530 AC97 Controller";
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, geodeintr_5530, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+ }
+
+ return init_geode (devc); /* Detected */
+}
+
+
+int
+oss_geode_detach (oss_device_t * osdev)
+{
+ geode_devc *devc = (geode_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ CS_WRITEB (devc, 0x20, 0); /* Disable output */
+ CS_WRITEB (devc, 0x28, 0); /* Disable input */
+ CS_WRITEL (devc, 0x24, 0);
+ CS_WRITEL (devc, 0x2c, 0);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+
+ if (devc->prdin != NULL)
+ CONTIG_FREE (devc->osdev, devc->prdin, 512 * sizeof (PRD_rec), devc->prdin_dma_handle);
+ if (devc->prdout != NULL)
+ CONTIG_FREE (devc->osdev, devc->prdout, 512 * sizeof (PRD_rec), devc->prdout_dma_handle);
+
+ devc->prdin = devc->prdout = NULL;
+ oss_unregister_device (devc->osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_geode/oss_geode.man b/kernel/drv/oss_geode/oss_geode.man
new file mode 100644
index 0000000..d833217
--- /dev/null
+++ b/kernel/drv/oss_geode/oss_geode.man
@@ -0,0 +1,25 @@
+NAME
+oss_geode - National Semiconductor Geode audio driver.
+
+DESCRIPTION
+Open Sound System driver for National Semiconductor Geode/CS5530/CS5536 audio
+controllers.
+
+Geode device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo playback/recording
+ o 8KHz to 48Khz sample rate.
+
+NOTES
+Some old Geode CPUs are not able to handle heavy computational loads.
+If your audio streams are use a lot of CPU, you can start getting garbled audio
+since the OSS Sample Rate Convertor is CPU intensive. Setting vmix0-src to
+OFF will allow you to play audio but only at a fixed rate set via vmixctl
+(Default: 48Khz).
+
+FILES
+CONFIGFILEPATH/oss_geode.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_hdaudio/.changelog b/kernel/drv/oss_hdaudio/.changelog
new file mode 100644
index 0000000..d26ec7a
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/.changelog
@@ -0,0 +1,7 @@
+20080111 by Hannu: Fixed problem of several jack widgets getting named as "lineout"
+
+20080205 by Hannu: Improved support for systems with multiple codecs.
+
+20080221 by Hannu: Changed default volumes in hdaudio_generic.c to be louder. Earlier the volumes were 80% now 90%.
+
+
diff --git a/kernel/drv/oss_hdaudio/.config b/kernel/drv/oss_hdaudio/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_hdaudio/.devices b/kernel/drv/oss_hdaudio/.devices
new file mode 100644
index 0000000..7ee6bb3
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/.devices
@@ -0,0 +1,27 @@
+oss_hdaudio pci8086,2668 Intel High Definition Audio (ICH6)
+oss_hdaudio pci8086,27d8 Intel High Definition Audio (ICH7)
+oss_hdaudio pci8086,269a Intel High Definition Audio (ESB2)
+oss_hdaudio pci8086,284b Intel High Definition Audio (ICH8)
+oss_hdaudio pci8086,293e Intel High Definition Audio (P35)
+oss_hdaudio pci8086,293f Intel High Definition Audio (ICH9)
+oss_hdaudio pci8086,3a3e Intel High Definition Audio (ICH10)
+oss_hdaudio pci8086,3a6e Intel High Definition Audio (ICH10)
+oss_hdaudio pci8086,3b56 Intel High Definition Audio (PCH)
+oss_hdaudio pci8086,3b57 Intel High Definition Audio (PCH)
+oss_hdaudio pci8086,1c20 Intel High Definition Audio (CPT)
+oss_hdaudio pci8086,811b Intel High Definition Audio (SCH)
+oss_hdaudio pci10de,26c Nvidia High Definition Audio (MCP51)
+oss_hdaudio pci10de,371 Nvidia High Definition Audio (MCP55)
+oss_hdaudio pci10de,3e4 Nvidia High Definition Audio (MCP61)
+oss_hdaudio pci10de,3f0 Nvidia High Definition Audio (MCP61)
+oss_hdaudio pci10de,44a Nvidia High Definition Audio (MCP65)
+oss_hdaudio pci10de,55c Nvidia High Definition Audio (MCP67)
+oss_hdaudio pci10de,7fc Nvidia High Definition Audio (MCP73)
+oss_hdaudio pci10de,774 Nvidia High Definition Audio (MCP78S)
+oss_hdaudio pci10de,ac0 Nvidia High Definition Audio (MCP79)
+oss_hdaudio pci1002,437b ATI High Definition Audio (SB450)
+oss_hdaudio pci1002,4383 ATI High Definition Audio (SB600)
+oss_hdaudio pci1106,3288 VIA High Definition Audio
+oss_hdaudio pci1039,7502 SiS High Definition Audio
+oss_hdaudio pci10b9,5461 ULI High Definition Audio
+oss_hdaudio pci1102,9 Creative Labs SB XFi Xtreme
diff --git a/kernel/drv/oss_hdaudio/.name b/kernel/drv/oss_hdaudio/.name
new file mode 100644
index 0000000..21af427
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/.name
@@ -0,0 +1 @@
+High Definition Audio (Azalia)
diff --git a/kernel/drv/oss_hdaudio/.params b/kernel/drv/oss_hdaudio/.params
new file mode 100644
index 0000000..916648f
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/.params
@@ -0,0 +1,24 @@
+int hdaudio_snoopy=0;
+/*
+ * hdaudio_snopy is reserved for diagnostic purposes and it must be 0
+ * in all situations. Other values may make the driver vulnerable to
+ * DoS attacks. For security reasons only root can use this diagnostic
+ * interface.
+ */
+int hdaudio_jacksense=0;
+/*
+ * Setting hdaudio_jacksense=1 enables jack sensing mode when the
+ * hdaudio driver is loaded. In this mode all I/O pin's that are not
+ * in use will be disabled as well as the mixer controls that are related
+ * with them. In this way the mixer/control panel will become more intuitive.
+ * However OSS will need to be restarted with soundoff;soundon every time
+ * new inputs or outputs are attached to the audio jacks.
+ *
+ * NOTE! hdaudio_jacksense=1 works only in some systems. Many laptops and
+ * motherboards don't support jack sensing.
+ */
+int hdaudio_noskip=0;
+/*
+ * Disable checks to skip unconnected jack. Values: 0-7, where value is a
+ * bitmask - every bit disables another check. Can override hdaudio_jacksense.
+ */
diff --git a/kernel/drv/oss_hdaudio/hdaudio.h b/kernel/drv/oss_hdaudio/hdaudio.h
new file mode 100644
index 0000000..964fd7f
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio.h
@@ -0,0 +1,168 @@
+/*
+ * Purpose: Common definitions for the hdaudio driver files
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+#define HDA_GCAP 0x00 /* Global Capabilities */
+#define HDA_VMIN 0x02 /* Minor Version */
+#define HDA_VMAJ 0x03 /* Major Version */
+#define HDA_OUTPAY 0x04 /* Output Payload Capability */
+#define HDA_INPAY 0x06 /* Input Payload Capability */
+#define HDA_GCTL 0x08 /* Global Control */
+# define CRST 0x00000001 /* Controller reset */
+#define HDA_WAKEEN 0x0C /* Wake Enable */
+#define HDA_STATESTS 0x0E /* Wake Status */
+#define HDA_GSTST 0x10 /* Global Status */
+#define HDA_INTCTL 0x20 /* Interrupt Control */
+#define HDA_INTSTS 0x24 /* Interrupt Status */
+#define HDA_WCCNT 0x30 /* Wall Clock Counter */
+#define HDA_SSYNC 0x38 /* Stream Synchronization */
+#define HDA_CORBLBASE 0x40 /* CORB Lower Base Address */
+#define HDA_CORBUBASE 0x44 /* CORB Upper Base Address */
+#define HDA_CORBWP 0x48 /* CORB Write Pointer */
+#define HDA_CORBRP 0x4A /* CORB Read Pointer */
+#define HDA_CORBCTL 0x4C /* CORB Control */
+#define HDA_CORBSTS 0x4D /* CORB Status */
+#define HDA_CORBSIZE 0x4E /* CORB Size */
+#define HDA_RIRBLBASE 0x50 /* RIRB Lower Base Address */
+#define HDA_RIRBUBASE 0x54 /* RIRB Upper Base Address */
+#define HDA_RIRBWP 0x58 /* RIRB Write Pointer */
+#define HDA_RINTCNT 0x5A /* Response Interrupt Count */
+#define HDA_RIRBCTL 0x5C /* RIRB Control */
+#define HDA_RIRBSTS 0x5D /* RIRB Status */
+#define HDA_RIRBSIZE 0x5E /* RIRB Size */
+#define HDA_IC 0x60 /* Immediate Command Output Interface */
+#define HDA_IR 0x64 /* Immediate Command Input Interface */
+#define HDA_IRS 0x68 /* Immediate Command Status */
+#define HDA_DPLBASE 0x70 /* DMA Position Lower Base Address */
+#define HDA_DPUBASE 0x74 /* DMA Position Upper Base Address */
+
+#define HDA_SD_CTL 0x0
+#define HDA_SD_STS 0x3
+#define HDA_SD_LPIB 0x4
+#define HDA_SD_CBL 0x8
+#define HDA_SD_LVI 0xC
+#define HDA_SD_FIFOSIZE 0x10
+#define HDA_SD_FORMAT 0x12
+#define HDA_SD_BDLPL 0x18
+#define HDA_SD_BDLPU 0x1C
+#define HDA_SD_LPIBA 0x2004
+
+#define HDA_SDI0CTL 0x80 /* Stream Descriptor Control */
+#define HDA_SDI0STS 0x83 /* Stream Descriptor Status */
+#define HDA_SDI0LPIB 0x84 /* Link Position in Current Buffer */
+#define HDA_SDI0CBL 0x88 /* Cyclic Buffer Length */
+#define HDA_SDI0LVI 0x8C /* Last Valid Index */
+#define HDA_SDI0FIFOSIZE 0x90 /* FIFO Size */
+#define HDA_SDI0FORMAT 0x92 /* Format */
+#define HDA_SDI0BDLPL 0x98 /* List Pointer - Lower */
+#define HDA_SDI0BDLPU 0x9C /* List Pointer - Upper */
+#define HDA_SDI0LPIBA 0x2084 /* Link Position in Buffer n Alias */
+
+#define HDA_SDI1CTL 0xA0 /* Stream Descriptor Control */
+#define HDA_SDI1STS 0xA3 /* Stream Descriptor Status */
+#define HDA_SDI1LPIB 0xA4 /* Link Position in Current Buffer */
+#define HDA_SDI1CBL 0xA8 /* Cyclic Buffer Length */
+#define HDA_SDI1LVI 0xAC /* Last Valid Index */
+#define HDA_SDI1FIFOSIZE 0xB0 /* FIFO Size */
+#define HDA_SDI1FORMAT 0xB2 /* Format */
+#define HDA_SDI1BDLPL 0xB8 /* List Pointer - Lower */
+#define HDA_SDI1BDLPU 0xBC /* List Pointer - Upper */
+#define HDA_SDI1LPIBA 0x20A4 /* Link Position in Buffer n Alias */
+
+#define HDA_SDI2CTL 0xC0 /* Stream Descriptor Control */
+#define HDA_SDI2STS 0xC3 /* Stream Descriptor Status */
+#define HDA_SDI2LPIB 0xC4 /* Link Position in Current Buffer */
+#define HDA_SDI2CBL 0xC8 /* Cyclic Buffer Length */
+#define HDA_SDI2LVI 0xCC /* Last Valid Index */
+#define HDA_SDI2FIFOSIZ 0xD0 /* FIFO Size */
+#define HDA_SDI2FORMAT 0xD2 /* Format */
+#define HDA_SDI2BDLPL 0xD8 /* List Pointer - Lower */
+#define HDA_SDI2BDLPU 0xDC /* List Pointer - Upper */
+#define HDA_SDI2LPIBA 0x20D4 /* Link Position in Buffer n Alias */
+
+#define HDA_SDI3CTL 0xE0 /* Stream Descriptor Control */
+#define HDA_SDI3STS 0xE3 /* Stream Descriptor Status */
+#define HDA_SDI3LPIB 0xE4 /* Link Position in Current Buffer */
+#define HDA_SDI3CBL 0xE8 /* Cyclic Buffer Length */
+#define HDA_SDI3LVI 0xEC /* Last Valid Index */
+#define HDA_SDI3FIFOSIZE 0xF0 /* FIFO Size */
+#define HDA_SDI3FORMAT 0xF2 /* Format */
+#define HDA_SDI3BDLPL 0xF8 /* List Pointer - Lower */
+#define HDA_SDI3BDLPU 0xFC /* List Pointer - Upper */
+#define HDA_SDI3LPIBA 0x20E4 /* Link Position in Buffer n Alias */
+
+#define HDA_SDO0CTL 0x100 /* Stream Descriptor Control */
+#define HDA_SDO0STS 0x103 /* Stream Descriptor Status */
+#define HDA_SDO0LPIB 0x104 /* Link Position in Current Buffer */
+#define HDA_SDO0CBL 0x108 /* Cyclic Buffer Length */
+#define HDA_SDO0LVI 0x10C /* Last Valid Index */
+#define HDA_SDO0FIFOSIZE 0x110 /* FIFO Size */
+#define HDA_SDO0FORMAT 0x112 /* Format */
+#define HDA_SDO0BDLPL 0x118 /* List Pointer - Lower */
+#define HDA_SDO0BDLPU 0x11C /* List Pointer - Upper */
+#define HDA_SDO0LPIBA 0x2104 /* Link Position in Buffer n Alias */
+
+#define HDA_SDO1CTL 0x120 /* Stream Descriptor Control */
+#define HDA_SDO1STS 0x123 /* Stream Descriptor Status */
+#define HDA_SDO1LPIB 0x124 /* Link Position in Current Buffer */
+#define HDA_SDO1CBL 0x128 /* Cyclic Buffer Length */
+#define HDA_SDO1LVI 0x12C /* Last Valid Index */
+#define HDA_SDO1FIFOSIZE 0x130 /* FIFO Size */
+#define HDA_SDO1FORMAT 0x132 /* Format */
+#define HDA_SDO1BDLPL 0x138 /* List Pointer - Lower */
+#define HDA_SDO1BDLPU 0x13C /* List Pointer - Upper */
+#define HDA_SDO1LPIBA 0x2124 /* Link Position in Buffer n Alias */
+
+#define HDA_SDO2CTL 0x140 /* Stream Descriptor Control */
+#define HDA_SDO2STS 0x143 /* Stream Descriptor Status */
+#define HDA_SDO2LPIB 0x144 /* Link Position in Current Buffer */
+#define HDA_SDO2CBL 0x148 /* Cyclic Buffer Length */
+#define HDA_SDO2LVI 0x14C /* Last Valid Index */
+#define HDA_SDO2FIFOSIZE 0x150 /* FIFO Size */
+#define HDA_SDO2FORMAT 0x152 /* Format */
+#define HDA_SDO2BDLPL 0x158 /* List Pointer - Lower */
+#define HDA_SDO2BDLPU 0x15C /* List Pointer - Upper */
+#define HDA_SDO2LPIBA 0x2144 /* Link Position in Buffer n Alias */
+
+#define HDA_SDO3CTL 0x160 /* Stream Descriptor Control */
+#define HDA_SDO3STS 0x163 /* Stream Descriptor Status */
+#define HDA_SDO3LPIB 0x164 /* Link Position in Current Buffer */
+#define HDA_SDO3CBL 0x168 /* Cyclic Buffer Length */
+#define HDA_SDO3LVI 0x16C /* Last Valid Index */
+#define HDA_SDO3FIFOSIZE 0x170 /* FIFO Size */
+#define HDA_SDO3FORMAT 0x172 /* Format */
+#define HDA_SDO3BDLPL 0x178 /* List Pointer - Lower */
+#define HDA_SDO3BDLPU 0x17C /* List Pointer - Upper */
+
+#define HWINFO_SIZE 256
+
+/*
+ * Debugging ioctl calls
+ */
+
+typedef struct
+{
+ int cad, wid;
+ char name[32];
+} hda_name_t;
+
+typedef struct
+{
+ int cad, wid;
+ char info[4000];
+} hda_widget_info_t;
+
+#define HDA_IOCTL_WRITE __SIOWR('H', 0, int)
+#define HDA_IOCTL_READ __SIOWR('H', 1, int)
+#define HDA_IOCTL_NAME __SIOWR('H', 2, hda_name_t)
+#define HDA_IOCTL_WIDGET __SIOWR('H', 3, hda_widget_info_t)
diff --git a/kernel/drv/oss_hdaudio/hdaudio_abit_AA8.c b/kernel/drv/oss_hdaudio/hdaudio_abit_AA8.c
new file mode 100644
index 0000000..6d7366d
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_abit_AA8.c
@@ -0,0 +1,347 @@
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+/* Codec index is 0 */
+/* Codec vendor 10ec:0880 */
+/* HD codec revision 0.9 (5.0) (0x00090500) */
+/* Subsystem ID 08800000 */
+/* Default amplifier caps: in=00000000, out=00000000 */
+#include "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_dedicated.h"
+
+int
+hdaudio_abit_AA8_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad,
+ int top_group)
+{
+ int ctl = 0;
+
+ DDB (cmn_err (CE_CONT, "hdaudio_abit_AA8_mixer_init got called.\n"));
+
+ /* Handle PIN widgets */
+ {
+ int n, group, pin_group;
+
+ n = 0;
+
+ HDA_GROUP (pin_group, top_group, "jack");
+
+ if (HDA_PIN_GROUP (0x14, group, pin_group, "green", n, "jack", 4)) /* Pin widget 0x14 */
+ {
+ /* Src 0xc=front */
+ if (HDA_PINSELECT (0x14, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "front input");
+ HDA_OUTMUTE (0x14, group, "mute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP (0x15, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x15 */
+ {
+ /* Src 0xd=rear */
+ if (HDA_PINSELECT (0x15, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "rear input");
+ HDA_OUTMUTE (0x15, group, "mute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP (0x16, group, pin_group, "C-L", n, "jack", 4)) /* Pin widget 0x16 */
+ {
+ /* Src 0xe=center/LFE */
+ if (HDA_PINSELECT (0x16, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "center/LFE input");
+ HDA_OUTMUTE (0x16, group, "mute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP (0x17, group, pin_group, "surr", n, "jack", 4)) /* Pin widget 0x17 */
+ {
+ /* Src 0xf=side */
+ if (HDA_PINSELECT (0x17, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "side input");
+ HDA_OUTMUTE (0x17, group, "mute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP (0x18, group, pin_group, "pink1", n, "jack", 4)) /* Pin widget 0x18 */
+ {
+ /* Src 0x10=out-source */
+ if (HDA_PINSELECT (0x18, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "out-source input");
+ HDA_OUTMUTE (0x18, group, "mute", UNMUTE);
+
+ /* Widget 0x10 (out-source) */
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ if (HDA_SELECT (0x10, "out-source", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "front rear center/LFE side");
+ }
+ }
+
+ if (HDA_PIN_GROUP (0x19, group, pin_group, "pink2", n, "jack", 4)) /* Pin widget 0x19 */
+ {
+ /* Src 0x11=out-source */
+ if (HDA_PINSELECT (0x19, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "out-source input");
+ HDA_OUTMUTE (0x19, group, "mute", UNMUTE);
+
+ /* Widget 0x11 (out-source) */
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ if (HDA_SELECT (0x11, "out-source", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "front rear center/LFE side");
+ }
+ }
+
+ if (HDA_PIN_GROUP (0x1a, group, pin_group, "blue1", n, "jack", 4)) /* Pin widget 0x1a */
+ {
+ /* Src 0x12=out-source */
+ if (HDA_PINSELECT (0x1a, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "out-source input");
+ HDA_OUTMUTE (0x1a, group, "mute", UNMUTE);
+
+ /* Widget 0x12 (out-source) */
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ if (HDA_SELECT (0x12, "out-source", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "front rear center/LFE side");
+ }
+ }
+
+ if (HDA_PIN_GROUP (0x1b, group, pin_group, "blue2", n, "jack", 4)) /* Pin widget 0x1b */
+ {
+ /* Src 0x13=out-source */
+ if (HDA_PINSELECT (0x1b, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "out-source input");
+ HDA_OUTMUTE (0x1b, group, "mute", UNMUTE);
+
+ /* Widget 0x13 (out-source) */
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ if (HDA_SELECT (0x13, "out-source", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "front rear center/LFE side");
+ }
+ }
+
+ if (HDA_PIN_GROUP (0x1c, group, pin_group, "cd", n, "jack", 4)) /* Pin widget 0x1c */
+ {
+ if (HDA_PINSELECT (0x1c, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "input");
+ }
+
+ if (HDA_PIN_GROUP (0x1d, group, pin_group, "beep", n, "jack", 4)) /* Pin widget 0x1d */
+ {
+ if (HDA_PINSELECT (0x1d, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "input");
+ }
+ }
+ /* Handle ADC widgets */
+ {
+ int n, group, rec_group;
+
+ n = 0;
+
+ HDA_GROUP (rec_group, top_group, "record");
+
+ if (HDA_ADC_GROUP (0x07, group, rec_group, "rec1", n, "record", 2)) /* ADC widget 0x07 */
+ {
+ /* Src 0x18=pink1 */
+ /* Src 0x19=pink2 */
+ /* Src 0x1a=blue1 */
+ /* Src 0x1b=blue2 */
+ /* Src 0x1c=cd */
+ /* Src 0x14=green */
+ /* Src 0x15=black */
+ if (HDA_SELECT (0x07, "src", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "pink1 pink2 blue1 blue2 cd green black");
+ }
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "vol");
+ HDA_INAMP (0x07, 0, amp_group, "pink1", 90); /* From widget 0x18 */
+ HDA_INAMP (0x07, 1, amp_group, "pink2", 90); /* From widget 0x19 */
+ HDA_INAMP (0x07, 2, amp_group, "blue1", 90); /* From widget 0x1a */
+ HDA_INAMP (0x07, 3, amp_group, "blue2", 90); /* From widget 0x1b */
+ HDA_INAMP (0x07, 4, amp_group, "cd", 90); /* From widget 0x1c */
+ HDA_INAMP (0x07, 5, amp_group, "green", 90); /* From widget 0x14 */
+ HDA_INAMP (0x07, 6, amp_group, "black", 90); /* From widget 0x15 */
+ }
+ }
+
+ if (HDA_ADC_GROUP (0x08, group, rec_group, "rec2", n, "record", 2)) /* ADC widget 0x08 */
+ {
+ /* Src 0x18=pink1 */
+ /* Src 0x19=pink2 */
+ /* Src 0x1a=blue1 */
+ /* Src 0x1b=blue2 */
+ /* Src 0x1c=cd */
+ /* Src 0x14=green */
+ /* Src 0x15=black */
+ if (HDA_SELECT (0x08, "src", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "pink1 pink2 blue1 blue2 cd green black");
+ }
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "vol");
+ HDA_INAMP (0x08, 0, amp_group, "pink1", 90); /* From widget 0x18 */
+ HDA_INAMP (0x08, 1, amp_group, "pink2", 90); /* From widget 0x19 */
+ HDA_INAMP (0x08, 2, amp_group, "blue1", 90); /* From widget 0x1a */
+ HDA_INAMP (0x08, 3, amp_group, "blue2", 90); /* From widget 0x1b */
+ HDA_INAMP (0x08, 4, amp_group, "cd", 90); /* From widget 0x1c */
+ HDA_INAMP (0x08, 5, amp_group, "green", 90); /* From widget 0x14 */
+ HDA_INAMP (0x08, 6, amp_group, "black", 90); /* From widget 0x15 */
+ }
+ }
+
+ if (HDA_ADC_GROUP (0x09, group, rec_group, "rec3", n, "record", 2)) /* ADC widget 0x09 */
+ {
+ /* Src 0x18=pink1 */
+ /* Src 0x19=pink2 */
+ /* Src 0x1a=blue1 */
+ /* Src 0x1b=blue2 */
+ /* Src 0x1c=cd */
+ /* Src 0xb=inputmix */
+ /* Src 0x14=green */
+ /* Src 0x15=black */
+ /* Src 0x16=C-L */
+ /* Src 0x17=surr */
+ if (HDA_SELECT (0x09, "src", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl,
+ "pink1 pink2 blue1 blue2 cd inputmix green black C-L surr");
+ }
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "vol");
+ HDA_INAMP (0x09, 0, amp_group, "pink1", 90); /* From widget 0x18 */
+ HDA_INAMP (0x09, 1, amp_group, "pink2", 90); /* From widget 0x19 */
+ HDA_INAMP (0x09, 2, amp_group, "blue1", 90); /* From widget 0x1a */
+ HDA_INAMP (0x09, 3, amp_group, "blue2", 90); /* From widget 0x1b */
+ HDA_INAMP (0x09, 4, amp_group, "cd", 90); /* From widget 0x1c */
+ HDA_INAMP (0x09, 5, amp_group, "inputmix", 90); /* From widget 0x0b */
+ HDA_INAMP (0x09, 6, amp_group, "green", 90); /* From widget 0x14 */
+ HDA_INAMP (0x09, 7, amp_group, "black", 90); /* From widget 0x15 */
+ HDA_INAMP (0x09, 8, amp_group, "C-L", 90); /* From widget 0x16 */
+ HDA_INAMP (0x09, 9, amp_group, "surr", 90); /* From widget 0x17 */
+ }
+ }
+
+#if 0
+ if (HDA_ADC_GROUP (0x0a, group, rec_group, "spdif-in", n, "record", 2)) /* ADC widget 0x0a */
+ {
+ /* Src 0x1f=spdin */
+ }
+#endif
+ }
+ /* Handle misc widgets */
+ {
+ int n, group, misc_group;
+
+ n = 0;
+
+ HDA_GROUP (misc_group, top_group, "misc");
+
+ if (HDA_MISC_GROUP (0x0c, group, misc_group, "front", n, "misc", 8)) /* Misc widget 0x0c */
+ {
+ /* Src 0x2=front */
+ /* Src 0xb=inputmix */
+ HDA_OUTAMP (0x0c, group, "-", 90);
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE (0x0c, 0, amp_group, "front", UNMUTE); /* From widget 0x02 */
+ HDA_INMUTE (0x0c, 1, amp_group, "inputmix", UNMUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP (0x0d, group, misc_group, "rear", n, "misc", 8)) /* Misc widget 0x0d */
+ {
+ /* Src 0x3=rear */
+ /* Src 0xb=inputmix */
+ HDA_OUTAMP (0x0d, group, "-", 90);
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE (0x0d, 0, amp_group, "rear", UNMUTE); /* From widget 0x03 */
+ HDA_INMUTE (0x0d, 1, amp_group, "inputmix", UNMUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP (0x0e, group, misc_group, "center/LFE", n, "misc", 8)) /* Misc widget 0x0e */
+ {
+ /* Src 0x4=center/LFE */
+ /* Src 0xb=inputmix */
+ HDA_OUTAMP (0x0e, group, "-", 90);
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE (0x0e, 0, amp_group, "center/LFE", UNMUTE); /* From widget 0x04 */
+ HDA_INMUTE (0x0e, 1, amp_group, "inputmix", UNMUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP (0x0f, group, misc_group, "side", n, "misc", 8)) /* Misc widget 0x0f */
+ {
+ /* Src 0x5=side */
+ /* Src 0xb=inputmix */
+ HDA_OUTAMP (0x0f, group, "-", 90);
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE (0x0f, 0, amp_group, "side", UNMUTE); /* From widget 0x05 */
+ HDA_INMUTE (0x0f, 1, amp_group, "inputmix", UNMUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP (0x0b, group, misc_group, "inputmix", n, "misc", 0)) /* Misc widget 0x0b */
+ {
+ /* Src 0x18=pink1 */
+ /* Src 0x19=pink2 */
+ /* Src 0x1a=blue1 */
+ /* Src 0x1b=blue2 */
+ /* Src 0x1c=cd */
+ /* Src 0x1d=beep */
+ /* Src 0x14=green */
+ /* Src 0x15=black */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "vol");
+ HDA_INAMP (0x0b, 0, amp_group, "pink1", 90); /* From widget 0x18 */
+ HDA_INAMP (0x0b, 1, amp_group, "pink2", 90); /* From widget 0x19 */
+ HDA_INAMP (0x0b, 2, amp_group, "blue1", 90); /* From widget 0x1a */
+ HDA_INAMP (0x0b, 3, amp_group, "blue2", 90); /* From widget 0x1b */
+ HDA_INAMP (0x0b, 4, amp_group, "cd", 90); /* From widget 0x1c */
+ HDA_INAMP (0x0b, 5, amp_group, "beep", 90); /* From widget 0x1d */
+ HDA_INAMP (0x0b, 6, amp_group, "green", 90); /* From widget 0x14 */
+ HDA_INAMP (0x0b, 7, amp_group, "black", 90); /* From widget 0x15 */
+ }
+ }
+ }
+ return 0;
+}
diff --git a/kernel/drv/oss_hdaudio/hdaudio_asus_P4B_E.c b/kernel/drv/oss_hdaudio/hdaudio_asus_P4B_E.c
new file mode 100644
index 0000000..c7f416c
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_asus_P4B_E.c
@@ -0,0 +1,395 @@
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+/* Codec index is 0 */
+/* Codec vendor 11d4:1988 */
+/* HD codec revision 1.0 (4.0) (0x00100400) */
+/* Subsystem ID 104381e1 */
+/* Default amplifier caps: in=80000000, out=00052727 */
+#include "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_dedicated.h"
+
+int
+hdaudio_Asus_P4B_E_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad,
+ int top_group)
+{
+ int ctl = 0;
+
+ DDB (cmn_err (CE_CONT, "hdaudio_Asus_P4B_E_mixer_init got called.\n"));
+
+ HDA_OUTAMP_F (0x04, top_group, "front", 100, MIXF_PCMVOL);
+ HDA_COLOR (ctl, OSS_RGB_GREEN);
+ HDA_OUTAMP_F (0x0a, top_group, "side", 100, MIXF_PCMVOL);
+ HDA_COLOR (ctl, OSS_RGB_GRAY);
+ HDA_OUTAMP_F (0x05, top_group, "center/LFE", 100, MIXF_PCMVOL);
+ HDA_COLOR (ctl, OSS_RGB_ORANGE);
+ HDA_OUTAMP_F (0x06, top_group, "rear", 100, MIXF_PCMVOL);
+ HDA_COLOR (ctl, OSS_RGB_BLACK);
+ HDA_OUTAMP_F (0x03, top_group, "headphone", 100, MIXF_PCMVOL);
+ HDA_OUTAMP_F (0x21, top_group, "input-mix", 100, MIXF_PCMVOL);
+ HDA_OUTAMP_F (0x10, top_group, "pcbeep", 100, MIXF_PCMVOL);
+
+ /* Handle misc widgets */
+ {
+ int n, group;
+
+ n = 0;
+
+ HDA_GROUP (group, top_group, "input-mix");
+
+ //if (HDA_MISC_GROUP(0x20, group, misc_group, "input-mix", n, "misc", 4)) /* Misc widget 0x20 */
+ {
+ /* Src 0x39=fppink-micboost */
+ /* Src 0x33=blue-insel */
+ /* Src 0x38=fpgreen-micboost */
+ /* Src 0x3d=green-micboost */
+ /* Src 0x34=pink-insel */
+ /* Src 0x3b=black-micboost */
+ /* Src 0x18=cd */
+ /* Src 0x1a=beep */
+ HDA_INAMP (0x20, 0, group, "fp-pink", 100); /* From widget 0x39 */
+ HDA_COLOR (ctl, OSS_RGB_PINK);
+
+ HDA_INAMP (0x20, 1, group, "blue", 100); /* From widget 0x33 */
+ HDA_COLOR (ctl, OSS_RGB_BLUE);
+
+ HDA_INAMP (0x20, 2, group, "fp-green", 100); /* From widget 0x38 */
+ HDA_COLOR (ctl, OSS_RGB_GREEN);
+
+ HDA_INAMP (0x20, 3, group, "green", 100); /* From widget 0x3d */
+ HDA_COLOR (ctl, OSS_RGB_GREEN);
+
+ HDA_INAMP (0x20, 4, group, "pink", 100); /* From widget 0x34 */
+ HDA_COLOR (ctl, OSS_RGB_PINK);
+
+ HDA_INAMP (0x20, 5, group, "black", 100); /* From widget 0x3b */
+ HDA_COLOR (ctl, OSS_RGB_BLACK);
+
+ HDA_INAMP (0x20, 6, group, "cd", 100); /* From widget 0x18 */
+ HDA_COLOR (ctl, 0);
+
+ HDA_INAMP (0x20, 7, group, "pcbeep", 100); /* From widget 0x1a */
+ HDA_COLOR (ctl, 0);
+
+#if 0
+ // This seems to be unnecessary selector
+ /* Widget 0x33 (blue-insel) */
+ /* Src 0x3a=blue-micboost */
+ /* Src 0x25=grey */
+ /* Src 0x24=orange */
+ if (HDA_SELECT (0x33, "src", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "blue grey orange");
+ }
+#endif
+
+#if 0
+ // This seems to be unnecessary selector
+ /* Widget 0x34 (pink-insel) */
+ /* Src 0x3c=pink-micboost */
+ /* Src 0x25=grey */
+ /* Src 0x24=orange */
+ if (HDA_SELECT (0x34, "src", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "pink grey orange");
+ }
+#endif
+ }
+ }
+ /* Handle ADC widgets */
+ {
+ int n, group, rec_group;
+
+ n = 0;
+
+ HDA_GROUP (rec_group, top_group, "record");
+
+#if 0
+ if (HDA_ADC_GROUP (0x07, group, rec_group, "spdin", n, "record", 4)) /* ADC widget 0x07 */
+ {
+ /* Src 0x1c=spdif-in */
+ }
+#endif
+
+ if (HDA_ADC_GROUP (0x08, group, rec_group, "rec1", n, "record", 4)) /* ADC widget 0x08 */
+ {
+ /* Src 0xc=rec1-src */
+
+ /* Widget 0x0c (rec1-src) */
+ /* Src 0x38=fpgreen-micboost */
+ /* Src 0xbc= (0x3c=porte-boost?) */
+ /* Src 0x18=int-black */
+ /* Src 0x24=orange */
+ /* Src 0x25=grey */
+ /* Src 0x3d=green-micboost */
+ /* Src 0x20=input-mix */
+ if (HDA_SELECT (0x0c, "src", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "fp-green pink cd orange grey green input-mix");
+ }
+ HDA_OUTAMP_F (0x0c, group, "-", 100, MIXF_RECVOL);
+ }
+
+ if (HDA_ADC_GROUP (0x09, group, rec_group, "rec2", n, "record", 4)) /* ADC widget 0x09 */
+ {
+ /* Src 0xd=rec2-src */
+
+ /* Widget 0x0d (rec2-src) */
+ /* Src 0x38=fpgreen-micboost */
+ /* Src 0xbc= (0x3c=porte-boost?) */
+ /* Src 0x18=int-black */
+ /* Src 0x24=orange */
+ /* Src 0x25=grey */
+ /* Src 0x3d=green-micboost */
+ /* Src 0x20=input-mix */
+ if (HDA_SELECT (0x0d, "src", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "fp-green pink cd orange grey green input-mix");
+ }
+ HDA_OUTAMP_F (0x0d, group, "-", 100, MIXF_RECVOL);
+ }
+
+ if (HDA_ADC_GROUP (0x0f, group, rec_group, "rec3", n, "record", 4)) /* ADC widget 0x0f */
+ {
+ /* Src 0xe=rec3-src */
+
+ /* Widget 0x0e (rec3-src) */
+ /* Src 0x38=fpgreen-micboost */
+ /* Src 0xbc= (0x3c=porte-boost?) */
+ /* Src 0x18=int-black */
+ /* Src 0x24=orange */
+ /* Src 0x25=grey */
+ /* Src 0x3d=green-micboost */
+ /* Src 0x20=input-mix */
+ if (HDA_SELECT (0x0e, "src", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "fp-green pink cd orange grey green input-mix");
+ }
+ HDA_OUTAMP_F (0x0e, group, "-", 100, MIXF_RECVOL);
+ }
+ }
+
+ /* Handle PIN widgets */
+ {
+ int n, group, pin_group;
+
+ n = 0;
+
+ HDA_GROUP (pin_group, top_group, "jack");
+
+ if (HDA_PIN_GROUP (0x11, group, pin_group, "fp-green", n, "jack", 4)) /* Pin widget 0x11 */
+ {
+ /* Src 0x22=headphon-mix */
+ if (HDA_PINSELECT (0x11, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "headphone-out input");
+ HDA_OUTMUTE (0x11, group, "inmute", UNMUTE);
+
+ /* Widget 0x22 (headphon-mix) */
+ /* Src 0x37=fpgreen-outsel */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE_F (0x22, 0, amp_group, "headphone", UNMUTE, MIXF_MAINVOL); /* From widget 0x37 */
+ HDA_INMUTE_F (0x22, 1, amp_group, "input-mix", UNMUTE, MIXF_MAINVOL); /* From widget 0x21 */
+ }
+ /* Widget 0x38 (fpgreen-micboost) */
+ /* Src 0x11=fp-green */
+ HDA_OUTAMP (0x38, group, "micboost", 100);
+ }
+
+ if (HDA_PIN_GROUP (0x14, group, pin_group, "fp-pink", n, "jack", 4)) /* Pin widget 0x14 */
+ {
+ /* Src 0x2b=fp-mic-mix */
+ if (HDA_PINSELECT (0x14, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "headphone-out input");
+ HDA_OUTMUTE (0x14, group, "inmute", UNMUTE);
+
+ /* Widget 0x2b (fp-mic-mix) */
+ /* Src 0x30=fppink-outsel */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE_F (0x2b, 0, amp_group, "headphone", UNMUTE, MIXF_MAINVOL); /* From widget 0x30 */
+ HDA_INMUTE_F (0x2b, 1, amp_group, "input-mix", UNMUTE, MIXF_MAINVOL); /* From widget 0x21 */
+ }
+ /* Widget 0x39 (fppink-micboost) */
+ /* Src 0x14=fp-pink */
+ HDA_OUTAMP (0x39, group, "micboost", 100);
+ }
+
+ if (HDA_PIN_GROUP (0x12, group, pin_group, "green", n, "jack", 0)) /* Pin widget 0x12 */
+ {
+ /* Src 0x29=front-mix */
+ if (HDA_PINSELECT (0x12, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "front-out input");
+ HDA_OUTMUTE (0x12, group, "inmute", UNMUTE);
+
+ /* Widget 0x29 (front-mix) */
+ /* Src 0x4=front */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE_F (0x29, 0, amp_group, "front", UNMUTE, MIXF_MAINVOL); /* From widget 0x04 */
+ HDA_INMUTE_F (0x29, 1, amp_group, "input-mix", UNMUTE, MIXF_MAINVOL); /* From widget 0x21 */
+ }
+ /* Widget 0x3d (green-micboost) */
+ /* Src 0x12=green */
+ HDA_OUTAMP (0x3d, group, "micboost", 100);
+ }
+
+ if (HDA_PIN_GROUP (0x13, group, pin_group, "int-black", n, "jack", 4)) /* Pin widget 0x13 */
+ {
+ /* Src 0x2d=mono-mixdown */
+ if (HDA_PINSELECT (0x13, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "mono-out input");
+ HDA_OUTAMP (0x13, group, "invol", 100);
+
+ /* Widget 0x2d (mono-mixdown) */
+ /* Src 0x1e=mono-mix */
+
+ /* Widget 0x1e (mono-mix) */
+ /* Src 0x36=mono-sel */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE_F (0x1e, 0, amp_group, "mono", UNMUTE, MIXF_MAINVOL); /* From widget 0x36 */
+ HDA_INMUTE_F (0x1e, 1, amp_group, "input-mix", UNMUTE, MIXF_MAINVOL); /* From widget 0x21 */
+ }
+ }
+
+ if (HDA_PIN_GROUP (0x15, group, pin_group, "blue", n, "jack", 4)) /* Pin widget 0x15 */
+ {
+ /* Src 0x2c=linein-mix */
+ if (HDA_PINSELECT (0x15, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "front-out input");
+ HDA_OUTMUTE (0x15, group, "inmute", UNMUTE);
+
+ /* Widget 0x2c (linein-mix) */
+ /* Src 0x31=blue-outsel */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE_F (0x2c, 0, amp_group, "front", UNMUTE, MIXF_MAINVOL); /* From widget 0x31 */
+ HDA_INMUTE_F (0x2c, 1, amp_group, "input-mix", UNMUTE, MIXF_MAINVOL); /* From widget 0x21 */
+ }
+ /* Src 0x15=linein */
+ HDA_OUTAMP (0x3a, group, "micboost", 100);
+ }
+
+ if (HDA_PIN_GROUP (0x16, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x16 */
+ {
+ /* Src 0x2a=rear-mix */
+ if (HDA_PINSELECT (0x16, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "rear-out input");
+ HDA_OUTMUTE (0x16, group, "inmute", UNMUTE);
+
+ /* Widget 0x2a (rear-mix) */
+ /* Src 0x6=rear */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE_F (0x2a, 0, amp_group, "rear", UNMUTE, MIXF_MAINVOL); /* From widget 0x06 */
+ HDA_INMUTE_F (0x2a, 1, amp_group, "input-mix", UNMUTE, MIXF_MAINVOL); /* From widget 0x21 */
+ }
+ /* Widget 0x3b (black-micboost) */
+ /* Src 0x16=black */
+ HDA_OUTAMP (0x3b, group, "micboost", 100);
+ }
+
+ if (HDA_PIN_GROUP (0x17, group, pin_group, "pink", n, "jack", 0)) /* Pin widget 0x17 */
+ {
+ /* Src 0x26=mic-mix */
+ if (HDA_PINSELECT (0x17, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "center/LFE-out input");
+ HDA_OUTMUTE (0x17, group, "inmute", UNMUTE);
+
+ /* Widget 0x26 (mic-mix) */
+ /* Src 0x32=pink-outsel */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE_F (0x26, 0, amp_group, "center/LFE", UNMUTE, MIXF_MAINVOL); /* From widget 0x32 */
+ HDA_INMUTE_F (0x26, 1, amp_group, "input-mix", UNMUTE, MIXF_MAINVOL); /* From widget 0x21 */
+ }
+ /* Src 0x17=mic */
+ HDA_OUTAMP (0x3c, group, "micboost", 100);
+ }
+
+#if 0
+ if (HDA_PIN_GROUP (0x18, group, pin_group, "int-black", n, "jack", 4)) /* Pin widget 0x18 */
+ {
+ if (HDA_PINSELECT (0x18, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "input");
+ }
+
+ if (HDA_PIN_GROUP (0x1a, group, pin_group, "int-black", n, "jack", 4)) /* Pin widget 0x1a */
+ {
+ if (HDA_PINSELECT (0x1a, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "input");
+ }
+#endif
+
+ if (HDA_PIN_GROUP (0x24, group, pin_group, "orange", n, "jack", 4)) /* Pin widget 0x24 */
+ {
+ /* Src 0x27=center/LFE-mix */
+ if (HDA_PINSELECT (0x24, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "center/LFE-out input");
+ HDA_OUTMUTE (0x24, group, "inmute", UNMUTE);
+
+ /* Widget 0x27 (center/LFE-mix) */
+ /* Src 0x5=center/LFE */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE_F (0x27, 0, amp_group, "center/LFE", UNMUTE, MIXF_MAINVOL); /* From widget 0x05 */
+ HDA_INMUTE_F (0x27, 1, amp_group, "input-mix", UNMUTE, MIXF_MAINVOL); /* From widget 0x21 */
+ }
+ }
+
+ if (HDA_PIN_GROUP (0x25, group, pin_group, "grey", n, "jack", 4)) /* Pin widget 0x25 */
+ {
+ /* Src 0x28=side-mix */
+ if (HDA_PINSELECT (0x25, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "side-out input");
+ HDA_OUTMUTE (0x25, group, "inmute", UNMUTE);
+
+ /* Widget 0x28 (side-mix) */
+ /* Src 0xa=side */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP (amp_group, group, "mute");
+ HDA_INMUTE_F (0x28, 0, amp_group, "side", UNMUTE, MIXF_MAINVOL); /* From widget 0x0a */
+ HDA_INMUTE_F (0x28, 1, amp_group, "input-mix", UNMUTE, MIXF_MAINVOL); /* From widget 0x21 */
+ }
+ }
+ }
+ return 0;
+}
diff --git a/kernel/drv/oss_hdaudio/hdaudio_asus_m9.c b/kernel/drv/oss_hdaudio/hdaudio_asus_m9.c
new file mode 100644
index 0000000..054b4eb
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_asus_m9.c
@@ -0,0 +1,36 @@
+/*
+ * Purpose: init handler for Asus m9.
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/* Codec index is 0 */
+/* Codec vendor 10ec:0260 */
+/* HD codec revision 1.0 (4.0) (0x00100400) */
+/* Subsystem ID 1025160d */
+#include "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_dedicated.h"
+#include "hdaudio_mixers.h"
+
+int
+hdaudio_asus_m9_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+{
+ DDB(cmn_err(CE_CONT, "hdaudio_asus_m9_mixer_init got called.\n"));
+
+ corb_write (mixer, cad, 0x1b, 0, SET_EAPD, 0);
+
+ return hdaudio_generic_mixer_init(dev, mixer, cad, top_group);
+}
+
diff --git a/kernel/drv/oss_hdaudio/hdaudio_codec.c b/kernel/drv/oss_hdaudio/hdaudio_codec.c
new file mode 100644
index 0000000..fb29840
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_codec.c
@@ -0,0 +1,3580 @@
+/*
+ * Purpose: Codec handling for Intel High Definition Audio (HDA/Azalia).
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_codecids.h"
+
+extern int hdaudio_snoopy;
+extern int hdaudio_jacksense;
+extern int hdaudio_noskip;
+
+static codec_t NULL_codec = { 0 }; /* TODO: Temporary workaround - to be removed */
+
+
+/* Si3055 functions (implemented in hdaudio_si3055.c) */
+extern void hdaudio_si3055_endpoint_init(hdaudio_mixer_t *mixer, int cad);
+extern void hdaudio_si3055_set_rate(hdaudio_mixer_t *mixer, int cad, int rate);
+extern int hdaudio_si3055_set_offhook(hdaudio_mixer_t *mixer, int cad, int offhook);
+
+
+static int attach_codec (hdaudio_mixer_t * mixer, int cad, char *hw_info,
+ unsigned int pci_subdevice, int group_type);
+int
+hdaudio_mixer_get_outendpoints (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t ** endpoints, int size)
+{
+ int i;
+
+ if (size != sizeof (hdaudio_endpointinfo_t))
+ {
+ cmn_err (CE_WARN, "Bad endpoint size\n");
+ return OSS_EIO;
+ }
+
+ *endpoints = (hdaudio_endpointinfo_t *) & mixer->outendpoints;
+
+ for (i = 0; i < mixer->num_outendpoints; i++)
+ {
+ hdaudio_endpointinfo_t *ep = *endpoints + i;
+
+ ep->skip = mixer->codecs[ep->cad]->widgets[ep->base_wid].skip;
+
+ if (hdaudio_snoopy)
+ {
+ char *s = ep->name + strlen(ep->name);
+ sprintf(s, ":%d:%d", ep->cad, ep->base_wid);
+ }
+ }
+ return mixer->num_outendpoints;
+}
+
+int
+hdaudio_mixer_get_inendpoints (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t ** endpoints, int size)
+{
+ int i;
+
+ if (size != sizeof (hdaudio_endpointinfo_t))
+ {
+ cmn_err (CE_WARN, "Bad endpoint size\n");
+ return OSS_EIO;
+ }
+
+ *endpoints = (hdaudio_endpointinfo_t *) & mixer->inendpoints;
+
+ for (i = 0; i < mixer->num_inendpoints; i++)
+ {
+ hdaudio_endpointinfo_t *ep = *endpoints + i;
+
+ ep->skip = mixer->codecs[ep->cad]->widgets[ep->base_wid].skip;
+
+ if (hdaudio_snoopy)
+ {
+ char *s = ep->name + strlen(ep->name);
+ sprintf(s, ":%d:%d", ep->cad, ep->base_wid);
+ }
+ }
+ return mixer->num_inendpoints;
+}
+
+/*ARGSUSED*/
+static int
+hda_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ if (cmd == SOUND_MIXER_READ_DEVMASK ||
+ cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC ||
+ cmd == SOUND_MIXER_READ_STEREODEVS)
+ return *arg = 0;
+
+ return OSS_EINVAL;
+}
+
+static mixer_driver_t hda_mixer_driver = {
+ hda_mixer_ioctl
+};
+
+
+static void
+propagate_names (hdaudio_mixer_t * mixer)
+{
+ int c, w;
+ int i;
+/*
+ * Check if the same name can be used for all the widgets on an unique path.
+ */
+
+ for (i = 0; i < 20; i++)
+ for (c = 0; c < mixer->ncodecs; c++)
+ if (mixer->codecs[c] != &NULL_codec)
+ {
+ for (w = 1; w < mixer->codecs[c]->nwidgets; w++)
+ {
+ widget_t *widget = &mixer->codecs[c]->widgets[w];
+ widget_t *src_widget =
+ &mixer->codecs[c]->widgets[widget->connections[0]];
+
+ if (widget->nconn != 1)
+ continue;
+
+#if 0
+ if (src_widget->wid_type == NT_PIN
+ || src_widget->wid_type == NT_DAC)
+ continue;
+
+ if (src_widget->wid_type != NT_MIXER && src_widget->wid_type != NT_VENDOR) /* Mixer */
+ continue;
+#endif
+
+ strcpy (widget->name, src_widget->name);
+
+ /*
+ * Copy widget's RGB color to all widgets in the path
+ */
+ if (widget->rgbcolor == 0)
+ widget->rgbcolor = src_widget->rgbcolor;
+ }
+ }
+#if 0
+ // Debugging code
+ for (c = 0; c < mixer->ncodecs; c++)
+ if (mixer->codecs[c] != &NULL_codec)
+ for (w = 1; w < mixer->codecs[c]->nwidgets; w++)
+ {
+ widget_t *widget = &mixer->codecs[c]->widgets[w];
+
+ cmn_err(CE_CONT, "w= %02x rgb=%06x: %s (%s)\n", w, widget->rgbcolor, widget->name, widget->color);
+ }
+#endif
+}
+
+static void
+check_names (hdaudio_mixer_t * mixer)
+{
+ int c, c2, w, w2;
+ int n, start;
+
+/*
+ * Make sure all widgets have unique names.
+ */
+ for (c = 0; c < mixer->ncodecs; c++)
+ if (mixer->codecs[c] != &NULL_codec)
+ {
+ for (w = 1; w < mixer->codecs[c]->nwidgets; w++)
+ {
+ char tmp[16];
+ n = 0;
+ if (mixer->codecs[c]->widgets[w].skip) /* Not available */
+ continue;
+
+ strcpy (tmp, mixer->codecs[c]->widgets[w].name);
+
+ start = w + 1;
+
+ for (c2 = c; c2 < mixer->ncodecs; c2++)
+ {
+ for (w2 = start; w2 < mixer->codecs[c2]->nwidgets; w2++)
+ {
+ if (mixer->codecs[c2]->widgets[w2].skip) /* Not available */
+ continue;
+
+ if (strcmp (tmp, mixer->codecs[c2]->widgets[w2].name) ==
+ 0)
+ n++;
+ }
+
+ start = 1;
+ }
+
+ if (n > 0) /* Duplicates found */
+ {
+ n = 0;
+ start = w;
+ for (c2 = c; c2 < mixer->ncodecs; c2++)
+ {
+ for (w2 = start; w2 < mixer->codecs[c2]->nwidgets; w2++)
+ {
+ if (mixer->codecs[c2]->widgets[w2].skip) /* Not available */
+ continue;
+
+ if (strcmp (tmp, mixer->codecs[c2]->widgets[w2].name)
+ == 0)
+ {
+ n++;
+ sprintf (mixer->codecs[c2]->widgets[w2].name,
+ "%s%d", tmp, n);
+ }
+ }
+
+ start = 1;
+ }
+ }
+ }
+ }
+}
+
+int
+hdaudio_amp_maxval (unsigned int ampcaps)
+{
+ int step, range, maxval;
+
+ range = ((ampcaps >> AMPCAP_NUMSTEPS_SHIFT) & AMPCAP_NUMSTEPS_MASK) + 1;
+ step = ((ampcaps >> AMPCAP_STEPSIZE_SHIFT) & AMPCAP_STEPSIZE_MASK) + 1;
+
+ maxval = range * step * 25; /* Now in 0.01 dB steps */
+ maxval = (maxval / 10) - 1; /* Truncate to centibel (0.1 dB) scaling */
+
+ return maxval;
+}
+
+static int
+scaleout_vol (int v, unsigned int ampcaps)
+{
+ int step, range, maxval;
+
+ range = ((ampcaps >> AMPCAP_NUMSTEPS_SHIFT) & AMPCAP_NUMSTEPS_MASK) + 1;
+ step = ((ampcaps >> AMPCAP_STEPSIZE_SHIFT) & AMPCAP_STEPSIZE_MASK) + 1;
+
+ maxval = range * step * 25; /* Now in 0.01 dB steps */
+ maxval = (maxval / 10) - 1; /* Truncate to centibel (0.1 dB) scaling */
+ if (v > maxval)
+ v = maxval;
+
+ v *= 10; /* centibels -> millibels */
+
+ v = (v + (25 * step) / 2) / (25 * step);
+
+ if (v > 0x7f || v >= range)
+ {
+ v = range - 1;
+ }
+
+ if (v < 0)
+ v = 0;
+ return v;
+}
+
+static int
+scalein_vol (int v, unsigned int ampcaps)
+{
+ int step, range, maxval;
+
+ range = ((ampcaps >> AMPCAP_NUMSTEPS_SHIFT) & AMPCAP_NUMSTEPS_MASK) + 1;
+ step = ((ampcaps >> AMPCAP_STEPSIZE_SHIFT) & AMPCAP_STEPSIZE_MASK) + 1;
+
+ maxval = range * step * 25; /* Now in 0.01 dB steps */
+ maxval = (maxval / 10) - 1; /* Truncate to centibel (0.1 dB) scaling */
+
+ v *= step * 25; /* Convert to millibels */
+
+ v = v / 10 - 1; /* millibels -> centibels */
+
+ if (v > maxval)
+ {
+ v = maxval;
+ }
+ if (v < 0)
+ v = 0;
+
+ return v;
+}
+
+static int
+handle_insrcselect (hdaudio_mixer_t * mixer, widget_t * widget, int value)
+{
+/*
+ * Emulated (recording) source selection based on input amp mute controls.
+ *
+ * Mute all inputs other than the selected one.
+ */
+ int i;
+
+ widget->current_selector = value;
+
+ for (i = 0; i < widget->nconn; i++)
+ {
+ int v = (i == value) ? 0 : 0x80;
+
+ corb_write (mixer, widget->cad, widget->wid, 0,
+ SET_GAIN (0, 1, 1, 1, i), v);
+ }
+
+ return value;
+}
+
+int
+hdaudio_set_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ hdaudio_mixer_t *mixer = mixer_devs[dev]->devc;
+
+ unsigned int cad, wid, linked_wid, typ, ix, left, right, a, b, v;
+ widget_t *widget;
+
+ ix = ctrl & 0xff;
+ typ = (ctrl >> 8) & 0xff;
+ wid = (ctrl >> 16) & 0xff;
+ cad = (ctrl >> 24) & 0xff;
+
+ if (cad >= mixer->ncodecs)
+ return OSS_EIO;
+
+ if (wid >= mixer->codecs[cad]->nwidgets)
+ return OSS_EIO;
+
+ widget = &mixer->codecs[cad]->widgets[wid];
+
+ if (mixer->codecs[cad]->vendor_flags & VF_VAIO_HACK)
+ linked_wid = (wid == 0x02) ? 0x05 : ((wid == 0x05) ? 0x02 : 0);
+ else
+ linked_wid = 0;
+
+ if (cmd == SNDCTL_MIX_READ)
+ switch (typ)
+ {
+ case CT_INGAINSEL:
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (0, 0), ix, &a, &b))
+ return OSS_EIO;
+ return a & 0x7f; // TODO: Handle mute
+ break;
+
+ case CT_INMONO:
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (0, 0), ix, &a, &b))
+ return OSS_EIO;
+ if (a & 0x80)
+ left = 0;
+ else
+ left = scalein_vol (a, widget->inamp_caps);
+ return left | (left << 16);
+ break;
+
+ case CT_INSTEREO:
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (0, 1), ix, &a, &b))
+ return OSS_EIO;
+ if (a & 0x80)
+ left = 0;
+ else
+ left = scalein_vol (a, widget->inamp_caps);
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (0, 0), ix, &a, &b))
+ return OSS_EIO;
+ if (a & 0x80)
+ right = 0;
+ else
+ right = scalein_vol (a, widget->inamp_caps);
+ return left | (right << 16);
+ break;
+
+ case CT_INMUTE:
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (0, 0), ix, &a, &b))
+ return OSS_EIO;
+ return (a >> 7) & 0x01;
+ break;
+
+ case CT_INSRC: /* Inverse mute */
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (0, 0), ix, &a, &b))
+ return OSS_EIO;
+ return !((a >> 7) & 0x01);
+ break;
+
+ case CT_SELECT:
+ return widget->current_selector;
+ break;
+
+ case CT_INSRCSELECT: /* Emulated selector based on input mute controls */
+ return widget->current_selector;
+
+ case CT_OUTGAINSEL:
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (1, 1), 0, &a, &b))
+ return OSS_EIO;
+ return a; // TODO: Handle mute
+ break;
+
+ case CT_OUTMONO:
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (1, 1), 0, &a, &b))
+ return OSS_EIO;
+ left = a & 0x7f;
+ if (a & 0x80)
+ left = 0;
+ else
+ left = scalein_vol (a, widget->outamp_caps);
+ return left | (left << 16);
+ break;
+
+ case CT_OUTSTEREO:
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (1, 1), 0, &a, &b))
+ return OSS_EIO;
+ left = a & 0x7f;
+ if (a & 0x80)
+ left = 0;
+ else
+ left = scalein_vol (a, widget->outamp_caps);
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (1, 0), 0, &a, &b))
+ return OSS_EIO;
+ right = a & 0x7f;
+ if (a & 0x80)
+ right = 0;
+ else
+ right = scalein_vol (a, widget->outamp_caps);
+ return left | (right << 16);
+ break;
+
+ case CT_OUTMUTE:
+ if (!corb_read (mixer, cad, wid, 0, GET_GAIN (1, 0), 0, &a, &b))
+ return OSS_EIO;
+ return (a >> 7) & 0x01;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (typ)
+ {
+ case CT_INMONO:
+ v = (value & 0xffff);
+ if (v == 0)
+ v = 0x80; /* Muted */
+ else
+ v = scaleout_vol (v, widget->inamp_caps);
+
+ corb_write (mixer, cad, wid, 0, SET_GAIN (0, 1, 1, 1, ix), v);
+ return value;
+ break;
+
+ case CT_INSTEREO:
+ v = (value & 0xffff);
+ if (v == 0)
+ v = 0x80; /* Muted */
+ else
+ v = scaleout_vol (v, widget->inamp_caps);
+
+ corb_write (mixer, cad, wid, 0, SET_GAIN (0, 1, 1, 0, ix), v);
+ v = ((value >> 16) & 0xffff);
+ if (v == 0)
+ v = 0x80; /* Muted */
+ else
+ v = scaleout_vol (v, widget->inamp_caps);
+ corb_write (mixer, cad, wid, 0, SET_GAIN (0, 1, 0, 1, ix), v);
+ return value;
+ break;
+
+ case CT_INGAINSEL:
+ v = (value & 0x7f);
+ // TODO: Handle mute
+ corb_write (mixer, cad, wid, 0, SET_GAIN (0, 1, 1, 0, ix), v);
+ corb_write (mixer, cad, wid, 0, SET_GAIN (0, 1, 0, 1, ix), v);
+ return value;
+ break;
+
+ case CT_INMUTE:
+ v = 0;
+ if (value)
+ v = 0x80;
+ corb_write (mixer, cad, wid, 0, SET_GAIN (0, 1, 1, 1, ix), v);
+ return value;
+ break;
+
+ case CT_INSRC: /* Inverse mute */
+ v = 0;
+ if (!value)
+ v = 0x80;
+ corb_write (mixer, cad, wid, 0, SET_GAIN (0, 1, 1, 1, ix), v);
+ return value;
+ break;
+
+ case CT_SELECT:
+ if (value < 0)
+ value = 0;
+ widget->current_selector = value;
+
+ if (value < widget->nconn)
+ {
+ /* Output source select */
+ corb_write (mixer, cad, wid, 0, SET_SELECTOR, value);
+ /* Enable output and HP amp. Set vref=Ground */
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0xc0);
+ }
+ else
+ {
+ /* Input select
+ * Program the correct VRef Values
+ */
+
+ if (widget->pin_type == PIN_IN) /* Line-in */
+ {
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0x20); /*Ground*/
+ }
+ else /* Mic-in */
+ {
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0x24); /*Vref=8
+ 0% */
+ }
+ }
+ return value;
+ break;
+
+ case CT_INSRCSELECT: /* Emulated selector based on input mute mask */
+ if (value < 0)
+ value = 0;
+ if (value >= widget->nconn)
+ value = widget->nconn;
+ return handle_insrcselect (mixer, widget, value);
+ break;
+
+ case CT_OUTGAINSEL:
+ // TODO: Handle mute
+ corb_write (mixer, cad, wid, 0, SET_GAIN (1, 0, 1, 0, ix), value);
+ corb_write (mixer, cad, wid, 0, SET_GAIN (1, 0, 0, 1, ix), value);
+ return value;
+ break;
+
+ case CT_OUTMONO:
+ v = (value & 0xffff);
+ if (v == 0)
+ v = 0x80; /* Muted */
+ else
+ v = scaleout_vol (v, widget->outamp_caps);
+ corb_write (mixer, cad, wid, 0, SET_GAIN (1, 0, 1, 0, ix), v);
+ if (linked_wid)
+ corb_write (mixer, cad, wid, 0, SET_GAIN (1, 0, 1, 0, ix), v);
+ return value;
+ break;
+
+ case CT_OUTSTEREO:
+ v = (value & 0xffff);
+ if (v == 0)
+ v = 0x80; /* Muted */
+ else
+ v = scaleout_vol (v, widget->outamp_caps);
+ corb_write (mixer, cad, wid, 0, SET_GAIN (1, 0, 1, 0, ix), v);
+ if (linked_wid)
+ corb_write (mixer, cad, linked_wid, 0, SET_GAIN (1, 0, 1, 0, ix), v);
+ v = ((value >> 16) & 0xffff);
+ if (v == 0)
+ v = 0x80; /* Muted */
+ else
+ v = scaleout_vol (v, widget->outamp_caps);
+ corb_write (mixer, cad, wid, 0, SET_GAIN (1, 0, 0, 1, ix), v);
+ if (linked_wid)
+ corb_write (mixer, cad, linked_wid, 0, SET_GAIN (1, 0, 0, 1, ix), v);
+ return value;
+ break;
+
+ case CT_OUTMUTE:
+ v = 0;
+ if (value)
+ v = 0x80;
+ corb_write (mixer, cad, wid, 0, SET_GAIN (1, 0, 1, 1, ix), v);
+ if (linked_wid)
+ corb_write (mixer, cad, linked_wid, 0, SET_GAIN (1, 0, 1, 1, ix), v);
+ return value;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+perform_pin_sense (hdaudio_mixer_t * mixer)
+{
+ int cad, wid;
+ unsigned int a, b;
+ int plugged_in;
+ codec_t *codec;
+
+ for (cad = 0; cad < mixer->ncodecs; cad++)
+ if (mixer->codecs[cad] != &NULL_codec)
+ {
+ codec = mixer->codecs[cad];
+
+ for (wid = 1; wid < mixer->codecs[cad]->nwidgets; wid++)
+ if (mixer->codecs[cad]->widgets[wid].wid_type == NT_PIN) /* Pin complex */
+ {
+ widget_t *widget = &mixer->codecs[cad]->widgets[wid];
+
+ widget->impsense = -1;
+ widget->sensed_pin = widget->pin_type;
+
+ plugged_in = 1;
+
+ /* Load the sense information */
+ if ((widget->pincaps & PINCAP_JACKSENSE_CAPABLE)
+ || (widget->pincaps & PINCAP_IMPSENSE_CAPABLE))
+ {
+ int tmout = 0;
+ if (!corb_read
+ (mixer, cad, wid, 0, GET_PIN_SENSE, 0, &a, &b))
+ a = 0x7fffffff; /* No jack present */
+
+ if (a & (1UL << 31)) /* Jack present */
+ if (widget->pincaps & PINCAP_TRIGGERR_RQRD) /* Trigger required */
+ {
+ corb_write (mixer, cad, wid, 0, TRIGGER_PIN_SENSE, 0);
+
+ do
+ {
+ oss_udelay (10);
+ if (!corb_read
+ (mixer, cad, wid, 0, GET_PIN_SENSE, 0, &a,
+ &b))
+ break;
+ }
+ while (tmout++ < 10000
+ && ((a & 0x7fffffff) == 0x7fffffff));
+ }
+
+ if (!corb_read
+ (mixer, cad, wid, 0, GET_PIN_SENSE, 0, &a, &b))
+ continue;
+ }
+ else
+ continue;
+
+ /* Precence detect */
+ if (widget->pincaps & PINCAP_JACKSENSE_CAPABLE)
+ {
+#if 0
+ if (a & (1UL << 31))
+ cmn_err (CE_WARN, "%s jack is plugged in\n",
+ widget->name);
+ else
+ cmn_err (CE_WARN, "%s NOT plugged in\n", widget->name);
+#endif
+ if (!(a & (1UL << 31)))
+ plugged_in = 0;
+ }
+
+ widget->plugged_in = plugged_in;
+ if (plugged_in)
+ codec->num_jacks_plugged++;
+
+ /* Impedance sensing */
+ widget->impsense = a & 0x7fffffff;
+ if (plugged_in && (widget->pincaps & PINCAP_IMPSENSE_CAPABLE))
+ if (hdaudio_jacksense > 0)
+ if (widget->impsense != 0x7fffffff) /* Sense operation finished */
+ {
+ /* cmn_err (CE_WARN, "%s sense %08x (%d)\n", widget->name, a, a & 0x7fffffff); */
+
+ if (widget->impsense >= 1000000) /* High impedance (line-in) pin */
+ {
+ /* cmn_err(CE_CONT, " --> Line level input\n"); */
+ widget->pin_type = widget->sensed_pin = PIN_IN;
+ }
+ else if (widget->impsense <= 10000) /* Low impedance (speaker/hp out) */
+ {
+ /* cmn_err(CE_CONT, " --> Output pin\n"); */
+ widget->pin_type = widget->sensed_pin = PIN_OUT;
+ }
+ else /* Something between low and high (mic?) */
+ {
+ /* cmn_err(CE_CONT, " --> Mic level input\n"); */
+ widget->pin_type = widget->sensed_pin = PIN_MIC;
+ }
+ }
+ }
+ }
+
+/*
+ * Set all pins to correct mode
+ */
+
+ for (cad = 0; cad < mixer->ncodecs; cad++)
+ if (mixer->codecs[cad] != &NULL_codec)
+ for (wid = 1; wid < mixer->codecs[cad]->nwidgets; wid++)
+ {
+ if (mixer->codecs[cad]->widgets[wid].wid_type == NT_PIN) /* Pin complex */
+ {
+ widget_t *widget = &mixer->codecs[cad]->widgets[wid];
+
+ if (widget->pin_type == PIN_IN
+ || widget->pin_type == PIN_UNKNOWN)
+ { /* Input PIN */
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0x20);
+ }
+ if (widget->pin_type == PIN_MIC)
+ { /* Input PIN (mic) */
+ /* TODO: Handle mic amp */
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0x24);
+ }
+ else
+ { /* Output PIN */
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0xc0);
+ }
+
+ if (widget->pincaps & PINCAP_EAPD)
+ {
+ unsigned int eapd, dummy;
+ DDB (cmn_err
+ (CE_CONT, "Pin widget %d is EAPD capable.\n",
+ widget->wid));
+ if (corb_read
+ (mixer, cad, wid, 0, GET_EAPD, 0, &eapd, &dummy))
+ {
+ eapd |= 0x02; /* EAPD enable */
+ corb_write (mixer, cad, wid, 0, SET_EAPD, eapd);
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+static int
+hdaudio_mix_init (int dev)
+{
+ hdaudio_mixer_t *mixer = mixer_devs[dev]->devc;
+ char tmp[32];
+ int err;
+ int working_codecs=0;
+ int cad;
+
+/*
+ * First pass. Count the number of active codecs.
+ */
+
+ for (cad = 0; cad < mixer->ncodecs; cad++)
+ if (mixer->codecs[cad] != &NULL_codec)
+ {
+ codec_t *codec = mixer->codecs[cad];
+
+ if (codec == &NULL_codec || codec->nwidgets == 0) /* Codec not active */
+ continue;
+
+ /*
+ * Enable the new generic mixer driver
+ */
+ if (codec->mixer_init == NULL)
+ {
+ codec->mixer_init = hdaudio_generic_mixer_init;
+ }
+
+ if (codec->active && codec->mixer_init != NULL_mixer_init)
+ working_codecs++;
+ }
+
+ /*
+ * Second pass. Initialize the mixer interfaces for all active codecs.
+ */
+
+ for (cad = 0; cad < mixer->ncodecs; cad++)
+ if (mixer->codecs[cad] != &NULL_codec)
+ {
+ codec_t *codec = mixer->codecs[cad];
+ int group = 0;
+
+ if (codec == &NULL_codec || codec->nwidgets == 0) /* Codec not active */
+ continue;
+
+ if (working_codecs > 1)
+ {
+ sprintf (tmp, "codec%d", cad + 1);
+ if ((group = mixer_ext_create_group (dev, 0, tmp)) < 0)
+ {
+ return group;
+ }
+ }
+
+ if (codec->active && codec->mixer_init != NULL_mixer_init)
+ {
+ if ((err = codec->mixer_init (dev, mixer, cad, group)) < 0)
+ {
+ if (err != OSS_EAGAIN)
+ return err;
+ /*
+ * We got EAGAIN whic means that we should fall
+ * to the old generic mixer.
+ */
+ if ((err =
+ hdaudio_generic_mixer_init (dev, mixer, cad, group)) < 0)
+ {
+ return err;
+ }
+ }
+ else
+ continue;
+ }
+ }
+
+ if (mixer->client_mixer_init != 0)
+ mixer->client_mixer_init (dev);
+
+ return 0;
+}
+
+static void
+copy_endpoints(hdaudio_mixer_t * mixer, codec_t *codec, int pass)
+{
+ int i;
+
+/*
+ * Install output endpoints from the codec to the global endpoint table.
+ */
+
+ for (i = 0; i < codec->num_outendpoints; i++)
+ {
+ hdaudio_endpointinfo_t *ep = &codec->outendpoints[i];
+ ep->skip = mixer->codecs[ep->cad]->widgets[ep->base_wid].skip;
+ }
+
+ for (i=0;i<codec->num_outendpoints;i++)
+ {
+ int ix = (codec->multich_map >> (i * 4)) & 0x0f;
+ hdaudio_endpointinfo_t *ep = &codec->outendpoints[ix];
+
+ ep->skip = mixer->codecs[ep->cad]->widgets[ep->base_wid].skip;
+
+ if (ep->skip || ep->already_used)
+ continue;
+
+ switch (pass)
+ {
+ case 0: /* Pick analog endpoints */
+ if (ep->is_digital)
+ continue;
+ break;
+
+ case 1: /* Pick digital endpoints */
+ if (!ep->is_digital)
+ continue;
+ break;
+ }
+
+ if (mixer->copied_outendpoints >= HDA_MAX_OUTSTREAMS)
+ {
+ cmn_err (CE_WARN,
+ "Too many output endpoints (%d)\n",
+ mixer->copied_outendpoints);
+ continue;
+ }
+
+ memcpy(&mixer->outendpoints[mixer->copied_outendpoints++], ep, sizeof(*ep));
+ ep->already_used=1;
+ }
+ mixer->num_outendpoints = mixer->copied_outendpoints;
+
+/*
+ * Install input endpoints from the codec to the global endpoint table.
+ */
+
+ for (i = 0; i < codec->num_inendpoints; i++)
+ {
+ hdaudio_endpointinfo_t *ep = &codec->inendpoints[i];
+ ep->skip = mixer->codecs[ep->cad]->widgets[ep->base_wid].skip;
+ }
+
+ for (i=0;i<codec->num_inendpoints;i++)
+ {
+ hdaudio_endpointinfo_t *ep = &codec->inendpoints[i];
+
+ ep->skip = mixer->codecs[ep->cad]->widgets[ep->base_wid].skip;
+
+ if (ep->skip || ep->already_used)
+ continue;
+
+ switch (pass)
+ {
+ case 0: /* Pick analog endpoints */
+ if (ep->is_digital)
+ continue;
+ break;
+
+ case 1: /* Pick digital endpoints */
+ if (!ep->is_digital)
+ continue;
+ break;
+ }
+
+ if (mixer->copied_inendpoints >= HDA_MAX_INSTREAMS)
+ {
+ cmn_err (CE_WARN,
+ "Too many output endpoints (%d)\n",
+ mixer->copied_inendpoints);
+ continue;
+ }
+
+ memcpy(&mixer->inendpoints[mixer->copied_inendpoints++], ep, sizeof(*ep));
+ ep->already_used=1;
+ }
+ mixer->num_inendpoints = mixer->copied_inendpoints;
+}
+
+ /*ARGSUSED*/
+ hdaudio_mixer_t *
+hdaudio_mixer_create (char *name, void *devc,
+ oss_device_t * osdev,
+ hdmixer_write_t writefunc,
+ hdmixer_read_t readfunc, unsigned int codecmask,
+ unsigned int vendor_id, unsigned int subvendor_id)
+{
+ hdaudio_mixer_t *mixer;
+ int i, func;
+ int ncodecs = 0;
+ char tmp[128];
+ int mixer_dev;
+
+ char *hw_info = osdev->hw_info; /* For printing hardware information */
+
+ if ((mixer = PMALLOC (osdev, sizeof (*mixer))) == NULL)
+ {
+ cmn_err (CE_WARN, "hdaudio_mixer_create: Out of memory\n");
+ return NULL;
+ }
+
+ memset (mixer, 0, sizeof (*mixer));
+
+ mixer->devc = devc;
+ mixer->osdev = osdev;
+ mixer->mixer_dev = 0;
+ strncpy (mixer->name, name, sizeof (mixer->name));
+ mixer->name[sizeof (mixer->name) - 1] = 0;
+
+ for (i = 0; i < MAX_CODECS; i++)
+ mixer->codecs[i] = &NULL_codec;
+
+ mixer->read = readfunc;
+ mixer->write = writefunc;
+ mixer->codecmask = codecmask;
+
+ sprintf (hw_info, "HD Audio controller %s\n"
+ "Vendor ID 0x%08x\n"
+ "Subvendor ID 0x%08x\n", name, vendor_id, subvendor_id);
+ hw_info += strlen (hw_info);
+
+ if (hdaudio_snoopy)
+ {
+ sprintf(hw_info, "**** Warning: Diagnostic mode enabled (hdaudio_snoopy) ****\n");
+ hw_info += strlen (hw_info);
+ }
+
+/*
+ * Search first all audio function groups for all codecs and then
+ * handle modem function groups.
+ */
+ for (func=1;func<=2;func++)
+ for (i = 0; i < 16; i++)
+ if (mixer->codecmask & (1 << i))
+ {
+ if (attach_codec (mixer, i, hw_info, subvendor_id, func) >= 0)
+ ncodecs++;
+ hw_info += strlen (hw_info);
+ }
+
+ if (ncodecs == 0)
+ {
+ cmn_err (CE_WARN, "No hdaudio codecs were detected\n");
+ return NULL;
+ }
+
+/*
+ * The attach_codec routine copied all analog endpoints to the global endpoint
+ * table. Now pick possible digital endpoints from the active codecs.
+ */
+
+ for (i = 0; i < 16; i++)
+ if (mixer->codecmask & (1 << i))
+ if (mixer->codecs[i]->active)
+ {
+ copy_endpoints(mixer, mixer->codecs[i], 1); /* Copy digital endpoints from codec to mixer */
+ }
+
+ if (!mixer->remap_avail)
+ check_names (mixer);
+
+ propagate_names (mixer);
+ perform_pin_sense (mixer);
+
+ if (mixer->chip_name == NULL)
+ mixer->chip_name = "None";
+ DDB (cmn_err (CE_CONT, "Mixer: %s %s\n", mixer->name, mixer->chip_name));
+ //sprintf (tmp, "%s %s", mixer->name, mixer->chip_name);
+ sprintf (tmp, "High Definition Audio %s", mixer->chip_name);
+
+ if ((mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ osdev,
+ osdev,
+ tmp,
+ &hda_mixer_driver,
+ sizeof (mixer_driver_t), mixer)) < 0)
+ {
+ return NULL;
+ }
+
+ mixer_devs[mixer_dev]->hw_devc = devc;
+ mixer_devs[mixer_dev]->priority = 10; /* Known motherboard device */
+ mixer->mixer_dev = mixer_dev;
+ mixer_ext_set_init_fn (mixer->mixer_dev, hdaudio_mix_init,
+ mixer->ncontrols * 4);
+ touch_mixer (mixer->mixer_dev);
+
+ return mixer;
+}
+
+/*ARGSUSED*/
+static int
+find_playvol_widget (hdaudio_mixer_t * mixer, int cad, int wid)
+{
+ int this_wid = wid;
+
+ return this_wid;
+}
+
+/*ARGSUSED*/
+static int
+find_recvol_widget (hdaudio_mixer_t * mixer, int cad, int wid)
+{
+ int this_wid = wid;
+
+ return this_wid;
+}
+
+/*ARGSUSED*/
+static int
+find_recsrc_widget (hdaudio_mixer_t * mixer, int cad, int wid)
+{
+ int this_wid = wid;
+
+ return this_wid;
+}
+
+static int
+attach_node (hdaudio_mixer_t * mixer, int cad, int wid, int parent)
+{
+ static const char *widget_types[16] = {
+ "Audio output",
+ "Audio input",
+ "Audio mixer",
+ "Audio selector",
+ "Pin complex",
+ "Power widget",
+ "Volume knob",
+ "Beep generator",
+ "Reserved8",
+ "Reserved9",
+ "ReservedA",
+ "ReservedB",
+ "ReservedC",
+ "ReservedD",
+ "ReservedE",
+ "Vendor defined audio"
+ };
+
+ static const char *widget_id[16] = {
+ "pcm",
+ "rec",
+ "mix",
+ "select",
+ "jack",
+ "power",
+ "vol",
+ "beep",
+ "unkn",
+ "unkn",
+ "unkn",
+ "unkn",
+ "unkn",
+ "unkn",
+ "unkn",
+ "vendor"
+ };
+
+ static const int bit_sizes[] = {
+ 8,
+ 16,
+ 20,
+ 24,
+ 32
+ };
+
+ static const unsigned int bit_fmts[] = {
+ AFMT_U8,
+ AFMT_S16_LE,
+ AFMT_S32_LE,
+ AFMT_S32_LE,
+ AFMT_S32_LE
+ };
+
+ static const int srates[] = {
+ 8000,
+ 11025,
+ 16000,
+ 22050,
+ 32000,
+ 44100,
+ 48000,
+ 88200,
+ 96000,
+ 176400,
+ 192000,
+ 384000
+ };
+
+ unsigned int widget_caps, b, pstate, group_type_in;
+ unsigned int inamp_caps, outamp_caps;
+ int group_type, wid_type;
+ int i;
+
+ codec_t *codec = mixer->codecs[cad];
+ widget_t *widget;
+
+ if (codec == &NULL_codec)
+ return 0;
+
+ if (!corb_read
+ (mixer, cad, wid, 0, GET_PARAMETER, HDA_GROUP_TYPE, &group_type_in, &b))
+ group_type_in = 0;
+
+ if (wid >= MAX_WIDGETS)
+ {
+ cmn_err (CE_WARN, "Too many widgets for codec %d (%d/%d)\n", cad, wid, MAX_WIDGETS);
+ return 0;
+ }
+
+ mixer->ncontrols++;
+
+ codec->nwidgets = wid + 1;
+ widget = &codec->widgets[wid];
+
+ widget->cad = cad;
+ widget->wid = wid;
+
+ widget->rgbcolor = 0;
+
+ group_type = group_type_in & 0xff;
+ widget->group_type = group_type_in;
+
+ DDB (cmn_err (CE_CONT, "Node %d, parent %d type %d, unsol capa %d\n",
+ wid, parent, group_type, !!(group_type_in & 0x100)));
+
+ if (!corb_read
+ (mixer, cad, wid, 0, GET_PARAMETER, HDA_WIDGET_CAPS, &widget_caps, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_WIDGET_CAPS failed\n");
+ return 0;
+ }
+
+ if (widget_caps & WCAP_AMP_CAP_OVERRIDE) /* Amp param override? */
+ {
+ if (!corb_read (mixer, widget->cad, widget->wid, 0,
+ GET_PARAMETER, HDA_OUTPUTAMP_CAPS, &outamp_caps, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_OUTPUTAMP_CAPS failed\n");
+ return OSS_EIO;
+ }
+ widget->outamp_caps = outamp_caps;
+
+ if (!corb_read (mixer, widget->cad, widget->wid, 0,
+ GET_PARAMETER, HDA_INPUTAMP_CAPS, &inamp_caps, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_INPUTAMP_CAPS failed\n");
+ return OSS_EIO;
+ }
+ widget->inamp_caps = inamp_caps;
+ }
+ else
+ {
+ widget->outamp_caps = outamp_caps = codec->default_outamp_caps;
+ widget->inamp_caps = inamp_caps = codec->default_inamp_caps;
+ }
+
+ if (!corb_read (mixer, cad, wid, 0, GET_POWER_STATE, 0, &pstate, &b))
+ return 0;
+
+ /* power up each of the widgets if there is a Power Capability (1<<10) */
+ if (widget_caps & WCAP_POWER_CTL)
+ corb_write (mixer, cad, wid, 0, SET_POWER_STATE, 0);
+
+ widget->widget_caps = widget_caps;
+
+ wid_type = (widget_caps >> 20) & 0x0f;
+ DDB (cmn_err
+ (CE_CONT, "\tWidget type %d (%s)(%s)\n", wid_type,
+ widget_types[wid_type], widget_id[wid_type]));
+ DDB (cmn_err (CE_CONT, "\tPower State %d\n", pstate));
+
+ if (widget_caps & WCAP_CONN_LIST)
+ {
+ unsigned int clen;
+ /* Handle connection list */
+
+ if (!corb_read
+ (mixer, cad, wid, 0, GET_PARAMETER, HDA_CONNLIST_LEN, &clen, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_CONNLIST_LEN failed\n");
+ return 0;
+ }
+
+ if (clen & 0x80)
+ {
+ cmn_err (CE_WARN, "Long form connection list not supported\n");
+ return 0;
+ }
+
+ if (clen > 0)
+ {
+ if (clen > MAX_CONN)
+ {
+ cmn_err (CE_WARN, "Too many connections\n");
+ return 0;
+ }
+
+ DDB (cmn_err (CE_CONT, "\tConn list (%d): ", clen));
+
+ for (i = 0; i < clen; i += 4)
+ {
+ int j;
+ unsigned int a;
+
+ if (!corb_read
+ (mixer, cad, wid, 0, GET_CONNECTION_LIST_ENTRY, i, &a, &b))
+ {
+ cmn_err (CE_WARN, "GET_CONNECTION_LIST_ENTRY failed\n");
+ return 0;
+ }
+
+ for (j = 0; j < 4 && (i + j) < clen; j++)
+ {
+ int v, is_range = 0;
+
+ if (widget->nconn >= MAX_CONN)
+ {
+ cmn_err (CE_WARN,
+ "Too many connections for widget %d (%d)\n",
+ widget->wid, widget->nconn);
+ break;
+ }
+
+ v = (a >> (j * 8)) & 0xff;
+ DDB (cmn_err (CE_CONT, "%d ", v));
+
+ if (v & 0x80)
+ {
+ is_range = 1;
+ v &= ~0x80;
+ }
+
+ if (v < 0 || v >= MAX_WIDGETS)
+ {
+ cmn_err (CE_NOTE,
+ "Connection %d for widget %d is out of range (%d) - Skipped\n",
+ j, widget->wid, v);
+ continue;
+ }
+
+ if (is_range) /* Range: prev...v */
+ {
+ int x;
+ codec->widgets[v].references[codec->widgets[v].
+ refcount++] = wid;
+
+ if (widget->nconn < 1)
+ {
+ cmn_err (CE_CONT,
+ "Bad range connection for widget %d\n",
+ widget->wid);
+ continue;
+ }
+
+ for (x = widget->connections[widget->nconn - 1] + 1;
+ x <= v; x++)
+ {
+ if (widget->nconn >= MAX_CONN)
+ {
+ cmn_err (CE_WARN,
+ "Too many connections(B) for widget %d (%d)\n",
+ widget->wid, widget->nconn);
+ break;
+ }
+
+ widget->connections[widget->nconn++] = x;
+ codec->widgets[x].references[codec->widgets[x].
+ refcount++] = wid;
+ }
+ }
+ else
+ {
+ widget->connections[widget->nconn++] = v;
+ codec->widgets[v].references[codec->widgets[v].
+ refcount++] = wid;
+ }
+ }
+ }
+
+ DDB (cmn_err (CE_CONT, "\n"));
+ }
+ }
+
+ widget->wid_type = wid_type;
+
+ strcpy (widget->name, widget_id[wid_type]);
+
+ if (group_type == 0) /* Not group but a widget */
+ switch (wid_type)
+ {
+ case NT_DAC: /* Audio output */
+ case NT_ADC: /* Audio input */
+ {
+ unsigned int sizes;
+ int j;
+ hdaudio_endpointinfo_t *endpoint;
+
+ if (wid_type == 0)
+ { /* Output endpoint */
+ if (mixer->num_outendpoints >= HDA_MAX_OUTSTREAMS)
+ {
+ cmn_err (CE_WARN, "Too many output endpoints\n");
+ return 0;
+ }
+
+ endpoint = &codec->outendpoints[codec->num_outendpoints++];
+
+ endpoint->stream_number = endpoint->default_stream_number =
+ ++mixer->num_outendpoints;
+ endpoint->ix = codec->num_outendpoints - 1;
+ endpoint->iddle_stream = 0;
+ }
+ else
+ { /* Input endpoint */
+ if (mixer->num_inendpoints >= HDA_MAX_INSTREAMS)
+ {
+ cmn_err (CE_WARN, "Too many input endpoints\n");
+ return 0;
+ }
+
+ endpoint = &codec->inendpoints[codec->num_inendpoints++];
+
+ endpoint->stream_number = endpoint->default_stream_number =
+ ++mixer->num_inendpoints;
+ endpoint->ix = codec->num_inendpoints - 1;
+ endpoint->iddle_stream = 0;
+ }
+
+ endpoint->cad = cad;
+ endpoint->base_wid = wid;
+ endpoint->recsrc_wid = wid;
+ endpoint->volume_wid = wid;
+ endpoint->nrates=0;
+ endpoint->name = widget->name;
+
+ widget->endpoint = endpoint;
+
+ /*
+ * Find the widgets that manage rec/play volumes and recording
+ * source selection.
+ */
+ switch (wid_type)
+ {
+ case NT_DAC:
+ endpoint->volume_wid = find_playvol_widget (mixer, cad, wid);
+ break;
+
+ case NT_ADC:
+ endpoint->volume_wid = find_recvol_widget (mixer, cad, wid);
+ endpoint->recsrc_wid = find_recsrc_widget (mixer, cad, wid);
+ break;
+ }
+
+ if (widget->widget_caps & WCAP_STEREO)
+ endpoint->channels = 2;
+ else
+ endpoint->channels = 1;
+
+ sizes = codec->sizes;
+
+ if (widget->widget_caps & WCAP_DIGITAL) /* Digital */
+ {
+ endpoint->is_digital = 1;
+ if (wid_type == NT_ADC)
+ strcpy (widget->name, "spdifin");
+ else
+ {
+ strcpy (widget->name, "spdifout");
+ corb_write (mixer, cad, wid, 0, SET_SPDIF_CONTROL1, 1); /* Digital output enable */
+ endpoint->iddle_stream = FRONT_STREAM;
+ }
+
+ endpoint->fmt_mask |= AFMT_AC3;
+ if (sizes & (1 << 20)) /* 32 bits */
+ {
+ endpoint->fmt_mask |= AFMT_SPDIF_RAW;
+ }
+ }
+ else
+ {
+ endpoint->is_digital = 0;
+ }
+
+ if (widget->widget_caps & WCAP_FORMAT_OVERRIDE) /* Override */
+ {
+ if (!corb_read (mixer, cad, wid, 0,
+ GET_PARAMETER, HDA_PCM_SIZES, &sizes, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_PCM_SIZES failed\n");
+ return 0;
+ }
+ }
+
+ widget->sizes = sizes;
+ endpoint->sizemask = sizes;
+ if (sizes == 0)
+ {
+ corb_read (mixer, cad, codec->afg, 0, GET_PARAMETER,
+ HDA_PCM_SIZES, &sizes, &b);
+ widget->sizes = sizes;
+ endpoint->sizemask = sizes;
+ }
+
+ DDB (cmn_err (CE_CONT, "\tPCM Size/Rate %08x\n", sizes));
+
+ for (j = 0; j < 5; j++)
+ if (sizes & (1 << (j + 16)))
+ {
+ DDB (cmn_err
+ (CE_CONT, "\t\tSupports %d bits\n", bit_sizes[j]));
+ endpoint->fmt_mask |= bit_fmts[j];
+ }
+
+ for (j = 0; j < 12; j++)
+ if (sizes & (1 << j))
+ {
+ DDB (cmn_err (CE_CONT, "\t\tSupports %d Hz\n", srates[j]));
+ if (endpoint->nrates < 20)
+ {
+ endpoint->rates[endpoint->nrates++] = srates[j];
+ }
+ }
+
+ if ((widget->widget_caps & WCAP_DIGITAL) && wid_type == NT_DAC) /* Digital output */
+ {
+ /*
+ * Select front output as the default stream number. In
+ * this way copy of the analog front signal will automatically
+ * be delivered to the S/PDIF outpput when the S/PDIF device
+ * is not being used for some other purpose.
+ */
+ corb_write (mixer, cad, wid, 0, SET_CONVERTER,
+ FRONT_STREAM << 4);
+ }
+ else
+ {
+ /* Select the iddle stream (0) for analog outputs */
+ corb_write (mixer, cad, wid, 0, SET_CONVERTER,
+ IDDLE_STREAM << 4);
+ }
+ /* Select 48 kHz/16 bits/stereo */
+ corb_write (mixer, cad, wid, 0, SET_CONVERTER_FORMAT, 0x0009);
+
+ }
+ break;
+
+ case NT_KNOB: /* Volume knob */
+ /* Clear the direct control bit */
+ corb_write (mixer, cad, wid, 0, SET_VOLUME_KNOB_CONTROL, 0x00);
+ break;
+
+ case NT_PIN: /* Pin complex */
+ {
+ unsigned int conf;
+ unsigned int pincaps;
+
+ if (!corb_read
+ (mixer, cad, wid, 0, GET_CONFIG_DEFAULT, 0, &conf, &b))
+ return 0;
+ if (!corb_read (mixer, cad, wid, 0,
+ GET_PARAMETER, HDA_PIN_CAPS, &pincaps, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_PIN_CAPS failed\n");
+ return 0;
+ }
+
+ widget->pincaps = pincaps;
+#if 0
+ if (widget->widget_caps & WCAP_UNSOL_CAPABLE)
+ corb_write (mixer, cad, wid, 0, SET_UNSOLICITED, 0x80 | wid);
+#endif
+
+ if (conf != 0)
+ {
+ int default_device = (conf >> 20) & 0x0f;
+ int default_loc = (conf >> 24) & 0x3f;
+ int conn = (conf >> 30) & 0x03;
+
+ int color;
+ int no_color=0;
+ char *name = NULL, *loc = "", *color_name = NULL;
+
+ color = (conf >> 12) & 0x0f;
+
+ if (pincaps & (1 << 6))
+ cmn_err (CE_WARN, "Balanced I/O not supported\n");
+ if (!(pincaps & (1 << 5))) /* No input */
+ widget->pin_type = PIN_OUT;
+ if (!(pincaps & (1 << 4)))
+ widget->pin_type = PIN_IN;
+
+ DDB (cmn_err (CE_CONT, "\tConfig default %08x\n", conf));
+
+ if ((default_loc & 0x0f) == 0x1) /* Rear panel - default */
+ loc = "";
+ if ((default_loc & 0x0f) == 0x2) /* Front panel */
+ loc = "fp-";
+ if ((default_loc & 0xf0) == 0x10) /* Internal func - eg cd/tad/spk */
+ loc = "int-";
+
+ if (conn == 1 && !(hdaudio_noskip & 1)) /* Pin not connected to anything */
+ {
+ widget->skip = 1;
+ widget->skip_output = 1;
+ }
+
+ switch (default_device)
+ {
+ case 0x0:
+ name = "lineout";
+ widget->pin_type = PIN_OUT;
+ break;
+ case 0x1:
+ name = "speaker";
+ no_color=1;
+ widget->pin_type = PIN_OUT;
+ break;
+ case 0x2:
+ name = "headphone";
+ widget->pin_type = PIN_OUT;
+ break;
+ case 0x3:
+ name = "cd";
+ no_color=1;
+ widget->pin_type = PIN_IN;
+ break;
+ case 0x4:
+ name = "spdifout";
+ no_color=1;
+ widget->pin_type = PIN_OUT;
+ break;
+ case 0x5:
+ name = "digout";
+ no_color=1;
+ widget->pin_type = PIN_OUT;
+ break;
+ case 0x6:
+ name = "modem";
+ no_color=1;
+ break;
+ case 0x7:
+ name = "phone";
+ no_color=1;
+ break;
+ case 0x8:
+ name = "linein";
+ widget->pin_type = PIN_IN;
+ break;
+ case 0x9:
+ name = "aux";
+ break;
+ case 0xa:
+ name = "mic";
+ widget->pin_type = PIN_MIC;
+ break;
+ case 0xb:
+ name = "telephony";
+ no_color=1;
+ break;
+ case 0xc:
+ name = "spdifin";
+ no_color=1;
+ break;
+ case 0xd:
+ name = "digin";
+ no_color=1;
+ break;
+ case 0xe:
+ name = "reserved";
+ no_color=1;
+ break;
+ case 0xf: /* Unused pin widget */
+ if (hdaudio_noskip & 2) break;
+ widget->skip = 1;
+ widget->skip_output = 1;
+ break;
+ }
+
+/* process only colored jacks and skip fixed function jacks */
+ switch (color)
+ {
+ case 0x1:
+ color_name = "black";
+ widget->rgbcolor = OSS_RGB_BLACK;
+ break;
+ case 0x2:
+ color_name = "gray";
+ widget->rgbcolor = OSS_RGB_GRAY;
+ break;
+ case 0x3:
+ color_name = "blue";
+ widget->rgbcolor = OSS_RGB_BLUE;
+ break;
+ case 0x4:
+ color_name = "green";
+ widget->rgbcolor = OSS_RGB_GREEN;
+ break;
+ case 0x5:
+ color_name = "red";
+ widget->rgbcolor = OSS_RGB_RED;
+ break;
+ case 0x6:
+ color_name = "orange";
+ widget->rgbcolor = OSS_RGB_ORANGE;
+ break;
+ case 0x7:
+ color_name = "yellow";
+ widget->rgbcolor = OSS_RGB_YELLOW;
+ break;
+ case 0x8:
+ color_name = "purple";
+ widget->rgbcolor = OSS_RGB_PURPLE;
+ break;
+ case 0x9:
+ color_name = "pink";
+ widget->rgbcolor = OSS_RGB_PINK;
+ break;
+ case 0xe:
+ color_name = "white";
+ widget->rgbcolor = OSS_RGB_WHITE;
+ break;
+
+ default:
+ if (name != NULL)
+ color_name = name;
+ else
+ color_name = "internal";
+ }
+
+ if (no_color)
+ widget->rgbcolor = 0;
+
+ if (default_device == 0xf) /* Not present */
+ {
+ widget->rgbcolor=0;
+ color_name = "internal";
+ }
+
+ sprintf (widget->color, "%s%s", loc, color_name);
+/*
+ * By Hannu 20080111
+ * Use jack color as the widget name if no name was defined or if the default
+ * function is lineout. This fixes the problem of several jacks being named
+ * as lineout.
+ */
+ if (name == NULL || default_device == 0x00)
+ name = color_name;
+ sprintf (widget->name, "%s%s", loc, name);
+ }
+ }
+ break;
+ }
+
+#if 0
+ if (!corb_read
+ (mixer, cad, wid, 0, GET_PARAMETER, HDA_NODE_COUNT, &node_count, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_NODE_COUNT1 failed\n");
+ return 0;
+ }
+
+ first_node = (node_count >> 16) & 0xff;
+ num_nodes = node_count & 0xff;
+
+ DDB (cmn_err
+ (CE_CONT, "\tFirst node %d, num nodes %d\n", first_node, num_nodes));
+
+ if (first_node > 0)
+ for (i = first_node; i < first_node + num_nodes; i++)
+ if (!attach_node (mixer, cad, i, wid))
+ return 0;
+#endif
+/*
+ * Handle hardcodded widget names
+ */
+
+ if (codec->remap != NULL)
+ {
+ int w;
+
+ mixer->remap_avail=1;
+
+ for (w = 0; codec->remap[w] != NULL; w++)
+ if (w == wid)
+ {
+ char *s = codec->remap[w];
+
+ if (*s != 0)
+ {
+ strcpy (widget->name, s);
+ if (*widget->color == 0)
+ {
+ strcpy (widget->color, widget->name);
+ }
+ }
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+attach_group (hdaudio_mixer_t * mixer, int cad, int wid, int parent, int group_type)
+{
+ unsigned int a, b, gt;
+ int i, first_node, num_nodes;
+ codec_t *codec = mixer->codecs[cad];
+
+ if (codec == &NULL_codec)
+ return 0;
+
+ if (!corb_read (mixer, cad, wid, 0,
+ GET_PARAMETER, HDA_OUTPUTAMP_CAPS,
+ &codec->default_outamp_caps, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_OUTPUTAMP_CAPS failed\n");
+ return 0;
+ }
+
+ if (!corb_read (mixer, cad, wid, 0,
+ GET_PARAMETER, HDA_INPUTAMP_CAPS,
+ &codec->default_inamp_caps, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_INPUTTAMP_CAPS failed\n");
+ return 0;
+ }
+
+ if (!corb_read (mixer, cad, wid, 0, GET_PARAMETER, HDA_NODE_COUNT, &a, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_NODE_COUNT2 failed\n");
+ return 0;
+ }
+
+ first_node = (a >> 16) & 0xff;
+ num_nodes = a & 0xff;
+
+ corb_read (mixer, cad, wid, 0, GET_PARAMETER, HDA_GROUP_TYPE, &gt, &b);
+ DDB (cmn_err (CE_CONT, "\tGroup %d First node %d, num nodes %d\n", wid,
+ first_node, num_nodes));
+/*
+ * Ignore other than audio function groups. Codecs probably allocate
+ * higher widget number for the modem group than the audio group. So in this
+ * way we can have smaller MAX_WIDGETS which in turn conserves memory.
+ */
+ if ((gt & 0xff) != group_type)
+ return 0;
+
+ if (corb_read (mixer, cad, wid, 0, GET_PARAMETER, HDA_PCM_SIZES, &a, &b))
+ {
+ codec->sizes = a;
+ }
+
+ if (first_node > 0)
+ for (i = first_node; i < first_node + num_nodes; i++)
+ if (!attach_node (mixer, cad, i, wid))
+ return 0;
+
+ if (num_nodes >= 1)
+ codec->active=1;
+ return 1;
+}
+
+static void
+polish_widget_list (hdaudio_mixer_t * mixer, int cad)
+{
+ widget_t *widget;
+ codec_t *codec;
+ int wid, conn, loop;
+ int skip = 0;
+ int do_jacksense = 0;
+
+ if (hdaudio_noskip & 4) return;
+
+ if (mixer->codecs[cad] == &NULL_codec)
+ {
+ cmn_err (CE_WARN, "Bad codec %d\n", cad);
+ }
+ codec = mixer->codecs[cad];
+
+ for (wid = 0; wid < codec->nwidgets; wid++)
+ {
+ widget = &codec->widgets[wid];
+ }
+
+/*
+ * Use jack sensing information to remove unconnected I/O pints from the mixer
+ * interface.
+ */
+
+ do_jacksense = 1;
+ if (codec->num_jacks_plugged < 1 || hdaudio_jacksense < 1)
+ do_jacksense = 0;
+
+ if (do_jacksense)
+ for (wid = 0; wid < codec->nwidgets; wid++)
+ {
+ widget = &codec->widgets[wid];
+
+ if (widget->wid_type != NT_PIN) /* Not a pin widget */
+ continue;
+
+ if (!widget->plugged_in)
+ widget->skip = 1;
+ }
+
+ /*
+ * Check all widgets and mark them unusable (skip=1) if all of their input
+ * connections are marked to be skipped.
+ *
+ * This needs to be done number of times so that the skip status propagates
+ * to the end of the longest path.
+ */
+
+ for (loop = 0; loop < codec->nwidgets / 4; loop++) /* nwidgets/4 iterations */
+ for (wid = 0; wid < codec->nwidgets; wid++)
+ {
+ widget = &codec->widgets[wid];
+
+ if (widget->skip || widget->used)
+ continue;
+
+ skip = 1; /* For now */
+ for (conn = 0; conn < widget->nconn; conn++)
+ {
+ if (!codec->widgets[widget->connections[conn]].skip)
+ skip = 0; /* Cannot be skipped */
+ }
+
+ if (skip && widget->nconn > 0)
+ {
+ widget->skip = 1;
+ widget->used = 1;
+ }
+ }
+
+/*
+ * Do the same backwards. Remove widgets that don't have connectivity to any
+ * of the pin widgets.
+ */
+ for (loop = 0; loop < codec->nwidgets / 4; loop++) /* nwidgets/4 iterations */
+ for (wid = 0; wid < codec->nwidgets; wid++)
+ {
+ widget = &codec->widgets[wid];
+
+ if (widget->skip_output || widget->used)
+ continue;
+
+ skip = 1; /* For now */
+ for (conn = 0; conn < widget->refcount; conn++)
+ {
+ if (!codec->widgets[widget->references[conn]].skip_output)
+ skip = 0; /* Cannot be skipped */
+ }
+
+ if (skip && widget->refcount > 0)
+ {
+ widget->skip_output = 1;
+ widget->used = 1;
+ }
+ }
+
+/*
+ * Final pass.
+ */
+
+ for (wid = 0; wid < codec->nwidgets; wid++)
+ {
+ widget = &codec->widgets[wid];
+
+ if (widget->skip_output)
+ {
+ widget->skip = 1;
+ }
+ }
+}
+
+
+/* ARGSUSED */
+static int
+attach_codec (hdaudio_mixer_t * mixer, int cad, char *hw_info,
+ unsigned int pci_subdevice, int group_type)
+{
+ unsigned int a, b, x;
+ int subix, ix, i;
+ int first_node, num_nodes;
+ int has_audio_group = 0;
+ codec_t *codec;
+
+ if (cad >= MAX_CODECS)
+ {
+ cmn_err (CE_WARN, "attach_codec: Too many codecs %d\n", cad);
+ return OSS_EIO;
+ }
+
+ mixer->ncodecs = cad + 1;
+
+ if (mixer->codecs[cad] == &NULL_codec)
+ {
+ if ((codec = PMALLOC (mixer->osdev, sizeof (*codec))) == NULL)
+ {
+ cmn_err (CE_CONT, "Cannot allocate codec descriptor\n");
+ return OSS_ENOMEM;
+ }
+
+ memset (codec, 0, sizeof (*codec));
+
+ mixer->codecs[cad] = codec;
+ }
+ else
+ {
+ codec = mixer->codecs[cad];
+ }
+
+ corb_write (mixer, cad, 0, 0, SET_POWER_STATE, 0); /* Power up everything */
+
+ if (!corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_VENDOR, &a, &b))
+ {
+ if (group_type == 1)
+ {
+ sprintf (hw_info, " Codec %2d: Not present\n", cad);
+ cmn_err (CE_NOTE,
+ "attach_codec: Codec #%d is not physically present\n",
+ cad);
+ }
+ return OSS_EIO;
+ }
+ codec->vendor_id = a;
+
+/*
+ * Find out the primary group list
+ */
+
+ if (!corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_NODE_COUNT, &x, &b))
+ {
+ cmn_err (CE_WARN, "GET_PARAMETER HDA_NODE_COUNT3 failed\n");
+ return OSS_EIO;
+ }
+
+ codec->first_node = first_node = (x >> 16) & 0xff;
+ num_nodes = x & 0xff;
+
+/*
+ * Check if this one is an audio codec (has an audio function group)
+ */
+ for (i = first_node; i < first_node + num_nodes; i++)
+ {
+ unsigned int gt;
+
+ corb_read (mixer, cad, i, 0, GET_PARAMETER, HDA_GROUP_TYPE, &gt, &b);
+/*
+ * Handle only the function group type requested by the upper layer code.
+ */
+ if ((gt & 0xff) != 1)
+ continue;
+
+ has_audio_group = 1;
+ }
+
+/*
+ * Find codec specific settings
+ */
+ for (ix = 0; codecs[ix].id != 0; ix++)
+ if (codecs[ix].id == a)
+ break;
+
+ DDB (cmn_err
+ (CE_CONT, "HD audio Codec ID: %08x (%s)\n", a, codecs[ix].name));
+
+ if (codecs[ix].id == 0) /* Unknown codec */
+ {
+ if (group_type == 1)
+ sprintf (hw_info, " Codec %2d: Unknown (0x%08x", cad, a);
+ cmn_err (CE_NOTE, "HDA codec 0x%08x not known yet\n", a);
+ /*
+ * Create hexadecimal codec ID
+ */
+ if (has_audio_group && mixer->chip_name == NULL)
+ if ((mixer->chip_name = PMALLOC (mixer->osdev, 32)) != NULL)
+ {
+ sprintf (mixer->chip_name, "0x%08x", a);
+ }
+ }
+ else
+ {
+ if (group_type == 1)
+ sprintf (hw_info, " Codec %2d: %s (0x%08x", cad, codecs[ix].name, a);
+ }
+
+ if (has_audio_group && mixer->chip_name == NULL)
+ {
+ mixer->chip_name = codecs[ix].name;
+
+ }
+
+ if (codecs[ix].remap != NULL)
+ codec->remap = codecs[ix].remap;
+
+ if (codecs[ix].flags != 0)
+ codec->vendor_flags = codecs[ix].flags;
+
+ if (codecs[ix].mixer_init != NULL)
+ codec->mixer_init = codecs[ix].mixer_init;
+
+ codec->multich_map = codecs[ix].multich_map;
+
+ if (corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_REVISION, &a, &b))
+ {
+ DDB (cmn_err (CE_CONT, "HDA codec revision %d.%d (%d.%d) (0x%08x)\n",
+ (a >> 20) & 0xf,
+ (a >> 16) & 0xf, (a >> 8) & 0xff, a & 0xff, a));
+ }
+ else
+ DDB (cmn_err (CE_CONT, "Can't get codec revision\n"));
+
+ codec->codec_desc = &codecs[ix];
+
+ DDB (cmn_err (CE_CONT, "**** Codec %d ****\n", cad));
+ DDB (cmn_err
+ (CE_CONT, "First node %d, num nodes %d\n", first_node, num_nodes));
+
+ for (i = first_node; i < first_node + num_nodes; i++)
+ {
+ corb_read (mixer, cad, i, 0, GET_PARAMETER, HDA_GROUP_TYPE, &a, &b);
+ if ((a & 0xff) == group_type) /* Proper function group type */
+ {
+ codec->afg = i;
+
+ if (corb_read (mixer, cad, i, 0, GET_SUBSYSTEM_ID, 0, &a, &b))
+ {
+ DDB (cmn_err (CE_CONT, "Subsystem ID = 0x%08x\n", a));
+
+ if (group_type == 1)
+ {
+ /* Append subvendor ID to hw_info */
+ hw_info += strlen (hw_info);
+ sprintf (hw_info, "/0x%08x", a);
+ }
+
+ codec->subvendor_id = a;
+
+ for (subix = 0; subdevices[subix].id != 0; subix++)
+ if (subdevices[subix].id == a)
+ {
+ if (subdevices[subix].main_id != 0)
+ if (subdevices[subix].main_id != codec->vendor_id)
+ continue;
+
+ if (subdevices[subix].pci_subdevice != 0)
+ if (subdevices[subix].pci_subdevice != pci_subdevice)
+ continue;
+
+
+ DDB (cmn_err
+ (CE_CONT, "Subdevice known as %s\n",
+ subdevices[subix].name));
+ if (group_type == 1)
+ {
+ hw_info += strlen (hw_info);
+ sprintf (hw_info, " %s", subdevices[subix].name);
+ }
+ if (subdevices[subix].remap != NULL)
+ {
+ codec->remap = subdevices[subix].remap;
+ }
+
+ if (subdevices[subix].multich_map != 0)
+ codec->multich_map = subdevices[subix].multich_map;
+ if (subdevices[subix].flags != 0)
+ codec->vendor_flags = subdevices[subix].flags;
+ if (subdevices[subix].mixer_init != NULL)
+ {
+ codec->mixer_init = subdevices[subix].mixer_init;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ hw_info += strlen (hw_info);
+ if (group_type == 1)
+ strcpy (hw_info, ")\n");
+
+ if (codec->multich_map == 0)
+ {
+ codec->multich_map = 0x76543210; /* Sequential order */
+ }
+
+ for (i = first_node; i < first_node + num_nodes; i++)
+ {
+ if (!attach_group (mixer, cad, i, 0, group_type))
+ continue;
+
+ /* power up the AFG! */
+ corb_write (mixer, cad, i, 0, SET_POWER_STATE, 0);
+ }
+
+ /* Initialize and setup manually endpoints for Si3055. */
+ if ((mixer->codecs[cad]->vendor_flags & VF_SI3055_HACK) && (group_type == 2))
+ {
+ hdaudio_si3055_endpoint_init(mixer, cad);
+ }
+
+ if (has_audio_group)
+ {
+ polish_widget_list (mixer, cad);
+ }
+
+ copy_endpoints(mixer, codec, 0); /* Copy analog endpoints from codec to mixer */
+
+ return (has_audio_group) ? 0 : OSS_EIO;
+}
+
+int
+hdaudio_mixer_get_mixdev (hdaudio_mixer_t * mixer)
+{
+ return mixer->mixer_dev;
+}
+
+void
+hdaudio_mixer_set_initfunc (hdaudio_mixer_t * mixer,
+ mixer_create_controls_t func)
+{
+ mixer->client_mixer_init = func;
+}
+
+#define BASE44k (1<<14)
+
+static const struct hdaudio_rate_def _hdaudio_rates[] = {
+ /* 48 kHz based rates */
+ {192000, (3 << 11)}, /* 4x */
+ {96000, (1 << 11)}, /* 2x */
+ {48000, 0}, /* 1x */
+ {24000, (1 << 8)}, /* 1/2x */
+ {16000, (2 << 8)}, /* 1/3x */
+ {12000, (3 << 8)}, /* 1/4x */
+ {9600, (4 << 8)}, /* 1/5x */
+ {8000, (5 << 8)}, /* 1/6x */
+ /* TODO: These rates didn't work for some reason. */
+ /* 44.1 kHz based rates */
+ {176400, BASE44k | (3 << 11)}, /* 4x */
+ {88200, BASE44k | (1 << 11)}, /* 2x */
+ {44100, BASE44k}, /* 1x */
+ {22050, BASE44k | (1 << 8)}, /* 1/2x */
+ {14700, BASE44k | (2 << 8)}, /* 1/3x */
+ {11025, BASE44k | (3 << 8)}, /* 1/4x */
+ {8820, BASE44k | (4 << 8)}, /* 1/5x */
+ {7350, BASE44k | (5 << 8)}, /* 1/6x */
+ {0}
+};
+
+const struct hdaudio_rate_def *hdaudio_rates = _hdaudio_rates;
+
+int
+hdaudio_codec_setup_endpoint (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t * endpoint,
+ int rate, int channels, int fmt,
+ int stream_number, unsigned int *setupbits)
+{
+
+ unsigned int tmp, spdif, dummy;
+ int i;
+
+ endpoint->auto_muted = 0;
+
+ if (!corb_read
+ (mixer, endpoint->cad, endpoint->base_wid, 0, GET_SPDIF_CONTROL, 0,
+ &spdif, &dummy))
+ spdif = 0;
+
+ spdif &= ~(1 << 5); /* Audio */
+
+ tmp = 0;
+
+ if (fmt == AFMT_AC3)
+ channels = 2;
+
+ tmp |= channels - 1;
+
+ switch (fmt)
+ {
+ case AFMT_U8:
+ break;
+
+ case AFMT_S16_LE:
+ tmp |= 0x00000010;
+ break;
+
+ case AFMT_S32_LE:
+ if (endpoint->sizemask & (1 << 20)) /* 32 bits */
+ tmp |= 0x00000040;
+ else if (endpoint->sizemask & (1 << 19)) /* 24 bits */
+ tmp |= 0x00000030;
+ else if (endpoint->sizemask & (1 << 18)) /* 20 bits */
+ tmp |= 0x00000020;
+ else
+ {
+ cmn_err (CE_WARN, "Bad bit size\n");
+ return OSS_EIO;
+ }
+ break;
+
+ case AFMT_AC3:
+ tmp &= 0xff;
+ tmp |= 0x11; /* 16 bits stereo */
+ spdif |= (1 << 5); /* Data */
+ break;
+
+ case AFMT_SPDIF_RAW:
+ tmp &= 0xff;
+ tmp |= 0x81; /* 32 bits stereo */
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Bad format %x\n", fmt);
+ return OSS_EIO;
+ }
+
+ corb_write (mixer, endpoint->cad, endpoint->base_wid, 0, SET_SPDIF_CONTROL1,
+ spdif & 0xff);
+/*
+ * Finally the sample rate setup
+ */
+
+ for (i = 0; hdaudio_rates[i].rate != 0; i++)
+ if (hdaudio_rates[i].rate == rate)
+ {
+ tmp |= hdaudio_rates[i].mask;
+ break;
+ }
+
+ *setupbits = tmp;
+
+ if (mixer->codecs[endpoint->cad]->vendor_flags & VF_SI3055_HACK)
+ {
+ hdaudio_si3055_set_rate(mixer, endpoint->cad, rate);
+ }
+
+ corb_write (mixer, endpoint->cad, endpoint->base_wid, 0,
+ SET_CONVERTER_FORMAT, tmp);
+ corb_write (mixer, endpoint->cad, endpoint->base_wid, 0, SET_CONVERTER,
+ stream_number << 4);
+
+ if (channels > 2)
+ {
+ /*
+ * Set up the converters for the other stereo pairs
+ */
+#if 1
+ // TODO: Test this
+
+ int n = (channels + 1) / 2;
+
+ for (i = 1; i < n; i++)
+ {
+ hdaudio_endpointinfo_t *ep;
+ ep = &endpoint[i];
+
+ corb_write (mixer, ep->cad, ep->base_wid, 0, SET_CONVERTER_FORMAT,
+ tmp);
+ corb_write (mixer, ep->cad, ep->base_wid, 0, SET_CONVERTER,
+ (stream_number << 4) | (i * 2));
+ }
+#endif
+ }
+
+ if (mixer->codecs[endpoint->cad]->vendor_flags & VF_VAIO_HACK)
+ {
+ /*
+ * STAC9872 specific hack. In Sony VAIO configurations, the DAC widget
+ * used for the headphone jack needs to duplicate the stream playing on
+ * the DAC widget for the speaker when not in multichannel mode.
+ */
+ if (channels <= 2 && endpoint->base_wid == 0x05)
+ {
+ corb_write (mixer, endpoint->cad, 0x02, 0, SET_CONVERTER_FORMAT,
+ tmp);
+ corb_write (mixer, endpoint->cad, 0x02, 0, SET_CONVERTER,
+ stream_number << 4);
+ }
+ }
+
+#if 1
+ if (mixer->codecs[endpoint->cad]->vendor_flags & VF_ALC88X_HACK)
+ {
+ /*
+ * ALC88x specfic hack. These codecs cannot play S/PDIF unless the front
+ * DAC widget is playing the same stream.
+ *
+ * Analog front output (widget 0x14) will be automatically muted.
+ */
+ if (endpoint->is_digital)
+ {
+ unsigned int v, b;
+
+ hdaudio_codec_setup_endpoint (mixer, &mixer->outendpoints[0], rate,
+ channels, fmt, stream_number, &tmp);
+
+ if (fmt == AFMT_AC3)
+ if (corb_read
+ (mixer, endpoint->cad, 0x14, 0, GET_GAIN (1, 0), 0, &v, &b))
+ {
+ endpoint->auto_muted = !(v & 0x80);
+
+ v |= 0x80; /* Mute */
+ corb_write (mixer, endpoint->cad, 0x14, 0,
+ SET_GAIN (1, 0, 1, 1, 0), v);
+ }
+ }
+ }
+#endif
+
+ return 0;
+}
+
+int
+hdaudio_codec_reset_endpoint (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t * endpoint, int channels)
+{
+
+ int i;
+ unsigned int v, b;
+ int n = (channels + 1) / 2;
+
+ /*
+ * Set all converters to play stream iddle stream (usually 0=silence).
+ */
+
+ corb_write (mixer, endpoint->cad, endpoint->base_wid, 0, SET_CONVERTER,
+ endpoint->iddle_stream << 4);
+
+#if 1
+ // TODO: Test this
+ if (channels > 2)
+ for (i = 1; i < n; i++)
+ {
+ hdaudio_endpointinfo_t *ep;
+
+ ep = &endpoint[i];
+
+ corb_write (mixer, ep->cad, ep->base_wid, 0, SET_CONVERTER,
+ ep->iddle_stream << 4);
+ }
+#endif
+
+ if (mixer->codecs[endpoint->cad]->vendor_flags & VF_VAIO_HACK)
+ /* Also set headphone DAC to play the iddle stream */
+ if (channels <= 2 && endpoint->base_wid == 0x05)
+ {
+ corb_write (mixer, endpoint->cad, 0x02, 0, SET_CONVERTER,
+ endpoint->iddle_stream << 4);
+ }
+
+ if (mixer->codecs[endpoint->cad]->vendor_flags & VF_ALC88X_HACK)
+ if (endpoint->is_digital && endpoint->auto_muted) /* Restore automatic analog mute back to normal */
+ {
+ if (corb_read
+ (mixer, endpoint->cad, 0x14, 0, GET_GAIN (1, 0), 0, &v, &b))
+ {
+ v &= ~0x80; /* Unmute */
+ corb_write (mixer, endpoint->cad, 0x14, 0,
+ SET_GAIN (1, 0, 1, 1, 0), v);
+ endpoint->auto_muted = 0;
+ }
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+void
+hda_codec_unsol (hdaudio_mixer_t * mixer, unsigned int upper,
+ unsigned int lower)
+{
+ DDB (cmn_err (CE_CONT, "Unsol event %08x %08x\n", upper, lower));
+}
+
+int
+hda_codec_getname (hdaudio_mixer_t * mixer, hda_name_t * name)
+{
+ widget_t *widget;
+
+ if (name->cad >= mixer->ncodecs)
+ return OSS_EIO;
+ if (mixer->codecs[name->cad] == &NULL_codec)
+ return OSS_EIO;
+#if 1
+ if (name->wid >= mixer->codecs[name->cad]->nwidgets)
+ return OSS_EIO;
+#endif
+
+ widget = &mixer->codecs[name->cad]->widgets[name->wid];
+ strcpy (name->name, widget->name);
+
+ return 0;
+}
+
+int
+hda_codec_getwidget (hdaudio_mixer_t * mixer, hda_widget_info_t * info)
+{
+ widget_t *widget;
+
+ if (info->cad >= mixer->ncodecs)
+ return OSS_EIO;
+ if (mixer->codecs[info->cad] == &NULL_codec)
+ return OSS_EIO;
+
+ widget = &mixer->codecs[info->cad]->widgets[info->wid];
+ if (info->wid >= mixer->codecs[info->cad]->nwidgets)
+ return OSS_EIO;
+ if (widget == NULL)
+ return OSS_EIO;
+ memcpy (info->info, widget, sizeof (*widget));
+
+ return 0;
+}
+
+int
+hdaudio_codec_audio_ioctl (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t * endpoint,
+ unsigned int cmd, ioctl_arg arg)
+{
+ //widget_t *base_widget = &mixer->codecs[endpoint->cad]->widgets[endpoint->base_wid];
+ widget_t *recsrc_widget =
+ &mixer->codecs[endpoint->cad]->widgets[endpoint->recsrc_wid];
+ widget_t *volume_widget =
+ &mixer->codecs[endpoint->cad]->widgets[endpoint->volume_wid];
+ char tmp[128], *t;
+ unsigned int linked_wid, a, b;
+ int i, v, left, right;
+ int nsteps;
+
+ if (mixer->codecs[endpoint->cad]->vendor_flags & VF_VAIO_HACK)
+ linked_wid = (endpoint->volume_wid == 0x02) ? 0x05 :
+ ((endpoint->volume_wid == 0x05) ? 0x02 : 0);
+ else
+ linked_wid = 0;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_GET_RECSRC_NAMES:
+ *tmp = 0;
+ t = tmp;
+
+ for (i = 0; i < recsrc_widget->nconn; i++)
+ {
+ if (*tmp) /* Not empty */
+ *t++ = ' ';
+ strcpy (t,
+ mixer->codecs[recsrc_widget->cad]->widgets[recsrc_widget->
+ connections[i]].
+ name);
+ t += strlen (t);
+ }
+ return oss_encode_enum ((oss_mixer_enuminfo *) arg, tmp, 0);
+ break;
+
+ case SNDCTL_DSP_GET_RECSRC:
+ if (!corb_read
+ (mixer, recsrc_widget->cad, recsrc_widget->wid, 0, GET_SELECTOR, 0,
+ &a, &b))
+ return OSS_EIO;
+ return *arg = a;
+ break;
+
+ case SNDCTL_DSP_SET_RECSRC:
+ a = *arg;
+ if (a > recsrc_widget->nconn)
+ return OSS_EIO;
+
+ corb_write (mixer, recsrc_widget->cad, recsrc_widget->wid, 0,
+ SET_SELECTOR, a);
+ recsrc_widget->current_selector = a;
+ mixer_devs[mixer->mixer_dev]->modify_counter++;
+ return *arg = a;
+ break;
+
+ case SNDCTL_DSP_GETRECVOL:
+ nsteps = (volume_widget->inamp_caps >> 8) & 0x3f;
+ if (nsteps < 1)
+ nsteps = 1;
+ if (!corb_read
+ (mixer, volume_widget->cad, volume_widget->wid, 0, GET_GAIN (0, 1),
+ 0, &a, &b))
+ return OSS_EIO;
+ if (a & 0x80) /* Muted */
+ left = 0;
+ else
+ left = ((a & 0x7f) * 100) / nsteps;
+ if (!corb_read
+ (mixer, volume_widget->cad, volume_widget->wid, 0, GET_GAIN (0, 0),
+ 0, &a, &b))
+ return OSS_EIO;
+ if (a & 0x80) /* Muted */
+ right = 0;
+ else
+ right = ((a & 0x7f) * 100) / nsteps;
+ v = left | (right << 8);
+ return *arg = v;
+ break;
+
+ case SNDCTL_DSP_SETRECVOL:
+ v = *arg;
+
+ left = v & 0xff;
+ right = (v >> 8) & 0xff;
+
+ if (left < 0)
+ left = 0;
+ if (left > 100)
+ left = 100;
+ if (right < 0)
+ right = 0;
+ if (right > 100)
+ right = 100;
+ v = left | (right << 8);
+
+ nsteps = (volume_widget->inamp_caps >> 8) & 0x3f;
+ if (nsteps < 1)
+ nsteps = 1;
+
+ a = (left * nsteps) / 100;
+ if (left == 0)
+ a |= 0x80; /* Mute */
+ corb_write (mixer, volume_widget->cad, volume_widget->wid, 0,
+ SET_GAIN (0, 1, 1, 0, 0), a);
+ a = (right * nsteps) / 100;
+ if (right == 0)
+ a |= 0x80; /* Mute */
+ corb_write (mixer, volume_widget->cad, volume_widget->wid, 0,
+ SET_GAIN (0, 1, 0, 1, 0), a);
+
+ mixer_devs[mixer->mixer_dev]->modify_counter++;
+ return *arg = v;
+ break;
+
+ case SNDCTL_DSP_GETPLAYVOL:
+ nsteps = (volume_widget->outamp_caps >> 8) & 0x3f;
+ if (nsteps < 1)
+ nsteps = 1;
+ if (!corb_read
+ (mixer, volume_widget->cad, volume_widget->wid, 0, GET_GAIN (1, 1),
+ 0, &a, &b))
+ return OSS_EIO;
+ if (a & 0x80) /* Muted */
+ left = 0;
+ else
+ left = ((a & 0x7f) * 100) / nsteps;
+ if (!corb_read
+ (mixer, volume_widget->cad, volume_widget->wid, 0, GET_GAIN (1, 0),
+ 0, &a, &b))
+ return OSS_EIO;
+ if (a & 0x80) /* Muted */
+ right = 0;
+ else
+ right = ((a & 0x7f) * 100) / nsteps;
+ v = left | (right << 8);
+ return *arg = v;
+ break;
+
+ case SNDCTL_DSP_SETPLAYVOL:
+ v = *arg;
+
+ left = v & 0xff;
+ right = (v >> 8) & 0xff;
+
+ if (left < 0)
+ left = 0;
+ if (left > 100)
+ left = 100;
+ if (right < 0)
+ right = 0;
+ if (right > 100)
+ right = 100;
+ v = left | (right << 8);
+
+ nsteps = (volume_widget->outamp_caps >> 8) & 0x3f;
+ if (nsteps < 1)
+ nsteps = 1;
+
+ a = (left * nsteps) / 100;
+ if (left == 0)
+ a |= 0x80; /* Mute */
+ corb_write (mixer, volume_widget->cad, volume_widget->wid, 0,
+ SET_GAIN (1, 0, 1, 0, 0), a);
+ if (linked_wid)
+ corb_write (mixer, volume_widget->cad, linked_wid, 0,
+ SET_GAIN (1, 0, 1, 0, 0), a);
+ a = (right * nsteps) / 100;
+ if (right == 0)
+ a |= 0x80; /* Mute */
+ corb_write (mixer, volume_widget->cad, volume_widget->wid, 0,
+ SET_GAIN (1, 0, 0, 1, 1), a);
+ if (linked_wid)
+ corb_write (mixer, volume_widget->cad, linked_wid, 0,
+ SET_GAIN (1, 0, 0, 1, 1), a);
+
+ mixer_devs[mixer->mixer_dev]->modify_counter++;
+ return *arg = v;
+ break;
+
+ case SNDCTL_DSP_MODEM_OFFHOOK:
+ if (!endpoint->is_modem)
+ {
+ return OSS_EINVAL;
+ }
+ v = *arg;
+ if (mixer->codecs[endpoint->cad]->vendor_flags & VF_SI3055_HACK)
+ {
+ v = hdaudio_si3055_set_offhook(mixer, endpoint->cad, v);
+ }
+ else
+ {
+ return OSS_ENOTSUP;
+ }
+ return *arg = v;
+ break;
+ }
+
+ return OSS_EINVAL;
+}
+
+/*
+ * Support routines for dedicated mixer drivers
+ */
+
+void
+hda_codec_add_group (int dev, hdaudio_mixer_t * mixer, int cad, int *group,
+ int parent_group, const char *name)
+{
+ int grp;
+
+ if ((grp = mixer_ext_create_group (dev, parent_group, name)) > 0)
+ *group = grp;
+}
+
+int
+hda_codec_add_pingroup (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int *group, int top_group, int *parent_group,
+ const char *name, int *n, const char *parent_name,
+ int group_size)
+{
+ int grp;
+ widget_t *widget;
+ codec_t *codec;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+ if (widget->used || widget->skip)
+ return 0;
+
+ if (group_size <= 1 || ((*n % group_size) == 0 && *n > 0))
+ {
+ if ((grp = mixer_ext_create_group (dev, top_group, parent_name)) > 0)
+ *parent_group = grp;
+ *n = 0;
+ }
+
+ if ((grp = mixer_ext_create_group (dev, *parent_group, name)) > 0)
+ *group = grp;
+ (*n)++;
+
+ return 1;
+}
+
+int
+hda_codec_add_adcgroup (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int *group, int top_group, int *parent_group,
+ const char *name, int *n, const char *parent_name,
+ int group_size)
+{
+ int grp;
+ widget_t *widget;
+ codec_t *codec;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+ if (widget->used || widget->skip)
+ return 0;
+
+ if (group_size <= 1 || ((*n % group_size) == 0 && *n > 0))
+ {
+ if ((grp = mixer_ext_create_group (dev, top_group, parent_name)) > 0)
+ *parent_group = grp;
+ *n = 0;
+ }
+
+ if ((grp = mixer_ext_create_group (dev, *parent_group, name)) > 0)
+ *group = grp;
+ (*n)++;
+
+ return 1;
+}
+
+int
+hda_codec_add_miscgroup (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int *group, int top_group, int *parent_group,
+ const char *name, int *n, const char *parent_name,
+ int group_size)
+{
+ int grp;
+ widget_t *widget;
+ codec_t *codec;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+ if (widget->used || widget->skip)
+ return 0;
+
+ if (group_size <= 1 || ((*n % group_size) == 0 && *n > 0))
+ {
+ if ((grp = mixer_ext_create_group (dev, top_group, parent_name)) > 0)
+ *parent_group = grp;
+ *n = 0;
+ }
+
+ if ((grp = mixer_ext_create_group (dev, *parent_group, name)) > 0)
+ *group = grp;
+ (*n)++;
+
+ return 1;
+}
+
+int
+create_outgain_selector (hdaudio_mixer_t * mixer, widget_t * widget,
+ int group, const char *name)
+{
+ int num = MIXNUM (widget, CT_OUTGAINSEL, 0);
+ int ctl, i;
+ int maxval;
+ int offs, step, range;
+ oss_mixext *ent;
+
+ char tmp[128], *t;
+
+ range =
+ ((widget->outamp_caps >> AMPCAP_NUMSTEPS_SHIFT) & AMPCAP_NUMSTEPS_MASK) +
+ 1;
+ step =
+ ((widget->outamp_caps >> AMPCAP_STEPSIZE_SHIFT) & AMPCAP_STEPSIZE_MASK) +
+ 1;
+ offs = (widget->outamp_caps >> AMPCAP_OFFSET_SHIFT) & AMPCAP_OFFSET_MASK;
+
+ maxval = range;
+
+ if (widget->outamp_caps & AMPCAP_MUTE)
+ maxval += 1;
+
+ if ((ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ num, hdaudio_set_control,
+ MIXT_ENUM,
+ name, maxval,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ t = tmp;
+ *t = 0;
+
+ for (i = 0; i < range; i++)
+ {
+ int v;
+
+ v = (i - offs) * step * 4;
+
+ if (*tmp != 0)
+ *t++ = ' ';
+
+ sprintf (t, "%d.%ddB", v / 10, v % 10);
+ t += strlen (t);
+ }
+
+ if (widget->outamp_caps & AMPCAP_MUTE)
+ {
+ if (*tmp != 0)
+ *t++ = ' ';
+ strcpy (t, "mute");
+ t += strlen (t);
+ }
+
+ mixer_ext_set_strings (mixer->mixer_dev, ctl, tmp, 0);
+ /* Copy RGB color */
+ if (widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (mixer->mixer_dev, ctl)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+
+ return 0;
+}
+
+int
+create_ingain_selector (hdaudio_mixer_t * mixer, codec_t * codec,
+ widget_t * widget, int group, int ix,
+ const char *name)
+{
+ int num = MIXNUM (widget, CT_INGAINSEL, ix);
+
+ int ctl, i;
+ int maxval;
+ int offs, step, range;
+ oss_mixext *ent;
+
+ char tmp[128], *t;
+
+ range =
+ ((widget->inamp_caps >> AMPCAP_NUMSTEPS_SHIFT) & AMPCAP_NUMSTEPS_MASK) +
+ 1;
+ step =
+ ((widget->inamp_caps >> AMPCAP_STEPSIZE_SHIFT) & AMPCAP_STEPSIZE_MASK) +
+ 1;
+ offs = (widget->inamp_caps >> AMPCAP_OFFSET_SHIFT) & AMPCAP_OFFSET_MASK;
+
+ maxval = range;
+
+ if (widget->inamp_caps & AMPCAP_MUTE)
+ maxval += 1;
+
+ if ((ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ num, hdaudio_set_control,
+ MIXT_ENUM,
+ name, maxval,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ t = tmp;
+ *t = 0;
+
+ for (i = 0; i < range; i++)
+ {
+ int v;
+
+ v = (i - offs) * step * 4;
+
+ if (*tmp != 0)
+ *t++ = ' ';
+
+ sprintf (t, "%d.%ddB", v / 10, v % 10);
+ t += strlen (t);
+ }
+
+ if (widget->inamp_caps & AMPCAP_MUTE)
+ {
+ if (*tmp != 0)
+ *t++ = ' ';
+ strcpy (t, "mute");
+ t += strlen (t);
+ }
+
+ mixer_ext_set_strings (mixer->mixer_dev, ctl, tmp, 0);
+ /* Copy RGB color */
+ if (widget->color != 0)
+ if ((ent = mixer_find_ext (mixer->mixer_dev, ctl)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+ return 0;
+}
+
+int
+hda_codec_add_outamp (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int group, const char *name, int percent,
+ unsigned int flags)
+{
+ widget_t *widget;
+ codec_t *codec;
+ int typ, num, maxval, val, ctl = 0;
+ int range, step;
+ oss_mixext *ent;
+ extern int mixer_muted;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+
+ range =
+ ((widget->
+ outamp_caps >> AMPCAP_NUMSTEPS_SHIFT) & AMPCAP_NUMSTEPS_MASK) + 1;
+ step =
+ ((widget->
+ outamp_caps >> AMPCAP_STEPSIZE_SHIFT) & AMPCAP_STEPSIZE_MASK) + 1;
+
+ if (step > 20 /* 5dB */ && range < 5)
+ {
+ create_outgain_selector (mixer, widget, group, name);
+ }
+ else
+ {
+
+ maxval = hdaudio_amp_maxval (widget->outamp_caps);
+
+ if (widget->widget_caps & WCAP_STEREO)
+ {
+ typ = MIXT_STEREOSLIDER16;
+ num = MIXNUM (widget, CT_OUTSTEREO, 0);
+ }
+ else
+ {
+ typ = MIXT_MONOSLIDER16;
+ num = MIXNUM (widget, CT_OUTMONO, 0);
+ }
+
+ if ((ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ num, hdaudio_set_control,
+ typ,
+ name, maxval,
+ flags | MIXF_READABLE |
+ MIXF_WRITEABLE |
+ MIXF_CENTIBEL)) < 0)
+ return ctl;
+
+ /* setup volume */
+ val = (maxval * percent) / 100;
+ val = val | (val << 16);
+ if (mixer_muted)
+ val = 0;
+ /* Copy RGB color */
+ if (widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (dev, ctl)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+ hdaudio_set_control (mixer->mixer_dev, num, SNDCTL_MIX_WRITE, val);
+ }
+
+ return ctl;
+}
+
+int
+hda_codec_add_outmute (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int group, const char *name, int muted)
+{
+ widget_t *widget;
+ codec_t *codec;
+ int ctl = 0;
+ oss_mixext *ent;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+
+ if (widget->outamp_caps & AMPCAP_MUTE) /* Only mute control */
+ {
+ // name = "mute";
+
+ if ((ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ MIXNUM (widget,
+ CT_OUTMUTE, 0),
+ hdaudio_set_control,
+ MIXT_MUTE, name, 2,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return ctl;
+ /* Copy RGB color */
+ if (widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (dev, ctl)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+
+ hdaudio_set_control (mixer->mixer_dev,
+ MIXNUM (widget, CT_OUTMUTE, 0),
+ SNDCTL_MIX_WRITE, muted);
+ return ctl;
+ }
+ return 0;
+}
+
+int
+hda_codec_add_inamp (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int ix, int group, const char *name, int percent, int flags)
+{
+ widget_t *widget;
+ widget_t *src_widget;
+ codec_t *codec;
+ int typ, num, maxval, val, ctl = 0, range, step;
+ oss_mixext *ent;
+ extern int mixer_muted;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+
+ range =
+ ((widget->
+ outamp_caps >> AMPCAP_NUMSTEPS_SHIFT) & AMPCAP_NUMSTEPS_MASK) + 1;
+ step =
+ ((widget->
+ outamp_caps >> AMPCAP_STEPSIZE_SHIFT) & AMPCAP_STEPSIZE_MASK) + 1;
+
+ if (step > 20 /* 5dB */ && range < 5)
+ {
+ return create_ingain_selector (mixer, codec, widget, group, ix, name);
+ }
+ maxval = hdaudio_amp_maxval (widget->inamp_caps);
+
+ if (widget->widget_caps & WCAP_STEREO)
+ {
+ typ = MIXT_STEREOSLIDER16;
+ num = MIXNUM (widget, CT_INSTEREO, ix);
+ }
+ else
+ {
+ typ = MIXT_MONOSLIDER16;
+ num = MIXNUM (widget, CT_INMONO, ix);
+ }
+
+ if (codec->widgets[widget->connections[ix]].skip)
+ {
+ hdaudio_set_control (mixer->mixer_dev, num, SNDCTL_MIX_WRITE, 0);
+ return 0;
+ }
+
+ if ((ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ num,
+ hdaudio_set_control,
+ typ,
+ name, maxval,
+ MIXF_READABLE |
+ MIXF_WRITEABLE | MIXF_CENTIBEL | flags)) < 0)
+ return ctl;
+
+ /* Setup initial volume */
+ val = (maxval * percent) / 100;
+ val = val | (val << 16);
+ if (mixer_muted)
+ val = 0;
+
+ hdaudio_set_control (mixer->mixer_dev, num, SNDCTL_MIX_WRITE, val);
+
+ /* Copy RGB color */
+ src_widget = &codec->widgets[widget->connections[ix]];
+ if (src_widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (dev, ctl)) != NULL)
+ ent->rgbcolor = src_widget->rgbcolor;
+
+ return ctl;
+}
+
+int
+hda_codec_add_inmute (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int ix, int group, const char *name, int muted, unsigned int flags)
+{
+ widget_t *widget;
+ codec_t *codec;
+ oss_mixext *ent;
+ int ctl = 0;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+
+ if (codec->widgets[widget->connections[ix]].skip)
+ {
+ int num = MIXNUM (widget, CT_INMUTE, ix);
+ hdaudio_set_control (mixer->mixer_dev, num, SNDCTL_MIX_WRITE, 1);
+ return 0;
+ }
+
+ if ((ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ MIXNUM (widget,
+ CT_INMUTE, ix),
+ hdaudio_set_control,
+ MIXT_MUTE, name, 2,
+ flags | MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ /* Copy RGB color */
+ if (widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (dev, ctl)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+
+ hdaudio_set_control (mixer->mixer_dev,
+ MIXNUM (widget, CT_INMUTE, ix),
+ SNDCTL_MIX_WRITE, muted);
+ return ctl;
+}
+
+int
+hda_codec_set_inmute (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int ix, int group, const char *name, int muted)
+{
+ widget_t *widget;
+ codec_t *codec;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+
+// cmn_err(CE_CONT, "Set inmute 0x%02x:%d=%d\n", wid, ix, muted);
+ return hdaudio_set_control (mixer->mixer_dev,
+ MIXNUM (widget, CT_INMUTE, ix),
+ SNDCTL_MIX_WRITE, muted);
+}
+
+int
+hda_codec_add_insrc (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int ix, int group, const char *name, int unselected)
+{
+ widget_t *widget;
+ codec_t *codec;
+ oss_mixext *ent;
+ int ctl = 0;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+
+ if (codec->widgets[widget->connections[ix]].skip)
+ {
+ int num = MIXNUM (widget, CT_INMUTE, ix);
+
+ hdaudio_set_control (mixer->mixer_dev, num, SNDCTL_MIX_WRITE, 1);
+ return 0;
+ }
+
+ if ((ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ MIXNUM (widget,
+ CT_INSRC, ix),
+ hdaudio_set_control,
+ MIXT_ONOFF, name, 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ /* Copy RGB color */
+ if (widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (dev, ctl)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+
+ hdaudio_set_control (mixer->mixer_dev,
+ MIXNUM (widget, CT_INSRC, ix),
+ SNDCTL_MIX_WRITE, unselected);
+ return ctl;
+}
+
+int
+hda_codec_add_insrcselect (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int group, int *ctl, const char *name,
+ int initial_selection)
+{
+ widget_t *widget;
+ codec_t *codec;
+ int i;
+ oss_mixext *ext;
+
+ *ctl = 0;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+
+ if ((*ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ MIXNUM (widget,
+ CT_INSRCSELECT, 0),
+ hdaudio_set_control,
+ MIXT_ENUM, name, widget->nconn,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return 0;
+
+ ext = mixer_find_ext (mixer->mixer_dev, *ctl);
+ if (ext == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot locate the mixer extension (x)\n");
+ return OSS_EIO;
+ }
+
+ /* Copy RGB color */
+ if (widget->color != 0)
+ ext->rgbcolor = widget->rgbcolor;
+
+ memset (ext->enum_present, 0, sizeof (ext->enum_present));
+
+ for (i = 0; i < widget->nconn; i++)
+ {
+
+ /*
+ * ensure that the connection list has a valid widget id - some
+ * devices have bogus connection lists
+ */
+ if (codec->widgets[widget->connections[i]].wid < codec->first_node)
+ continue;
+
+ /*
+ * Show only widgets that are not marked to be ignored.
+ * Also hide I/O pins that are known to be outputs.
+ */
+ if (!codec->widgets[widget->connections[i]].skip
+ && codec->widgets[widget->connections[i]].sensed_pin != PIN_OUT)
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+ }
+
+ hdaudio_set_control (mixer->mixer_dev,
+ MIXNUM (widget, CT_INSRCSELECT, 0),
+ SNDCTL_MIX_WRITE, initial_selection);
+ return 1;
+}
+
+int
+hda_codec_add_select (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int group, const char *name, int *ctl,
+ int initial_select)
+{
+ widget_t *widget;
+ codec_t *codec;
+ oss_mixext *ext;
+ int i;
+
+ *ctl = 0;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+
+ if ((*ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ MIXNUM (widget, CT_SELECT, 0),
+ hdaudio_set_control,
+ MIXT_ENUM,
+ name,
+ widget->nconn,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return *ctl;
+
+ ext = mixer_find_ext (mixer->mixer_dev, *ctl);
+
+ if (ext == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot locate the mixer extension (x)\n");
+ return OSS_EIO;
+ }
+ /* Copy RGB color */
+ if (widget->color != 0)
+ ext->rgbcolor = widget->rgbcolor;
+
+ memset (ext->enum_present, 0, sizeof (ext->enum_present));
+
+ for (i = 0; i < widget->nconn; i++)
+ {
+
+ /*
+ * ensure that the connection list has a valid widget id - some
+ * devices have bogus connection lists
+ */
+ if (codec->widgets[widget->connections[i]].wid < codec->first_node)
+ continue;
+
+ /*
+ * Show only widgets that are not marked to be ignored.
+ * Also hide I/O pins that are known to be outputs.
+ */
+ if (!codec->widgets[widget->connections[i]].skip
+ && codec->widgets[widget->connections[i]].sensed_pin != PIN_OUT)
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+ }
+
+ if (initial_select > -1)
+ widget->current_selector = initial_select;
+
+ if (widget->current_selector >= widget->nconn)
+ widget->current_selector = 0;
+ corb_write (mixer, widget->cad, widget->wid, 0, SET_SELECTOR,
+ widget->current_selector);
+
+ return *ctl;
+}
+
+int
+hda_codec_add_pinselect (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int group, const char *name, int *ctl,
+ int initial_select)
+{
+ widget_t *widget;
+ codec_t *codec;
+ unsigned int conf, b;
+ oss_mixext *ext;
+ int i;
+
+ *ctl = 0;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return OSS_ENXIO;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return OSS_ENXIO;
+
+ widget = &codec->widgets[wid];
+
+ if ((*ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ MIXNUM (widget, CT_SELECT, 0),
+ hdaudio_set_control,
+ MIXT_ENUM,
+ name,
+ widget->nconn + 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return *ctl;
+
+ ext = mixer_find_ext (mixer->mixer_dev, *ctl);
+
+ if (ext == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot locate the mixer extension (x)\n");
+ return OSS_EIO;
+ }
+
+ /* Copy RGB color */
+ if (widget->color != 0)
+ ext->rgbcolor = widget->rgbcolor;
+ memset (ext->enum_present, 0, sizeof (ext->enum_present));
+
+ for (i = 0; i < widget->nconn; i++)
+ {
+
+ /*
+ * ensure that the connection list has a valid widget id - some
+ * devices have bogus connection lists
+ */
+ if (codec->widgets[widget->connections[i]].wid < codec->first_node)
+ continue;
+
+ /*
+ * Show only widgets that are not marked to be ignored.
+ * Also hide I/O pins that are known to be outputs.
+ */
+ if (!codec->widgets[widget->connections[i]].skip
+ && codec->widgets[widget->connections[i]].sensed_pin != PIN_OUT)
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+ }
+
+ /*
+ * Enable the input selection (if available)
+ */
+ i = widget->nconn;
+ if (widget->pincaps & PINCAP_INPUT_CAPABLE)
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+
+/*
+ * Set the initial value.
+ *
+ * Use the default sequence as an index to the output source selectors.
+ */
+ if (widget->sensed_pin == PIN_OUT)
+ {
+ if (corb_read
+ (mixer, widget->cad, widget->wid, 0, GET_CONFIG_DEFAULT, 0, &conf,
+ &b))
+ {
+ int association, sequence;
+
+ association = (conf >> 4) & 0x0f;
+ sequence = conf & 0x0f;
+
+ if (association != 0)
+ {
+ widget->current_selector = sequence;
+ }
+
+ }
+ }
+ else if (widget->sensed_pin == PIN_IN || widget->sensed_pin == PIN_MIC)
+ widget->current_selector = widget->nconn; /* Turn on input mode */
+
+ if (initial_select > -1)
+ widget->current_selector = initial_select;
+
+ if (widget->current_selector < 0
+ || widget->current_selector >= widget->nconn + 1)
+ widget->current_selector = 0;
+
+ if (widget->current_selector < widget->nconn)
+ {
+ /* Output source select */
+ corb_write (mixer, cad, wid, 0, SET_SELECTOR, widget->current_selector);
+ /* Enable output and HP amp. Set vref=Ground */
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0xc0);
+ }
+ else
+ {
+ /* Input select
+ * Program the correct VRef Values
+ */
+
+ if (widget->pin_type == PIN_IN) /* Line-in */
+ {
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0x20); /*Ground*/
+ }
+ else /* Mic-in */
+ {
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0x24); /*Vref=8
+ 0% */
+ }
+ }
+
+ return *ctl;
+}
+
+void
+hda_codec_set_select (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int value)
+{
+ codec_t *codec;
+ widget_t *widget;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return;
+
+ widget = &codec->widgets[wid];
+
+ widget->current_selector = value;
+
+ corb_write (mixer, cad, wid, 0, SET_SELECTOR, value);
+}
+
+void
+hda_codec_set_pinselect (int dev, hdaudio_mixer_t * mixer, int cad, int wid,
+ int value)
+{
+ codec_t *codec;
+ widget_t *widget;
+
+ if (cad < 0 || cad >= mixer->ncodecs)
+ return;
+ codec = mixer->codecs[cad];
+
+ if (wid < 0 || wid >= codec->nwidgets)
+ return;
+
+ widget = &codec->widgets[wid];
+
+ widget->current_selector = value;
+
+ if (widget->current_selector < widget->nconn)
+ {
+ /* Output source select */
+ corb_write (mixer, cad, wid, 0, SET_SELECTOR, widget->current_selector);
+ /* Enable output and HP amp. Set vref=Ground */
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0xc0);
+ }
+ else
+ {
+ /* Input select
+ * Program the correct VRef Values
+ */
+
+ if (widget->pin_type == PIN_IN) /* Line-in */
+ {
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0x20); /*Ground*/
+ }
+ else /* Mic-in */
+ {
+ corb_write (mixer, cad, wid, 0, SET_PINCTL, 0x24); /*Vref=8
+ 0% */
+ }
+ }
+}
+
+int
+hda_codec_add_choices (int dev, hdaudio_mixer_t * mixer, int ctl,
+ const char *choiselist)
+{
+ mixer_ext_set_strings (dev, ctl, choiselist, 0);
+
+ return 0;
+}
+
+void
+hda_codec_set_color(int dev, hdaudio_mixer_t *mixer, int ctl, int color)
+{
+ oss_mixext *ext;
+
+ if ((ext = mixer_find_ext (mixer->mixer_dev, ctl)) != NULL)
+ {
+ ext->rgbcolor = color;
+//cmn_err(CE_CONT, "Mixer %s rgb->%06x\n", ext->extname, ext->rgbcolor);
+ }
+}
diff --git a/kernel/drv/oss_hdaudio/hdaudio_codec.h b/kernel/drv/oss_hdaudio/hdaudio_codec.h
new file mode 100644
index 0000000..c990e31
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_codec.h
@@ -0,0 +1,379 @@
+/*
+ * Purpose: Definitions of HD audio codec functions, structures and macros
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 HDAUDIO_CODEC_H
+#define HDAUDIO_CODEC_H
+
+#define HDA_MAX_OUTSTREAMS 12
+#define HDA_MAX_INSTREAMS 8
+
+#define MAX_CODECS 16
+#define MAX_WIDGETS 150
+#define MAX_CONN 24
+
+#define CT_INMONO 0x0001
+#define CT_INSTEREO 0x0002
+#define CT_INMUTE 0x0003
+#define CT_INSRC 0x0004 /* Negation of a mute control */
+#define CT_SELECT 0x0005
+
+#define CT_OUTMONO 0x0006
+#define CT_OUTSTEREO 0x0007
+#define CT_OUTMUTE 0x0008
+
+#define CT_OUTGAINSEL 0x0009
+#define CT_INGAINSEL 0x000a
+#define CT_INSRCSELECT 0x000b
+
+#define corb_read(m, cad, wid, d, verb, parm, p1, p2) \
+ m->read(m->devc, cad, wid, d, verb, parm, p1, p2)
+#define corb_write(m, cad, wid, d, verb, parm) \
+ m->write(m->devc, cad, wid, d, verb, parm)
+
+#define MIXNUM(widget, ty, ix) \
+ ((ix) | (ty<<8) | (widget->wid<<16) | (widget->cad << 24))
+extern int hdaudio_set_control (int dev, int ctrl, unsigned int cmd,
+ int value);
+
+typedef struct _hdaudio_mixer_struct hdaudio_mixer_t;
+
+/*
+ * Reserved (predefined) stream numbers
+ */
+#define IDDLE_STREAM 0 /* Reserved for silence */
+#define FRONT_STREAM 1 /* Reserved for front channel stereo pair */
+
+typedef struct
+{
+ char *name;
+ int is_output;
+ unsigned char ix, cad, base_wid;
+ unsigned char recsrc_wid;
+ unsigned char volume_wid;
+ int borrow_count; /* Number of other endpoints grouped with this one (for multich) */
+ int binding;
+ int afg;
+ int min_rate, max_rate;
+ int channels;
+ int fmt_mask;
+ volatile int busy;
+ int nrates, rates[20];
+ unsigned int sizemask;
+ int stream_number, default_stream_number, iddle_stream;
+ int is_digital;
+ int is_modem;
+ int auto_muted;
+ int skip; /* Not connected to anywhere */
+ int already_used;
+} hdaudio_endpointinfo_t;
+
+/*
+ * Codec requests
+ */
+
+#define GET_GAIN(inout, leftright) (0xb00|(inout<<7)|(leftright<<5))
+#define SET_GAIN(out,inp,lft, rght, ix) (0x300|(out<<7)|(inp<<6)|(lft<<5)|(rght<<4)|ix)
+#define GET_CONVERTER_FORMAT 0xa00
+#define SET_CONVERTER_FORMAT 0x200
+#define GET_PARAMETER 0xf00
+#define GET_SELECTOR 0xf01
+#define SET_SELECTOR 0x701
+#define GET_CONNECTION_LIST_ENTRY 0xf02
+#define GET_PROCESSING_STATE 0xf03
+#define SET_PROCESSING_STATE 0x703
+#define GET_SDI_SELECT 0xf04
+#define SET_SDI_SELECT 0x704
+#define GET_CONVERTER 0xf06
+#define SET_CONVERTER 0x706
+#define GET_PINCTL 0xf07
+#define SET_PINCTL 0x707
+#define GET_UNSOLICITED 0xf08
+#define SET_UNSOLICITED 0x708
+#define GET_CONFIG_DEFAULT 0xf1c
+#define SET_POWER_STATE 0x705
+#define GET_POWER_STATE 0xf05
+#define GET_PIN_SENSE 0xf09
+#define TRIGGER_PIN_SENSE 0x709
+#define GET_BEEP 0xf0a
+#define SET_BEEP 0x70a
+#define GET_EAPD 0xf0c
+#define SET_EAPD 0x70c
+#define GET_SPDIF_CONTROL 0xf0d
+#define SET_SPDIF_CONTROL1 0x70d
+#define SET_SPDIF_CONTROL2 0x70e
+#define GET_VOLUME_KNOB_CONTROL 0xf0f
+#define SET_VOLUME_KNOB_CONTROL 0x70f
+#define GET_GPI_DATA 0xf10
+#define SET_GPI_DATA 0x710
+#define GET_GPI_WAKE 0xf11
+#define SET_GPI_WAKE 0x711
+#define GET_GPI_UNSOL 0xf12
+#define SET_GPI_UNSOL 0x712
+#define GET_GPI_STICKY 0xf13
+#define SET_GPI_STICKY 0x713
+#define GET_GPO_DATA 0xf14
+#define SET_GPO_DATA 0x714
+#define GET_GPIO_DATA 0xf15
+#define SET_GPIO_DATA 0x715
+#define GET_GPIO_ENABLE 0xf16
+#define SET_GPIO_ENABLE 0x716
+#define GET_GPIO_DIR 0xf17
+#define SET_GPIO_DIR 0x717
+#define GET_GPIO_WKEN 0xf18
+#define SET_GPIO_WKEN 0x718
+#define GET_GPIO_UNSOL 0xf19
+#define SET_GPIO_UNSOL 0x719
+#define GET_GPIO_STICKY 0xf1a
+#define SET_GPIO_STICKY 0x71a
+#define GET_SUBSYSTEM_ID 0xf20
+#define GET_STRIPE_CONTROL 0xf24
+#define SET_CODEC_RESET 0x7ff
+
+/*
+ * Parameters
+ */
+
+#define HDA_VENDOR 0x00
+#define HDA_REVISION 0x02
+#define HDA_NODE_COUNT 0x04
+#define HDA_GROUP_TYPE 0x05
+#define HDA_AUDIO_GROUP_CAPS 0x08
+#define HDA_WIDGET_CAPS 0x09
+#define HDA_PCM_SIZES 0x0a
+#define HDA_STREAM_FMTS 0x0b
+#define HDA_PIN_CAPS 0x0c
+#define HDA_INPUTAMP_CAPS 0x0d
+#define HDA_CONNLIST_LEN 0x0e
+#define HDA_SUPPORTED_POWER_STATES 0x0f
+#define HDA_PROCESSING_CAPS 0x10
+#define HDA_GPIO_COUNT 0x11
+#define HDA_OUTPUTAMP_CAPS 0x12
+#define HDA_VOLUMEKNOB_CAPS 0x13
+
+typedef int (*hdmixer_write_t) (void *devc, unsigned int cad,
+ unsigned int nid, unsigned int d,
+ unsigned int verb, unsigned int parm);
+typedef int (*hdmixer_read_t) (void *devc, unsigned int cad, unsigned int nid,
+ unsigned int d, unsigned int verb,
+ unsigned int parm, unsigned int *upper,
+ unsigned int *lower);
+
+#ifdef _KERNEL
+extern hdaudio_mixer_t *hdaudio_mixer_create (char *name, void *devc,
+ oss_device_t * osdev,
+ hdmixer_write_t writefunc,
+ hdmixer_read_t readfunc,
+ unsigned int codecmask,
+ unsigned int vendor_id,
+ unsigned int subvendor_id);
+extern void hdaudio_mixer_set_initfunc (hdaudio_mixer_t * mixer,
+ mixer_create_controls_t func);
+#endif
+
+extern int hdaudio_mixer_get_mixdev (hdaudio_mixer_t * mixer);
+
+extern int hdaudio_mixer_get_outendpoints (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t **
+ endpoints, int size);
+extern int hdaudio_mixer_get_inendpoints (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t ** endpoints,
+ int size);
+
+extern int hdaudio_codec_setup_endpoint (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t * endpoint,
+ int rate, int channels, int fmt,
+ int stream_number,
+ unsigned int *setupbits);
+extern int hdaudio_codec_reset_endpoint (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t * endpoint,
+ int channels);
+extern int hdaudio_codec_audio_ioctl (hdaudio_mixer_t * mixer,
+ hdaudio_endpointinfo_t * endpoint,
+ unsigned int cmd, ioctl_arg arg);
+
+extern int hda_codec_getname (hdaudio_mixer_t * mixer, hda_name_t *name);
+extern int hda_codec_getwidget (hdaudio_mixer_t * mixer, hda_widget_info_t *info);
+extern void hda_codec_unsol (hdaudio_mixer_t * mixer, unsigned int upper,
+ unsigned int lower);
+extern int hdaudio_amp_maxval (unsigned int ampcaps);
+
+/*
+ * Audio widget types
+ */
+
+#define NT_DAC 0
+#define NT_ADC 1
+#define NT_MIXER 2
+#define NT_SELECT 3
+#define NT_PIN 4
+#define NT_POWER 5
+#define NT_KNOB 6
+#define NT_BEEP 7
+#define NT_VENDOR 15
+
+#endif
+
+/*
+ * Struct for sample rate table
+ */
+struct hdaudio_rate_def
+{
+ unsigned int rate, mask;
+};
+
+extern const struct hdaudio_rate_def *hdaudio_rates;
+
+typedef struct
+{
+ unsigned char cad, wid;
+ char name[32];
+ char color[32];
+ unsigned char wid_type, group_type;
+ char used; /* Already bound to mixer */
+ char skip; /* Ignore this widget as input source */
+ char skip_output; /* Ignore this widget as output target */
+
+ unsigned int widget_caps;
+#define WCAP_STEREO (1 << 0)
+#define WCAP_INPUT_AMP_PRESENT (1 << 1)
+#define WCAP_OUTPUT_AMP_PRESENT (1 << 2)
+#define WCAP_AMP_CAP_OVERRIDE (1 << 3)
+#define WCAP_FORMAT_OVERRIDE (1 << 4)
+#define WCAP_STRIPE (1 << 5)
+#define WCAP_PROC_WIDGET (1 << 6)
+#define WCAP_UNSOL_CAPABLE (1 << 7)
+#define WCAP_CONN_LIST (1 << 8)
+#define WCAP_DIGITAL (1 << 9)
+#define WCAP_POWER_CTL (1 << 10)
+#define WCAP_LR_SWAP (1 << 11)
+
+ unsigned int inamp_caps;
+ unsigned int outamp_caps;
+#define AMPCAP_MUTE (1UL<<31)
+#define AMPCAP_STEPSIZE_SHIFT 16
+#define AMPCAP_STEPSIZE_MASK 0x7f
+#define AMPCAP_NUMSTEPS_SHIFT 8
+#define AMPCAP_NUMSTEPS_MASK 0x7f
+#define AMPCAP_OFFSET_SHIFT 0
+#define AMPCAP_OFFSET_MASK 0x7f
+
+ unsigned int pincaps;
+#define PINCAP_EAPD (1<<16)
+#define PINCAP_VREF_MASK 0x7f
+#define PINCAP_VREF_SHIFT 8
+#define PINCAP_RESERVED (1<<7)
+#define PINCAP_BALANCED_PINS (1<<6)
+#define PINCAP_INPUT_CAPABLE (1<<5)
+#define PINCAP_OUTPUT_CAPABLE (1<<4)
+#define PINCAP_HP_DRIVE_CAPABLE (1<<3)
+#define PINCAP_JACKSENSE_CAPABLE (1<<2)
+#define PINCAP_TRIGGERR_RQRD (1<<1)
+#define PINCAP_IMPSENSE_CAPABLE (1<<0)
+
+ unsigned int sizes;
+
+ int nconn;
+ short connections[MAX_CONN];
+ short references[MAX_CONN];
+ short refcount;
+ char plugged_in;
+ int impsense; /* Impedanse sensing result. -1=no info */
+ char pin_type, sensed_pin;
+#define PIN_UNKNOWN 0
+#define PIN_IN 1
+#define PIN_MIC 2
+#define PIN_OUT 3
+#define PIN_HEADPHONE 4
+ hdaudio_endpointinfo_t *endpoint;
+ int current_selector;
+ int rgbcolor; /* RGB value of the jack color */
+ int association, sequence;
+} widget_t;
+
+typedef int (*hda_mixer_init_func) (int dev, hdaudio_mixer_t * mixer, int cad,
+ int group);
+
+typedef struct codec_desc codec_desc_t;
+
+typedef struct
+{
+ const codec_desc_t *codec_desc;
+ int active; /* Codec has audio or modem functionality */
+ unsigned long vendor_flags;
+
+ int nwidgets;
+ widget_t widgets[MAX_WIDGETS];
+ int afg;
+ int jack_number;
+ int first_node;
+ int num_jacks_plugged;
+ unsigned int sizes;
+ hda_mixer_init_func mixer_init;
+ unsigned int default_inamp_caps;
+ unsigned int default_outamp_caps;
+ unsigned int vendor_id, subvendor_id;
+
+ int speaker_mode;
+#define SPKMODE_DEFAULT 0
+#define SPKMODE_SPEAKER 1
+#define SPKMODE_STEREO 2
+#define SPKMODE_51 3
+#define SPKMODE_71 4
+
+ int num_inendpoints;
+ hdaudio_endpointinfo_t inendpoints[HDA_MAX_INSTREAMS];
+ int num_outendpoints;
+ hdaudio_endpointinfo_t outendpoints[HDA_MAX_OUTSTREAMS];
+
+ unsigned int multich_map; /* See codec_desc_t.multich_map */
+
+ int mixer_mode; /* For use by dedicated drivers. Initially set to 0 */
+ char **remap;
+} codec_t;
+
+struct _hdaudio_mixer_struct
+{
+ void *devc;
+ oss_device_t *osdev;
+
+ char name[64];
+ char *chip_name;
+ int mixer_dev;
+
+ hdmixer_write_t write;
+ hdmixer_read_t read;
+
+ unsigned int codecmask;
+
+ int ncodecs;
+ codec_t *codecs[MAX_CODECS];
+
+ int ncontrols; /* Total number of widgets (all codecs) */
+
+ int num_inendpoints, copied_inendpoints;
+ hdaudio_endpointinfo_t inendpoints[HDA_MAX_INSTREAMS];
+ int num_outendpoints, copied_outendpoints;
+ hdaudio_endpointinfo_t outendpoints[HDA_MAX_OUTSTREAMS];
+
+ int npins; /* Used for managing the width of the connectors group */
+ int split_connectors; /* Fearless flag used for splitting the connectors geroup */
+ mixer_create_controls_t client_mixer_init;
+
+ int remap_avail;
+};
+
+extern int create_outgain_selector (hdaudio_mixer_t * mixer, widget_t * widget, int group, const char *name);
+extern int create_ingain_selector (hdaudio_mixer_t * mixer, codec_t * codec, widget_t * widget, int group, int ix, const char *name);
+
+#include "hdaudio_mixers.h"
diff --git a/kernel/drv/oss_hdaudio/hdaudio_codecids.h b/kernel/drv/oss_hdaudio/hdaudio_codecids.h
new file mode 100644
index 0000000..22e6c70
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_codecids.h
@@ -0,0 +1,1154 @@
+/*
+ * Purpose: Definitions for HDaudio codec chips known by OSS.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * NULL mixer init function. Used to disable mixer creation for given codec.
+ */
+static int NULL_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group) { return 0;}
+
+struct codec_desc
+{
+ unsigned int id; /* Codec id (however subdevice ID in the subdevices[] table) */
+ char *name;
+ unsigned long flags;
+#define VF_NONE 0x00000000
+#define VF_ALC88X_HACK 0x00000001 /* ALC88x requires special handling for
+S/PDIF */
+#define VF_VAIO_HACK 0x00000002 /* VAIO STAC9872 requires special
+handling for headphone DAC */
+#define VF_SI3055_HACK 0x00000004 /* Si3055 modem requires manual endpoint
+setuping and rate and ioctl hacks. */
+ char **remap;
+
+ /*
+ * Order of the output converter (DAC) widgets in multi channel mode.
+ * If left to 0 then 0x76543210 (sequential order) is assumed. Some
+ * motherboards are known to use their own channel ordering which can be
+ * fixed using this approach.
+ */
+ unsigned int multich_map;
+ hda_mixer_init_func mixer_init;
+ unsigned int main_id; /* In the subdevices[] table this is used for the codec ID */
+ unsigned int pci_subdevice; /* PCI subdevice ID of the controller (subdevices[]) */
+};
+
+
+/*
+ * Meaningful widget naming schemes for some known codecs.
+ * The list is terminated by a NULL string. An empty string
+ * (EMPTY_STR) means that the automatically selected name will be used.
+ *
+ * Define EMPTY_STR as a pointer to a common "" variable to conserve space.
+ */
+
+static const char hda_empty_string[] = "";
+#define EMPTY_STR hda_empty_string
+
+static const char *alc880remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 1 */
+ "front", /* 2 */
+ "rear", /* 3 */
+ "center/LFE", /* 4 */
+ "side", /* 5 */
+ "spdif-out", /* 6 */
+ "rec1", /* 7 */
+ "rec2", /* 8 */
+ "rec3", /* 9 */
+ "spdif-in", /* 10 */
+ "inputmix", /* 11 */
+ "front", /* 12 */
+ "rear", /* 13 */
+ "center/LFE", /* 14 */
+ "side", /* 15 */
+ "source-a", /* 16 */
+ "source-b", /* 17 */
+ "source-c", /* 18 */
+ "source-d", /* 19 */
+ EMPTY_STR, /* 20 */
+ EMPTY_STR, /* 21 */
+ EMPTY_STR, /* 22 */
+ EMPTY_STR, /* 23 */
+ EMPTY_STR, /* 24 */
+ EMPTY_STR, /* 25 */
+ EMPTY_STR, /* 26 */
+ EMPTY_STR, /* 27 */
+ EMPTY_STR, /* 28 */
+ EMPTY_STR, /* 29 */
+ EMPTY_STR, /* 30 */
+ EMPTY_STR, /* 31 */
+ EMPTY_STR, /* 32 */
+ EMPTY_STR, /* 33 */
+ EMPTY_STR, /* 34 */
+ EMPTY_STR, /* 35 */
+ EMPTY_STR, /* 36 */
+ "fp-front", /* 37 */
+ NULL
+};
+
+static const char *alc883remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 1 */
+ "front", /* 2 */
+ "rear", /* 3 */
+ "center/LFE", /* 4 */
+ "side", /* 5 */
+ "spdif-out", /* 6 */
+ EMPTY_STR, /* 7 */
+ "rec1", /* 8 */
+ "rec2", /* 9 */
+ "spdif-in", /* a */
+ "input-mix", /* b */
+ "front", /* c */
+ "rear", /* d */
+ "center/LFE", /* e */
+ "side", /* f */
+ EMPTY_STR, /* 10 */
+ EMPTY_STR, /* 11 */
+ EMPTY_STR, /* 12 */
+ EMPTY_STR, /* 13 */
+ EMPTY_STR, /* 14 */
+ EMPTY_STR, /* 15 */
+ EMPTY_STR, /* 16 */
+ EMPTY_STR, /* 17 */
+ EMPTY_STR, /* 18 */
+ EMPTY_STR, /* 19 */
+ EMPTY_STR, /* 1a */
+ EMPTY_STR, /* 1b */
+ EMPTY_STR, /* 1c */
+ EMPTY_STR, /* 1d */
+ EMPTY_STR, /* 1e */
+ EMPTY_STR, /* 1f */
+ EMPTY_STR, /* 20 */
+ EMPTY_STR, /* 21 */
+ EMPTY_STR, /* 22 */
+ EMPTY_STR, /* 23 */
+ EMPTY_STR, /* 24 */
+ "pcm4", /* 25 */
+ "pcm4", /* 26 */
+ NULL
+};
+
+static const char *alc260remap[] = {
+ EMPTY_STR, /* 0x00 */
+ EMPTY_STR, /* 0x01 */
+ "front", /* 0x02 */
+ "spdif-out", /* 0x03 */
+ "rec1", /* 0x04 */
+ "rec2", /* 0x05 */
+ "spdif-in", /* 0x06 */
+ "inputmix", /* 0x07 */
+ "speaker-mix", /* 0x08 */
+ "headphone-mix", /* 0x09 */
+ "mono-mix", /* 0x0a */
+ EMPTY_STR, /* 0x0b */
+ EMPTY_STR, /* 0x0c */
+ EMPTY_STR, /* 0x0d */
+ EMPTY_STR, /* 0x0e */
+ "speaker", /* 0x0f */
+ "headphone", /* 0x10 */
+ "mono", /* 0x11 */
+ EMPTY_STR, /* 0x12 */
+ EMPTY_STR, /* 0x13 */
+ EMPTY_STR, /* 0x14 */
+ EMPTY_STR, /* 0x15 */
+ EMPTY_STR, /* 0x16 */
+ "beep", /* 0x17 */
+ "spdif-out", /* 0x18 */
+ "spdif-in", /* 0x19 */
+ NULL
+};
+
+static const char *alc262remap[] = {
+ EMPTY_STR, /* 0x00 */
+ EMPTY_STR, /* 0x01 */
+ "speaker", /* 0x02 */
+ "headphone", /* 0x03 */
+ EMPTY_STR, /* 0x04 */
+ EMPTY_STR, /* 0x05 */
+ "spdif-out", /* 0x06 */
+ "rec1", /* 0x07 */
+ "rec2", /* 0x08 */
+ "rec3", /* 0x09 */
+ "spdif-in", /* 0x0a */
+ "mix", /* 0x0b */
+ EMPTY_STR, /* 0x0c */
+ EMPTY_STR, /* 0x0d */
+ EMPTY_STR, /* 0x0e */
+ EMPTY_STR, /* 0x0f */
+ EMPTY_STR, /* 0x10 */
+ "mono", /* 0x11 */
+ "dmic", /* 0x12 */
+ EMPTY_STR, /* 0x13 */
+ "line-out", /* 0x14 */
+ "headphone", /* 0x15 */
+ "mono", /* 0x16 */
+ "beep", /* 0x17 */
+ EMPTY_STR, /* 0x18 */
+ EMPTY_STR, /* 0x19 */
+ EMPTY_STR, /* 0x1a */
+ EMPTY_STR, /* 0x1b */
+ EMPTY_STR, /* 0x1c */
+ "beep", /* 0x1d */
+ "spdif-out", /* 0x1e */
+ "spdif-in", /* 0x1f */
+ NULL
+};
+
+static const char *alc662remap[] = {
+ EMPTY_STR, /* 0x00 */
+ EMPTY_STR, /* 0x01 */
+ "front", /* 0x02 */
+ "rear", /* 0x03 */
+ "center/LFE", /* 0x04 */
+ EMPTY_STR, /* 0x05 */
+ "spdif-out", /* 0x06 */
+ "spdout", /* 0x07 */
+ "rec1", /* 0x08 */
+ "rec2", /* 0x09 */
+ EMPTY_STR, /* 0x0a */
+ "mix", /* 0x0b */
+ "front", /* 0x0c */
+ "rear", /* 0x0d */
+ "c/lfe", /* 0x0e */
+ EMPTY_STR, /* 0x0f */
+ EMPTY_STR, /* 0x10 */
+ EMPTY_STR, /* 0x11 */
+ EMPTY_STR, /* 0x12 */
+ EMPTY_STR, /* 0x13 */
+ EMPTY_STR, /* 0x14 */
+ EMPTY_STR, /* 0x15 */
+ EMPTY_STR, /* 0x16 */
+ EMPTY_STR, /* 0x17 */
+ EMPTY_STR, /* 0x18 */
+ EMPTY_STR, /* 0x19 */
+ EMPTY_STR, /* 0x1a */
+ EMPTY_STR, /* 0x1b */
+ EMPTY_STR, /* 0x1c */
+ EMPTY_STR, /* 0x1d */
+ EMPTY_STR, /* 0x1e */
+ EMPTY_STR, /* 0x1f */
+ EMPTY_STR, /* 0x20 */
+ EMPTY_STR, /* 0x21 */
+ EMPTY_STR, /* 0x22 */
+ EMPTY_STR, /* 0x23 */
+ NULL
+};
+
+static const char *alc861remap[] = {
+ EMPTY_STR, /* 0x00 */
+ EMPTY_STR, /* 0x01 */
+ EMPTY_STR, /* 0x02 */
+ "front", /* 0x03 */
+ "side", /* 0x04 */
+ "center/LFE", /* 0x05 */
+ "rear", /* 0x06 */
+ "spdout", /* 0x07 */
+ "rec", /* 0x08 */
+ EMPTY_STR, /* 0x09 */
+ EMPTY_STR, /* 0x0a */
+ EMPTY_STR, /* 0x0b */
+ EMPTY_STR, /* 0x0c */
+ EMPTY_STR, /* 0x0d */
+ EMPTY_STR, /* 0x0e */
+ EMPTY_STR, /* 0x0f */
+ EMPTY_STR, /* 0x10 */
+ EMPTY_STR, /* 0x11 */
+ EMPTY_STR, /* 0x12 */
+ EMPTY_STR, /* 0x13 */
+ "recmix", /* 0x14 */
+ "outmix", /* 0x15 */
+ "frontmix", /* 0x16 */
+ "sidemix", /* 0x17 */
+ "c/l-mix", /* 0x18 */
+ "rearmix", /* 0x19 */
+ "line2-mix", /* 0x1a */
+ "mic2mix", /* 0x1b */
+ "line1mix", /* 0x1c */
+ EMPTY_STR, /* 0x1d */
+ "vendor", /* 0x1e */
+ "center/LFE", /* 0x1f */
+ "side", /* 0x20 */
+ EMPTY_STR, /* 0x21 */
+ EMPTY_STR, /* 0x22 */
+ "beep", /* 0x23 */
+ NULL
+};
+
+static const char *cmi9880remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 1 */
+ EMPTY_STR, /* 2 */
+ "front", /* 3 */
+ "rear", /* 4 */
+ "side", /* 5 */
+ "center/LFE", /* 6 */
+ "spdif-out", /* 7 */
+ EMPTY_STR, /* 8 */
+ EMPTY_STR, /* 9 */
+ EMPTY_STR, /* 10 */
+ EMPTY_STR, /* 11 */
+ EMPTY_STR, /* 12 */
+ EMPTY_STR, /* 13 */
+ EMPTY_STR, /* 14 */
+ EMPTY_STR, /* 15 */
+ EMPTY_STR, /* 16 */
+ EMPTY_STR, /* 17 */
+ EMPTY_STR, /* 18 */
+ EMPTY_STR, /* 19 */
+ EMPTY_STR, /* 20 */
+ EMPTY_STR, /* 21 */
+ EMPTY_STR, /* 22 */
+ "pcbeep", /* 23 */
+ EMPTY_STR, /* 24 */
+ EMPTY_STR, /* 25 */
+ EMPTY_STR, /* 26 */
+ EMPTY_STR, /* 27 */
+ EMPTY_STR, /* 28 */
+ EMPTY_STR, /* 29 */
+ EMPTY_STR, /* 30 */
+ EMPTY_STR, /* 31 */
+ NULL
+};
+
+static const char *ad1981remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 1 */
+ "spdif", /* 2 */
+ "play", /* 3 */
+ "rec", /* 4 */
+ EMPTY_STR, /* 5 */
+ EMPTY_STR, /* 6 */
+ EMPTY_STR, /* 7 */
+ EMPTY_STR, /* 8 */
+ EMPTY_STR, /* 9 */
+ "spdif-out", /* a */
+ "mono-sel", /* b */
+ "mic-mix", /* c */
+ "pcbeep-sel", /* d */
+ "rec-mix", /* e */
+ "mono-mix", /* f */
+ "digital-beep", /* 10 */
+ "frontmix-amp", /* 11 */
+ "mic-mixamp", /* 12 */
+ "linein-mixamp", /* 13 */
+ "powerdown", /* 14 */
+ "rec-sel", /* 15 */
+ EMPTY_STR, /* 16 */
+ EMPTY_STR, /* 17 */
+ EMPTY_STR, /* 18 */
+ EMPTY_STR, /* 19 */
+ "lineout-mixamp", /* 1a */
+ "aux-mixamp", /* 1b */
+ "mic-mixamp", /* 1c */
+ "CD-mixamp", /* 1d */
+ "fp-mic-mute", /* 1e */
+ "mic-mute", /* 1f */
+ NULL
+};
+
+static const char *ad1983remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 1 */
+ "spdif", /* 2 */
+ "play", /* 3 */
+ "rec", /* 4 */
+ EMPTY_STR, /* 5 */
+ EMPTY_STR, /* 6 */
+ EMPTY_STR, /* 7 */
+ EMPTY_STR, /* 8 */
+ EMPTY_STR, /* 9 */
+ "spdif-out", /* a */
+ "mono-sel", /* b */
+ "mic-boost", /* c */
+ "linein-sel", /* d */
+ "rec-mix", /* e */
+ "mono-mix", /* f */
+ "digital-beep", /* 10 */
+ "frontmix-amp", /* 11 */
+ "mic-mixamp", /* 12 */
+ "linein-mixamp", /* 13 */
+ "rec-sel", /* 14 */
+ "powerdown", /* 15 */
+ NULL
+};
+
+static const char *ad1984remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 1 */
+ "spdif", /* 2 */
+ "headphone", /* 3 */
+ "front", /* 4 */
+ "dig-mic1", /* 5 */
+ "dig-mic2", /* 6 */
+ "headphone-mix", /* 7 */
+ "rec1", /* 8 */
+ "rec2", /* 9 */
+ "lineout-mix", /* a */
+ "aux-mix", /* b */
+ "rec1-sel", /* c */
+ "rec2-sel", /* d */
+ "mono-sel", /* e */
+ "aux-sel", /* f */
+ "beep", /* 10 */
+ EMPTY_STR, /* 11 */
+ EMPTY_STR, /* 12 */
+ EMPTY_STR, /* 13 */
+ EMPTY_STR, /* 14 */
+ EMPTY_STR, /* 15 */
+ EMPTY_STR, /* 16 */
+ EMPTY_STR, /* 17 */
+ EMPTY_STR, /* 18 */
+ "mixer-powerdown", /* 19 */
+ "beep", /* 1a */
+ "spdif-out", /* 1b */
+ EMPTY_STR, /* 1c */
+ EMPTY_STR, /* 1d */
+ "mono-mix", /* 1e */
+ "mono-downmix", /* 1f */
+ "input-mix", /* 20 */
+ "input-mixamp", /* 21 */
+ "headphone-sel", /* 22 */
+ "dock-sel", /* 23 */
+ "dock-mix", /* 24 */
+ "dock-micboost", /* 25 */
+ EMPTY_STR, /* 26 */
+ NULL
+};
+
+static const char *ad1986remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 1 */
+ "spdif-out", /* 2 */
+ "front", /* 3 */
+ "rear", /* 4 */
+ "center/LFE", /* 5 */
+ "rec", /* 6 */
+ "recmon", /* 7 */
+ "mono-mix", /* 8 */
+ "stereo-downmix", /* 9 */
+ "headphone-sel", /* a */
+ "lineout-sel", /* b */
+ "rear-sel", /* c */
+ "center/LFE-sel", /* d */
+ "mono-sel", /* e */
+ "mic-sel", /* f */
+ "linein-sel", /* 10 */
+ "mic-src", /* 11 */
+ "rec-src" /* 12 */
+ "mic-mix", /* 13 */
+ "phone-mix", /* 14 */
+ "cd-mix", /* 15 */
+ "aux-mix", /* 16 */
+ "linein-mix", /* 17 */
+ "beep", /* 18 */
+ "digital-beep", /* 19 */
+ EMPTY_STR, /* 1a */
+ EMPTY_STR, /* 1b */
+ EMPTY_STR, /* 1c */
+ EMPTY_STR, /* 1d */
+ EMPTY_STR, /* 1e */
+ EMPTY_STR, /* 1f */
+ EMPTY_STR, /* 20 */
+ EMPTY_STR, /* 21 */
+ EMPTY_STR, /* 22 */
+ EMPTY_STR, /* 23 */
+ EMPTY_STR, /* 24 */
+ "spdif-out", /* 25 */
+ "analog-powerdown", /* 26 */
+ "mic-c/LFE-mix", /* 27 */
+ "mic-linein-mix", /* 28 */
+ "c/LFE-linein-mix", /* 29 */
+ "mic-linein-c/LFE-mix", /* 2a */
+ "mic-sel", /* 2b */
+ NULL
+};
+
+static const char *ad1988remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 1 */ /* This is both audio-fgr and DAC???? */
+ "spdout", /* 2 */ /* Not used? */
+ "headphone", /* 3 */
+ "front", /* 4 */
+ "center/LFE", /* 5 */
+ "rear", /* 6 */
+ "spdin", /* 7 */
+ "rec1", /* 8 */
+ "rec2", /* 9 */
+ "side", /* a */
+ "spdin-src", /* b */
+ "rec1-src", /* c */
+ "rec2-src", /* d */
+ "rec3-src", /* e */
+ "rec3", /* f */
+ "pcbeep", /* 10 */
+ EMPTY_STR, /* 11 */
+ EMPTY_STR, /* 12 */
+ EMPTY_STR, /* 13 */
+ EMPTY_STR, /* 14 */
+ EMPTY_STR, /* 15 */
+ EMPTY_STR, /* 16 */
+ EMPTY_STR, /* 17 */
+ EMPTY_STR, /* 18 */
+ "power-down", /* 19 */
+ "beep", /* 1a */
+ "spdif-out", /* 1b */
+ "spdif-in", /* 1c */
+ "spdifout-mix", /* 1d */
+ "mono-mix", /* 1e */
+ "main-volume", /* 1f */
+ "analog-mix", /* 20 */
+ "outamp", /* 21 */
+ "headphon-mix", /* 22 */
+ "hp-powerdown", /* 23 */
+ EMPTY_STR, /* 24 */
+ EMPTY_STR, /* 25 */
+ "mic-mix", /* 26 */
+ "center/LFE-mix", /* 27 */
+ "side-mix", /* 28 */
+ "front-mix", /* 29 */
+ "rear-mix", /* 2a */
+ "fp-mic-mix", /* 2b */
+ "linein-mix", /* 2c */
+ "mono-mixdown", /* 2d */
+ EMPTY_STR, /* 2e */
+ "bias-pdown", /* 2f */
+ "fppink-outsel", /* 30 */
+ "blue-outsel", /* 31 */
+ "pink-outsel", /* 32 */
+ "blue-insel", /* 33 */
+ "pink-insel", /* 34 */
+ EMPTY_STR, /* 35 */
+ "mono-sel", /* 36 */
+ "fpgreen-outsel", /* 37 */
+ "fpgreen-micboost", /* 38 */
+ "fppink-micboost", /* 39 */
+ "blue-micboost", /* 3a */
+ "black-micboost", /* 3b */
+ "pink-micboost", /* 3c */
+ "green-micboost", /* 3d */
+ NULL
+};
+
+#if 0
+static const char *stac9200remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 0x01 */
+ "play", /* 0x02 */
+ "rec", /* 0x03 */
+ "spdif-in", /* 0x04 */
+ "spdif-out", /* 0x05 */
+ EMPTY_STR, /* 0x06 */
+ "playmux", /* 0x07 */
+ EMPTY_STR, /* 0x08 */
+ EMPTY_STR, /* 0x09 */
+ "recmux", /* 0x0a */
+ "mainvol", /* 0x0b */
+ "inputmux", /* 0x0c */
+ EMPTY_STR, /* 0x0d */
+ EMPTY_STR, /* 0x0e */
+ EMPTY_STR, /* 0x0f */
+ EMPTY_STR, /* 0x10 */
+ EMPTY_STR, /* 0x11 */
+ EMPTY_STR, /* 0x12 */
+ "mono-mix", /* 0x13 */
+ "beep", /* 0x14 */
+ NULL
+};
+#endif
+
+static const char *stac920xremap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 0x01 */
+ EMPTY_STR, /* 0x02 */
+ EMPTY_STR, /* 0x03 */
+ EMPTY_STR, /* 0x04 */
+ EMPTY_STR, /* 0x05 */
+ EMPTY_STR, /* 0x06 */
+ EMPTY_STR, /* 0x07 */
+ EMPTY_STR, /* 0x08 */
+ EMPTY_STR, /* 0x09 */
+ EMPTY_STR, /* 0x0a */
+ EMPTY_STR, /* 0x0b */
+ EMPTY_STR, /* 0x0c */
+ EMPTY_STR, /* 0x0d */
+ EMPTY_STR, /* 0x0e */
+ EMPTY_STR, /* 0x0f */
+ "front", /* 0x10 */
+ "rear", /* 0x11 */
+ "rec1", /* 0x12 */
+ "rec2", /* 0x13 */
+ "mono-out", /* 0x14 */
+ "mono-mix", /* 0x15 */
+ "cd", /* 0x16 */
+ "dig-mic1", /* 0x17 */
+ "dig-mic2", /* 0x18 */
+ "input1-mux", /* 0x19 */
+ "input2-mux", /* 0x1a */
+ "rec1-vol", /* 0x1b */
+ "rec2-vol", /* 0x1c */
+ "rec1-mux", /* 0x1d */
+ "rec2-mux", /* 0x1e */
+ "spdif-out", /* 0x1f */
+ "spdif-in", /* 0x20 */
+ "digital-out", /* 0x21 */
+ "digital-in", /* 0x22 */
+ "beep", /* 0x23 */
+ "mastervol", /* 0x24 */
+ EMPTY_STR, /* 0x25 */
+ NULL
+};
+
+static const char *stac925xremap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 0x01 */
+ "play", /* 0x02 */
+ "rec", /* 0x03 */
+ "spdif-in", /* 0x04 */
+ "spdif-out", /* 0x05 */
+ "output-mux", /* 0x06 */
+ EMPTY_STR, /* 0x07 */
+ EMPTY_STR, /* 0x08 */
+ "rec-vol", /* 0x09 */
+ EMPTY_STR, /* 0x0a */
+ EMPTY_STR, /* 0x0b */
+ EMPTY_STR, /* 0x0c */
+ EMPTY_STR, /* 0x0d */
+ "vol", /* 0x0e */
+ "input-mux", /* 0x0f */
+ EMPTY_STR, /* 0x10 */
+ EMPTY_STR, /* 0x11 */
+ "mono-mix", /* 0x12 */
+ "beep", /* 0x13 */
+ "rec-mux", /* 0x14 */
+ EMPTY_STR, /* 0x15 */
+ NULL
+};
+
+static const char *stac922xremap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 0x01 */
+ "front", /* 0x02 */
+ "center/LFE", /* 0x03 */
+ "rear", /* 0x04 */
+ "side", /* 0x05 */
+ "rec1", /* 0x06 */
+ "rec2", /* 0x07 */
+ "spdif-out", /* 0x08 */
+ "spdif-in", /* 0x09 */
+ EMPTY_STR, /* 0x0a */
+ EMPTY_STR, /* 0x0b */
+ EMPTY_STR, /* 0x0c */
+ EMPTY_STR, /* 0x0d */
+ EMPTY_STR, /* 0x0e */
+ EMPTY_STR, /* 0x0f */
+ EMPTY_STR, /* 0x10 */
+ EMPTY_STR, /* 0x11 */
+ "rec1mux", /* 0x12 */
+ "rec2mux", /* 0x13 */
+ "pcbeep", /* 0x14 */
+ "cd", /* 0x15 */
+ "mainvol", /* 0x16 */
+ "rec1vol", /* 0x17 */
+ "rec2vol", /* 0x18 */
+ "adat", /* 0x19 */
+ "i2s-out", /* 0x1a */
+ "i2s-in", /* 0x1b */
+ NULL
+};
+
+static const char *stac923xremap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 0x01 */
+ "front", /* 0x02 */
+ "center/LFE", /* 0x03 */
+ "rear", /* 0x04 */
+ "side", /* 0x05 */
+ "headphone", /* 0x06 */
+ "rec1", /* 0x07 */
+ "rec2", /* 0x08 */
+ "rec3", /* 0x09 */
+ EMPTY_STR, /* 0x0a */
+ EMPTY_STR, /* 0x0b */
+ EMPTY_STR, /* 0x0c */
+ EMPTY_STR, /* 0x0d */
+ EMPTY_STR, /* 0x0e */
+ EMPTY_STR, /* 0x0f */
+ EMPTY_STR, /* 0x10 */
+ EMPTY_STR, /* 0x11 */
+ "cd", /* 0x12 */
+ "dig-mic1", /* 0x13 */
+ "dig-mic2", /* 0x14 */
+ "input1-mux", /* 0x15 */
+ "input2-mux", /* 0x16 */
+ "input3-mux", /* 0x17 */
+ "rec1vol", /* 0x18 */
+ "rec2vol", /* 0x19 */
+ "rec3vol", /* 0x1a */
+ "rec1-mux", /* 0x1b */
+ "rec2-mux", /* 0x1c */
+ "rec3-mux", /* 0x1d */
+ "spdif-out", /* 0x1e */
+ "adat", /* 0x1f */
+ NULL
+};
+
+
+static const char *conexant_modem_remap[] =
+{
+ EMPTY_STR, /* 0x00 */
+ EMPTY_STR, /* 0x01 */
+ EMPTY_STR, /* 0x02 */
+ EMPTY_STR, /* 0x03 */
+ EMPTY_STR, /* 0x04 */
+ EMPTY_STR, /* 0x05 */
+ EMPTY_STR, /* 0x06 */
+ EMPTY_STR, /* 0x07 */
+ EMPTY_STR, /* 0x08 */
+ EMPTY_STR, /* 0x09 */
+ EMPTY_STR, /* 0x0a */
+ EMPTY_STR, /* 0x0b */
+ EMPTY_STR, /* 0x0c */
+ EMPTY_STR, /* 0x0d */
+ EMPTY_STR, /* 0x0e */
+ EMPTY_STR, /* 0x0f */
+ EMPTY_STR, /* 0x10 */
+ EMPTY_STR, /* 0x11 */
+ EMPTY_STR, /* 0x12 */
+ EMPTY_STR, /* 0x13 */
+ EMPTY_STR, /* 0x14 */
+ EMPTY_STR, /* 0x15 */
+ EMPTY_STR, /* 0x16 */
+ EMPTY_STR, /* 0x17 */
+ EMPTY_STR, /* 0x18 */
+ EMPTY_STR, /* 0x19 */
+ EMPTY_STR, /* 0x1a */
+ EMPTY_STR, /* 0x1b */
+ EMPTY_STR, /* 0x1c */
+ EMPTY_STR, /* 0x1d */
+ EMPTY_STR, /* 0x1e */
+ EMPTY_STR, /* 0x1f */
+ EMPTY_STR, /* 0x20 */
+ EMPTY_STR, /* 0x21 */
+ EMPTY_STR, /* 0x22 */
+ EMPTY_STR, /* 0x23 */
+ EMPTY_STR, /* 0x24 */
+ EMPTY_STR, /* 0x25 */
+ EMPTY_STR, /* 0x26 */
+ EMPTY_STR, /* 0x27 */
+ EMPTY_STR, /* 0x28 */
+ EMPTY_STR, /* 0x29 */
+ EMPTY_STR, /* 0x2a */
+ EMPTY_STR, /* 0x2b */
+ EMPTY_STR, /* 0x2c */
+ EMPTY_STR, /* 0x2d */
+ EMPTY_STR, /* 0x2e */
+ EMPTY_STR, /* 0x2f */
+ EMPTY_STR, /* 0x30 */
+ EMPTY_STR, /* 0x31 */
+ EMPTY_STR, /* 0x32 */
+ EMPTY_STR, /* 0x33 */
+ EMPTY_STR, /* 0x34 */
+ EMPTY_STR, /* 0x35 */
+ EMPTY_STR, /* 0x36 */
+ EMPTY_STR, /* 0x37 */
+ EMPTY_STR, /* 0x38 */
+ EMPTY_STR, /* 0x39 */
+ EMPTY_STR, /* 0x3a */
+ EMPTY_STR, /* 0x3b */
+ EMPTY_STR, /* 0x3c */
+ EMPTY_STR, /* 0x3d */
+ EMPTY_STR, /* 0x3e */
+ EMPTY_STR, /* 0x3f */
+ EMPTY_STR, /* 0x40 */
+ EMPTY_STR, /* 0x41 */
+ EMPTY_STR, /* 0x42 */
+ EMPTY_STR, /* 0x43 */
+ EMPTY_STR, /* 0x44 */
+ EMPTY_STR, /* 0x45 */
+ EMPTY_STR, /* 0x46 */
+ EMPTY_STR, /* 0x47 */
+ EMPTY_STR, /* 0x48 */
+ EMPTY_STR, /* 0x49 */
+ EMPTY_STR, /* 0x4a */
+ EMPTY_STR, /* 0x4b */
+ EMPTY_STR, /* 0x4c */
+ EMPTY_STR, /* 0x4d */
+ EMPTY_STR, /* 0x4e */
+ EMPTY_STR, /* 0x4f */
+ EMPTY_STR, /* 0x50 */
+ EMPTY_STR, /* 0x51 */
+ EMPTY_STR, /* 0x52 */
+ EMPTY_STR, /* 0x53 */
+ EMPTY_STR, /* 0x54 */
+ EMPTY_STR, /* 0x55 */
+ EMPTY_STR, /* 0x56 */
+ EMPTY_STR, /* 0x57 */
+ EMPTY_STR, /* 0x58 */
+ EMPTY_STR, /* 0x59 */
+ EMPTY_STR, /* 0x5a */
+ EMPTY_STR, /* 0x5b */
+ EMPTY_STR, /* 0x5c */
+ EMPTY_STR, /* 0x5d */
+ EMPTY_STR, /* 0x5e */
+ EMPTY_STR, /* 0x5f */
+ EMPTY_STR, /* 0x60 */
+ EMPTY_STR, /* 0x61 */
+ EMPTY_STR, /* 0x62 */
+ EMPTY_STR, /* 0x63 */
+ EMPTY_STR, /* 0x64 */
+ EMPTY_STR, /* 0x65 */
+ EMPTY_STR, /* 0x66 */
+ EMPTY_STR, /* 0x67 */
+ EMPTY_STR, /* 0x68 */
+ EMPTY_STR, /* 0x69 */
+ EMPTY_STR, /* 0x6a */
+ EMPTY_STR, /* 0x6b */
+ EMPTY_STR, /* 0x6c */
+ EMPTY_STR, /* 0x6d */
+ EMPTY_STR, /* 0x6e */
+ EMPTY_STR, /* 0x6f */
+ "modem-control",/* 0x70 */ // Vendor defined widget
+ "modem-in", /* 0x71 */
+ "modem-out", /* 0x72 */
+ "modem-jack", /* 0x73 */
+ NULL
+};
+
+extern int hdaudio_GPIO_init_1 (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+
+static const codec_desc_t codecs[] = {
+ /* Realtek HDA codecs */
+ {0x10ec0260, "ALC260", VF_NONE, (char **) &alc260remap},
+ {0x10ec0262, "ALC262", VF_NONE, (char **) &alc262remap},
+ {0x10ec0268, "ALC268", VF_NONE, (char **) &alc262remap},
+ {0x10ec0662, "ALC662", VF_NONE, (char **) &alc662remap},
+ {0x10ec0663, "ALC663", VF_NONE, (char **) &alc662remap},
+ {0x10ec0861, "ALC861", VF_NONE, (char **) &alc861remap},
+ {0x10ec0862, "ALC862", VF_NONE, (char **) &alc861remap},
+ {0x10ec0880, "ALC880", VF_ALC88X_HACK, (char **) &alc880remap},
+ {0x10ec0882, "ALC882", VF_ALC88X_HACK, (char **) &alc880remap},
+ {0x10ec0883, "ALC883", VF_ALC88X_HACK, (char **) &alc883remap},
+ {0x10ec0885, "ALC885", VF_ALC88X_HACK, (char **) &alc883remap},
+ {0x10ec0887, "ALC887", VF_ALC88X_HACK, (char **) &alc883remap},
+ {0x10ec0888, "ALC888", VF_ALC88X_HACK, (char **) &alc883remap},
+ {0x10ec0889, "ALC889", VF_ALC88X_HACK, (char **) &alc883remap},
+ {0x10ec0892, "ALC892", VF_ALC88X_HACK, (char **) &alc883remap},
+
+ /* CMedia HDA codecs */
+ {0x13f69880, "CMI9880", VF_NONE, (char **) &cmi9880remap},
+ {0x434d4980, "CMI9880", VF_NONE, (char **) &cmi9880remap},
+
+ {0x111d7603, "92HD75B3X5", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+ {0x111d7608, "92HD75B2X5", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+ {0x111d76b0, "92HD71B8X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+ {0x111d76b1, "92HD71B8X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+ {0x111d76b2, "92HD71B7X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+ {0x111d76b3, "92HD71B7X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+ {0x111d76b4, "92HD71B6X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+ {0x111d76b5, "92HD71B6X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+ {0x111d76b6, "92HD71B5X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+ {0x111d76b7, "92HD71B5X", VF_NONE, NULL, 0, hdaudio_GPIO_init_1},
+
+ /* Analog Devices HDA codecs */
+ {0x11d41981, "AD1981", VF_NONE, (char **) &ad1981remap, 0x76543021},
+ {0x11d41983, "AD1983", VF_NONE, (char **) &ad1983remap, 0x76543021},
+ {0x11d41984, "AD1984", VF_NONE, (char **) &ad1984remap, 0x76543012},
+ {0x11d41986, "AD1986A", VF_NONE, (char **) &ad1986remap, 0x76540321},
+ {0x11d41988, "AD1988A", VF_NONE, (char **) &ad1988remap, 0x76015432},
+ {0x11d4198b, "AD1988B", VF_NONE, (char **) &ad1988remap, 0x76015432},
+
+ /* Sigmatel HDA codecs (some of them) */
+ {0x83847690, "STAC9200", VF_NONE, (char **) &stac920xremap },
+ {0x838476a0, "STAC9205", VF_NONE, (char **) &stac920xremap },
+ {0x838476a1, "STAC9205D", VF_NONE, (char **) &stac920xremap },
+ {0x838476a2, "STAC9204", VF_NONE, (char **) &stac920xremap },
+ {0x838476a3, "STAC9204D", VF_NONE, (char **) &stac920xremap },
+
+ /* Apple Macbook ids */
+ {0x83847880, "STAC9220 A1", VF_NONE, (char **) &stac922xremap },
+ {0x83847882, "STAC9220 A2", VF_NONE, (char **) &stac922xremap },
+ {0x83847680, "STAC9221 A1", VF_NONE, (char **) &stac922xremap },
+
+ {0x83847681, "STAC9220D", VF_NONE, (char **) &stac922xremap },
+ {0x83847682, "STAC9221", VF_NONE, (char **) &stac922xremap },
+ {0x83847683, "STAC9221D", VF_NONE, (char **) &stac922xremap },
+
+ {0x83847610, "STAC9230XN", VF_NONE, (char **) &stac923xremap },
+ {0x83847611, "STAC9230DN", VF_NONE, (char **) &stac923xremap },
+ {0x83847612, "STAC9230XT", VF_NONE, (char **) &stac923xremap },
+ {0x83847613, "STAC9230DT", VF_NONE, (char **) &stac923xremap },
+ {0x83847614, "STAC9229X", VF_NONE, (char **) &stac923xremap },
+ {0x83847615, "STAC9229D", VF_NONE, (char **) &stac923xremap },
+ {0x83847616, "STAC9228X", VF_NONE, (char **) &stac923xremap },
+ {0x83847617, "STAC9228D", VF_NONE, (char **) &stac923xremap },
+ {0x83847618, "STAC9227X", VF_NONE, (char **) &stac923xremap }, /* Intel D975XBX2 (at least) */
+ {0x83847619, "STAC9227D", VF_NONE, (char **) &stac923xremap },
+
+ {0x838476a4, "STAC9255", VF_NONE, (char **) &stac925xremap },
+ {0x838476a5, "STAC9255D", VF_NONE, (char **) &stac925xremap },
+ {0x838476a6, "STAC9254", VF_NONE, (char **) &stac925xremap },
+ {0x838476a7, "STAC9254D", VF_NONE, (char **) &stac925xremap },
+
+ {0x83847620, "STAC9274", VF_NONE, (char **) &stac923xremap },
+ {0x83847621, "STAC9274D", VF_NONE, (char **) &stac923xremap },
+ {0x83847622, "STAC9273X", VF_NONE, (char **) &stac923xremap },
+ {0x83847623, "STAC9273D", VF_NONE, (char **) &stac923xremap },
+ {0x83847624, "STAC9272X", VF_NONE, (char **) &stac923xremap },
+ {0x83847625, "STAC9272D", VF_NONE, (char **) &stac923xremap },
+ {0x83847626, "STAC9271X", VF_NONE, (char **) &stac923xremap },
+ {0x83847627, "STAC9271D", VF_NONE, (char **) &stac923xremap },
+
+ {0x83847628, "STAC9274X5NH", VF_NONE, (char **) &stac923xremap },
+ {0x83847629, "STAC9274D5NH", VF_NONE, (char **) &stac923xremap },
+ {0x83847661, "CXD9872RD", VF_NONE, NULL, 0x76543012},
+ {0x83847662, "STAC9872AK", VF_NONE, NULL, 0x76543012},
+ {0x83847664, "STAC9872K", VF_NONE, NULL, 0x76543210}, /* Vaio VGN-AR51J */
+
+ /* Conexant */
+ {0x14f15045, "CX20548", VF_NONE, NULL, 0x76543201},
+ {0x14f15047, "CX20551", VF_NONE, NULL, 0x76543201},
+ {0x14f15051, "CX20561", VF_NONE, NULL, 0x76543210},
+ {0x14f12c06, "Conexant2c06", VF_NONE, (char **) &conexant_modem_remap, 0, NULL_mixer_init}, /* Modem codec (Vaio) */
+ {0x14f12bfa, "Conexant2bfa", VF_NONE, (char **) &conexant_modem_remap, 0, NULL_mixer_init}, /* Modem codec (Acer Ferrari 5k) */
+
+ /* Si3055 and compatible modems */
+ {0x163c3055, "Si3055", VF_SI3055_HACK, NULL, 0, NULL_mixer_init },
+ {0x163c3155, "Si3155", VF_SI3055_HACK, NULL, 0, NULL_mixer_init },
+ {0x11c13026, "Agere3026", VF_SI3055_HACK, NULL, 0, NULL_mixer_init },
+ {0x11c13055, "Agere3055", VF_SI3055_HACK, NULL, 0, NULL_mixer_init },
+ {0x11c13155, "Agere3155", VF_SI3055_HACK, NULL, 0, NULL_mixer_init },
+ {0x10573055, "Motorola3055", VF_SI3055_HACK, NULL, 0, NULL_mixer_init },
+ {0x10573057, "Motorola3057", VF_SI3055_HACK, NULL, 0, NULL_mixer_init },
+ {0x10573155, "Motorola3155", VF_SI3055_HACK, NULL, 0, NULL_mixer_init },
+
+ /* Creative Labs */
+ {0x1102000a, "Createive XFi XTreme", VF_NONE, NULL, 0x76543210},
+
+ {0x11c11040, "Agere HDA Modem", VF_NONE, NULL, 0, NULL_mixer_init},
+
+ /* Unknown */
+ {0, "Unknown"}
+};
+
+static const char *abit_AA8_remap[] = {
+ EMPTY_STR, /* 0 */
+ EMPTY_STR, /* 1 */
+ "front", /* 2 */
+ "rear", /* 3 */
+ "center/LFE", /* 4 */
+ "side", /* 5 */
+ "spdif-out", /* 6 */
+ "rec1", /* 7 */
+ "rec2", /* 8 */
+ "rec3", /* 9 */
+ "spdif-in", /* 10 */
+ "inputmix", /* 11 */
+ "front", /* 12 */
+ "rear", /* 13 */
+ "center/LFE", /* 14 */
+ "side", /* 15 */
+ "out-source", /* 16 */
+ "out-source", /* 17 */
+ "out-source", /* 18 */
+ "out-source", /* 19 */
+ "green1", /* 20 */
+ "black1", /* 21 */
+ "C-L", /* 22 */
+ "surr", /* 23 */
+ "pink1", /* 24 */
+ "pink2", /* 25 */
+ "blue1", /* 26 */
+ "blue2", /* 27 */
+ "cd", /* 28 */
+ "beep", /* 29 */
+ "spdout", /* 30 */
+ "spdin", /* 31 */
+ "vendor", /* 32 */
+ "vol", /* 33 */
+ NULL
+};
+
+static const char *vaio_remap[] = {
+ EMPTY_STR, /* 0x00 */
+ EMPTY_STR, /* 0x01 */
+ "headphone", /* 0x02 */
+ "pcm", /* 0x03 */ // Unused
+ "pcm", /* 0x04 */ // Unused
+ "speaker", /* 0x05 */
+ "rec1", /* 0x06 */
+ "rec1-vol", /* 0x07 */
+ "rec", /* 0x08 */
+ "rec-vol", /* 0x09 */
+ "headphone", /* 0x0a */
+ EMPTY_STR, /* 0x0b */ // Unused
+ EMPTY_STR, /* 0x0c */ // Unused
+ "mic", /* 0x0d */
+ EMPTY_STR, /* 0x0e */
+ "int-speaker", /* 0x0f */
+ "spdifout1", /* 0x10 */
+ "int-digout1", /* 0x11 */
+ "spdifin", /* 0x12 */
+ "int-digout", /* 0x13 */
+ "int-mic", /* 0x14 */
+ "rec", /* 0x15 */
+ "beep", /* 0x16 */
+ "vol", /* 0x17 */
+ "spdifout", /* 0x18 */
+ NULL
+};
+
+static const char *alc262_vaio_remap[] =
+{
+ EMPTY_STR, /* 0x00 */
+ EMPTY_STR, /* 0x01 */
+ "speaker", /* 0x02 */
+ "headphone", /* 0x03 */
+ "vendor", /* 0x04 */
+ "vendor", /* 0x05 */
+ "hdmi-out", /* 0x06 */
+ "rec1", /* 0x07 */
+ "rec2", /* 0x08 */
+ "rec3", /* 0x09 */
+ "spdif-in", /* 0x0a */
+ "mix", /* 0x0b */
+ "mix", /* 0x0c */
+ "mix", /* 0x0d */
+ "mono", /* 0x0e */
+ "vendor", /* 0x0f */
+ "vendor", /* 0x10 */
+ "mono", /* 0x11 */
+ "dmic", /* 0x12 */
+ "vendor", /* 0x13 */
+ "line-out", /* 0x14 */
+ "headphone", /* 0x15 */
+ "mono", /* 0x16 */
+ "beep", /* 0x17 */
+ "speaker", /* 0x18 */
+ "speaker", /* 0x19 */
+ "speaker", /* 0x1a */
+ "speaker", /* 0x1b */
+ "speaker", /* 0x1c */
+ "beep", /* 0x1d */
+ "spdif-out", /* 0x1e */
+ "spdif-in", /* 0x1f */
+ "vendor", /* 0x20 */
+ "vol", /* 0x21 */
+ "rec3", /* 0x22 */
+ "rec2", /* 0x23 */
+ "rec1", /* 0x24 */
+ NULL
+};
+
+/*
+ * Table for subsystem ID's that require special handling
+ */
+
+extern int hdaudio_Asus_P4B_E_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_scaleoP_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_abit_AA8_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_ferrari5k_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_vaio_vgn_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_thinkpad_r61_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_mac_sigmatel_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_mac_realtek_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_eeepc_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_asus_a7k_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+extern int hdaudio_asus_m9_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group);
+
+static const codec_desc_t subdevices[] = {
+ {0x98801019, "ECS 915P-A", VF_NONE, NULL, 0x76541320},
+ {0x104381e1, "Asus P4B-E/AD1988A", VF_NONE, (char **) &ad1988remap, 0x76015432, hdaudio_Asus_P4B_E_mixer_init},
+ // {0x1043e601, "ScaleoP/ALC888", VF_ALC88X_HACK, (char **) &alc883remap, 0, hdaudio_scaleoP_mixer_init},
+
+ /* Abit AA8 (at least some revisions) have bogus codec config information,
+ * including the subvendor ID. 0x08800000 is used by many other motherboards
+ * too. Have to use the pci_subvendor field for alc880 based devices:
+ * 0x147b1039 = Abit AA8 motherboard.
+ * 0x15849077 = Rock Pegasus 665 laptop.
+ */
+ {0x08800000, "Abit AA8/ALC880", VF_ALC88X_HACK, (char **) &abit_AA8_remap, 0, hdaudio_abit_AA8_mixer_init, 0, 0x147b1039},
+
+ {0x10250000, "Ferrari5k/ALC883", VF_ALC88X_HACK, (char **) &alc883remap, 0, hdaudio_ferrari5k_mixer_init, 0x10ec0883, 0x1025010a},
+ {0x10250000, "Acer_aspire5052/ALC883", VF_ALC88X_HACK, (char **) &alc883remap, 0, hdaudio_ferrari5k_mixer_init, 0x10ec0883, 0x1025010f},
+ {0x1025160d, "Acer_travelmate4060/ALC260", VF_NONE, (char **) &alc260remap, 0, hdaudio_GPIO_init_1, 0x10ec0260, 0x1025008f},
+ {0x10431153, "Asus M9", VF_NONE, (char **) &ad1986remap, 0x76540321, hdaudio_asus_m9_mixer_init},
+
+ /*
+ **** Sony Vaio VGN-AR51 ***
+ * Has three codecs. Primary (Stac9872K), Modem (Conexant) and
+ * HDMI digital output (ALC262). Disable the mixer entries for codecs 2 and 3.
+ */
+ {0x104d2200, "Vaio/STAC9872K", VF_VAIO_HACK, (char**) &vaio_remap, 0x76540213, hdaudio_vaio_vgn_mixer_init, 0x83847664, 0x104d9016},
+ /* 2nd codec (#1) is "Conexant2c06" modem */
+ {0x104d2200, "Vaio/HDMI", VF_NONE, (char **) &alc262_vaio_remap, 0, NULL_mixer_init, 0x10ec0262, 0x104d9016},
+ /****/
+
+ /*
+ * Sony VAIO SZ2, SZ3, FE and FE31B
+ */
+ {0x104d0700, "Vaio/CXD9872RD", VF_VAIO_HACK, (char**) &vaio_remap, 0x76540213, hdaudio_vaio_vgn_mixer_init, 0x83847661, 0x104d81e6},
+ {0x104d1000, "Vaio/CXD9872RD", VF_VAIO_HACK, (char**) &vaio_remap, 0x76540213, hdaudio_vaio_vgn_mixer_init, 0x83847661, 0x104d81ef},
+ {0x104d0c00, "Vaio/CXD9872RD", VF_VAIO_HACK, (char**) &vaio_remap, 0x76540213, hdaudio_vaio_vgn_mixer_init, 0x83847661, 0x104d81ef},
+
+ /*
+ * Sony VAIO AR
+ */
+ {0x104d1300, "Vaio/CXD9872AKD", VF_VAIO_HACK, (char**) &vaio_remap, 0x76540213, hdaudio_vaio_vgn_mixer_init, 0x83847664, 0x104d81fd},
+
+ /*
+ * Sony Vaio SZ (SZ650) has two codecs, STAC9872AK and Conexant modem.
+ * Assume the audio codec is identical with Vaio AGN (above).
+ */
+ {0x104d1e00, "Vaio/STAC9872AK", VF_VAIO_HACK, (char**) &vaio_remap, 0x76540213, hdaudio_vaio_vgn_mixer_init, 0x83847662, 0x104d9008},
+ /* Vaio VGC-LA1 */
+ {0x104d1200, "Vaio/STAC9872AK", VF_VAIO_HACK, (char**) &vaio_remap, 0x76540213, hdaudio_vaio_vgn_mixer_init, 0x83847662, 0x104d8205},
+
+/*
+ * Thinkpad R61
+ */
+ {0x17aa20bb, "Thinkpad R61", VF_NONE, (char**) &ad1984remap, 0, hdaudio_thinkpad_r61_mixer_init},
+
+/*
+ * Asus Eee PC (model 900 at least)
+ */
+ {0x10438337, "Asus Eee PC", VF_NONE, NULL, 0, hdaudio_eeepc_mixer_init},
+
+ /*
+ * Asus A7K
+ */
+ {0x10431339, "Asus A7K", VF_ALC88X_HACK, (char **) &alc880remap, 0, hdaudio_asus_a7k_GPIO_init}, // ALC660
+
+/*
+ * Known Macintosh systems
+ */
+ {0x106b0800, "Intel Mac V1", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b0700, "Intel Mac V2", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b0600, "Intel Mac V2", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b0200, "Intel Mac V3", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b0e00, "Intel Mac V3", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b0f00, "Intel Mac V3", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b1600, "Intel Mac V3", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b1700, "Intel Mac V3", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b1e00, "Intel Mac V3", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b1a00, "Intel Mac V4", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ // {0x00000100, "Intel Mac V4", VF_NONE, (char **) &stac922xremap, ?, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b0a00, "Intel Mac V5", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b2200, "Intel Mac V5", VF_NONE, (char **) &stac922xremap, 0, hdaudio_mac_sigmatel_GPIO_init},
+ {0x106b3200, "Intel iMac", VF_ALC88X_HACK, (char **) &alc883remap, 0, hdaudio_mac_realtek_GPIO_init}, // ALC885
+
+ {0, "Unknown"}
+};
+
diff --git a/kernel/drv/oss_hdaudio/hdaudio_dedicated.h b/kernel/drv/oss_hdaudio/hdaudio_dedicated.h
new file mode 100644
index 0000000..a4ddcfb
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_dedicated.h
@@ -0,0 +1,74 @@
+/*
+ * Purpose: Definitions for dedicated HD audio codec drivers
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 HDAUDIO_DEDICATED_H
+#define HDAUDIO_DEDICATED_H
+
+extern void hda_codec_add_group(int dev, hdaudio_mixer_t * mixer, int cad, int *group, int parent_group, const char *name);
+extern int hda_codec_add_pingroup(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int *group, int top_group, int *parent_group, const char *name, int *n, const char *parent_name, int group_size);
+extern int hda_codec_add_adcgroup(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int *group, int top_group, int *parent_group, const char *name, int *n, const char *parent_name, int group_size);
+extern int hda_codec_add_miscgroup(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int *group, int top_group, int *parent_group, const char *name, int *n, const char *parent_name, int group_size);
+
+#define HDA_GROUP(group, top_group, name) hda_codec_add_group(dev, mixer, cad, &group, top_group, name)
+#define HDA_PIN_GROUP(wid, group, pin_group, name, n, parent_name, group_size) \
+ hda_codec_add_pingroup(dev, mixer, cad, wid, &group, top_group, &pin_group, name, &n, parent_name, group_size)
+#define HDA_ADC_GROUP(wid, group, rec_group, name, n, parent_name, group_size) \
+ hda_codec_add_adcgroup(dev, mixer, cad, wid, &group, top_group, &rec_group, name, &n, parent_name, group_size)
+#define HDA_MISC_GROUP(wid, group, misc_group, name, n, parent_name, group_size) \
+ hda_codec_add_miscgroup(dev, mixer, cad, wid, &group, top_group, &misc_group, name, &n, parent_name, group_size)
+
+#define UNMUTE 0
+#define MUTE 1
+#define RECORD 1
+#define NOREC 0
+
+extern int hda_codec_add_outamp(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int group, const char *name, int percent, unsigned int flags);
+extern int hda_codec_add_outmute(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int group, const char *name, int state);
+#define HDA_OUTAMP(wid, group, name, percent) ctl=hda_codec_add_outamp(dev, mixer, cad, wid, group, name, percent, 0)
+#define HDA_OUTAMP_F(wid, group, name, percent, flags) hda_codec_add_outamp(dev, mixer, cad, wid, group, name, percent, flags)
+#define HDA_OUTMUTE(wid, group, name, muted) ctl=hda_codec_add_outmute(dev, mixer, cad, wid, group, name, muted)
+
+extern int hda_codec_add_inamp(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int ix, int group, const char *name, int percent, unsigned int flags);
+extern int hda_codec_add_inmute(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int ix, int group, const char *name, int muted, int flags);
+extern int hda_codec_set_inmute(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int ix, int muted);
+extern int hda_codec_add_insrc(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int ix, int group, const char *name, int muted);
+extern int hda_codec_add_insrcselect(int dev, hdaudio_mixer_t * mixer, int cad, int wid, int group, int *ctl, const char *name, int initial_selection);
+
+#define HDA_INAMP(wid, ix, group, name, percent) ctl=hda_codec_add_inamp(dev, mixer, cad, wid, ix, group, name, percent, 0)
+#define HDA_INAMP_F(wid, ix, group, name, percent, flags) ctl=hda_codec_add_inamp(dev, mixer, cad, wid, ix, group, name, percent, flags)
+
+#define HDA_INMUTE(wid, ix, group, name, muted) ctl=hda_codec_add_inmute(dev, mixer, cad, wid, ix, group, name, muted, 0)
+#define HDA_INMUTE_F(wid, ix, group, name, muted, flags) ctl=hda_codec_add_inmute(dev, mixer, cad, wid, ix, group, name, muted, flags)
+#define HDA_SET_INMUTE(wid, ix, muted) hda_codec_set_inmute(dev, mixer, cad, wid, ix, muted)
+#define HDA_INSRC(wid, ix, group, name, muted) hda_codec_add_insrc(dev, mixer, cad, wid, ix, group, name, muted)
+#define HDA_INSRC_SELECT(wid, group, ctl, name, initial_selection) \
+ hda_codec_add_insrcselect(dev, mixer, cad, wid, group, &ctl, name, initial_selection)
+
+extern int hda_codec_add_select(int dev, hdaudio_mixer_t *mixer, int cad, int wid, int group, const char *name, int *ctl, int initial_select);
+extern void hda_codec_set_select(int dev, hdaudio_mixer_t *mixer, int cad, int wid, int value);
+extern void hda_codec_set_pinselect(int dev, hdaudio_mixer_t *mixer, int cad, int wid, int value);
+extern int hda_codec_add_pinselect(int dev, hdaudio_mixer_t *mixer, int cad, int wid, int group, const char *name, int *ctl, int initial_select);
+#define HDA_SELECT(wid, name, ctl, group, sel) hda_codec_add_select(dev, mixer, cad, wid, group, name, &ctl, sel)
+#define HDA_PINSELECT(wid, ctl, group, name, sel) hda_codec_add_pinselect(dev, mixer, cad, wid, group, name, &ctl, sel)
+#define HDA_SETSELECT(wid, value) hda_codec_set_select(dev, mixer, cad, wid, value)
+#define HDA_SET_PINSELECT(wid, value) hda_codec_set_pinselect(dev, mixer, cad, wid, value)
+
+extern int hda_codec_add_choices(int dev, hdaudio_mixer_t *mixer, int ctl, const char *choiselist);
+#define HDA_CHOICES(ctl, choicelist) hda_codec_add_choices(dev, mixer, ctl, choicelist)
+
+extern void hda_codec_set_color(int dev, hdaudio_mixer_t *mixer, int ctl, int color);
+#define HDA_COLOR(ctl, color) hda_codec_set_color(dev, mixer, ctl, color)
+
+#endif
+
diff --git a/kernel/drv/oss_hdaudio/hdaudio_eeepc.c b/kernel/drv/oss_hdaudio/hdaudio_eeepc.c
new file mode 100644
index 0000000..8fef9f7
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_eeepc.c
@@ -0,0 +1,293 @@
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * Purpose: Dedicated HDaudio mixer driver for Asus Eee PC
+ */
+
+/* Codec index is 0 */
+/* Codec vendor 10ec:0662 */
+/* HD codec revision 1.0 (1.1) (0x00100101) */
+/* Subsystem ID 10438337 */
+/* Default amplifier caps: in=00000000, out=00000000 */
+#include "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_dedicated.h"
+
+int
+hdaudio_eeepc_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+{
+ int ctl=0;
+
+ DDB(cmn_err(CE_CONT, "hdaudio_eeepc_mixer_init got called.\n"));
+
+ HDA_OUTAMP(0x02, top_group, "pcm-front", 100);
+ HDA_OUTAMP(0x04, top_group, "pcm-rear", 100);
+
+ /* Handle PIN widgets */
+ {
+ int n, group, pin_group;
+
+ n=0;
+
+ HDA_GROUP(pin_group, top_group, "jack");
+
+ if (HDA_PIN_GROUP(0x14, group, pin_group, "speaker", n, "jack", 4)) /* Pin widget 0x14 */
+ {
+ /* Src 0xc=front */
+#if 1
+ HDA_SET_PINSELECT(0x14, 0); // Hardwire as output
+#else
+ if (HDA_PINSELECT(0x14, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "front-out input");
+#endif
+ HDA_OUTMUTE(0x14, group, "mute", UNMUTE);
+ }
+
+#if 0
+ if (HDA_PIN_GROUP(0x15, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x15 */
+ {
+ /* Src 0xd=rear */
+ if (HDA_PINSELECT(0x15, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "rear-out input");
+ HDA_OUTMUTE(0x15, group, "mute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP(0x16, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x16 */
+ {
+ /* Src 0xe=rear */
+ if (HDA_PINSELECT(0x16, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "rear-out input");
+ HDA_OUTMUTE(0x16, group, "mute", UNMUTE);
+ }
+#endif
+
+ if (HDA_PIN_GROUP(0x19, group, pin_group, "mic", n, "jack", 4)) /* Pin widget 0x19 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xe=rear */
+#if 0
+ if (HDA_PINSELECT(0x19, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "front-out rear-out input");
+ // HDA_OUTMUTE(0x19, group, "inmute", UNMUTE);
+#else
+ HDA_SET_PINSELECT(0x19, 2); // Hardwire to input
+#endif
+ HDA_INAMP(0x19, 0, group, "in", 90); /* From widget 0x0c */
+ }
+
+#if 0
+ if (HDA_PIN_GROUP(0x1a, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x1a */
+ {
+ /* Src 0xd=rear */
+ if (HDA_PINSELECT(0x1a, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "rear-out input");
+ HDA_OUTMUTE(0x1a, group, "inmute", UNMUTE);
+ }
+#endif
+
+ if (HDA_PIN_GROUP(0x1b, group, pin_group, "green", n, "jack", 4)) /* Pin widget 0x1b */
+ {
+ /* Src 0xc=front */
+ /* Src 0xe=rear */
+ if (HDA_PINSELECT(0x1b, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "front-out rear-out input");
+ HDA_OUTMUTE(0x1b, group, "inmute", UNMUTE);
+ HDA_INAMP(0x1b, 0, group, "out", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP(0x18, group, pin_group, "pink", n, "jack", 4)) /* Pin widget 0x18 */
+ {
+ /* Src 0xe=rear */
+ if (HDA_PINSELECT(0x18, ctl, group, "mode", 1))
+ HDA_CHOICES(ctl, "rear-out input");
+ HDA_OUTMUTE(0x18, group, "mute", UNMUTE);
+ HDA_INAMP(0x18, 0, group, "in", 90); /* From widget 0x0e */
+ }
+
+#if 0
+ if (HDA_PIN_GROUP(0x1c, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x1c */
+ {
+ if (HDA_PINSELECT(0x1c, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "input");
+ }
+
+ if (HDA_PIN_GROUP(0x1d, group, pin_group, "purple", n, "jack", 4)) /* Pin widget 0x1d */
+ {
+ if (HDA_PINSELECT(0x1d, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "input");
+ }
+#endif
+ }
+ /* Handle ADC widgets */
+ {
+ int n, group, rec_group;
+
+ n=0;
+
+ HDA_GROUP(rec_group, top_group, "record");
+
+ if (HDA_ADC_GROUP(0x08, group, rec_group, "pcmin0", n, "record", 4)) /* ADC widget 0x08 */
+ {
+ /* Src 0x23=mix */
+ HDA_INAMP(0x08, 0, group, "-", 90); /* From widget 0x23 */
+
+ /* Widget 0x23 (mix) */
+ /* Src 0x18=pink */
+ /* Src 0x19=mic */
+ /* Src 0x1a=black */
+ /* Src 0x1b=green */
+ /* Src 0x1c=black */
+ /* Src 0x1d=purple */
+ /* Src 0x14=speaker */
+ /* Src 0x15=black */
+ /* Src 0x16=black */
+ /* Src 0xb=mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "rec-mute");
+ HDA_INMUTE(0x23, 0, amp_group, "pink", MUTE); /* From widget 0x18 */
+ HDA_INMUTE(0x23, 1, amp_group, "mic", UNMUTE); /* From widget 0x19 */
+ HDA_INMUTE(0x23, 2, amp_group, "black", MUTE); /* From widget 0x1a */
+ HDA_INMUTE(0x23, 3, amp_group, "green", MUTE); /* From widget 0x1b */
+ HDA_INMUTE(0x23, 4, amp_group, "black", MUTE); /* From widget 0x1c */
+ HDA_INMUTE(0x23, 5, amp_group, "purple", MUTE); /* From widget 0x1d */
+ HDA_INMUTE(0x23, 6, amp_group, "speaker", MUTE); /* From widget 0x14 */
+ HDA_INMUTE(0x23, 7, amp_group, "black", MUTE); /* From widget 0x15 */
+ HDA_INMUTE(0x23, 8, amp_group, "black", MUTE); /* From widget 0x16 */
+ HDA_INMUTE(0x23, 9, amp_group, "input-mixer", MUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_ADC_GROUP(0x09, group, rec_group, "pcmin1", n, "record", 4)) /* ADC widget 0x09 */
+ {
+ /* Src 0x22=mix */
+ HDA_INAMP(0x09, 0, group, "-", 90); /* From widget 0x22 */
+
+ /* Widget 0x22 (mix) */
+ /* Src 0x18=pink */
+ /* Src 0x19=mic */
+ /* Src 0x1a=black */
+ /* Src 0x1b=green */
+ /* Src 0x1c=black */
+ /* Src 0x1d=purple */
+ /* Src 0x14=speaker */
+ /* Src 0x15=black */
+ /* Src 0x16=black */
+ /* Src 0xb=mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "rec-mute");
+ HDA_INMUTE(0x22, 0, amp_group, "pink", MUTE); /* From widget 0x18 */
+ HDA_INMUTE(0x22, 1, amp_group, "mic", MUTE); /* From widget 0x19 */
+ HDA_INMUTE(0x22, 2, amp_group, "black", MUTE); /* From widget 0x1a */
+ HDA_INMUTE(0x22, 3, amp_group, "green", MUTE); /* From widget 0x1b */
+ HDA_INMUTE(0x22, 4, amp_group, "black", MUTE); /* From widget 0x1c */
+ HDA_INMUTE(0x22, 5, amp_group, "purple", MUTE); /* From widget 0x1d */
+ HDA_INMUTE(0x22, 6, amp_group, "speaker", MUTE); /* From widget 0x14 */
+ HDA_INMUTE(0x22, 7, amp_group, "black", MUTE); /* From widget 0x15 */
+ HDA_INMUTE(0x22, 8, amp_group, "black", MUTE); /* From widget 0x16 */
+ HDA_INMUTE(0x22, 9, amp_group, "input-mixer", UNMUTE); /* From widget 0x0b */
+ }
+ }
+ }
+ /* Handle misc widgets */
+ {
+ int n, group, misc_group;
+
+ n=0;
+
+ HDA_GROUP(misc_group, top_group, "misc");
+
+ if (HDA_MISC_GROUP(0x0c, group, misc_group, "front", n, "misc", 8)) /* Misc widget 0x0c */
+ {
+ /* Src 0x2=front */
+ /* Src 0xb=mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x0c, 0, amp_group, "pcm-front", UNMUTE); /* From widget 0x02 */
+ HDA_INMUTE(0x0c, 1, amp_group, "input-mixer", UNMUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x0d, group, misc_group, "rear", n, "misc", 8)) /* Misc widget 0x0d */
+ {
+ /* Src 0x3=rear */
+ /* Src 0xb=mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x0d, 0, amp_group, "pcm-rear", UNMUTE); /* From widget 0x03 */
+ HDA_INMUTE(0x0d, 1, amp_group, "input-mixer", UNMUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x0e, group, misc_group, "rear", n, "misc", 8)) /* Misc widget 0x0e */
+ {
+ /* Src 0x4=rear */
+ /* Src 0xb=mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x0e, 0, amp_group, "rear", UNMUTE); /* From widget 0x04 */
+ HDA_INMUTE(0x0e, 1, amp_group, "input-mixer", UNMUTE); /* From widget 0x0b */
+ }
+ }
+
+#if 0
+ if (HDA_MISC_GROUP(0x02, group, misc_group, "pcm-front", n, "misc", 8)) /* Misc widget 0x02 */
+ {
+ HDA_OUTAMP(0x02, group, "-", 90);
+ }
+
+ if (HDA_MISC_GROUP(0x03, group, misc_group, "pcm", n, "misc", 8)) /* Misc widget 0x03 */
+ {
+ HDA_OUTAMP(0x03, group, "-", 0);
+ }
+
+ if (HDA_MISC_GROUP(0x04, group, misc_group, "pcm-rear", n, "misc", 8)) /* Misc widget 0x04 */
+ {
+ HDA_OUTAMP(0x04, group, "-", 90);
+ }
+#endif
+
+ if (HDA_MISC_GROUP(0x0b, group, misc_group, "input-mixer", n, "misc", 8)) /* Misc widget 0x0b */
+ {
+ /* Src 0x18=rear */
+ /* Src 0x19=mic */
+ /* Src 0x1a=rear */
+ /* Src 0x1b=headphone */
+ /* Src 0x1c=speaker */
+ /* Src 0x1d=speaker */
+ /* Src 0x14=front */
+ /* Src 0x15=rear */
+ /* Src 0x16=rear */
+ HDA_INAMP(0x0b, 0, group, "pink", 20); /* From widget 0x18 */
+ HDA_INAMP(0x0b, 1, group, "mic", 20); /* From widget 0x19 */
+ HDA_INAMP(0x0b, 2, group, "black", 90); /* From widget 0x1a */
+ HDA_INAMP(0x0b, 3, group, "green", 90); /* From widget 0x1b */
+ HDA_INAMP(0x0b, 4, group, "black", 90); /* From widget 0x1c */
+ HDA_INAMP(0x0b, 5, group, "purple", 90); /* From widget 0x1d */
+ // HDA_INAMP(0x0b, 6, group, "speaker", 90); /* From widget 0x14 */
+ HDA_INAMP(0x0b, 7, group, "black", 90); /* From widget 0x15 */
+ HDA_INAMP(0x0b, 8, group, "black", 90); /* From widget 0x16 */
+ }
+ }
+ return 0;
+}
diff --git a/kernel/drv/oss_hdaudio/hdaudio_ferrari5k.c b/kernel/drv/oss_hdaudio/hdaudio_ferrari5k.c
new file mode 100644
index 0000000..1ee3eca
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_ferrari5k.c
@@ -0,0 +1,303 @@
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+/* Codec index is 1 */
+/* Codec vendor 10ec:0883 */
+/* HD codec revision 1.0 (0.2) (0x00100002) */
+/* Subsystem ID 10250000 */
+/* Default amplifier caps: in=00000000, out=00000000 */
+#include "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_dedicated.h"
+
+int
+hdaudio_ferrari5k_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+{
+ int ctl=0;
+
+ DDB(cmn_err(CE_CONT, "hdaudio_ferrari5k_mixer_init got called.\n"));
+
+ // Main volume controls for PCM channels. Moved from the misc group
+ HDA_OUTAMP_F(0x0c, top_group, "front", 90, MIXF_MAINVOL);
+ HDA_OUTAMP_F(0x0d, top_group, "rear", 90, MIXF_MAINVOL);
+ HDA_OUTAMP_F(0x0e, top_group, "center/lfe", 90, MIXF_MAINVOL);
+ HDA_OUTAMP_F(0x0f, top_group, "side", 90, MIXF_MAINVOL);
+ HDA_OUTAMP_F(0x26, top_group, "pcm4", 90, MIXF_MAINVOL);
+
+ // Mute controls for the output pins
+ HDA_OUTMUTE(0x15, top_group, "speaker-mute", UNMUTE);
+ HDA_OUTMUTE(0x14, top_group, "headph-mute", UNMUTE);
+ HDA_OUTMUTE(0x1a, top_group, "lineout-mute", UNMUTE);
+ HDA_OUTMUTE(0x18, top_group, "mic-jack-mute", UNMUTE);
+
+ /* Handle PIN widgets */
+ {
+ int n, group, pin_group;
+
+ n=0;
+
+ HDA_GROUP(pin_group, top_group, "jack");
+
+ if (HDA_PIN_GROUP(0x15, group, pin_group, "int-speaker", n, "jack", 8)) /* Pin widget 0x15 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT(0x15, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "front-out rear-out center/LFE-out side-out pcm4-out unused");
+ //HDA_INAMP(0x15, 0, group, "inlevel", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP(0x14, group, pin_group, "headphone", n, "jack", 8)) /* Pin widget 0x14 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT(0x14, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_INAMP(0x14, 0, group, "inlevel", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP(0x18, group, pin_group, "ext-mic", n, "jack", 8)) /* Pin widget 0x18 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT(0x18, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_INAMP(0x18, 0, group, "inlevel", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP(0x19, group, pin_group, "int-mic", n, "jack", 8)) /* Pin widget 0x19 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+#if 1
+ HDA_SETSELECT(0x19, 5); // Hardwired to mic-input
+#else
+ if (HDA_PINSELECT(0x19, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "front-out rear-out center/LFE-out side-out pcm4-out input");
+#endif
+ //HDA_OUTMUTE(0x19, group, "outmute", UNMUTE);
+ HDA_INAMP(0x19, 0, group, "inlevel", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP(0x1a, group, pin_group, "line-out", n, "jack", 8)) /* Pin widget 0x1a */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT(0x1a, ctl, group, "mode", 0))
+ HDA_CHOICES(ctl, "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_INAMP(0x1a, 0, group, "inlevel", 90); /* From widget 0x0c */
+ }
+ }
+
+ /* Handle ADC widgets */
+ {
+ int n, group, rec_group;
+
+ n=0;
+
+ HDA_GROUP(rec_group, top_group, "record");
+
+ if (HDA_ADC_GROUP(0x08, group, rec_group, "rec1", n, "record", 4)) /* ADC widget 0x08 */
+ {
+ /* Src 0x23=rec1 */
+ HDA_INAMP_F(0x08, 0, group, "rec1", 80, MIXF_RECVOL); /* From widget 0x23 */
+
+ /* Widget 0x23 (rec1) */
+ /* Src 0x18=ext-mic */
+ /* Src 0x19=int-mic */
+ /* Src 0x1a=line-out */
+ /* Src 0x1b=black */
+ /* Src 0x1c=black */
+ /* Src 0x1d=black */
+ /* Src 0x14=black */
+ /* Src 0x15=int-speaker */
+ /* Src 0x16=black */
+ /* Src 0x17=black */
+ /* Src 0xb=input-mix */
+ {
+#if 1
+ if (HDA_INSRC_SELECT(0x23, group, ctl, "recsrc", 1))
+ HDA_CHOICES(ctl, "ext-mic int-mic line-out-jack unused unused unused unused unused unused unused input-mix");
+#else
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x23, 0, amp_group, "ext-mic", UNMUTE); /* From widget 0x18 */
+ HDA_INMUTE(0x23, 1, amp_group, "int-mic", UNMUTE); /* From widget 0x19 */
+ HDA_INMUTE(0x23, 2, amp_group, "line-out", UNMUTE); /* From widget 0x1a */
+ HDA_INMUTE(0x23, 3, amp_group, "black", UNMUTE); /* From widget 0x1b */
+ HDA_INMUTE(0x23, 4, amp_group, "black", UNMUTE); /* From widget 0x1c */
+ HDA_INMUTE(0x23, 5, amp_group, "black", UNMUTE); /* From widget 0x1d */
+ HDA_INMUTE(0x23, 6, amp_group, "headph-jack", UNMUTE); /* From widget 0x14 */
+ HDA_INMUTE(0x23, 7, amp_group, "int-speaker", UNMUTE); /* From widget 0x15 */
+ HDA_INMUTE(0x23, 8, amp_group, "black", UNMUTE); /* From widget 0x16 */
+ HDA_INMUTE(0x23, 9, amp_group, "black", UNMUTE); /* From widget 0x17 */
+ HDA_INMUTE(0x23, 10, amp_group, "input-mix", MUTE); /* From widget 0x0b */
+#endif
+ }
+ }
+
+ if (HDA_ADC_GROUP(0x09, group, rec_group, "rec2", n, "record", 4)) /* ADC widget 0x09 */
+ {
+ /* Src 0x22=rec2 */
+ HDA_INAMP_F(0x09, 0, group, "rec2", 80, MIXF_RECVOL); /* From widget 0x22 */
+
+ /* Widget 0x22 (rec2) */
+ /* Src 0x18=ext-mic */
+ /* Src 0x19=int-mic */
+ /* Src 0x1a=line-out */
+ /* Src 0x1b=black */
+ /* Src 0x1c=black */
+ /* Src 0x1d=black */
+ /* Src 0x14=black */
+ /* Src 0x15=int-speaker */
+ /* Src 0x16=black */
+ /* Src 0x17=black */
+ /* Src 0xb=input-mix */
+ {
+#if 1
+ if (HDA_INSRC_SELECT(0x22, group, ctl, "recsrc", 1))
+ HDA_CHOICES(ctl, "ext-mic int-mic line-out-jack unused unused unused unused unused unused unused input-mix");
+#else
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x22, 0, amp_group, "ext-mic", UNMUTE); /* From widget 0x18 */
+ HDA_INMUTE(0x22, 1, amp_group, "int-mic", UNMUTE); /* From widget 0x19 */
+ HDA_INMUTE(0x22, 2, amp_group, "line-out", UNMUTE); /* From widget 0x1a */
+ HDA_INMUTE(0x22, 3, amp_group, "black", UNMUTE); /* From widget 0x1b */
+ HDA_INMUTE(0x22, 4, amp_group, "black", UNMUTE); /* From widget 0x1c */
+ HDA_INMUTE(0x22, 5, amp_group, "black", UNMUTE); /* From widget 0x1d */
+ HDA_INMUTE(0x22, 6, amp_group, "headph-jack", UNMUTE); /* From widget 0x14 */
+ HDA_INMUTE(0x22, 7, amp_group, "int-speaker", UNMUTE); /* From widget 0x15 */
+ HDA_INMUTE(0x22, 8, amp_group, "black", UNMUTE); /* From widget 0x16 */
+ HDA_INMUTE(0x22, 9, amp_group, "black", UNMUTE); /* From widget 0x17 */
+ HDA_INMUTE(0x22, 10, amp_group, "input-mix", MUTE); /* From widget 0x0b */
+#endif
+ }
+ }
+
+ if (HDA_ADC_GROUP(0x0a, group, rec_group, "spdif-in", n, "record", 4)) /* ADC widget 0x0a */
+ {
+ /* Src 0x1f=speaker */
+ }
+ }
+ /* Handle misc widgets */
+ {
+ int n, group, misc_group;
+
+ n=0;
+
+ HDA_GROUP(misc_group, top_group, "misc");
+
+ if (HDA_MISC_GROUP(0x0c, group, misc_group, "front", n, "misc", 8)) /* Misc widget 0x0c */
+ {
+ /* Src 0x2=front */
+ /* Src 0xb=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x0c, 0, amp_group, "front", UNMUTE); /* From widget 0x02 */
+ HDA_INMUTE(0x0c, 1, amp_group, "input-mix", MUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x0d, group, misc_group, "rear", n, "misc", 8)) /* Misc widget 0x0d */
+ {
+ /* Src 0x3=rear */
+ /* Src 0xb=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x0d, 0, amp_group, "rear", UNMUTE); /* From widget 0x03 */
+ HDA_INMUTE(0x0d, 1, amp_group, "input-mix", MUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x0e, group, misc_group, "center/LFE", n, "misc", 8)) /* Misc widget 0x0e */
+ {
+ /* Src 0x4=center/LFE */
+ /* Src 0xb=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x0e, 0, amp_group, "center/LFE", UNMUTE); /* From widget 0x04 */
+ HDA_INMUTE(0x0e, 1, amp_group, "input-mix", MUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x0f, group, misc_group, "side", n, "misc", 8)) /* Misc widget 0x0f */
+ {
+ /* Src 0x5=side */
+ /* Src 0xb=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x0f, 0, amp_group, "side", UNMUTE); /* From widget 0x05 */
+ HDA_INMUTE(0x0f, 1, amp_group, "input-mix", MUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x26, group, misc_group, "pcm4", n, "misc", 8)) /* Misc widget 0x26 */
+ {
+ /* Src 0x25=pcm4 */
+ /* Src 0xb=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x26, 0, amp_group, "pcm4", UNMUTE); /* From widget 0x25 */
+ HDA_INMUTE(0x26, 1, amp_group, "input-mix", MUTE); /* From widget 0x0b */
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x0b, group, misc_group, "input-mix", n, "misc", 8)) /* Misc widget 0x0b */
+ {
+ /* Src 0x18=mic */
+ /* Src 0x19=int-mic */
+ /* Src 0x1a=linein */
+ /* Src 0x1b=speaker */
+ /* Src 0x1c=speaker */
+ /* Src 0x1d=speaker */
+ /* Src 0x14=headphone */
+ /* Src 0x15=int-speaker */
+ /* Src 0x16=speaker */
+ /* Src 0x17=speaker */
+ HDA_INAMP(0x0b, 0, group, "ext-mic", 10); /* From widget 0x18 */
+ HDA_INAMP(0x0b, 1, group, "int-mic", 10); /* From widget 0x19 */
+ HDA_INAMP(0x0b, 2, group, "line-out", 0); /* From widget 0x1a */
+ HDA_INAMP(0x0b, 3, group, "black", 0); /* From widget 0x1b */
+ HDA_INAMP(0x0b, 4, group, "black", 0); /* From widget 0x1c */
+ HDA_INAMP(0x0b, 5, group, "black", 0); /* From widget 0x1d */
+ //HDA_INAMP(0x0b, 6, group, "headph-jack", 90); /* From widget 0x14 */
+ //HDA_INAMP(0x0b, 7, group, "int-speaker", 0); /* From widget 0x15 */
+ HDA_INAMP(0x0b, 8, group, "black", 0); /* From widget 0x16 */
+ HDA_INAMP(0x0b, 9, group, "black", 0); /* From widget 0x17 */
+ }
+ }
+ return 0;
+}
diff --git a/kernel/drv/oss_hdaudio/hdaudio_generic.c b/kernel/drv/oss_hdaudio/hdaudio_generic.c
new file mode 100644
index 0000000..2ea9811
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_generic.c
@@ -0,0 +1,868 @@
+/*
+ * Purpose: Default mixer/control panel driver for HDA codecs
+ *
+ * This generic driver is used to create mixer/control panels for HDaudio
+ * codec chips that don't have any dedicated driver available.
+ *
+ * This driver will obtain the widget definitions from the codec and then
+ * try to guess a mixer layout that makes some sense. However this approach
+ * works properly only with a small set of codecs.
+ *
+ * Most codecs are unbearably complex and provide loads of redundant
+ * functionality. The generic driver approach will not properly work with them
+ * because the mixer (GUI) layout will become too large to fit on any screen.
+ * In addition such automatically generated mixer controls will not make any
+ * sense to the users. So in the future the only possible approach will be
+ * creating dedicated mixer drivers for all possible codecs in the market.
+ * Unfortunately in some cases the driver may even need to be motherboard
+ * specific. Apparently this is going to be enormous task.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+
+extern int hdaudio_snoopy;
+extern int hdaudio_jacksense;
+extern int hdaudio_noskip;
+
+static int
+count_linked_controls (hdaudio_mixer_t * mixer, codec_t * codec,
+ widget_t * widget, int recursive)
+{
+/*
+ * This function counts the number of mixer control elements this
+ * widget has.
+ * If recursive==1 then control counts of the previous widgets in the
+ * processing chain will be counted if number of inputs is exactly 1.
+ * Input sources are not checked if number of connections is larger than 1
+ * because separate mixer group is required for such widgets.
+ *
+ * Note! The policies used by this function must match exactly the policies
+ * used by follow_widget_chain()
+ */
+ int count = 0;
+
+ if (widget->skip)
+ return 0;
+
+ /*
+ * Output amp?
+ */
+ if (widget->widget_caps & WCAP_OUTPUT_AMP_PRESENT)
+ count += 1;
+
+ /*
+ * Input amp(s)?
+ */
+ if (widget->widget_caps & WCAP_INPUT_AMP_PRESENT)
+ {
+ if (widget->wid_type == NT_MIXER)
+ count += widget->nconn;
+ else
+ count++;
+ }
+
+ /*
+ * Input selector?
+ */
+ if (widget->wid_type == NT_SELECT && widget->nconn > 1)
+ count += 1;
+
+ if (recursive)
+ if (widget->nconn == 1) /* Exactly one input wource */
+ count +=
+ count_linked_controls (mixer, codec,
+ &codec->widgets[widget->connections[0]],
+ recursive);
+
+ return count;
+}
+
+/*ARGSUSED*/
+static int
+attach_amplifiers (int dev, hdaudio_mixer_t * mixer, codec_t * codec,
+ widget_t * widget, int group, int group_mode)
+{
+ int i, cnum, ninputs;
+ int g = group;
+ int use_mutegroup = 0;
+ oss_mixext *ent;
+
+/*
+ * Control for input amplifier(s)
+ */
+ if (widget->widget_caps & WCAP_INPUT_AMP_PRESENT)
+ {
+ if (widget->wid_type == NT_MIXER)
+ ninputs = widget->nconn;
+ else
+ ninputs = 1;
+
+ /*
+ * Check if it's possible to save horizontal space by creating a separate
+ * mute group. In this way the names of mute selectors become shorter.
+ */
+ if (!(widget->inamp_caps & ~AMPCAP_MUTE)
+ && (widget->inamp_caps & AMPCAP_MUTE) && ninputs > 2)
+ {
+ use_mutegroup = 1;
+ if ((g =
+ mixer_ext_create_group (mixer->mixer_dev, group, "mute")) < 0)
+ return g;
+ }
+
+ for (i = 0; i < ninputs; i++) /* All inputs */
+ {
+ char tmpname[32], tmp[40];
+ char *name = codec->widgets[widget->connections[i]].name;
+
+ if (ninputs == 1) /* Hide name */
+ name = "-";
+
+ if (codec->widgets[widget->connections[i]].skip)
+ continue;
+
+ if (widget->inamp_caps & ~AMPCAP_MUTE) /* Supports gain control */
+ {
+ int typ, num, maxval, val, range, step;
+ range =
+ ((widget->
+ outamp_caps >> AMPCAP_NUMSTEPS_SHIFT) &
+ AMPCAP_NUMSTEPS_MASK) + 1;
+ step =
+ ((widget->
+ outamp_caps >> AMPCAP_STEPSIZE_SHIFT) &
+ AMPCAP_STEPSIZE_MASK) + 1;
+
+ if (step > 20 /* 5dB */ && range < 5)
+ {
+ create_ingain_selector (mixer, codec, widget, group, i,
+ name);
+ continue;
+ }
+ maxval = hdaudio_amp_maxval (widget->inamp_caps);
+
+ if (widget->widget_caps & WCAP_STEREO)
+ {
+ typ = MIXT_STEREOSLIDER16;
+ num = MIXNUM (widget, CT_INSTEREO, i);
+ }
+ else
+ {
+ typ = MIXT_MONOSLIDER16;
+ num = MIXNUM (widget, CT_INMONO, i);
+ }
+
+ if (hdaudio_snoopy > 0)
+ {
+ sprintf (tmp, "%s:R%x", name, widget->wid);
+ name = tmp;
+ }
+
+ if ((cnum = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ num,
+ hdaudio_set_control,
+ typ,
+ name, maxval,
+ MIXF_READABLE |
+ MIXF_WRITEABLE |
+ MIXF_CENTIBEL)) < 0)
+ return cnum;
+
+ /* Copy RGB color */
+ if (widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (dev, cnum)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+
+ /* Setup initial volume */
+ val = (maxval * 8) / 10; /* 80% of the maximum */
+ val = val | (val << 16);
+
+ hdaudio_set_control (mixer->mixer_dev, num, SNDCTL_MIX_WRITE,
+ val);
+ continue; /* Skip to the next input */
+ }
+
+ if (widget->inamp_caps & AMPCAP_MUTE) /* Supports only mute */
+ {
+ if (use_mutegroup)
+ strcpy (tmpname, name);
+ else
+ sprintf (tmpname, "%s-mute", name);
+ name = tmpname;
+
+ if (hdaudio_snoopy > 0)
+ {
+ sprintf (tmp, "%s:Q%x", name, widget->wid);
+ name = tmp;
+ }
+
+ if ((cnum = mixer_ext_create_control (mixer->mixer_dev,
+ g,
+ MIXNUM (widget,
+ CT_INMUTE, i),
+ hdaudio_set_control,
+ MIXT_MUTE, name, 2,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return cnum;
+ /* Copy RGB color */
+ if (widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (dev, cnum)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+
+ hdaudio_set_control (mixer->mixer_dev,
+ MIXNUM (widget, CT_INMUTE, i),
+ SNDCTL_MIX_WRITE, 0);
+ }
+
+ }
+ }
+
+/*
+ * Output amplifier control
+ */
+
+ if (widget->widget_caps & WCAP_OUTPUT_AMP_PRESENT)
+ {
+ char tmp[32];
+ char *name = "-";
+
+ if (hdaudio_snoopy)
+ name = "outamp";
+
+ if (widget->outamp_caps & ~AMPCAP_MUTE) /* Has gain control */
+ {
+ int range, step, typ, num, maxval, val;
+ range =
+ ((widget->
+ outamp_caps >> AMPCAP_NUMSTEPS_SHIFT) & AMPCAP_NUMSTEPS_MASK) +
+ 1;
+ step =
+ ((widget->
+ outamp_caps >> AMPCAP_STEPSIZE_SHIFT) & AMPCAP_STEPSIZE_MASK) +
+ 1;
+
+ if (step > 20 /* 5dB */ && range < 5)
+ {
+ create_outgain_selector (mixer, widget, group, name);
+ }
+ else
+ {
+
+ maxval = hdaudio_amp_maxval (widget->outamp_caps);
+
+ if (widget->widget_caps & WCAP_STEREO)
+ {
+ typ = MIXT_STEREOSLIDER16;
+ num = MIXNUM (widget, CT_OUTSTEREO, 0);
+ }
+ else
+ {
+ typ = MIXT_MONOSLIDER16;
+ num = MIXNUM (widget, CT_OUTMONO, 0);
+ }
+
+ if (hdaudio_snoopy > 0)
+ {
+ sprintf (tmp, "%s:V%x", name, widget->wid);
+ name = tmp;
+ }
+ else
+ {
+ sprintf (tmp, "%s", widget->name);
+ name = tmp;
+ }
+
+ if ((cnum = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ num, hdaudio_set_control,
+ typ,
+ name, maxval,
+ MIXF_READABLE |
+ MIXF_WRITEABLE |
+ MIXF_CENTIBEL)) < 0)
+ return cnum;
+
+ /* Copy RGB color */
+ if (widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (dev, cnum)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+
+ /* setup volume */
+ val = (maxval * 8) / 10; /* 80% of the maximum */
+ val = val | (val << 16);
+ hdaudio_set_control (mixer->mixer_dev, num, SNDCTL_MIX_WRITE,
+ val);
+ }
+ }
+ else if (widget->outamp_caps & AMPCAP_MUTE) /* Only mute control */
+ {
+ char tmpname[32];
+ name = "mute";
+ if (hdaudio_snoopy > 0)
+ {
+ sprintf (tmpname, "%s:U%x", name, widget->wid);
+ name = tmpname;
+ }
+
+ if ((cnum = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ MIXNUM (widget,
+ CT_OUTMUTE, 0),
+ hdaudio_set_control,
+ MIXT_MUTE, name, 2,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return cnum;
+
+ /* Copy RGB color */
+ if (widget->rgbcolor != 0)
+ if ((ent = mixer_find_ext (dev, cnum)) != NULL)
+ ent->rgbcolor = widget->rgbcolor;
+
+ hdaudio_set_control (mixer->mixer_dev,
+ MIXNUM (widget, CT_OUTMUTE, 0),
+ SNDCTL_MIX_WRITE, 0);
+ }
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+attach_selector (int dev, hdaudio_mixer_t * mixer, codec_t * codec,
+ widget_t * widget, int group, int group_mode)
+{
+ unsigned int c, b;
+ char *name = "src";
+
+ int i, ctl;
+ char tmp[256], *t = tmp;
+ oss_mixext *ext;
+ int count = 0;
+
+
+ /*
+ * first check to see if there are more that 2 valid options to create a
+ * selector for.
+ */
+ for (i = 0; i < widget->nconn; i++)
+ if (!codec->widgets[widget->connections[i]].skip
+ && codec->widgets[widget->connections[i]].sensed_pin != PIN_OUT)
+ count++;
+
+ if (count < 2)
+ return 0;
+
+
+ name = widget->name;
+
+ if (corb_read (mixer, widget->cad, widget->wid, 0, GET_SELECTOR, 0, &c, &b))
+ widget->current_selector = c;
+
+ if (hdaudio_snoopy > 0)
+ {
+ sprintf (tmp, "%s:%x", name, widget->wid);
+ name = tmp;
+ }
+
+
+ if ((ctl = mixer_ext_create_control (mixer->mixer_dev,
+ group,
+ MIXNUM (widget, CT_SELECT, 0),
+ hdaudio_set_control,
+ MIXT_ENUM,
+ name,
+ widget->nconn,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ *tmp = 0;
+ ext = mixer_find_ext (mixer->mixer_dev, ctl);
+
+ if (ext == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot locate the mixer extension (a)\n");
+ return OSS_EIO;
+ }
+
+ /* Copy RGB color */
+ ext->rgbcolor = widget->rgbcolor;
+
+ memset (ext->enum_present, 0, sizeof (ext->enum_present));
+
+ for (i = 0; i < widget->nconn; i++)
+ {
+ char *s;
+
+ /*
+ * ensure that the connection list has a valid widget id - some
+ * devices have bogus connection lists
+ */
+ if (codec->widgets[widget->connections[i]].wid < codec->first_node)
+ continue;
+
+ s = codec->widgets[widget->connections[i]].name;
+ if (strlen (tmp) + strlen (s) + 1 < sizeof (tmp) - 1)
+ {
+ if (*tmp != 0)
+ *t++ = ' ';
+ strcpy (t, s);
+ if (hdaudio_snoopy > 0)
+ sprintf (t, "A%s:%x", s,
+ mixer->codecs[widget->cad]->widgets[widget->
+ connections[i]].wid);
+ t += strlen (t);
+
+ /*
+ * Show only widgets that are not marked to be ignored.
+ * Also hide I/O pins that are known to be outputs.
+ */
+ if (!codec->widgets[widget->connections[i]].skip
+ && codec->widgets[widget->connections[i]].sensed_pin != PIN_OUT)
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+ else
+ {
+ if (widget->current_selector == i)
+ widget->current_selector++;
+ }
+ }
+ }
+ mixer_ext_set_strings (mixer->mixer_dev, ctl, tmp, 0);
+
+ if (widget->current_selector >= widget->nconn)
+ widget->current_selector = 0;
+ corb_write (mixer, widget->cad, widget->wid, 0, SET_SELECTOR,
+ widget->current_selector);
+
+ return 0;
+}
+
+static int
+follow_widget_chain (int dev, hdaudio_mixer_t * mixer, codec_t * codec,
+ widget_t * widget, int group)
+{
+ int err;
+
+ if (widget->used) /* Already handled */
+ return 0;
+
+ widget->used = 1;
+
+ if (widget->nconn >= 1)
+ if ((err =
+ follow_widget_chain (dev, mixer, codec,
+ &codec->widgets[widget->connections[0]],
+ group)) < 0)
+ return err;
+
+ if ((err = attach_amplifiers (dev, mixer, codec, widget, group, 1)) < 0)
+ return err;
+
+ if (widget->wid_type == NT_SELECT)
+ if ((err = attach_selector (dev, mixer, codec, widget, group, 1)) < 0)
+ return err;
+
+ return 0;
+}
+
+static int
+attach_pin_widget (int dev, hdaudio_mixer_t * mixer, codec_t * codec,
+ widget_t * widget, int parent_group)
+{
+ int group = parent_group, g;
+ unsigned int b, c, conf;
+ int i, ctl, err;
+ int inselects = 0, outselects = 0, linked_controls = 0;
+ int num_amps = 0;
+ char tmp[256], *t = tmp;
+ oss_mixext *ext;
+
+ if (widget->pincaps & PINCAP_OUTPUT_CAPABLE)
+ {
+ outselects = widget->nconn;
+
+ if (widget->nconn == 1) /* Exactly one connection */
+ {
+ linked_controls =
+ count_linked_controls (mixer, codec,
+ &codec->widgets[widget->connections[0]],
+ 1);
+ }
+ }
+
+ if (widget->pincaps & PINCAP_INPUT_CAPABLE)
+ {
+ if (!(widget->widget_caps & WCAP_DIGITAL)) /* Analog pin */
+ {
+ inselects = 1;
+ }
+ }
+
+ if (widget->widget_caps & WCAP_INPUT_AMP_PRESENT)
+ {
+ num_amps++;
+ }
+
+ if (widget->widget_caps & WCAP_OUTPUT_AMP_PRESENT)
+ {
+ num_amps++;
+ }
+
+ if ((inselects + outselects > 1) || num_amps > 0 || linked_controls > 0) /* Have something to control */
+ {
+ if (widget->color[0] == 0) /* Empty name */
+ sprintf (widget->color, "jack%02x", widget->wid);
+ if ((g =
+ mixer_ext_create_group (mixer->mixer_dev, group,
+ widget->color)) < 0)
+ return g;
+
+ if (corb_read
+ (mixer, widget->cad, widget->wid, 0, GET_SELECTOR, 0, &c, &b))
+ widget->current_selector = c;
+
+ if (inselects + outselects > 1)
+ {
+ if ((ctl = mixer_ext_create_control (mixer->mixer_dev,
+ g,
+ MIXNUM (widget, CT_SELECT, 0),
+ hdaudio_set_control,
+ MIXT_ENUM,
+ "mode",
+ inselects + outselects,
+ MIXF_READABLE |
+ MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ *tmp = 0;
+ ext = mixer_find_ext (mixer->mixer_dev, ctl);
+
+ if (ext == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot locate the mixer extension (b)\n");
+ return OSS_EIO;
+ }
+ /* Copy RGB color */
+ ext->rgbcolor = widget->rgbcolor;
+
+ memset (ext->enum_present, 0, sizeof (ext->enum_present));
+
+ for (i = 0; i < widget->nconn; i++)
+ {
+ char *s;
+
+ s = codec->widgets[widget->connections[i]].name;
+ if (strlen (tmp) + strlen (s) + 1 < sizeof (tmp) - 1)
+ {
+ if (*tmp != 0)
+ *t++ = ' ';
+ strcpy (t, s);
+ if (hdaudio_snoopy > 0)
+ sprintf (t, "A%s:%x", s,
+ mixer->codecs[widget->cad]->widgets[widget->
+ connections
+ [i]].wid);
+ t += strlen (t);
+
+ /*
+ * Show only widgets that are not marked to be ignored.
+ */
+ if (!codec->widgets[widget->connections[i]].skip)
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+ else
+ {
+ if (widget->current_selector == i)
+ widget->current_selector++;
+ }
+ }
+ }
+
+/*
+ * Use the default sequence as an index to the output source selectors.
+ */
+ if (widget->sensed_pin == PIN_OUT)
+ if (corb_read
+ (mixer, widget->cad, widget->wid, 0, GET_CONFIG_DEFAULT, 0,
+ &conf, &b))
+ {
+ int association, sequence;
+
+ association = (conf >> 4) & 0x0f;
+ sequence = conf & 0x0f;
+
+ if (association != 0)
+ {
+ widget->current_selector = sequence;
+ }
+
+ }
+
+ if (widget->current_selector >= widget->nconn)
+ widget->current_selector = 0;
+
+ if (inselects > 0) /* Input capable */
+ {
+ char *s;
+
+ i = widget->nconn;
+ s = widget->name;
+
+ if (*tmp != 0)
+ *t++ = ' ';
+
+ strcpy (t, "input");
+
+ t += strlen (t);
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+ i++;
+
+ if (widget->pin_type == PIN_IN)
+ widget->current_selector = widget->nconn;
+ }
+
+ mixer_ext_set_strings (mixer->mixer_dev, ctl, tmp, 0);
+ }
+
+ hdaudio_set_control (mixer->mixer_dev,
+ MIXNUM (widget, CT_SELECT, 0),
+ SNDCTL_MIX_WRITE, widget->current_selector);
+
+ if ((err = attach_amplifiers (dev, mixer, codec, widget, g, 0)) < 0)
+ return err;
+
+ if (widget->nconn == 1)
+ if ((err =
+ follow_widget_chain (dev, mixer, codec,
+ &codec->widgets[widget->connections[0]],
+ g)) < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+attach_record_widget (int dev, hdaudio_mixer_t * mixer, codec_t * codec,
+ widget_t * widget, int parent_group)
+{
+ int group = parent_group, g;
+ int err;
+ int linked_controls = 0;
+ int num_amps = 0;
+
+ if (widget->widget_caps & WCAP_INPUT_AMP_PRESENT)
+ {
+ num_amps++;
+ }
+
+ if (widget->widget_caps & WCAP_OUTPUT_AMP_PRESENT)
+ {
+ num_amps++;
+ }
+
+ if (widget->nconn == 1) /* Exactly one connection */
+ {
+ linked_controls =
+ count_linked_controls (mixer, codec,
+ &codec->widgets[widget->connections[0]], 1);
+ }
+
+ if (num_amps > 0 || linked_controls > 1) /* Have something to control */
+ {
+ if ((g =
+ mixer_ext_create_group (mixer->mixer_dev, group,
+ widget->name)) < 0)
+ return g;
+
+ if (widget->nconn == 1)
+ if ((err =
+ follow_widget_chain (dev, mixer, codec,
+ &codec->widgets[widget->connections[0]],
+ g)) < 0)
+ return err;
+
+ if ((err = attach_amplifiers (dev, mixer, codec, widget, g, 0)) < 0)
+ return err;
+ if ((err = attach_selector (dev, mixer, codec, widget, g, 0)) < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+attach_misc_widget (int dev, hdaudio_mixer_t * mixer, codec_t * codec,
+ widget_t * widget, int parent_group)
+{
+ int err;
+ int nselect = 0;
+ int num_amps = 0;
+
+ if (widget->widget_caps & WCAP_INPUT_AMP_PRESENT)
+ {
+ num_amps++;
+ }
+
+ if (widget->widget_caps & WCAP_OUTPUT_AMP_PRESENT)
+ {
+ num_amps++;
+ }
+
+ if ((widget->wid_type == NT_SELECT || widget->wid_type == NT_MIXER)
+ && widget->nconn > 0)
+ nselect = widget->nconn;
+
+ if (num_amps > 0 || nselect > 1) /* Have something to control */
+ {
+#if 0
+ if ((g =
+ mixer_ext_create_group (mixer->mixer_dev, group,
+ widget->name)) < 0)
+ return g;
+#endif
+ if ((err =
+ attach_amplifiers (dev, mixer, codec, widget, parent_group,
+ 0)) < 0)
+ return err;
+
+ if (nselect > 1)
+ if ((err =
+ attach_selector (dev, mixer, codec, widget, parent_group,
+ 0)) < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+int
+hdaudio_generic_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad,
+ int parent_group)
+{
+ unsigned int vendorid, b;
+ int err;
+ int wid, n;
+ codec_t *codec;
+ widget_t *widget;
+ int group = parent_group;
+
+ if (mixer->codecs[cad] == NULL)
+ {
+ cmn_err (CE_WARN, "Bad codec %d\n", cad);
+ return OSS_EIO;
+ }
+ codec = mixer->codecs[cad];
+
+ if (!corb_read (mixer, cad, 0, 0, GET_PARAMETER, HDA_VENDOR, &vendorid, &b))
+ {
+ cmn_err (CE_WARN, "Cannot get codec ID\n");
+ return OSS_EIO;
+ }
+
+/*
+ * First handle all the PIN widgets
+ */
+ n = 0;
+
+ for (wid = 0; wid < codec->nwidgets; wid++)
+ {
+ widget = &codec->widgets[wid];
+
+ if (widget->wid_type != NT_PIN) /* Not a pin widget */
+ continue;
+
+ widget->used = 1;
+
+ if (widget->skip) /* Unused/unconnected PIN widget */
+ {
+ continue;
+ }
+
+ if ((n++ % 3) == 0)
+ {
+ if ((group =
+ mixer_ext_create_group (mixer->mixer_dev, parent_group,
+ "jack")) < 0)
+ return group;
+ }
+
+
+ if ((err = attach_pin_widget (dev, mixer, codec, widget, group)) < 0)
+ return err;
+ }
+
+/*
+ * Next handle all the ADC widgets
+ */
+ n = 0;
+ for (wid = 0; wid < codec->nwidgets; wid++)
+ {
+ widget = &codec->widgets[wid];
+
+ if (widget->wid_type != NT_ADC) /* Not a pin widget */
+ continue;
+
+ if (widget->skip)
+ continue;
+
+ widget->used = 1;
+
+ if ((n++ % 3) == 0)
+ {
+ if ((group =
+ mixer_ext_create_group (mixer->mixer_dev, parent_group,
+ "record")) < 0)
+ return group;
+ }
+
+ if ((err = attach_record_widget (dev, mixer, codec, widget, group)) < 0)
+ return err;
+ }
+
+/*
+ * Finally handle all the widgets that have not been attached yet
+ */
+
+ n = 0;
+ for (wid = 0; wid < codec->nwidgets; wid++)
+ {
+ widget = &codec->widgets[wid];
+
+ if (widget->skip)
+ continue;
+
+ if (widget->used) /* Already handled */
+ continue;
+
+ widget->used = 1;
+
+ if (count_linked_controls (mixer, codec, widget, 0) > 0)
+ if ((n++ % 4) == 0)
+ {
+ if ((group =
+ mixer_ext_create_group (mixer->mixer_dev, parent_group,
+ "misc")) < 0)
+ return group;
+ }
+
+ if ((err = attach_misc_widget (dev, mixer, codec, widget, group)) < 0)
+ return err;
+ }
+ return 0;
+}
diff --git a/kernel/drv/oss_hdaudio/hdaudio_gpio_handlers.c b/kernel/drv/oss_hdaudio/hdaudio_gpio_handlers.c
new file mode 100644
index 0000000..357b689
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_gpio_handlers.c
@@ -0,0 +1,128 @@
+/*
+ * Purpose: GPIO initialization handlers for some High Definition Audio systems
+ *
+ * This file contains codec initialization functions for some HDaudio
+ * systems that require initialization of GPIO bits. All functions should
+ * return OSS_EAGAIN so that hdaudio_codec.c knows to call the generic
+ * codec/mixer initialization routine for the codec. Alternatively the
+ * GPIO init function may call the codec/mixer init function for the
+ * given system directly (return my_mixer_init_func()).
+ *
+ * Note that if the system has a dedicated mixer initialization function
+ * then also GPIO initialization needs to be performed in the mixer init
+ * function (since the same mixer_init function pointers in hdaudio_codecds.h
+ * are shared for both purposes).
+ *
+ * For example:
+ *
+ * int
+ * hdaudio_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+ * {
+ * codec_t *codec = mixer->codecs[cad];
+ * int afg = codec->afg; // Audio function group root widget
+ *
+ * // Now use the corb_read() and corb_write() functions to set the
+ * // GPIO related verbs (registers) to the required values.
+ *
+ * return OSS_EAGAIN; // Fallback
+ * }
+ *
+ * To write the GPIO registers you can use:
+ *
+ * corb_write (mixer, cad, afg, 0, SET_GPIO_DIR, 0xNNNNNNNN);
+ * corb_write (mixer, cad, afg, 0, SET_GPIO_ENABLE, 0xNNNNNNNN);
+ * corb_write (mixer, cad, afg, 0, SET_GPIO_DATA, 0xNNNNNNNN);
+ *
+ * Also (if necessary) you can use the following calls. However they will probably
+ * need changes to hdaudio_codec.c so that the unsolicited responses are handled peoperly:
+ *
+ * corb_write (mixer, cad, afg, 0, SET_GPIO_WKEN, 0xNNNNNNNN);
+ * corb_write (mixer, cad, afg, 0, SET_GPIO_UNSOL, 0xNNNNNNNN);
+ * corb_write (mixer, cad, afg, 0, SET_GPIO_STICKY, 0xNNNNNNNN);
+ *
+ * Next the function prototype should be added to hdaudio_codecids.h. Finally
+ * edit the subdevices[] array in hdaudio_codecids.h so that the function
+ * gets called when given codec (subsystem vendor+device) is detected in the
+ * system. It is not recommended to use the codecs[] table to
+ * detect systems that need GPIO handling. The same codec may be used
+ * in many different systems and most of them don't require GPIO init.
+ * However this is possible if the handler uses the subvendor+subdevice ID to detect the system.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_codecids.h"
+
+int
+hdaudio_mac_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+{
+ codec_t *codec = mixer->codecs[cad];
+ int afg = codec->afg; // Audio function group root widget
+ unsigned int subdevice = codec->subvendor_id;
+ unsigned int codec_id = codec->vendor_id;
+
+ // TODO: Populate this function with the real stuff
+
+cmn_err(CE_CONT, "hdaudio_mac_GPIO_init() entered, afg=%d, subdevice=0x%08x, codec=0x%08x\n", afg, subdevice, codec_id);
+
+ return OSS_EAGAIN; /* Continue with the default mixer init */
+}
+
+int
+hdaudio_mac_sigmatel_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+{
+cmn_err(CE_CONT, "iMac Sigmatel hdaudio initialization\n");
+ return hdaudio_mac_GPIO_init(dev, mixer, cad, top_group);
+}
+
+int
+hdaudio_mac_realtek_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+{
+ codec_t *codec = mixer->codecs[cad];
+ int afg = codec->afg; // Audio function group root widget
+
+cmn_err(CE_CONT, "iMac Realtek hdaudio initialization\n");
+
+ corb_write (mixer, cad, afg, 0, SET_GPIO_DIR, 0xffffffff);
+ corb_write (mixer, cad, afg, 0, SET_GPIO_ENABLE, 0xffffffff);
+ corb_write (mixer, cad, afg, 0, SET_GPIO_DATA, 0xffffffff);
+ return hdaudio_mac_GPIO_init(dev, mixer, cad, top_group);
+}
+
+int
+hdaudio_asus_a7k_GPIO_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+{
+ DDB(cmn_err(CE_CONT, "hdaudio_asus_a7k_GPIO_init got called.\n"));
+
+ corb_write (mixer, cad, 0x01, 0, SET_GPIO_ENABLE, 3);
+ corb_write (mixer, cad, 0x01, 0, SET_GPIO_DIR, 1);
+ corb_write (mixer, cad, 0x01, 0, SET_GPIO_DATA, 1);
+
+ return hdaudio_generic_mixer_init(dev, mixer, cad, top_group);
+}
+
+int
+hdaudio_GPIO_init_1 (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+{
+ DDB(cmn_err(CE_CONT, "hdaudio_GPIO_init_1 got called.\n"));
+
+ /* Acer TravelMate 4060 and similar Aspire series, with ALC260 codec, need
+ * that we init GPIO to get internal speaker and headphone jack working. */
+ corb_write(mixer, cad, 0x01, 0, SET_GPIO_ENABLE, 1);
+ corb_write(mixer, cad, 0x01, 0, SET_GPIO_DIR, 1);
+ corb_write(mixer, cad, 0x01, 0, SET_GPIO_DATA, 1);
+
+ return hdaudio_generic_mixer_init(dev, mixer, cad, top_group);
+}
diff --git a/kernel/drv/oss_hdaudio/hdaudio_mixers.h b/kernel/drv/oss_hdaudio/hdaudio_mixers.h
new file mode 100644
index 0000000..eb92910
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_mixers.h
@@ -0,0 +1,20 @@
+/*
+ * Purpose: Declarations of some functions and structures for HD audio mixers
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+/*
+ * Prototype definitions for dedicated HDAudio codec/mixer drivers.
+ */
+
+extern int hdaudio_generic_mixer_init (int dev, hdaudio_mixer_t * mixer,
+ int cad, int group);
diff --git a/kernel/drv/oss_hdaudio/hdaudio_scaleoP.c b/kernel/drv/oss_hdaudio/hdaudio_scaleoP.c
new file mode 100644
index 0000000..b4bab5f
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_scaleoP.c
@@ -0,0 +1,277 @@
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+/* Codec index is 0 */
+/* Codec vendor 0804:7d10 */
+/* HD codec revision 1.0 (0.1) (0x00100001) */
+/* Subsystem ID 1043e601 */
+/* Default amplifier caps: in=00000000, out=00000000 */
+#include "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_dedicated.h"
+
+int
+hdaudio_scaleoP_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad,
+ int top_group)
+{
+ int ctl = 0;
+
+ DDB (cmn_err (CE_CONT, "hdaudio_scaleoP_mixer_init got called.\n"));
+
+ HDA_OUTAMP_F (0x0c, top_group, "front", 90, MIXF_PCMVOL);
+ HDA_OUTAMP_F (0x0d, top_group, "rear", 90, MIXF_PCMVOL);
+ HDA_OUTAMP_F (0x0e, top_group, "center/LFE", 90, MIXF_PCMVOL);
+ HDA_OUTAMP_F (0x0f, top_group, "side", 90, MIXF_PCMVOL);
+ HDA_OUTAMP_F (0x26, top_group, "pcm4", 90, MIXF_PCMVOL);
+
+ /*
+ * Unmute all inputs for the above sliders.
+ */
+ HDA_SET_INMUTE (0x0c, 0, UNMUTE); /* From widget 0x02 */
+ HDA_SET_INMUTE (0x0c, 1, UNMUTE); /* From widget 0x0b */
+ HDA_SET_INMUTE (0x0d, 0, UNMUTE); /* From widget 0x03 */
+ HDA_SET_INMUTE (0x0d, 1, UNMUTE); /* From widget 0x0b */
+ HDA_SET_INMUTE (0x0e, 0, UNMUTE); /* From widget 0x04 */
+ HDA_SET_INMUTE (0x0e, 1, UNMUTE); /* From widget 0x0b */
+ HDA_SET_INMUTE (0x0f, 0, UNMUTE); /* From widget 0x05 */
+ HDA_SET_INMUTE (0x0f, 1, UNMUTE); /* From widget 0x0b */
+ HDA_SET_INMUTE (0x26, 0, UNMUTE); /* From widget 0x25 */
+ HDA_SET_INMUTE (0x26, 1, UNMUTE); /* From widget 0x0b */
+
+ /* Handle ADC widgets */
+ {
+ int n, group, rec_group;
+
+ n = 0;
+
+ HDA_GROUP (rec_group, top_group, "record");
+
+ if (HDA_ADC_GROUP (0x08, group, rec_group, "rec1", n, "record", 2)) /* ADC widget 0x08 */
+ {
+ /* Src 0x23=mix */
+ HDA_INAMP (0x08, 0, group, "-", 90); /* From widget 0x23 */
+
+ /* Widget 0x23 (mix) */
+ /* Src 0x18=pink */
+ /* Src 0x19=fp-pink */
+ /* Src 0x1a=blue */
+ /* Src 0x1b=fp-green */
+ /* Src 0x1c=int-aux */
+ /* Src 0x1d=black */
+ /* Src 0x14=green */
+ /* Src 0x15=black */
+ /* Src 0x16=orange */
+ /* Src 0x17=grey */
+ /* Src 0x0b=input-mix */
+ if (HDA_INSRC_SELECT (0x23, group, ctl, "recsrc", 10))
+ HDA_CHOICES (ctl,
+ "pink fp-pink blue fp-green int-aux black green black orange grey input-mix");
+ }
+
+ if (HDA_ADC_GROUP (0x09, group, rec_group, "rec2", n, "record", 2)) /* ADC widget 0x09 */
+ {
+ /* Src 0x22=mix */
+ HDA_INAMP (0x09, 0, group, "-", 90); /* From widget 0x22 */
+
+ /* Widget 0x22 (mix) */
+ /* Src 0x18=pink */
+ /* Src 0x19=fp-pink */
+ /* Src 0x1a=blue */
+ /* Src 0x1b=fp-green */
+ /* Src 0x1c=int-aux */
+ /* Src 0x1d=black */
+ /* Src 0x14=green */
+ /* Src 0x15=black */
+ /* Src 0x16=orange */
+ /* Src 0x17=grey */
+ /* Src 0xb=input-mix */
+ if (HDA_INSRC_SELECT (0x23, group, ctl, "recsrc", 10))
+ HDA_CHOICES (ctl,
+ "pink fp-pink blue fp-green int-aux black green black orange grey input-mix");
+ }
+
+#if 0
+ if (HDA_ADC_GROUP (0x0a, group, rec_group, "spdif-in", n, "record", 4)) /* ADC widget 0x0a */
+ {
+ /* Src 0x1f=speaker */
+ }
+#endif
+ }
+ /* Handle misc widgets */
+ {
+ int n, group;
+
+ n = 0;
+
+ HDA_GROUP (group, top_group, "input-mix");
+
+ /* Src 0x18=mic */
+ /* Src 0x19=fp-mic */
+ /* Src 0x1a=linein */
+ /* Src 0x1b=fp-headphone */
+ /* Src 0x1c=int-aux */
+ /* Src 0x1d=speaker */
+ /* Src 0x14=lineout */
+ /* Src 0x15=lineout */
+ /* Src 0x16=lineout */
+ /* Src 0x17=lineout */
+ HDA_INAMP (0x0b, 0, group, "pink", 30); /* From widget 0x18 */
+ HDA_INAMP (0x0b, 2, group, "blue", 90); /* From widget 0x1a */
+ HDA_INAMP (0x0b, 4, group, "int-aux", 90); /* From widget 0x1c */
+ HDA_INAMP (0x0b, 5, group, "black", 90); /* From widget 0x1d */
+ HDA_INAMP (0x0b, 6, group, "green", 90); /* From widget 0x14 */
+ HDA_INAMP (0x0b, 7, group, "black", 90); /* From widget 0x15 */
+ HDA_INAMP (0x0b, 8, group, "orange", 90); /* From widget 0x16 */
+ HDA_INAMP (0x0b, 9, group, "grey", 90); /* From widget 0x17 */
+ HDA_INAMP (0x0b, 3, group, "fp-green", 90); /* From widget 0x1b */
+ HDA_INAMP (0x0b, 1, group, "fp-pink", 30); /* From widget 0x19 */
+ }
+ /* Handle PIN widgets */
+ {
+ int n, group, pin_group;
+
+ n = 0;
+
+ HDA_GROUP (pin_group, top_group, "jack");
+
+ if (HDA_PIN_GROUP (0x14, group, pin_group, "green", n, "jack", 4)) /* Pin widget 0x14 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT (0x14, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl,
+ "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_OUTMUTE (0x14, group, "inmute", UNMUTE);
+ HDA_INAMP (0x14, 0, group, "in", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP (0x15, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x15 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT (0x15, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl,
+ "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_OUTMUTE (0x15, group, "inmute", UNMUTE);
+ HDA_INAMP (0x15, 0, group, "in", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP (0x16, group, pin_group, "orange", n, "jack", 4)) /* Pin widget 0x16 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT (0x16, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl,
+ "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_OUTMUTE (0x16, group, "inmute", UNMUTE);
+ HDA_INAMP (0x16, 0, group, "in", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP (0x17, group, pin_group, "grey", n, "jack", 4)) /* Pin widget 0x17 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT (0x17, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl,
+ "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_OUTMUTE (0x17, group, "inmute", UNMUTE);
+ HDA_INAMP (0x17, 0, group, "in", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP (0x18, group, pin_group, "pink", n, "jack", 4)) /* Pin widget 0x18 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT (0x18, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl,
+ "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_OUTMUTE (0x18, group, "inmute", UNMUTE);
+ HDA_INAMP (0x18, 0, group, "in", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP (0x1a, group, pin_group, "blue", n, "jack", 4)) /* Pin widget 0x1a */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT (0x1a, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl,
+ "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_OUTMUTE (0x1a, group, "inmute", UNMUTE);
+ HDA_INAMP (0x1a, 0, group, "in", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP (0x1b, group, pin_group, "fp-green", n, "jack", 4)) /* Pin widget 0x1b */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT (0x1b, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl,
+ "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_OUTMUTE (0x1b, group, "inmute", UNMUTE);
+ HDA_INAMP (0x1b, 0, group, "in", 90); /* From widget 0x0c */
+ }
+
+ if (HDA_PIN_GROUP (0x19, group, pin_group, "fp-pink", n, "jack", 4)) /* Pin widget 0x19 */
+ {
+ /* Src 0xc=front */
+ /* Src 0xd=rear */
+ /* Src 0xe=center/LFE */
+ /* Src 0xf=side */
+ /* Src 0x26=pcm4 */
+ if (HDA_PINSELECT (0x19, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl,
+ "front-out rear-out center/LFE-out side-out pcm4-out input");
+ HDA_OUTMUTE (0x19, group, "inmute", UNMUTE);
+ HDA_INAMP (0x19, 0, group, "in", 90); /* From widget 0x0c */
+ }
+
+#if 0
+ /*
+ * Non-used pins
+ */
+ if (HDA_PIN_GROUP (0x1c, group, pin_group, "int-aux", n, "jack", 4)) /* Pin widget 0x1c */
+ {
+ if (HDA_PINSELECT (0x1c, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "input");
+ }
+
+ if (HDA_PIN_GROUP (0x1d, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x1d */
+ {
+ if (HDA_PINSELECT (0x1d, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "input");
+ }
+#endif
+ }
+
+ return 0;
+}
diff --git a/kernel/drv/oss_hdaudio/hdaudio_si3055.c b/kernel/drv/oss_hdaudio/hdaudio_si3055.c
new file mode 100644
index 0000000..d47fbbd
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_si3055.c
@@ -0,0 +1,206 @@
+/*
+ * Purpose: Driver for Si3055 and compatible modems.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+
+/*
+ * Documentation Note
+ *
+ * There is no publicly available documentation for Si3055. However,
+ * there is a very similar modem (Si3038) for which a datasheet is
+ * publicly available:
+ *
+ * https://www.silabs.com/Support%20Documents/TechnicalDocs/si3038.pdf
+ *
+ * This driver was written by reading the ALSA code, looking for a
+ * similar modem (Si3038), and figuring out the corresponding Si3055
+ * register IDs for Si3038 registers, again by reading the ALSA code,
+ * and by checking the default after-reset values.
+ *
+ */
+
+#include "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_dedicated.h"
+#include "hdaudio_mixers.h"
+
+/*
+ * Si3055 register IDs.
+ */
+#define SI3055_EXT_MODEM_STATUS 2
+#define SI3055_LINE_RATE 3
+#define SI3055_HDA_STREAMS 4
+#define SI3055_GPIO_CONFIG 5
+#define SI3055_GPIO_PIN_STATUS 10
+#define SI3055_LINE_CONFIG 13
+
+
+/* Corresponding registers in Si3038 (for reference):
+ *
+ * SI3055_EXT_MODEM_STATUS 3Eh (Extended Modem Status & Control)
+ * SI3055_LINE_RATE 40h (Line 1 DAC/ADC Rate)
+ * SI3055_GPIO_PIN_STATUS 54h (GPIO Pin Status)
+ * SI3055_LINE_CONFIG 56h (Line Side Configuration 1)
+ */
+
+/*
+ * The SI3055_HDA_STREAMS register has no corresponding in Si3038.
+ * It contains the playback and recording stream descriptors in the
+ * following format:
+ *
+ * ((playback_stream_num << 4) << 8) | (recording_stream_num << 4)
+ */
+
+/* Si3055 verbs. */
+#define SI3055_REG_GET_VERB 0x900
+#define SI3055_REG_SET_VERB 0x100
+
+/* Convenience macros for reading from and writing to Si3055 registers. */
+#define SI3055_REG_GET(mixer, cad, reg, a, b) corb_read(mixer, cad, reg, 0, SI3055_REG_GET_VERB, 0, a, b)
+#define SI3055_REG_SET(mixer, cad, reg, val) corb_write(mixer, cad, reg, 0, SI3055_REG_SET_VERB, val)
+
+
+void hdaudio_si3055_set_rate(hdaudio_mixer_t *mixer, int cad, int rate)
+{
+ SI3055_REG_SET(mixer, cad, SI3055_LINE_RATE, rate);
+}
+
+int hdaudio_si3055_set_offhook(hdaudio_mixer_t *mixer, int cad, int offhook)
+{
+ unsigned int a, b;
+ SI3055_REG_GET(mixer, cad, SI3055_GPIO_PIN_STATUS, &a, &b);
+
+ if (offhook)
+ {
+ a |= 0x1; /* Set Off-Hook bit */
+ }
+ else
+ {
+ a &= ~0x1; /* Unset Off-Hook bit */
+ }
+
+ SI3055_REG_SET(mixer, cad, SI3055_GPIO_PIN_STATUS, a);
+ SI3055_REG_GET(mixer, cad, SI3055_GPIO_PIN_STATUS, &a, &b);
+ return ((a & 0x1) == 0x1);
+}
+
+void hdaudio_si3055_endpoint_init(hdaudio_mixer_t *mixer, int cad)
+{
+ codec_t *codec = mixer->codecs[cad]; /* Modem codec */
+ widget_t *widget; /* MFG widget */
+ hdaudio_endpointinfo_t *endpoint;
+ unsigned int a, b; /* Used for reading data. */
+ int tmout; /* Timeout counter. */
+
+ /* Output and input stream numbers. */
+ int playback_stream_num, recording_stream_num;
+
+
+ DDB(cmn_err(CE_CONT, "hdaudio_si3055_endpoint_init got called.\n"));
+
+ /* Reset the modem codec. */
+ corb_write(mixer, cad, 0x00, 0, SET_CODEC_RESET, 0);
+ corb_write(mixer, cad, codec->afg, 0, SET_CONVERTER, IDDLE_STREAM << 4);
+ corb_write(mixer, cad, codec->afg, 0, SET_CONVERTER_FORMAT, 0);
+
+ /* Set 9600Hz as the initial line sampling rate.
+ * It can be changed later when desired.
+ */
+ SI3055_REG_SET(mixer, cad, SI3055_LINE_RATE, 9600);
+
+ /* Assign the "unused" value to the playback and recording
+ * stream descriptors (ref. HDAudio_03.pdf, page 40).
+ */
+ SI3055_REG_SET(mixer, cad, SI3055_HDA_STREAMS, 0x0000);
+
+ /* Write 0x0000 to the Extended Modem Status & Control register
+ * to power up the modem (ref. si3038.pdf, page 22).
+ */
+ SI3055_REG_SET(mixer, cad, SI3055_EXT_MODEM_STATUS, 0x0000);
+
+ /* Wait for the modem to complete power up. The lower 8 bits
+ * indicate that it is ready (ref. si3038.pdf, page 22).
+ */
+ tmout = 10;
+ do
+ {
+ SI3055_REG_GET(mixer, cad, SI3055_EXT_MODEM_STATUS, &a, &b);
+ DDB(cmn_err(CE_CONT, "si3055: ext modem status: %04x.\n", a));
+ oss_udelay(1000);
+ }
+ while(((a & 0xf) == 0) && --tmout);
+
+ if ((a & 0xf) == 0)
+ {
+ cmn_err(CE_WARN, "si3055: power up timeout (status: %04x).\n", a);
+ }
+
+ /* This register contains 0x1fff after reset. We need to set it
+ * to zero to get the modem working. No corresponding register
+ * could be found in the Si3038 datasheet.
+ */
+ SI3055_REG_SET(mixer, cad, SI3055_GPIO_CONFIG, 0x0000);
+
+ /* Program line interface parameters. The register value after
+ * a reset is 0xF010. Set it to 0x0010 to unmute the analog
+ * receive and transmit paths.
+ */
+ SI3055_REG_SET(mixer, cad, SI3055_LINE_CONFIG, 0x0010);
+
+ /* Setup the widget info. */
+ widget = &codec->widgets[codec->afg];
+ widget->endpoint = &codec->inendpoints[0];
+ widget->sizes = 0x20000; /* 16 bits */
+ strcpy(widget->name, "modem");
+
+ /* Setup the output endpoint. */
+ codec->num_outendpoints = 1;
+ endpoint = &codec->outendpoints[0];
+ endpoint->ix = 0;
+ endpoint->iddle_stream = 0;
+ endpoint->cad = cad;
+ endpoint->base_wid = codec->afg;
+ endpoint->recsrc_wid = endpoint->volume_wid = -1;
+ endpoint->nrates = 3;
+ endpoint->rates[0] = 8000;
+ endpoint->rates[1] = 9600;
+ endpoint->rates[2] = 16000;
+ endpoint->name = widget->name;
+ endpoint->channels = 1;
+ endpoint->is_digital = 0;
+ endpoint->is_modem = 1;
+ endpoint->sizemask = widget->sizes;
+ endpoint->fmt_mask = AFMT_S16_LE;
+ endpoint->afg = codec->afg;
+ endpoint->min_rate = 8000;
+ endpoint->max_rate = 16000;
+
+ /* Setup the input endpoint. */
+ codec->num_inendpoints = 1;
+ memcpy(&codec->inendpoints[0], endpoint, sizeof(*endpoint));
+
+ /* Choose stream numbers for output and input streams. */
+ playback_stream_num = ++mixer->num_outendpoints;
+ endpoint->stream_number = endpoint->default_stream_number = playback_stream_num;
+
+ endpoint = &codec->inendpoints[0];
+ recording_stream_num = ++mixer->num_inendpoints;
+ endpoint->stream_number = endpoint->default_stream_number = recording_stream_num;
+
+ /* Setup the stream numbers. */
+ SI3055_REG_SET(mixer, cad, SI3055_HDA_STREAMS, ((playback_stream_num << 4) << 8) |
+ (recording_stream_num << 4));
+}
+
diff --git a/kernel/drv/oss_hdaudio/hdaudio_thinkpad_r61.c b/kernel/drv/oss_hdaudio/hdaudio_thinkpad_r61.c
new file mode 100755
index 0000000..047c493
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_thinkpad_r61.c
@@ -0,0 +1,301 @@
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+/* Codec index is 0 */
+/* Codec vendor 11d4:1984 */
+/* HD codec revision 1.0 (4.0) (0x00100400) */
+/* Subsystem ID 17aa20bb */
+/* Default amplifier caps: in=80000000, out=00052727 */
+#include "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_dedicated.h"
+
+int
+hdaudio_thinkpad_r61_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad, int top_group)
+{
+ int ctl=0;
+
+ DDB(cmn_err(CE_CONT, "hdaudio_thinkpad_r61_mixer_init got called.\n"));
+
+ /* Handle PIN widgets */
+ {
+ int n, group, pin_group;
+
+ n=0;
+
+ HDA_GROUP(pin_group, top_group, "jack");
+
+ if (HDA_PIN_GROUP(0x11, group, pin_group, "green", n, "jack", 4)) /* Pin widget 0x11 */
+ {
+ /* Src 0x7=headphone-mix */
+ if (HDA_PINSELECT(0x11, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "headphone-mix-out input");
+ HDA_OUTMUTE(0x11, group, "inmute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP(0x12, group, pin_group, "int-speaker", n, "jack", 4)) /* Pin widget 0x12 */
+ {
+ /* Src 0xa=lineout-mix */
+ if (HDA_PINSELECT(0x12, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "lineout-mix-out input");
+ HDA_OUTMUTE(0x12, group, "inmute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP(0x13, group, pin_group, "int-speaker", n, "jack", 4)) /* Pin widget 0x13 */
+ {
+ /* Src 0x1f=mono-mix */
+ if (HDA_PINSELECT(0x13, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "mono-mix-out input");
+ HDA_OUTAMP(0x13, group, "invol", 90);
+ }
+
+ if (HDA_PIN_GROUP(0x14, group, pin_group, "red", n, "jack", 4)) /* Pin widget 0x14 */
+ {
+ if (HDA_PINSELECT(0x14, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "input");
+ HDA_INAMP(0x14, 0, group, "out", 0); /* From widget 0x00 */
+ }
+
+ if (HDA_PIN_GROUP(0x15, group, pin_group, "int-mic", n, "jack", 4)) /* Pin widget 0x15 */
+ {
+ if (HDA_PINSELECT(0x15, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "input");
+ HDA_INAMP(0x15, 0, group, "out", 0); /* From widget 0x00 */
+ }
+
+ if (HDA_PIN_GROUP(0x16, group, pin_group, "int-cd", n, "jack", 4)) /* Pin widget 0x16 */
+ {
+ /* Src 0xb=aux-mix */
+ if (HDA_PINSELECT(0x16, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "aux-mix-out input");
+ HDA_OUTMUTE(0x16, group, "inmute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP(0x17, group, pin_group, "int-mic", n, "jack", 4)) /* Pin widget 0x17 */
+ {
+ if (HDA_PINSELECT(0x17, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "input");
+ }
+
+ if (HDA_PIN_GROUP(0x18, group, pin_group, "int-mic", n, "jack", 4)) /* Pin widget 0x18 */
+ {
+ if (HDA_PINSELECT(0x18, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "input");
+ }
+
+ if (HDA_PIN_GROUP(0x1a, group, pin_group, "int-internal", n, "jack", 4)) /* Pin widget 0x1a */
+ {
+ if (HDA_PINSELECT(0x1a, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "input");
+ }
+
+ if (HDA_PIN_GROUP(0x1b, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x1b */
+ {
+ /* Src 0x2=spdif */
+ if (HDA_PINSELECT(0x1b, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "spdif-out input");
+ HDA_OUTAMP(0x1b, group, "invol", 90);
+
+ /* Widget 0x02 (spdif) */
+ /* Src 0x1= */
+ /* Src 0x8=rec1-sel */
+ /* Src 0x9=rec2-sel */
+ }
+
+ if (HDA_PIN_GROUP(0x1c, group, pin_group, "red", n, "jack", 4)) /* Pin widget 0x1c */
+ {
+ /* Src 0x24=dock-mix */
+ if (HDA_PINSELECT(0x1c, ctl, group, "mode", -1))
+ HDA_CHOICES(ctl, "dock-mix-out input");
+ HDA_OUTMUTE(0x1c, group, "inmute", UNMUTE);
+ }
+ }
+ /* Handle ADC widgets */
+ {
+ int n, group, rec_group;
+
+ n=0;
+
+ HDA_GROUP(rec_group, top_group, "record");
+
+ if (HDA_ADC_GROUP(0x05, group, rec_group, "int-mic", n, "record", 4)) /* ADC widget 0x05 */
+ {
+ /* Src 0x17=int-mic */
+ HDA_INAMP(0x05, 0, group, "int-mic", 90); /* From widget 0x17 */
+ }
+
+ if (HDA_ADC_GROUP(0x06, group, rec_group, "int-mic", n, "record", 4)) /* ADC widget 0x06 */
+ {
+ /* Src 0x18=int-mic */
+ HDA_INAMP(0x06, 0, group, "int-mic", 90); /* From widget 0x18 */
+ }
+
+ if (HDA_ADC_GROUP(0x08, group, rec_group, "rec1-sel", n, "record", 4)) /* ADC widget 0x08 */
+ {
+ /* Src 0xc=rec1-sel */
+ }
+
+ if (HDA_ADC_GROUP(0x09, group, rec_group, "rec2-sel", n, "record", 4)) /* ADC widget 0x09 */
+ {
+ /* Src 0xd=rec2-sel */
+ }
+ }
+ /* Handle misc widgets */
+ {
+ int n, group, misc_group;
+
+ n=0;
+
+ HDA_GROUP(misc_group, top_group, "misc");
+
+ if (HDA_MISC_GROUP(0x03, group, misc_group, "headphone", n, "misc", 8)) /* Misc widget 0x03 */
+ {
+ HDA_OUTAMP(0x03, group, "-", 90);
+ }
+
+ if (HDA_MISC_GROUP(0x04, group, misc_group, "front", n, "misc", 8)) /* Misc widget 0x04 */
+ {
+ HDA_OUTAMP(0x04, group, "-", 90);
+ }
+
+ if (HDA_MISC_GROUP(0x07, group, misc_group, "headphone-mix", n, "misc", 8)) /* Misc widget 0x07 */
+ {
+ /* Src 0x22=headphone-sel */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x07, 0, amp_group, "headphone-sel", UNMUTE); /* From widget 0x22 */
+ HDA_INMUTE(0x07, 1, amp_group, "input-mix", UNMUTE); /* From widget 0x21 */
+ }
+
+ /* Widget 0x22 (headphone-sel) */
+ /* Src 0x3=headphone */
+ /* Src 0x4=front */
+ if (HDA_SELECT(0x22, "src", ctl, group, 1 /* Select front */))
+ {
+ HDA_CHOICES(ctl, "headphone front");
+ }
+
+ /* Widget 0x21 (input-mix) */
+ /* Src 0x20=input-mix */
+ HDA_OUTAMP(0x21, group, "-", 90);
+
+ /* Widget 0x20 (input-mix) */
+ /* Src 0x14=red */
+ /* Src 0x96= */
+ /* Src 0x1a=int-internal */
+ /* Src 0x25=dock-mix */
+ HDA_INAMP(0x20, 0, group, "red", 90); /* From widget 0x14 */
+ HDA_INAMP(0x20, 1, group, "", 90); /* From widget 0x96 */
+ HDA_INAMP(0x20, 2, group, "int-internal", 90); /* From widget 0x1a */
+ HDA_INAMP(0x20, 3, group, "dock-mix", 90); /* From widget 0x25 */
+ }
+
+ if (HDA_MISC_GROUP(0x0a, group, misc_group, "lineout-mix", n, "misc", 8)) /* Misc widget 0x0a */
+ {
+ /* Src 0x4=front */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x0a, 0, amp_group, "front", UNMUTE); /* From widget 0x04 */
+ HDA_INMUTE(0x0a, 1, amp_group, "input-mix", UNMUTE); /* From widget 0x21 */
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x0b, group, misc_group, "aux-mix", n, "misc", 8)) /* Misc widget 0x0b */
+ {
+ /* Src 0xf=aux-sel */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x0b, 0, amp_group, "aux-sel", UNMUTE); /* From widget 0x0f */
+ HDA_INMUTE(0x0b, 1, amp_group, "input-mix", UNMUTE); /* From widget 0x21 */
+ }
+
+ /* Widget 0x0f (aux-sel) */
+ /* Src 0x3=headphone */
+ /* Src 0x4=front */
+ if (HDA_SELECT(0x0f, "src", ctl, group, -1))
+ {
+ HDA_CHOICES(ctl, "headphone front");
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x0c, group, misc_group, "rec1-sel", n, "misc", 8)) /* Misc widget 0x0c */
+ {
+ /* Src 0x14=mic */
+ /* Src 0x96= */
+ /* Src 0x20=input-mix */
+ /* Src 0x25=dock-mix */
+ if (HDA_SELECT(0x0c, "src", ctl, group, -1))
+ {
+ HDA_CHOICES(ctl, "mic unknown input-mix dock-mix");
+ }
+ HDA_OUTAMP(0x0c, group, "-", 90);
+
+ /* Widget 0x25 (dock-mix) */
+ /* Src 0x1c=red */
+ HDA_OUTAMP(0x25, group, "-", 90);
+ }
+
+ if (HDA_MISC_GROUP(0x0d, group, misc_group, "rec2-sel", n, "misc", 8)) /* Misc widget 0x0d */
+ {
+ /* Src 0x14=mic */
+ /* Src 0x96= */
+ /* Src 0x20=input-mix */
+ /* Src 0x25=dock-mix */
+ if (HDA_SELECT(0x0d, "src", ctl, group, -1))
+ {
+ HDA_CHOICES(ctl, "mic unknown input-mix dock-mix");
+ }
+ HDA_OUTAMP(0x0d, group, "-", 90);
+ }
+
+ if (HDA_MISC_GROUP(0x10, group, misc_group, "beep", n, "misc", 8)) /* Misc widget 0x10 */
+ {
+ HDA_OUTAMP(0x10, group, "-", 90);
+ }
+
+ if (HDA_MISC_GROUP(0x1e, group, misc_group, "mono-mix", n, "misc", 8)) /* Misc widget 0x1e */
+ {
+ /* Src 0xe=mono-sel */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x1e, 0, amp_group, "mono-sel", UNMUTE); /* From widget 0x0e */
+ HDA_INMUTE(0x1e, 1, amp_group, "input-mix", UNMUTE); /* From widget 0x21 */
+ }
+ }
+
+ if (HDA_MISC_GROUP(0x24, group, misc_group, "dock-mix", n, "misc", 8)) /* Misc widget 0x24 */
+ {
+ /* Src 0x23=dock-sel */
+ /* Src 0x21=input-mix */
+ {
+ int amp_group;
+
+ HDA_GROUP(amp_group, group, "mute");
+ HDA_INMUTE(0x24, 0, amp_group, "dock-sel", UNMUTE); /* From widget 0x23 */
+ HDA_INMUTE(0x24, 1, amp_group, "input-mix", UNMUTE); /* From widget 0x21 */
+ }
+ }
+ }
+ return 0;
+}
diff --git a/kernel/drv/oss_hdaudio/hdaudio_vaio_vgn.c b/kernel/drv/oss_hdaudio/hdaudio_vaio_vgn.c
new file mode 100644
index 0000000..2472672
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/hdaudio_vaio_vgn.c
@@ -0,0 +1,144 @@
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+/* Codec index is 0 */
+/* Codec vendor 0804:73dc */
+/* HD codec revision 1.0 (2.1) (0x00100201) */
+/* Subsystem ID 104d2200 */
+/* Default amplifier caps: in=80050f00, out=80027f7f */
+#include "oss_hdaudio_cfg.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "hdaudio_dedicated.h"
+
+int
+hdaudio_vaio_vgn_mixer_init (int dev, hdaudio_mixer_t * mixer, int cad,
+ int top_group)
+{
+ int ctl = 0;
+
+ DDB (cmn_err (CE_CONT, "hdaudio_vaio_vgn_mixer_init got called.\n"));
+
+ HDA_OUTAMP_F (0x05, top_group, "speaker", 90, MIXF_MAINVOL);
+ /* We sync the volume of the headphone DAC to the speaker DAC */
+#if 1
+ HDA_OUTAMP_F (0x02, top_group, "headphone", 90, MIXF_MAINVOL);
+#endif
+
+
+ HDA_SETSELECT (0x0f, 0); /* Int speaker mode */
+ HDA_SETSELECT (0x14, 1); /* Int mic mode */
+
+ /* Handle PIN widgets */
+ {
+ int n, group, pin_group;
+
+ n = 0;
+
+ HDA_GROUP (pin_group, top_group, "jack");
+
+ if (HDA_PIN_GROUP (0x0a, group, pin_group, "headphone", n, "jack", 4)) /* Pin widget 0x0a */
+ {
+ /* Src 0x2=pcm */
+ if (HDA_PINSELECT (0x0a, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "pcm-out input");
+ HDA_OUTMUTE (0x0a, group, "mute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP (0x0b, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x0b */
+ {
+ /* Src 0x4=pcm */
+ if (HDA_PINSELECT (0x0b, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "pcm-out input");
+ HDA_OUTMUTE (0x0b, group, "mute", UNMUTE);
+
+ /* Widget 0x04 (pcm) */
+ HDA_OUTAMP (0x04, group, "-", 90);
+ }
+
+ if (HDA_PIN_GROUP (0x0c, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x0c */
+ {
+ /* Src 0x3=pcm */
+ if (HDA_PINSELECT (0x0c, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "pcm-out input");
+ HDA_OUTMUTE (0x0c, group, "mute", UNMUTE);
+
+ /* Widget 0x03 (pcm) */
+ HDA_OUTAMP (0x03, group, "-", 90);
+ }
+
+ if (HDA_PIN_GROUP (0x0d, group, pin_group, "red", n, "jack", 4)) /* Pin widget 0x0d */
+ {
+ /* Src 0x2=pcm */
+ if (HDA_PINSELECT (0x0d, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "pcm-out input");
+ HDA_OUTMUTE (0x0d, group, "mute", UNMUTE);
+ }
+
+ if (HDA_PIN_GROUP (0x0e, group, pin_group, "black", n, "jack", 4)) /* Pin widget 0x0e */
+ {
+ if (HDA_PINSELECT (0x0e, ctl, group, "mode", -1))
+ HDA_CHOICES (ctl, "input");
+ }
+ }
+ /* Handle ADC widgets */
+ {
+ int n, group, rec_group;
+
+ n = 0;
+
+ HDA_GROUP (rec_group, top_group, "record");
+
+ if (HDA_ADC_GROUP (0x06, group, rec_group, "rec1", n, "record", 4)) /* ADC widget 0x06 */
+ {
+ /* Src 0x7=rec */
+
+ /* Widget 0x07 (rec) */
+ /* Src 0xe=black */
+ HDA_INAMP_F (0x07, 0, group, "black", 80, MIXF_RECVOL); /* From widget 0x0e */
+ }
+
+ if (HDA_ADC_GROUP (0x08, group, rec_group, "rec", n, "record", 8)) /* ADC widget 0x08 */
+ {
+ /* Src 0x9=rec */
+
+ /* Widget 0x09 (rec) */
+ /* Src 0x15=rec */
+ HDA_INAMP_F (0x09, 0, group, "rec", 80, MIXF_RECVOL); /* From widget 0x15 */
+
+ /* Widget 0x15 (rec) */
+ /* Src 0xa=black */
+ /* Src 0xd=red */
+ /* Src 0x14=int-mic */
+ /* Src 0x2=pcm */
+ if (HDA_SELECT (0x15, "src", ctl, group, -1))
+ {
+ HDA_CHOICES (ctl, "headphone mic int-mic pcm");
+ }
+ HDA_OUTAMP (0x15, group, "micboost", 0);
+ }
+
+ if (HDA_ADC_GROUP (0x12, group, rec_group, "spdifin", n, "record", 4)) /* ADC widget 0x12 */
+ {
+ /* Src 0x13=speaker */
+ }
+ }
+ /* Handle misc widgets */
+ {
+#if 0
+ if (HDA_MISC_GROUP (0x16, group, misc_group, "beep", n, "misc", 8)) /* Misc widget 0x16 */
+ {
+ HDA_OUTAMP (0x16, group, "-", 90);
+ }
+#endif
+ }
+ return 0;
+}
diff --git a/kernel/drv/oss_hdaudio/oss_hdaudio.c b/kernel/drv/oss_hdaudio/oss_hdaudio.c
new file mode 100644
index 0000000..6492bec
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/oss_hdaudio.c
@@ -0,0 +1,1996 @@
+/*
+ * Purpose: The High Definition Audio (HDA/Azalia) driver.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_hdaudio_cfg.h"
+#include "oss_pci.h"
+#include "hdaudio.h"
+#include "hdaudio_codec.h"
+#include "spdif.h"
+
+#define CORB_DELAY 10
+#define CORB_LOOPS 1000
+
+#define INTEL_VENDOR_ID 0x8086
+#define INTEL_DEVICE_ICH6 0x2668
+#define INTEL_DEVICE_ICH7 0x27d8
+#define INTEL_DEVICE_ESB2 0x269a
+#define INTEL_DEVICE_ICH8 0x284b
+#define INTEL_DEVICE_ICH9 0x293f
+#define INTEL_DEVICE_ICH10 0x3a3e
+#define INTEL_DEVICE_ICH10_B 0x3a6e
+#define INTEL_DEVICE_CPT 0x1c20
+#define INTEL_DEVICE_PCH 0x3b56
+#define INTEL_DEVICE_PCH2 0x3b57
+#define INTEL_DEVICE_SCH 0x811b
+#define INTEL_DEVICE_P35 0x293e
+
+#define NVIDIA_VENDOR_ID 0x10de
+#define NVIDIA_DEVICE_MCP51 0x026c
+#define NVIDIA_DEVICE_MCP55 0x0371
+#define NVIDIA_DEVICE_MCP61 0x03e4
+#define NVIDIA_DEVICE_MCP61A 0x03f0
+#define NVIDIA_DEVICE_MCP65 0x044a
+#define NVIDIA_DEVICE_MCP67 0x055c
+#define NVIDIA_DEVICE_MCP73 0x07fc
+#define NVIDIA_DEVICE_MCP78S 0x0774
+#define NVIDIA_DEVICE_MCP79 0x0ac0
+
+#define ATI_VENDOR_ID 0x1002
+#define ATI_DEVICE_SB450 0x437b
+#define ATI_DEVICE_SB600 0x4383
+
+#define VIA_VENDOR_ID 0x1106
+#define VIA_DEVICE_HDA 0x3288
+
+#define SIS_VENDOR_ID 0x1039
+#define SIS_DEVICE_HDA 0x7502
+
+#define ULI_VENDOR_ID 0x10b9
+#define ULI_DEVICE_HDA 0x5461
+
+#define CREATIVE_ID 0x1102
+#define CREATIVE_XFI_HDA 0x0009
+
+#define BDL_SIZE 32
+#define HDA_MAX_ENGINES 8
+#define MAX_OUTPUTS 8
+#define MAX_INPUTS 4
+
+typedef struct
+{
+ oss_uint64_t addr;
+ unsigned int len;
+ unsigned int ioc;
+} bdl_t;
+
+typedef struct hda_portc_t hda_portc_t;
+
+typedef struct
+{
+ int num;
+ int busy;
+ bdl_t *bdl;
+ oss_uint64_t bdl_phys;
+ oss_dma_handle_t bdl_dma_handle;
+ int bdl_size, bdl_max;
+ unsigned char *base;
+ unsigned int intrmask;
+ hda_portc_t *portc;
+} hda_engine_t;
+
+struct hda_portc_t
+{
+ int num;
+ int open_mode;
+ int speed, bits, channels;
+ int audio_enabled;
+ int trigger_bits;
+ int audiodev;
+ int port_type;
+#define PT_OUTPUT 0
+#define PT_INPUT 1
+ hdaudio_endpointinfo_t *endpoint;
+ hda_engine_t *engine;
+};
+
+typedef struct
+{
+ unsigned int response, resp_ex;
+} rirb_entry_t;
+
+typedef struct hda_devc_t
+{
+ oss_device_t *osdev;
+ oss_native_word base;
+ unsigned int membar_addr;
+ unsigned char *azbar;
+
+ char *chip_name;
+ unsigned int vendor_id, subvendor_id;
+
+ int irq;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ /* CORB and RIRB */
+ int corbsize, rirbsize;
+ unsigned int *corb;
+ rirb_entry_t *rirb;
+ oss_uint64_t corb_phys, rirb_phys;
+ int rirb_rp;
+ unsigned int rirb_upper, rirb_lower;
+ volatile int rirb_empty;
+
+ oss_dma_handle_t corb_dma_handle;
+
+ /* Mixer */
+ unsigned short codecmask;
+ hdaudio_mixer_t *mixer;
+ int mixer_dev;
+ spdif_devc spdc;
+
+ /* Audio */
+ int first_dev;
+ hda_engine_t inengines[HDA_MAX_ENGINES];
+ hda_engine_t outengines[HDA_MAX_ENGINES];
+ int num_outengines, num_inengines;
+ hdaudio_endpointinfo_t *spdifout_endpoint;
+
+ hda_portc_t output_portc[MAX_OUTPUTS];
+ hda_portc_t input_portc[MAX_INPUTS];
+ int num_outputs, num_inputs;
+
+ int num_spdin, num_spdout;
+ int num_mdmin, num_mdmout;
+}
+hda_devc_t;
+
+static int
+rirb_intr (hda_devc_t * devc)
+{
+ int serviced = 0;
+ unsigned char rirbsts;
+ oss_native_word flags;
+
+ rirbsts = PCI_READB (devc->osdev, devc->azbar + HDA_RIRBSTS);
+ if (rirbsts != 0)
+ {
+ serviced = 1;
+
+ if (rirbsts & 0x01)
+ {
+ /* RIRB response interrupt */
+ int wp, rp;
+ unsigned int upper = 0, lower = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ wp = PCI_READB (devc->osdev, devc->azbar + HDA_RIRBWP) & 0x00ff;
+ while (devc->rirb_rp != wp)
+ {
+ devc->rirb_rp++;
+ devc->rirb_rp %= devc->rirbsize;
+ rp = devc->rirb_rp;
+ upper = devc->rirb[rp].response;
+ lower = devc->rirb[rp].resp_ex;
+
+ if (lower & 0x10) /* Unsolicited response */
+ {
+ hda_codec_unsol (devc->mixer, upper, lower);
+ }
+ else if (devc->rirb_empty)
+ {
+ devc->rirb_upper = upper;
+ devc->rirb_lower = lower;
+ devc->rirb_empty--;
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ }
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBSTS, rirbsts);
+ }
+
+ return serviced;
+}
+
+static int
+hdaintr (oss_device_t * osdev)
+{
+ hda_devc_t *devc = (hda_devc_t *) osdev->devc;
+ unsigned int status;
+ int serviced = 0;
+ int i;
+
+ if (devc == NULL) /* Too bad */
+ return 1;
+
+ status = PCI_READL (devc->osdev, devc->azbar + HDA_INTSTS);
+ if (status != 0)
+ {
+ serviced = 1;
+
+ for (i = 0; i < devc->num_outengines; i++)
+ {
+ hda_engine_t *engine = &devc->outengines[i];
+
+ hda_portc_t *portc;
+ if (status & engine->intrmask)
+ {
+ PCI_WRITEB (devc->osdev, engine->base + 0x03, 0x1e);
+
+ portc = engine->portc;
+
+ if (portc != NULL && (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+ }
+
+ for (i = 0; i < devc->num_inengines; i++)
+ {
+ hda_engine_t *engine = &devc->inengines[i];
+
+ hda_portc_t *portc;
+ if (status & engine->intrmask)
+ {
+ PCI_WRITEB (devc->osdev, engine->base + 0x03, 0x1e);
+
+ portc = engine->portc;
+
+ if (portc != NULL && (portc->trigger_bits & PCM_ENABLE_INPUT))
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_INTSTS, status); /* ACK */
+
+ if (status & (1 << 30)) /* Controller interrupt (RIRB) */
+ {
+ if (rirb_intr (devc))
+ serviced = 1;
+ }
+ }
+ return serviced;
+}
+
+static int
+do_corb_write (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
+ unsigned int verb, unsigned int parm)
+{
+ unsigned int wp;
+ unsigned int tmp;
+ oss_native_word flags;
+ hda_devc_t *devc = (hda_devc_t *) dc;
+
+ tmp = (cad << 28) | (d << 27) | (nid << 20) | (verb << 8) | (parm & 0xffff);
+ wp = PCI_READB (devc->osdev, devc->azbar + HDA_CORBWP) & 0x00ff;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ wp = (wp + 1) % devc->corbsize;
+
+ devc->corb[wp] = tmp;
+ devc->rirb_empty++;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_CORBWP, wp);
+
+ return 1;
+}
+
+static int
+do_corb_write_nomutex (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
+ unsigned int verb, unsigned int parm)
+{
+ unsigned int wp;
+ unsigned int tmp;
+ hda_devc_t *devc = (hda_devc_t *) dc;
+
+ tmp = (cad << 28) | (d << 27) | (nid << 20) | (verb << 8) | (parm & 0xffff);
+ wp = PCI_READB (devc->osdev, devc->azbar + HDA_CORBWP) & 0x00ff;
+
+ wp = (wp + 1) % devc->corbsize;
+
+ devc->corb[wp] = tmp;
+ devc->rirb_empty++;
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_CORBWP, wp);
+
+ return 1;
+}
+
+static int
+do_corb_read (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
+ unsigned int verb, unsigned int parm, unsigned int *upper,
+ unsigned int *lower)
+{
+ int tmout;
+ hda_devc_t *devc = (hda_devc_t *) dc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ do_corb_write_nomutex (devc, cad, nid, d, verb, parm);
+
+ tmout = CORB_LOOPS;
+ while (devc->rirb_empty)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (--tmout < 0)
+ {
+ devc->rirb_rp = PCI_READB (devc->osdev, devc->azbar + HDA_RIRBWP);
+ devc->rirb_empty = 0;
+ return 0;
+ }
+ oss_udelay (CORB_DELAY);
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ }
+
+ *upper = devc->rirb_upper;
+ *lower = devc->rirb_lower;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 1;
+}
+
+static int
+do_corb_read_poll (void *dc, unsigned int cad, unsigned int nid,
+ unsigned int d, unsigned int verb, unsigned int parm,
+ unsigned int *upper, unsigned int *lower)
+{
+ int tmout = 0;
+ hda_devc_t *devc = (hda_devc_t *) dc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ do_corb_write_nomutex (devc, cad, nid, d, verb, parm);
+
+ tmout = CORB_LOOPS;
+ while (devc->rirb_empty)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ rirb_intr (devc);
+
+ if (--tmout < 0)
+ {
+ devc->rirb_rp = PCI_READB (devc->osdev, devc->azbar + HDA_RIRBWP);
+ devc->rirb_empty = 0;
+ return 0;
+ }
+ oss_udelay (CORB_DELAY);
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ }
+
+ *upper = devc->rirb_upper;
+ *lower = devc->rirb_lower;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 1;
+}
+
+#undef corb_read
+
+static int
+corb_read (void *dc, unsigned int cad, unsigned int nid, unsigned int d,
+ unsigned int verb, unsigned int parm, unsigned int *upper,
+ unsigned int *lower)
+{
+ hda_devc_t *devc = (hda_devc_t *) dc;
+
+/*
+ * Do three retries using different access methods
+ */
+ if (do_corb_read (dc, cad, nid, d, verb, parm, upper, lower))
+ return 1;
+
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBCTL, 0x02); /* Intr disable */
+
+ if (do_corb_read_poll (dc, cad, nid, d, verb, parm, upper, lower))
+ {
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBCTL, 0x03); /* Intr re-enable */
+ return 1;
+ }
+
+ if (do_corb_read_poll (dc, cad, nid, d, verb, parm, upper, lower))
+ {
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBCTL, 0x03); /* Intr re-enable */
+ return 1;
+ }
+
+#if 0
+ // TODO: Implement this
+ if (do_corb_read_single (dc, cad, nid, d, verb, parm, upper, lower))
+ {
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBCTL, 0x03); /* Intr re-enable */
+ return 1;
+ }
+#endif
+
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBCTL, 0x03); /* Intr re-enable */
+
+ cmn_err (CE_WARN,
+ "RIRB timeout (cad=%d, nid=%d, d=%d, verb=%03x, parm=%x)\n",
+ cad, nid, d, verb, parm);
+
+ return 0;
+}
+
+/*
+ * Audio routines
+ */
+
+static int
+hda_audio_set_rate (int dev, int arg)
+{
+ hda_portc_t *portc = audio_engines[dev]->portc;
+ adev_p adev = audio_engines[dev];
+
+ int best = -1, bestdiff = 10000000;
+ int i;
+
+ if (arg == 0)
+ return portc->speed;
+
+ for (i = 0; i < adev->nrates; i++)
+ {
+ int diff = arg - adev->rates[i];
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < bestdiff)
+ {
+ best = i;
+ bestdiff = diff;
+ }
+ }
+
+ if (best == -1)
+ {
+ cmn_err (CE_WARN, "No suitable rate found!\n");
+ return portc->speed = 48000; /* Some default */
+ }
+ portc->speed = adev->rates[best];
+ return portc->speed;
+}
+
+static short
+hda_audio_set_channels (int dev, short arg)
+{
+ hda_portc_t *portc = audio_engines[dev]->portc;
+ hda_devc_t *devc = audio_engines[dev]->devc;
+ adev_p adev = audio_engines[dev];
+ int i, n1, n2;
+
+ if (arg == 0)
+ {
+ return portc->channels;
+ }
+
+ if (arg < 1)
+ arg = 1;
+
+ if (arg > adev->max_channels)
+ {
+ arg = adev->max_channels;
+ }
+
+ if (arg != 1 && arg != 2 && arg != 4 && arg != 6 && arg != 8)
+ {
+ cmn_err (CE_NOTE, "Ignored request for odd number (%d) of channels\n", arg);
+ return portc->channels = arg & ~1;
+ }
+
+ if (arg < adev->min_channels)
+ arg = adev->min_channels;
+
+ /*
+ * Check if more output endpoints need to be allocated
+ */
+ n2 = (arg + 1) / 2;
+ n1 = (portc->channels + 1) / 2;
+ if (n1 < 1)
+ n1 = 1;
+
+ if (n2 > n1) /* Needs more stereo pairs */
+ {
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ for (i = n1; i < n2; i++)
+ {
+ if (portc->endpoint[i].busy)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return portc->channels;
+ }
+ }
+
+ for (i = n1; i < n2; i++)
+ {
+ portc->endpoint[i].busy = 1;
+ portc->endpoint->borrow_count++;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ }
+ else if (n2 < n1) /* Some stereo pairs can be released */
+ {
+ for (i = n2; i < n1; i++)
+ {
+ portc->endpoint[i].busy = 0;
+ portc->endpoint->borrow_count--;
+ }
+ }
+
+ return portc->channels = arg;
+}
+
+static unsigned int
+hda_audio_set_format (int dev, unsigned int arg)
+{
+ hda_portc_t *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & audio_engines[dev]->oformat_mask))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+static int
+do_corb_write_simple (void *dc, unsigned int v)
+{
+ unsigned int wp;
+ hda_devc_t *devc = (hda_devc_t *) dc;
+
+ wp = PCI_READB (devc->osdev, devc->azbar + HDA_CORBWP) & 0x00ff;
+
+ wp = (wp + 1) % devc->corbsize;
+
+ devc->corb[wp] = v;
+ devc->rirb_empty++;
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_CORBWP, wp);
+
+ return 1;
+}
+
+static int
+do_corb_read_simple (void *dc, unsigned int cmd, unsigned int *v)
+{
+ int tmout = 0;
+ hda_devc_t *devc = (hda_devc_t *) dc;
+
+ do_corb_write_simple (dc, cmd);
+
+ tmout = CORB_LOOPS;
+ while (devc->rirb_empty)
+ {
+ if (--tmout < 0)
+ {
+ cmn_err (CE_WARN, "RIRB timeout (cmd=%08x)\n", cmd);
+ devc->rirb_rp = PCI_READB (devc->osdev, devc->azbar + HDA_RIRBWP);
+ devc->rirb_empty = 0;
+ return 0;
+ }
+ oss_udelay (CORB_DELAY);
+ }
+
+ *v = devc->rirb_upper;
+
+ return 1;
+}
+
+static int
+hda_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ hda_devc_t *devc = audio_engines[dev]->devc;
+ hda_portc_t *portc = audio_engines[dev]->portc;
+
+ //if (hdaudio_snoopy)
+ switch (cmd)
+ {
+ case HDA_IOCTL_WRITE:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ do_corb_write_simple (devc, *(unsigned int *) arg);
+ return 0;
+ break;
+
+ case HDA_IOCTL_READ:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ if (!do_corb_read_simple
+ (devc, *(unsigned int *) arg, (unsigned int *) arg))
+ return OSS_EIO;
+
+ return 0;
+ break;
+
+ case HDA_IOCTL_NAME:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ return hda_codec_getname (devc->mixer, (hda_name_t *) arg);
+ break;
+
+ case HDA_IOCTL_WIDGET:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ return hda_codec_getwidget (devc->mixer, (hda_widget_info_t *) arg);
+ break;
+
+ }
+ return hdaudio_codec_audio_ioctl (devc->mixer, portc->endpoint, cmd, arg);
+}
+
+static void hda_audio_trigger (int dev, int state);
+
+static void
+hda_audio_reset (int dev)
+{
+ hda_audio_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static int
+hda_audio_open (int dev, int mode, int openflags)
+{
+ hda_portc_t *portc = audio_engines[dev]->portc;
+ hda_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ hda_engine_t *engines, *engine = NULL;
+ int i, n;
+ unsigned int tmp;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode || portc->endpoint->busy)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (portc->port_type == PT_INPUT)
+ {
+ engines = devc->inengines;
+ n = devc->num_inengines;
+ }
+ else
+ {
+ engines = devc->outengines;
+ n = devc->num_outengines;
+ }
+
+ for (i = 0; i < n && engine == NULL; i++)
+ {
+ if (!engines[i].busy)
+ engine = &engines[i];
+ }
+
+ if (engine == NULL)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ cmn_err (CE_WARN, "No free DMA engines.\nn");
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ portc->endpoint->busy = 1;
+ portc->endpoint->borrow_count = 1;
+
+ portc->engine = engine;
+ engine->portc = portc;
+ portc->engine->busy = 1;
+
+ portc->endpoint->stream_number = portc->endpoint->default_stream_number;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+/*
+ * Reset the DMA engine and wait for the reset to complete
+ */
+ tmp = PCI_READL (devc->osdev, engine->base);
+ PCI_WRITEL (devc->osdev, engine->base, tmp | 0x01); /* Stream reset */
+
+ for (i = 0; i < 1000; i++)
+ {
+ if (PCI_READL (devc->osdev, engine->base) & 0x01)
+ break;
+ oss_udelay (1000);
+ }
+
+ /* Unreset and wait */
+
+ tmp = PCI_READL (devc->osdev, engine->base);
+ PCI_WRITEL (devc->osdev, engine->base, tmp & ~0x01); /* Release reset */
+
+ for (i = 0; i < 1000; i++)
+ {
+ if (!(PCI_READL (devc->osdev, engine->base) & 0x01))
+ break;
+ oss_udelay (1000);
+ }
+
+ return 0;
+}
+
+static void
+hda_audio_close (int dev, int mode)
+{
+ hda_portc_t *portc = audio_engines[dev]->portc;
+ hda_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ int i;
+
+ if (!portc->open_mode)
+ {
+ cmn_err (CE_WARN, "Bad close %d\n", dev);
+ return;
+ }
+
+ hda_audio_reset (dev);
+ hdaudio_codec_reset_endpoint (devc->mixer, portc->endpoint,
+ portc->channels);
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->audio_enabled &= ~mode;
+ portc->engine->busy = 0;
+ portc->engine->portc = NULL;
+ portc->engine = NULL;
+ portc->endpoint->busy = 0;
+ portc->endpoint->stream_number = portc->endpoint->default_stream_number;
+
+ for (i = 1; i < portc->endpoint->borrow_count; i++)
+ {
+ portc->endpoint[i].busy = 0;
+ }
+
+ portc->endpoint->borrow_count = 1;
+ portc->open_mode = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static void
+hda_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ hda_portc_t *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+hda_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ hda_portc_t *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+hda_audio_trigger (int dev, int state)
+{
+ hda_devc_t *devc = audio_engines[dev]->devc;
+ hda_portc_t *portc = audio_engines[dev]->portc;
+ hda_engine_t *engine = portc->engine;
+ oss_native_word flags;
+ unsigned char tmp, intr;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ tmp = PCI_READB (devc->osdev, engine->base + 0x00);
+ intr = PCI_READB (devc->osdev, devc->azbar + HDA_INTCTL);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ tmp |= 0x1e; /* DMA and Stream Interrupt enable */
+ intr |= engine->intrmask;
+ PCI_WRITEB (devc->osdev, engine->base + 0x00, tmp);
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_INTCTL, intr);
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ tmp &= ~0x1e; /* Run-off & intr disable */
+ intr &= ~engine->intrmask;
+ /* Stop DMA and Stream Int */
+ PCI_WRITEB (devc->osdev, engine->base + 0x00, tmp);
+ /* Ack pending ints */
+ PCI_WRITEB (devc->osdev, engine->base + 0x03, 0x1c);
+ /* Disable Interrupts */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_INTCTL, intr);
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ tmp |= 0x1e; /* dma & intr enable */
+ intr |= engine->intrmask;
+ PCI_WRITEB (devc->osdev, engine->base + 0x00, tmp);
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_INTCTL, intr);
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ tmp &= ~0x1e; /* Run-off & intr disable */
+ intr &= ~engine->intrmask;
+ /* Stop DMA and Stream Int */
+ PCI_WRITEB (devc->osdev, engine->base + 0x00, tmp);
+ /* Ack pending ints */
+ PCI_WRITEB (devc->osdev, engine->base + 0x03, 0x1c);
+ /* Disable Interrupts */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_INTCTL, intr);
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+init_bdl (hda_devc_t * devc, hda_engine_t * engine, dmap_p dmap)
+{
+ int i;
+ bdl_t *bdl = engine->bdl;
+
+ PCI_WRITEL (devc->osdev, engine->base + HDA_SD_BDLPL, 0);
+ PCI_WRITEL (devc->osdev, engine->base + HDA_SD_BDLPU, 0);
+ for (i = 0; i < dmap->nfrags; i++)
+ {
+ bdl[i].addr = dmap->dmabuf_phys + (i * dmap->fragment_size);
+ bdl[i].len = dmap->fragment_size;
+ bdl[i].ioc = 0x01;
+ }
+}
+
+static int
+setup_audio_engine (hda_devc_t * devc, hda_engine_t * engine, hda_portc_t * portc,
+ dmap_t * dmap)
+{
+ unsigned int tmp, tmout;
+
+/* make sure the run bit is zero for SD */
+ PCI_WRITEB (devc->osdev, engine->base + HDA_SD_CTL,
+ PCI_READB (devc->osdev, engine->base + HDA_SD_CTL) & ~0x2);
+/*
+ * First reset the engine.
+ */
+
+ tmp = PCI_READB (devc->osdev, engine->base + HDA_SD_CTL);
+ PCI_WRITEB (devc->osdev, engine->base + HDA_SD_CTL, tmp | 0x01); /* Reset */
+ oss_udelay (1000);
+
+ tmout = 300;
+ while (!(PCI_READB (devc->osdev, engine->base + HDA_SD_CTL) & 0x01)
+ && --tmout)
+ oss_udelay (1000);
+
+ PCI_WRITEB (devc->osdev, engine->base + HDA_SD_CTL, tmp & ~0x01); /* Release reset */
+ oss_udelay (1000);
+ tmout = 300;
+ while ((PCI_READB (devc->osdev, engine->base + HDA_SD_CTL) & 0x01)
+ && --tmout)
+ oss_udelay (1000);
+
+/*
+ * Set the engine tag number field
+ */
+ tmp = PCI_READL (devc->osdev, engine->base + HDA_SD_CTL);
+ tmp &= ~(0xf << 20);
+ tmp |= portc->endpoint->stream_number << 20;
+ PCI_WRITEL (devc->osdev, engine->base + HDA_SD_CTL, tmp);
+
+/* program buffer size and fragments in the engine */
+
+ PCI_WRITEL (devc->osdev, engine->base + HDA_SD_CBL, dmap->bytes_in_use);
+ PCI_WRITEW (devc->osdev, engine->base + HDA_SD_LVI, dmap->nfrags - 1);
+
+/* setup the BDL base address */
+ tmp = engine->bdl_phys;
+ PCI_WRITEL (devc->osdev, engine->base + HDA_SD_BDLPL, tmp & 0xffffffff);
+ tmp = engine->bdl_phys >> 32;
+ PCI_WRITEL (devc->osdev, engine->base + HDA_SD_BDLPU, tmp & 0xffffffff);
+ PCI_WRITEB (devc->osdev, engine->base + HDA_SD_STS, 0x1c); /* mask out ints */
+
+/*
+ * Next the sample rate and format setup
+ */
+ if (hdaudio_codec_setup_endpoint
+ (devc->mixer, portc->endpoint, portc->speed, portc->channels,
+ portc->bits, portc->endpoint->stream_number, &tmp) < 0)
+ {
+ cmn_err (CE_WARN, "Codec setup failed\n");
+ return OSS_EIO;
+ }
+
+ PCI_WRITEW (devc->osdev, engine->base + HDA_SD_FORMAT, tmp);
+ tmp = PCI_READW (devc->osdev, engine->base + HDA_SD_FORMAT);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+hda_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ hda_devc_t *devc = audio_engines[dev]->devc;
+ hda_portc_t *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ oss_native_word flags;
+ hda_engine_t *engine;
+
+ if (portc->port_type != PT_INPUT)
+ return OSS_ENOTSUP;
+
+ engine = portc->engine;
+
+ if (dmap->nfrags > engine->bdl_max) /* Overflow protection */
+ {
+ dmap->nfrags = engine->bdl_max;
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+ }
+
+ init_bdl (devc, engine, dmap);
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return setup_audio_engine (devc, engine, portc, dmap);
+}
+
+/*ARGSUSED*/
+static int
+hda_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ hda_devc_t *devc = audio_engines[dev]->devc;
+ hda_portc_t *portc = audio_engines[dev]->portc;
+ hda_engine_t *engine;
+
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ oss_native_word flags;
+
+ if (portc->port_type != PT_OUTPUT)
+ return OSS_ENOTSUP;
+
+ engine = portc->engine;
+
+ if (dmap->nfrags > engine->bdl_max) /* Overflow protection */
+ {
+ dmap->nfrags = engine->bdl_max;
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+ }
+
+ init_bdl (devc, engine, dmap);
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return setup_audio_engine (devc, engine, portc, dmap);
+}
+
+/*ARGSUSED*/
+static int
+hda_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ hda_portc_t *portc = audio_engines[dev]->portc;
+#ifdef sun
+ // PCI_READL under solaris needs devc->osdev
+ hda_devc_t *devc = audio_engines[dev]->devc;
+#endif
+ hda_engine_t *engine;
+ unsigned int ptr;
+
+ engine = portc->engine;
+ ptr =
+ PCI_READL (devc->osdev, engine->base + HDA_SD_LPIB) % dmap->bytes_in_use;
+
+ return ptr;
+}
+
+static const audiodrv_t hda_audio_driver = {
+ hda_audio_open,
+ hda_audio_close,
+ hda_audio_output_block,
+ hda_audio_start_input,
+ hda_audio_ioctl,
+ hda_audio_prepare_for_input,
+ hda_audio_prepare_for_output,
+ hda_audio_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ hda_audio_trigger,
+ hda_audio_set_rate,
+ hda_audio_set_format,
+ hda_audio_set_channels,
+ NULL,
+ NULL,
+ NULL, /* hda_check_input, */
+ NULL, /* hda_check_output, */
+ NULL, /* hda_alloc_buffer */
+ NULL, /* hda_free_buffer */
+ NULL,
+ NULL,
+ hda_get_buffer_pointer
+};
+
+static int
+reset_controller (hda_devc_t * devc)
+{
+ unsigned int tmp, tmout;
+
+ /*reset the controller by writing a 0*/
+ tmp = PCI_READL (devc->osdev, devc->azbar + HDA_GCTL);
+ tmp &= ~CRST;
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_GCTL, tmp);
+
+ /*wait until the controller writes a 0 to indicate reset is done or until 50ms have passed*/
+ tmout = 50;
+ while ((PCI_READL (devc->osdev, devc->azbar + HDA_GCTL) & CRST) && --tmout)
+ oss_udelay (1000);
+
+ oss_udelay (1000);
+
+ /*bring the controller out of reset by writing a 1*/
+ tmp = PCI_READL (devc->osdev, devc->azbar + HDA_GCTL);
+ tmp |= CRST;
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_GCTL, tmp);
+
+ /*wait until the controller writes a 1 to indicate it is ready is or until 50ms have passed*/
+ tmout = 50;
+ while (!(PCI_READL (devc->osdev, devc->azbar + HDA_GCTL) & CRST) && --tmout)
+ oss_udelay (1000);
+
+ oss_udelay (1000);
+
+ /*if the controller is not ready now, abort*/
+ if (!(PCI_READL (devc->osdev, devc->azbar + HDA_GCTL)))
+ {
+ cmn_err (CE_WARN, "Controller not ready\n");
+ return 0;
+ }
+
+ if (!devc->codecmask)
+ {
+ devc->codecmask = PCI_READW (devc->osdev, devc->azbar + HDA_STATESTS);
+ DDB (cmn_err (CE_CONT, "Codec mask %x\n", devc->codecmask));
+ }
+
+ return 1;
+}
+
+static int
+setup_controller (hda_devc_t * devc)
+{
+ unsigned int tmp, tmout;
+ oss_native_word phaddr;
+
+/*
+ * Allocate the CORB and RIRB buffers.
+ */
+ tmp = PCI_READB (devc->osdev, devc->azbar + HDA_CORBSIZE) & 0x03;
+
+ switch (tmp)
+ {
+ case 0:
+ devc->corbsize = 2;
+ break;
+ case 1:
+ devc->corbsize = 16;
+ break;
+ case 2:
+ devc->corbsize = 256;
+ break;
+ default:
+ cmn_err (CE_WARN, "Bad CORB size\n");
+ return 0;
+ }
+
+ tmp = PCI_READB (devc->osdev, devc->azbar + HDA_RIRBSIZE) & 0x03;
+
+ switch (tmp)
+ {
+ case 0:
+ devc->rirbsize = 2;
+ break;
+ case 1:
+ devc->rirbsize = 16;
+ break;
+ case 2:
+ devc->rirbsize = 256;
+ break;
+ default:
+ cmn_err (CE_WARN, "Bad CORB size\n");
+ return 0;
+ }
+
+ if ((devc->corb =
+ CONTIG_MALLOC (devc->osdev, 4096, MEMLIMIT_32BITS, &phaddr, devc->corb_dma_handle)) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory (CORB)\n");
+ return 0;
+ }
+
+ devc->corb_phys = phaddr;
+
+ devc->rirb = (rirb_entry_t *) (devc->corb + 512); /* 512 dwords = 2048 bytes */
+ devc->rirb_phys = devc->corb_phys + 2048;
+
+/*
+ * Initialize CORB registers
+ */
+
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_CORBCTL, 0); /* Stop */
+
+ tmout = 0;
+
+ while (tmout++ < 500
+ && (PCI_READB (devc->osdev, devc->azbar + HDA_CORBCTL) & 0x02));
+
+ if (PCI_READB (devc->osdev, devc->azbar + HDA_CORBCTL) & 0x02)
+ {
+ cmn_err (CE_WARN, "CORB didn't stop\n");
+ }
+
+ tmp = devc->corb_phys & 0xffffffff;
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_CORBLBASE, tmp);
+ tmp = (devc->corb_phys >> 32) & 0xffffffff;
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_CORBUBASE, tmp);
+
+ PCI_WRITEW (devc->osdev, devc->azbar + HDA_CORBWP, 0x0); /* Reset to 0 */
+ PCI_WRITEW (devc->osdev, devc->azbar + HDA_CORBRP, 0x8000); /* Reset to 0 */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_CORBCTL, 0x02); /* Start */
+
+/*
+ * Initialize RIRB registers
+ */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBCTL, 0); /* Stop */
+
+ tmout = 0;
+
+ while (tmout++ < 500
+ && (PCI_READB (devc->osdev, devc->azbar + HDA_RIRBCTL) & 0x02));
+
+ if (PCI_READB (devc->osdev, devc->azbar + HDA_RIRBCTL) & 0x02)
+ {
+ cmn_err (CE_WARN, "RIRB didn't stop\n");
+ }
+
+ tmp = devc->rirb_phys & 0xffffffff;
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_RIRBLBASE, tmp);
+ tmp = (devc->rirb_phys >> 32) & 0xffffffff;
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_RIRBUBASE, tmp);
+ devc->rirb_rp = 0;
+
+ PCI_WRITEW (devc->osdev, devc->azbar + HDA_RIRBWP, 0x8000); /* Reset to 0 */
+ PCI_WRITEW (devc->osdev, devc->azbar + HDA_RINTCNT, 1); /* reset hw write ptr */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBCTL, 0x03); /* Start & Intr enable */
+
+ return 1;
+}
+
+static int
+setup_engines (hda_devc_t * devc)
+{
+ int i, p;
+ unsigned int gcap;
+ unsigned int num_inputs, num_outputs;
+ oss_native_word phaddr;
+ gcap = PCI_READW (devc->osdev, devc->azbar + HDA_GCAP);
+
+ num_outputs = (gcap >> 12) & 0x0f;
+ num_inputs = (gcap >> 8) & 0x0f;
+
+ /* Init output engines */
+ p = num_inputs; /* Output engines are located after the input ones */
+
+ if (num_outputs > HDA_MAX_ENGINES)
+ {
+ cmn_err (CE_WARN,
+ "Using only %d out of %d available output engines\n",
+ HDA_MAX_ENGINES, num_outputs);
+ num_outputs = HDA_MAX_ENGINES;
+ }
+
+ if (num_inputs > HDA_MAX_ENGINES)
+ {
+ cmn_err (CE_WARN,
+ "Using only %d out of %d available input engines\n",
+ HDA_MAX_ENGINES, num_inputs);
+ num_inputs = HDA_MAX_ENGINES;
+ }
+
+ for (i = 0; i < num_outputs; i++)
+ {
+ hda_engine_t *engine = &devc->outengines[i];
+
+ engine->bdl =
+ CONTIG_MALLOC (devc->osdev, 4096, MEMLIMIT_32BITS, &phaddr, engine->bdl_dma_handle);
+ if (engine->bdl == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+ engine->bdl_max = 4096 / sizeof (bdl_t);
+ engine->bdl_phys = phaddr;
+ engine->base = devc->azbar + 0x80 + (p * 0x20);
+ engine->num = i;
+ engine->intrmask = (1 << p);
+ engine->portc = NULL;
+ p++;
+ devc->num_outengines = i + 1;
+ }
+
+ /* Init input engines */
+ p = 0;
+ for (i = 0; i < num_inputs; i++)
+ {
+ hda_engine_t *engine = &devc->inengines[i];
+
+ engine->bdl =
+ CONTIG_MALLOC (devc->osdev, 4096, MEMLIMIT_32BITS, &phaddr, engine->bdl_dma_handle);
+ if (engine->bdl == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+ engine->bdl_max = 4096 / sizeof (bdl_t);
+ engine->bdl_phys = phaddr;
+ engine->base = devc->azbar + 0x80 + (p * 0x20);
+ engine->num = i;
+ engine->intrmask = (1 << p);
+ engine->portc = NULL;
+ p++;
+ devc->num_inengines = i + 1;
+ }
+ return 1;
+}
+
+/*ARGSUSED*/
+static void
+init_adev_caps (hda_devc_t * devc, adev_p adev, hdaudio_endpointinfo_t * ep)
+{
+ int i;
+
+ adev->oformat_mask = ep->fmt_mask;
+ adev->iformat_mask = ep->fmt_mask;
+
+ adev->min_rate = 500000;
+ adev->max_rate = 0;
+
+ adev->nrates = ep->nrates;
+ if (adev->nrates > OSS_MAX_SAMPLE_RATES)
+ {
+ cmn_err(CE_NOTE, "Too many supported sample rates (%d)\n", adev->nrates);
+ adev->nrates = OSS_MAX_SAMPLE_RATES;
+ }
+
+ for (i = 0; i < adev->nrates; i++)
+ {
+ int r = ep->rates[i];
+
+ adev->rates[i] = r;
+
+ if (adev->min_rate > r)
+ adev->min_rate = r;
+ if (adev->max_rate < r)
+ adev->max_rate = r;
+ }
+}
+
+/*
+ * S/PDIF lowlevel driver
+ */
+/*ARGSUSED*/
+static int
+hdaudio_reprogram_spdif (void *_devc, void *_portc,
+ oss_digital_control * ctl, unsigned int mask)
+{
+ unsigned short cbits = 0;
+ hda_devc_t *devc = _devc;
+ oss_native_word flags;
+ hdaudio_endpointinfo_t *endpoint = devc->spdifout_endpoint;
+
+ if (endpoint == NULL)
+ return OSS_EIO;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ cbits = 0x01; /* Digital interface enabled */
+
+ cbits |= (1 << 2); /* VCFG */
+
+ if (ctl->out_vbit == VBIT_ON)
+ cbits |= (1 << 1); /* Turn on the V bit */
+
+ if (ctl->cbitout[0] & 0x02) /* Audio/Data */
+ cbits |= (1 << 5); /* /AUDIO */
+
+ if (ctl->cbitout[0] & 0x01) /* Pro */
+ cbits |= (1 << 6);
+ else
+ {
+
+ if (ctl->cbitout[0] & 0x04) /* Copyright */
+ cbits |= (1 << 4); /* COPY */
+
+ if (ctl->cbitout[1] & 0x80) /* Generation level */
+ cbits |= (1 << 7); /* L */
+
+ if (ctl->emphasis_type & 1) /* Pre-emphasis */
+ cbits |= (1 << 3); /* PRE */
+ }
+ do_corb_write (devc, endpoint->cad, endpoint->base_wid, 0,
+ SET_SPDIF_CONTROL1, cbits);
+
+ cbits = ctl->cbitout[1] & 0x7f; /* Category code */
+ do_corb_write (devc, endpoint->cad, endpoint->base_wid, 0,
+ SET_SPDIF_CONTROL2, cbits);
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+spdif_driver_t hdaudio_spdif_driver = {
+/* reprogram_device: */ hdaudio_reprogram_spdif,
+};
+
+static int
+spdif_mixer_init (int dev)
+{
+ hda_devc_t *devc = mixer_devs[dev]->hw_devc;
+ int err;
+
+ if ((err = oss_spdif_mix_init (&devc->spdc)) < 0)
+ return err;
+
+ return 0;
+}
+
+static void
+install_outputdevs (hda_devc_t * devc)
+{
+ int i, n, pass, audio_dev, output_num=0;
+ char tmp_name[64];
+ hdaudio_endpointinfo_t *endpoints;
+
+ if ((n =
+ hdaudio_mixer_get_outendpoints (devc->mixer, &endpoints,
+ sizeof (*endpoints))) < 0)
+ return;
+
+#if 0
+ // This check will be done later.
+ if (n > MAX_OUTPUTS)
+ {
+ cmn_err (CE_WARN,
+ "Only %d out of %d output devices can be installed\n",
+ MAX_OUTPUTS, n);
+ n = MAX_OUTPUTS;
+ }
+#endif
+
+/*
+ * Install the output devices in two passes. First install the analog
+ * endpoints and then the digital one(s).
+ */
+ for (pass = 0; pass < 3; pass++)
+ for (i = 0; i < n; i++)
+ {
+ adev_p adev;
+ hda_portc_t *portc = &devc->output_portc[i];
+ unsigned int formats = AFMT_S16_LE;
+ int opts = ADEV_AUTOMODE | ADEV_NOINPUT;
+ char *devfile_name = "";
+ char devname[16];
+
+/* Skip endpoints that are not physically connected on the motherboard. */
+ if (endpoints[i].skip)
+ continue;
+
+ if (output_num >= MAX_OUTPUTS)
+ {
+ cmn_err(CE_CONT, "Too many output endpoints. Endpoint %d ignored.\n", i);
+ continue;
+ }
+
+ switch (pass)
+ {
+ case 0: /* Pick analog and non-modem ones */
+ if (endpoints[i].is_digital || endpoints[i].is_modem)
+ continue;
+ break;
+
+ case 1: /* Pick digital one(s) */
+ if (!endpoints[i].is_digital)
+ continue;
+ break;
+
+ case 2: /* Pick modem one(s) */
+ if (!endpoints[i].is_modem)
+ continue;
+ }
+
+ if (endpoints[i].is_digital)
+ {
+ opts |= ADEV_SPECIAL;
+ sprintf (devname, "spdout%d", devc->num_spdout++);
+ devfile_name = devname;
+ }
+ if (endpoints[i].is_modem)
+ {
+ opts |= ADEV_SPECIAL;
+ sprintf (devname, "mdmout%d", devc->num_mdmout++);
+ devfile_name = devname;
+ }
+
+ // sprintf (tmp_name, "%s %s", devc->chip_name, endpoints[i].name);
+ sprintf (tmp_name, "HD Audio play %s", endpoints[i].name);
+
+ if ((audio_dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &hda_audio_driver,
+ sizeof (audiodrv_t),
+ opts, formats, devc, -1,
+ devfile_name)) < 0)
+ {
+ return;
+ }
+
+ if (output_num == 0)
+ devc->first_dev = audio_dev;
+
+ adev = audio_engines[audio_dev];
+ devc->num_outputs = i+1;
+
+ adev->devc = devc;
+ adev->portc = portc;
+ adev->rate_source = devc->first_dev;
+ adev->mixer_dev = devc->mixer_dev;
+ adev->min_rate = 8000;
+ adev->max_rate = 192000;
+ adev->min_channels = 2;
+
+ if (output_num == 0)
+ adev->max_channels = 8;
+ else
+ adev->max_channels = 2;
+
+ if (endpoints[i].is_modem)
+ {
+ adev->min_channels = 1;
+ adev->max_channels = 1;
+ adev->caps |= PCM_CAP_MODEM;
+ }
+
+ if (adev->max_channels > 4)
+ adev->dmabuf_alloc_flags |= DMABUF_LARGE | DMABUF_QUIET;
+ adev->min_block = 128; /* Hardware limitation */
+ adev->min_fragments = 4; /* Vmix doesn't work without this */
+ portc->num = output_num;
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+ portc->audiodev = audio_dev;
+ portc->port_type = PT_OUTPUT;
+ portc->endpoint = &endpoints[i];
+ init_adev_caps (devc, adev, portc->endpoint);
+ portc->engine = NULL;
+
+ if (portc->endpoint->is_digital)
+ {
+ int err;
+
+ devc->spdifout_endpoint = portc->endpoint;
+
+/*
+ * To be precise the right place for the spdc field might be portc instead of
+ * devc. In this way it's possible to have multiple S/PDIF output DACs connected
+ * to the same HDA controller. OTOH having it in devc saves space. Multiple
+ * oss_spdif_install() calls on the same spdc structure doesn't cause any
+ * problems.
+ *
+ * If spdc is moved to portc then care must be taken that oss_spdif_uninstall()
+ * is called for all all output_portc instances.
+ */
+ if ((err = oss_spdif_install (&devc->spdc, devc->osdev,
+ &hdaudio_spdif_driver,
+ sizeof (spdif_driver_t), devc, NULL,
+ devc->mixer_dev, SPDF_OUT,
+ DIG_PASSTHROUGH | DIG_EXACT |
+ DIG_CBITOUT_LIMITED | DIG_VBITOUT |
+ DIG_PRO | DIG_CONSUMER)) != 0)
+ {
+ cmn_err (CE_WARN,
+ "S/PDIF driver install failed. Error %d\n", err);
+ }
+ else
+ {
+ hdaudio_mixer_set_initfunc (devc->mixer, spdif_mixer_init);
+ }
+ }
+ output_num++;
+ }
+}
+
+static void
+install_inputdevs (hda_devc_t * devc)
+{
+ int i, n, audio_dev;
+ char tmp_name[64];
+ hdaudio_endpointinfo_t *endpoints;
+ char devname[16], *devfile_name = "";
+
+ if ((n =
+ hdaudio_mixer_get_inendpoints (devc->mixer, &endpoints,
+ sizeof (*endpoints))) < 0)
+ return;
+
+ if (n > MAX_INPUTS)
+ {
+ cmn_err (CE_WARN,
+ "Only %d out of %d input devices can be installed\n",
+ MAX_INPUTS, n);
+ n = MAX_INPUTS;
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ adev_p adev;
+ hda_portc_t *portc = &devc->input_portc[i];
+ unsigned int formats = AFMT_S16_LE;
+ int opts = ADEV_AUTOMODE | ADEV_NOOUTPUT;
+
+/* Skip endpoints that are not physically connected on the motherboard. */
+ if (endpoints[i].skip)
+ continue;
+
+ if (endpoints[i].is_digital)
+ {
+ opts |= ADEV_SPECIAL;
+ sprintf (devname, "spdin%d", devc->num_spdin++);
+ devfile_name = devname;
+ }
+ if (endpoints[i].is_modem)
+ {
+ opts |= ADEV_SPECIAL;
+ sprintf (devname, "mdmin%d", devc->num_mdmin++);
+ devfile_name = devname;
+ }
+
+ //sprintf (tmp_name, "%s %s", devc->chip_name, endpoints[i].name);
+ sprintf (tmp_name, "HD Audio rec %s", endpoints[i].name);
+
+ if ((audio_dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &hda_audio_driver,
+ sizeof (audiodrv_t),
+ opts, formats, devc, -1,
+ devfile_name)) < 0)
+ {
+ return;
+ }
+
+ if (i == 0 && devc->first_dev == -1)
+ devc->first_dev = audio_dev;
+
+ adev = audio_engines[audio_dev];
+ devc->num_inputs = i+1;
+
+ adev->devc = devc;
+ adev->portc = portc;
+ adev->rate_source = devc->first_dev;
+ adev->mixer_dev = devc->mixer_dev;
+ adev->min_rate = 8000;
+ adev->max_rate = 192000;
+ adev->min_channels = 2;
+ adev->max_channels = 2;
+
+ if (endpoints[i].is_modem)
+ {
+ adev->min_channels = 1;
+ adev->max_channels = 1;
+ adev->caps |= PCM_CAP_MODEM;
+ }
+
+ adev->min_block = 128; /* Hardware limitation */
+ adev->min_fragments = 4; /* Vmix doesn't work without this */
+ portc->num = i;
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+ portc->audiodev = audio_dev;
+ portc->port_type = PT_INPUT;
+ portc->endpoint = &endpoints[i];
+ portc->engine = NULL;
+ init_adev_caps (devc, adev, portc->endpoint);
+ }
+}
+
+static void
+activate_vmix (hda_devc_t * devc)
+{
+#ifdef CONFIG_OSS_VMIX
+/*
+ * Attach vmix engines to all outputs and inputs.
+ */
+
+ if (devc->num_outputs > 0)
+ {
+ if (devc->num_inputs < 1)
+ vmix_attach_audiodev(devc->osdev, devc->output_portc[0].audiodev, -1, 0);
+ else
+ vmix_attach_audiodev(devc->osdev, devc->output_portc[0].audiodev, devc->input_portc[0].audiodev, 0);
+ };
+#endif
+}
+
+static int
+init_HDA (hda_devc_t * devc)
+{
+ unsigned int gcap;
+ unsigned int tmp;
+
+ /* Reset controller */
+
+ if (!reset_controller (devc))
+ return 0;
+
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_INTCTL, PCI_READL (devc->osdev, devc->azbar + HDA_INTCTL) | 0xc0000000); /* Intr enable */
+
+ /*
+ * Set CORB and RIRB sizes to 256, 16 or 2 entries.
+ *
+ */
+ tmp = (PCI_READB (devc->osdev, devc->azbar + HDA_CORBSIZE) >> 4) & 0x07;
+ if (tmp & 0x4) /* 256 entries */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_CORBSIZE, 0x2);
+ else if (tmp & 0x2) /* 16 entries */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_CORBSIZE, 0x1);
+ else /* Assume that 2 entries is supported */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_CORBSIZE, 0x0);
+
+ tmp = (PCI_READB (devc->osdev, devc->azbar + HDA_RIRBSIZE) >> 4) & 0x07;
+ if (tmp & 0x4) /* 256 entries */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBSIZE, 0x2);
+ else if (tmp & 0x2) /* 16 entries */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBSIZE, 0x1);
+ else /* Assume that 2 entries is supported */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBSIZE, 0x0);
+
+ /* setup the CORB/RIRB structs */
+ if (!setup_controller (devc))
+ return 0;
+
+ /* setup the engine structs */
+ if (!setup_engines (devc))
+ return 0;
+
+ if (!devc->codecmask)
+ {
+ cmn_err (CE_WARN, "No codecs found after reset\n");
+ return 0;
+ }
+ else
+ devc->mixer = hdaudio_mixer_create (devc->chip_name, devc, devc->osdev,
+ do_corb_write, corb_read,
+ devc->codecmask, devc->vendor_id,
+ devc->subvendor_id);
+ if (devc->mixer == NULL)
+ return 0;
+
+ devc->mixer_dev = hdaudio_mixer_get_mixdev (devc->mixer);
+
+ gcap = PCI_READW (devc->osdev, devc->azbar + HDA_GCAP);
+ DDB (cmn_err (CE_CONT, " GCAP register content 0x%x\n", gcap));
+
+ if (((gcap >> 3) & 0x0f) > 0)
+ cmn_err (CE_WARN, "Bidirectional engines not supported\n");
+ if (((gcap >> 1) & 0x03) > 0)
+ cmn_err (CE_WARN, "Multiple SDOs not supported\n");
+
+ install_outputdevs (devc);
+ install_inputdevs (devc);
+ activate_vmix (devc);
+
+ return 1;
+}
+
+
+int
+oss_hdaudio_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision, btmp;
+ unsigned short pci_command, vendor, device, wtmp;
+ unsigned short subvendor, subdevice;
+ hda_devc_t *devc;
+ static int already_attached = 0;
+ int err;
+ unsigned short devctl;
+
+ DDB (cmn_err (CE_CONT, "oss_hdaudio_attach entered\n"));
+
+ if (already_attached)
+ {
+ cmn_err (CE_WARN, "oss_hdaudio_attach: Already attached\n");
+ return 0;
+ }
+ already_attached = 1;
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+#if 0
+ // This check is not necessary because the kernel has already checked
+ // the vendor&device ID
+
+ if ((vendor != INTEL_VENDOR_ID && vendor != NVIDIA_VENDOR_ID &&
+ vendor != ATI_VENDOR_ID && vendor != SIS_VENDOR_ID &&
+ vendor != VIA_VENDOR_ID && vendor != ULI_VENDOR_ID) ||
+ (device != INTEL_DEVICE_ICH6 && device != INTEL_DEVICE_ICH7 &&
+ device != INTEL_DEVICE_ESB2 && device != INTEL_DEVICE_ICH8 &&
+ device != INTEL_DEVICE_ICH9 && device != INTEL_DEVICE_P35 &&
+ device != INTEL_DEVICE_ICH10 && device != INTEL_DEVICE_ICH10_B &&
+ device != INTEL_DEVICE_PCH &&
+ device != NVIDIA_DEVICE_MCP51 && device != NVIDIA_DEVICE_MCP55 &&
+ device != NVIDIA_DEVICE_MCP61 && device != NVIDIA_DEVICE_MCP61A &&
+ device != NVIDIA_DEVICE_MCP65 && device != NVIDIA_DEVICE_MCP67 &&
+ device != NVIDIA_DEVICE_MCP73 && device != NVIDIA_DEVICE_MCP78S &&
+ device != NVIDIA_DEVICE_MCP79 &&
+ device != VIA_DEVICE_HDA &&
+ device != SIS_DEVICE_HDA &&
+ device != ULI_DEVICE_HDA &&
+ device != ATI_DEVICE_SB450 && device != ATI_DEVICE_SB600))
+
+ {
+ return 0;
+ }
+#endif
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor);
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_ID, &subdevice);
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->first_dev = -1;
+
+ osdev->hw_info = PMALLOC (osdev, HWINFO_SIZE); /* Text buffer for additional device info */
+ memset (osdev->hw_info, 0, HWINFO_SIZE);
+
+ devc->vendor_id = (vendor << 16) | device;
+ devc->subvendor_id = (subvendor << 16) | subdevice;
+
+ oss_pci_byteswap (osdev, 1);
+
+ switch (device)
+ {
+ case INTEL_DEVICE_SCH:
+ pci_read_config_word (osdev, 0x78, &devctl);
+ DDB (cmn_err (CE_CONT, " DEVC register content 0x%04x\n", devctl);)
+ pci_write_config_word (osdev, 0x78, (devctl & (~0x0800)) );
+ DDB (pci_read_config_word (osdev, 0x78, &devctl);)
+ DDB (cmn_err (CE_CONT, " DEVC register content (after clearing DEVC.NSNPEN) 0x%04x\n", devctl);)
+ /* continue is intentional */
+ case INTEL_DEVICE_ICH6:
+ case INTEL_DEVICE_ICH7:
+ case INTEL_DEVICE_ESB2:
+ case INTEL_DEVICE_ICH8:
+ case INTEL_DEVICE_ICH9:
+ case INTEL_DEVICE_P35:
+ case INTEL_DEVICE_ICH10:
+ case INTEL_DEVICE_ICH10_B:
+ case INTEL_DEVICE_PCH:
+ case INTEL_DEVICE_PCH2:
+ case INTEL_DEVICE_CPT:
+ devc->chip_name = "Intel HD Audio";
+ break;
+
+ case NVIDIA_DEVICE_MCP51:
+ case NVIDIA_DEVICE_MCP55:
+ case NVIDIA_DEVICE_MCP61:
+ case NVIDIA_DEVICE_MCP61A:
+ case NVIDIA_DEVICE_MCP65:
+ case NVIDIA_DEVICE_MCP67:
+ case NVIDIA_DEVICE_MCP73:
+ case NVIDIA_DEVICE_MCP78S:
+ case NVIDIA_DEVICE_MCP79:
+ devc->chip_name = "nVidia HD Audio";
+ pci_read_config_byte (osdev, 0x4e, &btmp);
+ pci_write_config_byte (osdev, 0x4e, (btmp & 0xf0) | 0x0f);
+ pci_read_config_byte (osdev, 0x4d, &btmp);
+ pci_write_config_byte (osdev, 0x4d, (btmp & 0xfe) | 0x01);
+ pci_read_config_byte (osdev, 0x4c, &btmp);
+ pci_write_config_byte (osdev, 0x4c, (btmp & 0xfe) | 0x01);
+ break;
+
+ case ATI_DEVICE_SB450:
+ case ATI_DEVICE_SB600:
+ devc->chip_name = "ATI HD Audio";
+ pci_read_config_byte (osdev, 0x42, &btmp);
+ pci_write_config_byte (osdev, 0x42, (btmp & 0xf8) | 0x2);
+ break;
+
+ case VIA_DEVICE_HDA:
+ devc->chip_name = "VIA HD Audio";
+ break;
+
+ case SIS_DEVICE_HDA:
+ devc->chip_name = "SiS HD Audio";
+ break;
+
+ case ULI_DEVICE_HDA:
+ devc->chip_name = "ULI HD Audio";
+ pci_read_config_word (osdev, 0x40, &wtmp);
+ pci_write_config_word (osdev, 0x40, wtmp | 0x10);
+ pci_write_config_dword (osdev, PCI_MEM_BASE_ADDRESS_1, 0);
+ break;
+
+ case CREATIVE_XFI_HDA:
+ devc->chip_name = "Creative Labs XFi XTreme Audio";
+ break;
+
+ default:
+ devc->chip_name = "High definition audio device";
+ }
+
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &devc->membar_addr);
+
+ devc->membar_addr &= ~7;
+
+ /* get virtual address */
+ devc->azbar =
+ (void *) MAP_PCI_MEM (devc->osdev, 0, devc->membar_addr, 16 * 1024);
+
+ /*verify interrupt*/
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS.\n");
+ return 0;
+ }
+
+ devc->irq = pci_irq_line;
+
+ /* activate the device */
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, hdaintr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+
+ devc->base = devc->membar_addr;
+
+ /* Setup the TCSEL register. Don't do this with ATI chipsets. */
+ if (vendor != ATI_VENDOR_ID)
+ {
+ pci_read_config_byte (osdev, 0x44, &btmp);
+ pci_write_config_byte (osdev, 0x44, btmp & 0xf8);
+ }
+
+ err = init_HDA (devc);
+ return err;
+}
+
+int
+oss_hdaudio_detach (oss_device_t * osdev)
+{
+ hda_devc_t *devc = (hda_devc_t *) osdev->devc;
+ int j;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_INTSTS, 0xc0000000); /* ack pending ints */
+
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_INTCTL, 0); /* Intr disable */
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_STATESTS, 0x7); /* Intr disable */
+ PCI_WRITEL (devc->osdev, devc->azbar + HDA_RIRBSTS, 0x5); /* Intr disable */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_RIRBCTL, 0); /* Stop */
+ PCI_WRITEB (devc->osdev, devc->azbar + HDA_CORBCTL, 0); /* Stop */
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+
+ if (devc->corb != NULL)
+ CONTIG_FREE (devc->osdev, devc->corb, 4096, devc->corb_dma_handle);
+
+ devc->corb = NULL;
+
+ for (j = 0; j < devc->num_outengines; j++)
+ {
+ hda_engine_t *engine = &devc->outengines[j];
+
+ if (engine->bdl == NULL)
+ continue;
+ CONTIG_FREE (devc->osdev, engine->bdl, 4096, engine->bdl_dma_handle);
+ }
+
+ for (j = 0; j < devc->num_inengines; j++)
+ {
+ hda_engine_t *engine = &devc->inengines[j];
+
+ if (engine->bdl == NULL)
+ continue;
+ CONTIG_FREE (devc->osdev, engine->bdl, 4096, engine->bdl_dma_handle);
+ }
+
+ if (devc->membar_addr != 0)
+ {
+ UNMAP_PCI_MEM (devc->osdev, 0, devc->membar_addr, devc->azbar,
+ 16 * 1024);
+ devc->membar_addr = 0;
+ }
+
+ oss_spdif_uninstall (&devc->spdc);
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_hdaudio/oss_hdaudio.man b/kernel/drv/oss_hdaudio/oss_hdaudio.man
new file mode 100644
index 0000000..e2bae7a
--- /dev/null
+++ b/kernel/drv/oss_hdaudio/oss_hdaudio.man
@@ -0,0 +1,77 @@
+NAME
+ oss_hdaudio - Intel High Definition Audio (AZALIA)
+
+DESCRIPTION
+ Open Sound System driver for Intels high definition audio known as
+ "Azalia". This driver supports Intel 915/925 chipsets with the
+ Realtek ALC880 and CMedia 9880 8 channel codecs.
+
+ The HDA driver supports:
+
+ o 8-96Khz Playback/Recording
+ o 8 or 16 or 32 bits
+ o 2, 4, 6 or 8 channel audio.
+ o SPDIF digital output and Input
+ o AC3 passthrough
+
+ HDAUDIO MIXER
+ The Intel HDA mixer is a new type of mixer that doesn't have
+ the normal volume controls found on AC97 or legacy SB devices.
+ The HDA mixer presents a concept of Jacks and you can configure
+ any jack to be either an output or an input jack.
+
+ Some motherboards may not correctly initialize the jacks according
+ to their color and functionality but in general here's the
+ configuration that should generally be followed:
+
+ o Orange = Center/LFE o Blue = Line-in
+ o Black = Rear o Green = Front
+ o Grey = Side o Pink = Mic
+
+ Some Azalia codecs support front panel connectors and so if you see
+ fp-green and fp-pink connectors, then these are for front panel
+ speaker and mic/line-in Jacks.
+
+ There is a function selector for most of the analog audio jacks (for example
+ connector.pink.mode). This selector is used to control if the jack is used
+ as an input (microphone or line in) or output (front, rear, side, speaker,
+ etc).
+
+KNOWN PROBLEMS
+In general Azalia based systems (laptops/motherboards) would require a custom
+driver to work properly. Due to enormous number of different systems it is not
+possible to develop such custom drivers for all systems. A generic driver is
+used for systems that don't have dedicated drivers.
+
+Unfortunately the mixer and control panel interface (see ossmix(1))
+for "generic" systems is very cryptic and difficult to
+understand. To solve problems with volumes or signal routing you need to
+start ossxmix(1) and change the controls one at time until you get the desired
+effect.
+
+OPTIONS
+o hdaudio_jacksense enables jack sensing mode when the hdaudio driver is
+ loaded. In this mode all I/O pin's that are not
+ in use will be disabled as well as the mixer controls
+ that are related with them. In this way the
+ mixer/control panel will become more intuitive.
+ However OSS will need to be restarted with soundoff;
+ soundon every time new inputs or outputs are attached
+ to the audio jacks. Default : 0.
+
+ NOTE! hdaudio_jacksense=1 works only in some systems.
+ Many laptops and motherboards don't support jack
+ sensing.
+
+o hdaudio_noskip Disable skipping unconnected jack. All mixer controls
+ will be shown, even for disabled I/O pins.
+ Can get values 0-7. 1-7 is a bitmask, where every bit
+ masks a different check. Bit 3 (= value 4) overrides
+ jacksense check too.
+ Default: 0 - unconnected jacks are skipped.
+FILES
+ CONFIGFILEPATH/oss_hdaudio.conf Device configuration file
+
+AUTHOR
+ 4Front Technologies
+
diff --git a/kernel/drv/oss_ich/.changelog b/kernel/drv/oss_ich/.changelog
new file mode 100644
index 0000000..7f16ede
--- /dev/null
+++ b/kernel/drv/oss_ich/.changelog
@@ -0,0 +1 @@
+20080115 by Dev: Added Nvidia MCP04 (10de:003a) model to driver/database
diff --git a/kernel/drv/oss_ich/.config b/kernel/drv/oss_ich/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_ich/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_ich/.devices b/kernel/drv/oss_ich/.devices
new file mode 100644
index 0000000..8880e15
--- /dev/null
+++ b/kernel/drv/oss_ich/.devices
@@ -0,0 +1,21 @@
+oss_ich pci1022,7445 AMD 786
+oss_ich pci1022,746d AMD 8111
+oss_ich pci1039,7012 SiS 7012
+oss_ich pci10de,1b1 Nvidia nForce
+oss_ich pci10de,3a Nvidia MCP4
+oss_ich pci10de,6a Nvidia nForce2
+oss_ich pci10de,8a Nvidia CK8
+oss_ich pci10de,da Nvidia nForce3
+oss_ich pci10de,ea Nvidia CK8S
+oss_ich pci10de,59 Nvidia nForce4
+oss_ich pci10de,26b Nvidia MCP51
+oss_ich pci8086,2415 Intel AC97 (ICH)
+oss_ich pci8086,2425 Intel AC97 (ICH1)
+oss_ich pci8086,2445 Intel AC97 (ICH2)
+oss_ich pci8086,2485 Intel AC97 (ICH3)
+oss_ich pci8086,24c5 Intel AC97 (ICH4)
+oss_ich pci8086,24d5 Intel AC97 (ICH5)
+oss_ich pci8086,25a6 Intel AC97 (ESB)
+oss_ich pci8086,266e Intel AC97 (ICH6)
+oss_ich pci8086,27de Intel AC97 (ICH7)
+oss_ich pci8086,7195 Intel 440MX (440MX)
diff --git a/kernel/drv/oss_ich/.name b/kernel/drv/oss_ich/.name
new file mode 100644
index 0000000..3ad1ec7
--- /dev/null
+++ b/kernel/drv/oss_ich/.name
@@ -0,0 +1 @@
+Intel ICH1-7, nVidia nForce, SiS7012, AMD8111/786
diff --git a/kernel/drv/oss_ich/.params b/kernel/drv/oss_ich/.params
new file mode 100644
index 0000000..4b7771d
--- /dev/null
+++ b/kernel/drv/oss_ich/.params
@@ -0,0 +1,16 @@
+int intelpci_rate_tuning = 240;
+/*
+ * Few broken motherboards had nonstandard crystal clocks that cause wrong
+ * sampling rates. With such motherboards it was necessary to use
+ * the intelpci_rate_tuning option to fix the rate. See the manual
+ * for more info.
+ */
+int intelpci_force_mmio = 0;
+/*
+ * intelpci_force_mmio forces the driver to use Memory Mapped IO
+ * (some bioses don't provide I/O mapped addresses).
+ */
+int ich_jacksense = 0;
+/*
+ * Force enabling jacksense on some AD198x mixers.
+ */
diff --git a/kernel/drv/oss_ich/oss_ich.c b/kernel/drv/oss_ich/oss_ich.c
new file mode 100644
index 0000000..fc23e01
--- /dev/null
+++ b/kernel/drv/oss_ich/oss_ich.c
@@ -0,0 +1,1470 @@
+/*
+ * Purpose: Driver for the Intel ICH AC97 audio controller
+ *
+ * The same design is also used in many PC chipsets by nVidia, AMD and SiS for
+ * audio functionality.
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_ich_cfg.h"
+#include <oss_pci.h>
+
+#include <ac97.h>
+extern int intelpci_force_mmio;
+
+#define INTEL_VENDOR_ID 0x8086
+#define SIS_VENDOR_ID 0x1039
+#define NVIDIA_VENDOR_ID 0x10de
+#define AMD_VENDOR_ID 0x1022
+#define SIS_DEVICE_7012 0x7012
+#define INTEL_DEVICE_ICH1 0x2415
+#define INTEL_DEVICE_ICH1R1 0x2425
+#define INTEL_DEVICE_ICH1R2 0x7195
+#define INTEL_DEVICE_ICH2 0x2445
+#define INTEL_DEVICE_ICH3 0x2485
+#define INTEL_DEVICE_ICH4 0x24c5
+#define INTEL_DEVICE_ICH5 0x24d5
+#define INTEL_DEVICE_ESB 0x25a6
+#define INTEL_DEVICE_ICH6 0x266e
+#define INTEL_DEVICE_ICH7 0x27de
+#define NVIDIA_DEVICE_NFORCE 0x01b1
+#define NVIDIA_DEVICE_MCP4 0x003a
+#define NVIDIA_DEVICE_NFORCE2 0x006a
+#define NVIDIA_DEVICE_CK8 0x008a
+#define NVIDIA_DEVICE_NFORCE3 0x00da
+#define NVIDIA_DEVICE_CK8S 0x00ea
+#define NVIDIA_DEVICE_NFORCE4 0x0059
+#define NVIDIA_DEVICE_MCP51 0x026b
+#define AMD_DEVICE_768 0x7445
+#define AMD_DEVICE_8111 0x746d
+
+extern int intelpci_rate_tuning;
+
+#define MAX_PORTC 3
+#define BDL_SIZE 32
+
+extern int ich_jacksense;
+
+typedef struct
+{
+ int open_mode;
+ int speed, bits, channels;
+ int audio_enabled;
+ int trigger_bits;
+ int audiodev;
+ int port_type;
+#define DF_PCM 0
+#define DF_SPDIF 1
+}
+ich_portc;
+
+typedef struct
+{
+ unsigned int addr;
+ unsigned short size;
+ unsigned short flags;
+}
+bdl_t;
+
+typedef struct ich_devc
+{
+ oss_device_t *osdev;
+ oss_native_word base, ac97_base;
+ oss_native_word membar_addr, ac97_membar_addr;
+ char *membar_virt, *ac97_membar_virt;
+#define CTL_BASE 0 /* addressing controller regs */
+#define MIXER_BASE 1 /* addressing mixer regs */
+ int mem_mode;
+#define MMAP_MODE 0 /* ICH4/ICH5 uses MEM BARS */
+#define IO_MODE 1 /* ICH1/2/3/4/5 uses IO BARS */
+
+ int irq;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ /* Mixer */
+ ac97_devc ac97devc;
+ int mixer_dev;
+ int inverted_amplifier;
+
+ /* Audio parameters */
+ int open_mode;
+ int fifo_errors;
+
+ /* Buffer Descriptor List */
+ char *bdlBuffer;
+ bdl_t *playBDL, *recBDL, *spdifBDL;
+ oss_native_word playBDL_phys, recBDL_phys, spdifBDL_phys;
+ oss_dma_handle_t bldbuf_dma_handle;
+
+ int play_currbuf, play_currfrag;
+ int spdif_currbuf, spdif_currfrag;
+ int rec_currbuf, rec_currfrag;
+#define INTEL_ICH1 0
+#define INTEL_ICH3 1
+#define INTEL_ICH4 2
+#define SIS_7012 3
+#define AMD_768 4
+#define AMD_8111 5
+#define NVIDIA_NFORCE 6
+#define NVIDIA_NFORCE2 7
+ int model;
+ char *chip_name;
+ ich_portc portc[MAX_PORTC];
+ int play_frag_index[BDL_SIZE];
+ int rec_frag_index[BDL_SIZE];
+ int spdif_frag_index[BDL_SIZE];
+}
+ich_devc;
+
+static unsigned int
+ich_INL (ich_devc * devc, int base, unsigned int a)
+{
+ if (devc->mem_mode == MMAP_MODE)
+ {
+ if (base == CTL_BASE)
+ return *(volatile unsigned int *) (devc->membar_virt + (a));
+ else
+ return *(volatile unsigned int *) (devc->ac97_membar_virt + (a));
+ }
+ else
+ {
+ if (base == CTL_BASE)
+ return INL (devc->osdev, devc->base + a);
+ else
+ return INL (devc->osdev, devc->ac97_base + a);
+ }
+}
+
+static unsigned short
+ich_INW (ich_devc * devc, int base, unsigned short a)
+{
+ if (devc->mem_mode == MMAP_MODE)
+ {
+ if (base == CTL_BASE)
+ return *(volatile unsigned short *) (devc->membar_virt + (a));
+ else
+ return *(volatile unsigned short *) (devc->ac97_membar_virt + (a));
+ }
+ else
+ {
+ if (base == CTL_BASE)
+ return INW (devc->osdev, devc->base + a);
+ else
+ return INW (devc->osdev, devc->ac97_base + a);
+ }
+}
+
+static unsigned char
+ich_INB (ich_devc * devc, int base, unsigned char a)
+{
+ if (devc->mem_mode == MMAP_MODE)
+ {
+ if (base == CTL_BASE)
+ return *(volatile unsigned char *) (devc->membar_virt + (a));
+ else
+ return *(volatile unsigned char *) (devc->ac97_membar_virt + (a));
+ }
+ else
+ {
+ if (base == CTL_BASE)
+ return INB (devc->osdev, devc->base + a);
+ else
+ return INB (devc->osdev, devc->ac97_base + a);
+ }
+}
+
+static void
+ich_OUTL (ich_devc * devc, unsigned int d, int base, unsigned int a)
+{
+ if (devc->mem_mode == MMAP_MODE)
+ {
+ if (base == CTL_BASE)
+ *(volatile unsigned int *) (devc->membar_virt + (a)) = d;
+ else
+ *(volatile unsigned int *) (devc->ac97_membar_virt + (a)) = d;
+ }
+ else
+ {
+ if (base == CTL_BASE)
+ OUTL (devc->osdev, d, devc->base + a);
+ else
+ OUTL (devc->osdev, d, devc->ac97_base + a);
+ }
+}
+
+static void
+ich_OUTW (ich_devc * devc, unsigned short d, int base, unsigned short a)
+{
+ if (devc->mem_mode == MMAP_MODE)
+ {
+ if (base == CTL_BASE)
+ *(volatile unsigned short *) (devc->membar_virt + (a)) = d;
+ else
+ *(volatile unsigned short *) (devc->ac97_membar_virt + (a)) = d;
+ }
+ else
+ {
+ if (base == CTL_BASE)
+ OUTW (devc->osdev, d, devc->base + a);
+ else
+ OUTW (devc->osdev, d, devc->ac97_base + a);
+ }
+}
+
+static void
+ich_OUTB (ich_devc * devc, unsigned char d, int base, unsigned char a)
+{
+ if (devc->mem_mode == MMAP_MODE)
+ {
+ if (base == CTL_BASE)
+ *(volatile unsigned char *) (devc->membar_virt + (a)) = d;
+ else
+ *(volatile unsigned char *) (devc->ac97_membar_virt + (a)) = d;
+ }
+ else
+ {
+ if (base == CTL_BASE)
+ OUTB (devc->osdev, d, devc->base + a);
+ else
+ OUTB (devc->osdev, d, devc->ac97_base + a);
+ }
+}
+
+static int
+ac97_read (void *devc_, int reg)
+{
+ ich_devc *devc = devc_;
+ int i = 100, status;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ status = ich_INB (devc, CTL_BASE, 0x34);
+
+ while (status & 0x01 && i-- > 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ oss_udelay (10);
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ status = ich_INB (devc, CTL_BASE, 0x34);
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ich_INW (devc, MIXER_BASE, reg);
+}
+
+static int
+ac97_write (void *devc_, int reg, int data)
+{
+ ich_devc *devc = devc_;
+ int i = 100, status;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ status = ich_INB (devc, CTL_BASE, 0x34);
+
+ while (status & 0x01 && i-- > 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ oss_udelay (10);
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ status = ich_INB (devc, CTL_BASE, 0x34);
+ }
+
+ ich_OUTW (devc, data, MIXER_BASE, reg);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 1;
+}
+
+/*
+ * The top half interrupt handler
+ */
+static int
+ichintr (oss_device_t * osdev)
+{
+ int serviced = 0;
+ ich_devc *devc = osdev->devc;
+ ich_portc *portc;
+ unsigned int glob_status, status, p, f;
+ oss_native_word flags;
+ int i;
+
+ flags = 0; /* To prevent compiler warnings */
+ MUTEX_ENTER (devc->mutex, flags);
+ /* Get pending interrupts and acknowledge them */
+ glob_status = ich_INL (devc, CTL_BASE, 0x30);
+ ich_OUTL (devc, glob_status, CTL_BASE, 0x30);
+
+ /*
+ * Check the interrupt bits of the status register
+ */
+ if (!(glob_status & 0x0cf7))
+ {
+ /* Not for me */
+ MUTEX_EXIT (devc->mutex, flags);
+ return 0;
+ }
+
+ /*-------------------- Handle PCM -------------------*/
+ if (devc->model == SIS_7012)
+ status = ich_INB (devc, CTL_BASE, 0x18);
+ else
+ status = ich_INB (devc, CTL_BASE, 0x16);
+
+ if (status & 0x10) /* FIFO error */
+ devc->fifo_errors++;
+
+ if (status & 0x08)
+ {
+ for (i = 0; i < MAX_PORTC - 1; i++)
+ {
+ portc = &devc->portc[i];
+ serviced = 1;
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT)) /* IOC interrupt */
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
+ p = ich_INB (devc, CTL_BASE, 0x14);
+
+ if (p != devc->play_currbuf)
+ {
+ p = devc->play_currbuf;
+ f = devc->play_currfrag;
+ devc->playBDL[p].addr =
+ dmap->dmabuf_phys + (f * dmap->fragment_size);
+
+ /* SIS uses bytes, intelpci uses samples */
+ if (devc->model == SIS_7012)
+ devc->playBDL[p].size = (dmap->fragment_size);
+ else
+ devc->playBDL[p].size = (dmap->fragment_size / 2);
+ devc->playBDL[p].flags = 0xc000; /* IOC interrupts */
+
+ ich_OUTB (devc, p, CTL_BASE, 0x15); /* Set LVD */
+ devc->play_frag_index[p] = f;
+ devc->play_currbuf = (p + 1) % BDL_SIZE;
+ devc->play_currfrag = (f + 1) % dmap->nfrags;
+ }
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+ }
+ if (devc->model == SIS_7012)
+ ich_OUTB (devc, status, CTL_BASE, 0x18); /* Clear interrupts */
+ else
+ ich_OUTB (devc, status, CTL_BASE, 0x16); /* Clear interrupts */
+ }
+
+ /*------------------- handle SPDIF interrupts -------------------------*/
+
+ if (devc->model == NVIDIA_NFORCE2)
+ {
+ status = ich_INB (devc, CTL_BASE, 0x76);
+ if (status & 0x08)
+ {
+ portc = &devc->portc[2];
+ serviced = 1;
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT)) /* IOC interrupt */
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
+ p = ich_INB (devc, CTL_BASE, 0x74);
+
+ if (p != devc->spdif_currbuf)
+ {
+ p = devc->spdif_currbuf;
+ f = devc->spdif_currfrag;
+ devc->spdifBDL[p].addr =
+ dmap->dmabuf_phys + (f * dmap->fragment_size);
+ /* SIS uses bytes, intelpci uses samples */
+ devc->spdifBDL[p].size = (dmap->fragment_size / 2);
+ devc->spdifBDL[p].flags = 0xc000; /* IOC interrupts */
+
+ ich_OUTB (devc, p, CTL_BASE, 0x75); /* Set LVD */
+ devc->spdif_frag_index[p] = f;
+ devc->spdif_currbuf = (p + 1) % BDL_SIZE;
+ devc->spdif_currfrag = (f + 1) % dmap->nfrags;
+ }
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+ ich_OUTB (devc, status, CTL_BASE, 0x76); /* Clear interrupts */
+ }
+ }
+
+ /*----------------------- Handle Recording Interrupts --------------------*/
+
+ if (devc->model == SIS_7012)
+ status = ich_INB (devc, CTL_BASE, 0x08);
+ else
+ status = ich_INB (devc, CTL_BASE, 0x06);
+
+ if (status & 0x08)
+ {
+ for (i = 0; i < MAX_PORTC - 1; i++)
+ {
+ portc = &devc->portc[i];
+ serviced = 1;
+ if ((portc->trigger_bits & PCM_ENABLE_INPUT)) /* IOC interrupt */
+ {
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_in;
+ p = ich_INB (devc, CTL_BASE, 0x04);
+
+ if (p != devc->rec_currbuf)
+ {
+ p = devc->rec_currbuf;
+ f = devc->rec_currfrag;
+ devc->recBDL[p].addr =
+ dmap->dmabuf_phys + (f * dmap->fragment_size);
+
+ /* SIS uses bytes, intelpci uses samples */
+ if (devc->model == SIS_7012)
+ devc->recBDL[p].size = (dmap->fragment_size);
+ else
+ devc->recBDL[p].size = (dmap->fragment_size / 2);
+
+ devc->recBDL[p].flags = 0xc000; /* IOC interrupts */
+
+ ich_OUTB (devc, p, CTL_BASE, 0x05); /* Set LVD */
+ devc->rec_frag_index[p] = f;
+ devc->rec_currbuf = (p + 1) % BDL_SIZE;
+ devc->rec_currfrag = (f + 1) % dmap->nfrags;
+ }
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+ if (devc->model == SIS_7012)
+ ich_OUTB (devc, status, CTL_BASE, 0x08); /* Clear int */
+ else
+ ich_OUTB (devc, status, CTL_BASE, 0x06); /* Clear int */
+ }
+ MUTEX_EXIT (devc->mutex, flags);
+ return serviced;
+}
+
+
+/*
+ * Audio routines
+ */
+
+static int
+ich_audio_set_rate (int dev, int arg)
+{
+ ich_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
+ arg = 48000;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+ich_audio_set_channels (int dev, short arg)
+{
+ ich_portc *portc = audio_engines[dev]->portc;
+
+ if ((arg == 1) || (arg == 2))
+ {
+ audio_engines[dev]->flags |= ADEV_STEREOONLY;
+ arg = 2;
+ }
+ else
+ audio_engines[dev]->flags &= ~ADEV_STEREOONLY;
+
+ if (arg>6)
+ arg=6;
+
+ if ((arg != 1) && (arg != 2) && (arg != 4) && (arg != 6))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+ich_audio_set_format (int dev, unsigned int arg)
+{
+ ich_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+#if 1
+ if (portc->open_mode & OPEN_READ)
+ return portc->bits = AFMT_S16_LE;
+#endif
+ if (!(arg & (AFMT_S16_LE | AFMT_AC3)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+ich_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void ich_audio_trigger (int dev, int state);
+
+static void
+ich_audio_reset (int dev)
+{
+ ich_audio_trigger (dev, 0);
+}
+
+static void
+ich_audio_reset_input (int dev)
+{
+ ich_portc *portc = audio_engines[dev]->portc;
+ ich_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+ich_audio_reset_output (int dev)
+{
+ ich_portc *portc = audio_engines[dev]->portc;
+ ich_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+ich_audio_open (int dev, int mode, int openflags)
+{
+ ich_portc *portc = audio_engines[dev]->portc;
+ ich_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ if (portc->port_type == DF_SPDIF)
+ {
+ if (mode & OPEN_READ)
+ {
+ cmn_err (CE_NOTE, "The S/PDIF device supports only playback\n");
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EIO;
+ }
+ }
+ else
+ {
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ devc->open_mode |= mode;
+ }
+
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ devc->fifo_errors = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+ich_audio_close (int dev, int mode)
+{
+ ich_portc *portc = audio_engines[dev]->portc;
+ ich_devc *devc = audio_engines[dev]->devc;
+
+ ich_audio_reset (dev);
+ portc->open_mode = 0;
+
+ if (devc->fifo_errors > 0)
+ cmn_err (CE_CONT, "%d fifo errors were detected\n", devc->fifo_errors);
+
+ if (portc->port_type != DF_SPDIF)
+ devc->open_mode &= ~mode;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+ich_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ich_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+ich_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ich_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+ich_audio_trigger (int dev, int state)
+{
+ ich_devc *devc = audio_engines[dev]->devc;
+ ich_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ if (portc->port_type == DF_SPDIF)
+ ich_OUTB (devc, 0x1d, CTL_BASE, 0x7b); /* Kickstart */
+ else
+ ich_OUTB (devc, 0x1d, CTL_BASE, 0x1b); /* Kickstart */
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ if (portc->port_type == DF_SPDIF)
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x7b); /* reset */
+ else
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x1b); /* reset */
+ }
+ }
+ }
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ ich_OUTB (devc, 0x1d, CTL_BASE, 0x0b); /* Kickstart */
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x0b); /* reset */
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+ich_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ ich_devc *devc = audio_engines[dev]->devc;
+ ich_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ int i, n, speed;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ ich_OUTB (devc, 0x02, CTL_BASE, 0x0b); /* Reset */
+ ich_OUTL (devc, devc->recBDL_phys, CTL_BASE, 0x00); /* BDL base */
+
+ speed = portc->speed;
+ speed = (speed * 240) / intelpci_rate_tuning;
+ ac97_recrate (&devc->ac97devc, speed);
+
+ n = bcount;
+ if (n > BDL_SIZE)
+ n = BDL_SIZE;
+
+ for (i = 0; i < n; i++)
+ {
+ devc->recBDL[i].addr = dmap->dmabuf_phys + (i * dmap->fragment_size);
+
+ /* SiS7012 uses bytes, ICH uses samples */
+ if (devc->model == SIS_7012)
+ devc->recBDL[i].size = (dmap->fragment_size);
+ else
+ devc->recBDL[i].size = (dmap->fragment_size / 2);
+
+ devc->recBDL[i].flags = 0xc000; /* IOC interrupts */
+ devc->rec_frag_index[i] = i;
+ }
+ ich_OUTB (devc, n - 1, CTL_BASE, 0x05); /* Set last valid descriptor */
+
+ devc->rec_currbuf = n % BDL_SIZE;
+ devc->rec_currfrag = n;
+ if (devc->rec_currfrag >= dmap->nfrags)
+ devc->rec_currfrag = 0;
+
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+ich_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ ich_devc *devc = audio_engines[dev]->devc;
+ ich_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ int i, n, speed;
+ unsigned int tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ /* We need to add ac3 pass through support */
+ if (devc->model == SIS_7012)
+ {
+ if (portc->bits == AFMT_AC3)
+ ich_OUTB (devc, 0, CTL_BASE, 0x4c);
+ else
+ ich_OUTB (devc, 1, CTL_BASE, 0x4c);
+ }
+
+ ac97_spdif_setup (devc->mixer_dev, portc->speed, portc->bits);
+
+ if (portc->bits == AFMT_AC3)
+ {
+ portc->channels = 2;
+ portc->bits = 16;
+ }
+
+ /* do SPDIF out */
+ if ((portc->port_type == DF_SPDIF) && (devc->model == NVIDIA_NFORCE2))
+ {
+ ich_OUTB (devc, 0x02, CTL_BASE, 0x7b); /* Reset */
+ ich_OUTL (devc, devc->spdifBDL_phys, CTL_BASE, 0x70); /* BDL base */
+ n = bcount;
+ if (n > BDL_SIZE)
+ n = BDL_SIZE;
+
+ for (i = 0; i < n; i++)
+ {
+ devc->spdifBDL[i].addr =
+ dmap->dmabuf_phys + (i * dmap->fragment_size);
+ devc->spdifBDL[i].size = (dmap->fragment_size / 2);
+ devc->spdifBDL[i].flags = 0xc000; /* IOC interrupts */
+ devc->spdif_frag_index[i] = i;
+ }
+ ich_OUTB (devc, n - 1, CTL_BASE, 0x75); /* Set last valid
+ * descriptor */
+ devc->spdif_currbuf = n % BDL_SIZE;
+ devc->spdif_currfrag = n;
+ if (devc->spdif_currfrag >= dmap->nfrags)
+ devc->spdif_currfrag = 0;
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+ }
+ /* else do PCM */
+ ich_OUTB (devc, 0x02, CTL_BASE, 0x1b); /* Reset */
+ ich_OUTL (devc, devc->playBDL_phys, CTL_BASE, 0x10); /* BDL base */
+
+ speed = portc->speed;
+ speed = (speed * 240) / intelpci_rate_tuning;
+ ac97_playrate (&devc->ac97devc, speed);
+
+ /* Handle 4/6 channel output on 7012 */
+ if (devc->model == SIS_7012)
+ {
+ tmp = ich_INL (devc, CTL_BASE, 0x30);
+
+ /* set default to 2 channel mode */
+ ich_OUTB (devc, ich_INB (devc, CTL_BASE, 0x2c) & 0x3f, CTL_BASE, 0x2c);
+
+ if ((portc->channels == 4) && (tmp & (1 << 20)))
+ ich_OUTB (devc, (ich_INB (devc, CTL_BASE, 0x2c) & 0x3f) | 0x40,
+ CTL_BASE, 0x2c);
+
+ if ((portc->channels == 6) && (tmp & (1 << 21)))
+ ich_OUTB (devc, (ich_INB (devc, CTL_BASE, 0x2c) & 0x3f) | 0x80,
+ CTL_BASE, 0x2c);
+ }
+ /* Handle 4/6 channel output on evrything other than ICH1 and SIS7012 */
+ if ((devc->model != INTEL_ICH1) && (devc->model != SIS_7012))
+ {
+ tmp = ich_INL (devc, CTL_BASE, 0x30);
+
+ /* set default to 2 channel mode */
+ ich_OUTL (devc, ich_INL (devc, CTL_BASE, 0x2c) & 0x0cfffff, CTL_BASE,
+ 0x2c);
+
+ if ((portc->channels == 4) && (tmp & (1 << 20)))
+ ich_OUTL (devc,
+ (ich_INL (devc, CTL_BASE, 0x2c) & 0x00fffff) | 0x0100000,
+ CTL_BASE, 0x2c);
+
+ if ((portc->channels == 6) && (tmp & (1 << 21)))
+ ich_OUTL (devc,
+ (ich_INL (devc, CTL_BASE, 0x2c) & 0x00fffff) | 0x0200000,
+ CTL_BASE, 0x2c);
+ }
+ n = bcount;
+ if (n > BDL_SIZE)
+ n = BDL_SIZE;
+
+ for (i = 0; i < n; i++)
+ {
+ devc->playBDL[i].addr = dmap->dmabuf_phys + (i * dmap->fragment_size);
+
+ /* SiS7012 uses bytes, ICH uses samples */
+ if (devc->model == SIS_7012)
+ devc->playBDL[i].size = (dmap->fragment_size);
+ else
+ devc->playBDL[i].size = (dmap->fragment_size / 2);
+
+ devc->playBDL[i].flags = 0xc000; /* IOC interrupts */
+ devc->play_frag_index[i] = i;
+ }
+ ich_OUTB (devc, n - 1, CTL_BASE, 0x15); /* Set last valid descriptor */
+
+
+ devc->play_currbuf = n % BDL_SIZE;
+ devc->play_currfrag = n;
+ if (devc->play_currfrag >= dmap->nfrags)
+ devc->play_currfrag = 0;
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+ich_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ ich_devc *devc = audio_engines[dev]->devc;
+ ich_portc *portc = audio_engines[dev]->portc;
+ int p = 0, f = 0, c = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ if (portc->port_type == DF_PCM)
+ {
+ f = ich_INB (devc, CTL_BASE, 0x14); /* Current buffer */
+
+ if (devc->model == SIS_7012)
+ p = ich_INW (devc, CTL_BASE, 0x16); /* Position in current
+ * buffer */
+ else
+ p = ich_INW (devc, CTL_BASE, 0x18); /* Position in current
+ * buffer */
+ c = devc->play_frag_index[f]; /* Current fragment */
+
+ if (devc->model == SIS_7012)
+ p = dmap->fragment_size - (p); /* Remaining bytes */
+ else
+ p = dmap->fragment_size - (p * 2); /* Remaining bytes */
+ }
+ if ((portc->port_type == DF_SPDIF) && (devc->model == NVIDIA_NFORCE2))
+ {
+ f = ich_INB (devc, CTL_BASE, 0x74); /* Current buffer */
+ p = ich_INW (devc, CTL_BASE, 0x78); /* Position in current
+ * buffer */
+ c = devc->play_frag_index[f]; /* Current fragment */
+ p = dmap->fragment_size - (p * 2); /* Remaining bytes */
+ }
+ }
+ /*
+ * Handle input
+ */
+ if (direction == PCM_ENABLE_INPUT)
+ {
+
+ f = ich_INB (devc, CTL_BASE, 0x04); /* Current buffer */
+
+ if (devc->model == SIS_7012)
+ p = ich_INW (devc, CTL_BASE, 0x06); /* Position in current
+ * buffer */
+ else
+ p = ich_INW (devc, CTL_BASE, 0x08); /* Position in current
+ * buffer */
+ c = devc->rec_frag_index[f]; /* Current fragment */
+
+ if (devc->model == SIS_7012)
+ p = dmap->fragment_size - (p); /* Remaining bytes */
+ else
+ p = dmap->fragment_size - (p * 2); /* Remaining bytes */
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return p + c * dmap->fragment_size;
+}
+
+#if 0
+static int
+ich_calibrate_speed (int dev, int nominal_speed, int true_speed)
+{
+ unsigned int fix;
+ DDB (smn_err (CE_CONT,
+ "ich_calibrate_speed(%d, %d, %d)\n", dev, nominal_speed,
+ true_speed));
+
+ fix = ((240 * true_speed) + nominal_speed / 2) / nominal_speed;
+ DDB (cmn_err (CE_NOTE, "intelpci_rate_tuning = %d\n", fix));
+ if (fix > 1)
+ intelpci_rate_tuning = fix;
+
+ return 0;
+}
+#endif
+
+static const audiodrv_t ich_audio_driver = {
+ ich_audio_open,
+ ich_audio_close,
+ ich_audio_output_block,
+ ich_audio_start_input,
+ ich_audio_ioctl,
+ ich_audio_prepare_for_input,
+ ich_audio_prepare_for_output,
+ ich_audio_reset,
+ NULL,
+ NULL,
+ ich_audio_reset_input,
+ ich_audio_reset_output,
+ ich_audio_trigger,
+ ich_audio_set_rate,
+ ich_audio_set_format,
+ ich_audio_set_channels,
+ NULL,
+ NULL,
+ NULL, /* ich_check_input, */
+ NULL, /* ich_check_output, */
+ NULL, /* ich_alloc_buffer, */
+ NULL, /* ich_free_buffer, */
+ NULL,
+ NULL,
+ ich_get_buffer_pointer,
+ NULL /* ich_calibrate_speed */
+};
+
+static int
+ich_init (ich_devc * devc)
+{
+ int my_mixer, adev, opts;
+ int i, max_port;
+ unsigned int reg;
+ int first_dev = 0;
+ oss_native_word phaddr;
+
+ /* ACLink on, warm reset */
+ reg = ich_INL (devc, CTL_BASE, 0x2c);
+ if ((reg & 0x02) == 0)
+ reg |= 2;
+ else
+ reg |= 4;
+ reg &= ~8;
+ ich_OUTL (devc, reg, CTL_BASE, 0x2c);
+ oss_udelay (500);
+ if (devc->model == SIS_7012)
+ {
+ reg |= 0x10;
+ ich_OUTL (devc, reg, CTL_BASE, 0x2c);
+ oss_udelay (500);
+ }
+ /* disable interrupts */
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x0b);
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x1b);
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x2b);
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x7b);
+
+ devc->bdlBuffer =
+ CONTIG_MALLOC (devc->osdev, 4 * 32 * 32, MEMLIMIT_32BITS, &phaddr, devc->bldbuf_dma_handle);
+ if (devc->bdlBuffer == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate BDL\n");
+ return 0;
+ }
+ devc->playBDL = (bdl_t *) devc->bdlBuffer;
+ devc->playBDL_phys = phaddr;
+ devc->recBDL = (bdl_t *) (devc->bdlBuffer + (32 * 32));
+ devc->recBDL_phys = phaddr + 32 * 32;
+ devc->spdifBDL = (bdl_t *) (devc->bdlBuffer + (2 * 32 * 32));
+ devc->spdifBDL_phys = phaddr + 2 * 32 * 32;
+
+ /*
+ * Init mixer
+ */
+ my_mixer =
+ ac97_install_full (&devc->ac97devc, "ICH AC97 Mixer", ac97_read, ac97_write,
+ devc, devc->osdev, devc->inverted_amplifier |
+ (ich_jacksense?AC97_FORCE_SENSE:0));
+ if (my_mixer == -1)
+ {
+ cmn_err (CE_WARN, "AC97 mixer installation failed\n");
+ return 0; /* No mixer */
+ }
+
+ devc->mixer_dev = my_mixer;
+ mixer_devs[my_mixer]->priority = 10; /* Known motherboard device */
+
+ /* enable S/PDIF */
+ devc->ac97devc.spdif_slot = SPDIF_SLOT34;
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 1);
+
+ /* enable variable rate mode */
+ ac97_write (devc, 0x2a, ac97_read (devc, 0x2a) | 9);
+ if (!(ac97_read (devc, 0x2a) & 1))
+ DDB (cmn_err (CE_NOTE, "VRA not supported...using GRC\n"));
+
+ /* Enable SPDIF for SiS 7012 */
+ if (devc->model == SIS_7012)
+ {
+ ich_OUTL (devc, ich_INL (devc, CTL_BASE, 0x2c) | (1 << 10), CTL_BASE,
+ 0x2c);
+ ich_OUTL (devc, ich_INL (devc, CTL_BASE, 0x4c) | 1, CTL_BASE, 0x4c);
+ }
+ if (devc->model == NVIDIA_NFORCE2)
+ max_port = 3;
+ else
+ max_port = 2;
+
+ for (i = 0; i < max_port; i++)
+ {
+ ich_portc *portc = &devc->portc[i];
+ char tmp_name[100];
+ int port_fmt = DF_PCM;
+ int formats = AFMT_S16_LE | AFMT_AC3;
+ char *devfile_name = "";
+
+ strcpy (tmp_name, devc->chip_name);
+ opts = ADEV_AUTOMODE | ADEV_16BITONLY | ADEV_STEREOONLY | ADEV_COLD;
+
+ if (!ac97_varrate (&devc->ac97devc))
+ {
+ opts |= ADEV_FIXEDRATE;
+ }
+ if (i == 0)
+ {
+ strcpy (tmp_name, devc->chip_name);
+ opts |= ADEV_DUPLEX;
+ }
+ if (i == 1)
+ {
+ strcpy (tmp_name, devc->chip_name);
+ opts |= ADEV_DUPLEX | ADEV_SHADOW;
+ }
+ if (i == 2)
+ {
+ sprintf (tmp_name, "%s S/PDIF out", devc->chip_name);
+ opts |= ADEV_NOINPUT | ADEV_SPECIAL | ADEV_FIXEDRATE;
+ port_fmt = DF_SPDIF;
+ devfile_name = "spdout";
+ }
+ if ((adev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &ich_audio_driver,
+ sizeof (audiodrv_t),
+ opts, formats, devc, -1,
+ devfile_name)) < 0)
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->max_block = 64 * 1024;
+
+ /* fix a timeout bug with Nforce2 */
+ if ((devc->model == NVIDIA_NFORCE) ||
+ (devc->model == NVIDIA_NFORCE2))
+ {
+ audio_engines[adev]->min_block = 4096;
+ audio_engines[adev]->max_block = 4096;
+ }
+
+ audio_engines[adev]->min_rate =
+ (opts & ADEV_FIXEDRATE) ? 48000 : 5000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ audio_engines[adev]->min_channels = 2;
+ audio_engines[adev]->max_channels = 6;
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+ portc->audiodev = adev;
+ portc->port_type = port_fmt;
+ if (audio_engines[adev]->flags & ADEV_FIXEDRATE)
+ audio_engines[adev]->fixed_rate = 48000;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+ }
+ return 1;
+}
+
+int
+oss_ich_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision /* , pci_latency */ ;
+ unsigned short pci_command, vendor, device, sub_vendor, sub_id;
+ unsigned int pci_ioaddr0, pci_ioaddr1;
+ unsigned int dw;
+
+ ich_devc *devc;
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->open_mode = 0;
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ DDB (cmn_err
+ (CE_CONT, "oss_ich_attach(Vendor %x, device %x)\n", vendor, device));
+
+#if 0
+ // This check is not necessary because the kernel has already checked
+ // the vendor&device ID
+
+ if ((vendor != INTEL_VENDOR_ID && vendor != SIS_VENDOR_ID &&
+ vendor != NVIDIA_VENDOR_ID && vendor != AMD_VENDOR_ID) ||
+ (device != INTEL_DEVICE_ICH1 && device != INTEL_DEVICE_ICH1R1 &&
+ device != INTEL_DEVICE_ICH1R2 && device != INTEL_DEVICE_ICH2 &&
+ device != INTEL_DEVICE_ICH3 && device != INTEL_DEVICE_ICH4 &&
+ device != INTEL_DEVICE_ICH5 && device != INTEL_DEVICE_ESB &&
+ device != INTEL_DEVICE_ICH6 && device != INTEL_DEVICE_ICH7 &&
+ device != SIS_DEVICE_7012 &&
+ device != AMD_DEVICE_768 && device != AMD_DEVICE_8111 &&
+ device != NVIDIA_DEVICE_NFORCE && device != NVIDIA_DEVICE_NFORCE2 &&
+ device != NVIDIA_DEVICE_NFORCE3 && device != NVIDIA_DEVICE_CK8S &&
+ device != NVIDIA_DEVICE_NFORCE4 && device != NVIDIA_DEVICE_CK8 &&
+ device != NVIDIA_DEVICE_MCP51 && device != NVIDIA_DEVICE_MCP4
+ ))
+ {
+ cmn_err (CE_WARN, "Hardware not recognized (vendor=%x, dev=%x)\n",
+ vendor, device);
+ return 0;
+ }
+#endif
+
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor);
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_ID, &sub_id);
+ dw = (sub_id << 16) | sub_vendor;
+
+ switch (dw)
+ {
+ case 0x202f161f: /* Gateway 7326GZ */
+ case 0x203a161f: /* Gateway 4028GZ or 4542GZ */
+ case 0x203e161f: /* Gateway 3520GZ/M210 */
+ case 0x204c161f: /* Kvazar-Micro Senator 3592XT */
+ case 0x8144104d: /* Sony VAIO PCG-TR* */
+ case 0x8197104d: /* Sony S1XP */
+ case 0x81c0104d: /* Sony VAIO type T */
+ case 0x81c5104d: /* Sony VAIO VGN B1VP/B1XP */
+ case 0x3089103c: /* Compaq Presario B3800 */
+ case 0x309a103c: /* HP Compaq nx4300 */
+ case 0x82131033: /* NEC VersaPro VJ10F/BH */
+ case 0x82be1033: /* NEC VersaPro VJ12F/CH */
+ devc->inverted_amplifier = AC97_INVERTED;
+ cmn_err (CE_CONT, "An inverted amplifier has been autodetected\n");
+ break;
+ default:
+ devc->inverted_amplifier = 0;
+ break;
+ }
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr0);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_1, &pci_ioaddr1);
+
+ switch (device)
+ {
+ case INTEL_DEVICE_ICH1:
+ devc->model = INTEL_ICH1;
+ devc->chip_name = "Intel ICH (2415)";
+ break;
+ case INTEL_DEVICE_ICH1R1:
+ devc->model = INTEL_ICH1;
+ devc->chip_name = "Intel ICHR1(2425)";
+ break;
+ case INTEL_DEVICE_ICH1R2:
+ devc->model = INTEL_ICH1;
+ devc->chip_name = "Intel ICHR2 (7195)";
+ break;
+ case INTEL_DEVICE_ICH2:
+ devc->model = INTEL_ICH1;
+ devc->chip_name = "Intel ICH2 (2445)";
+ break;
+ case INTEL_DEVICE_ICH3:
+ devc->model = INTEL_ICH3;
+ devc->chip_name = "Intel ICH3 (2485)";
+ break;
+ case INTEL_DEVICE_ICH4:
+ devc->model = INTEL_ICH4;
+ devc->chip_name = "Intel ICH4 (24C5)";
+ break;
+ case INTEL_DEVICE_ICH5:
+ devc->model = INTEL_ICH4;
+ devc->chip_name = "Intel ICH5 (24D5)";
+ break;
+ case INTEL_DEVICE_ICH6:
+ devc->model = INTEL_ICH4;
+ devc->chip_name = "Intel ICH6 (266E)";
+ break;
+ case INTEL_DEVICE_ICH7:
+ devc->model = INTEL_ICH4;
+ devc->chip_name = "Intel ICH7 (27DE)";
+ break;
+ case INTEL_DEVICE_ESB:
+ devc->model = INTEL_ICH4;
+ devc->chip_name = "Intel ICH5 (25a6)";
+ break;
+ case SIS_DEVICE_7012:
+ devc->model = SIS_7012;
+ devc->chip_name = "SiS 7012";
+ break;
+ case NVIDIA_DEVICE_NFORCE:
+ devc->model = NVIDIA_NFORCE;
+ devc->chip_name = "Nvidia nForce";
+ break;
+ case NVIDIA_DEVICE_NFORCE2:
+ devc->model = NVIDIA_NFORCE2;
+ devc->chip_name = "Nvidia nForce2";
+ pci_read_config_dword (osdev, 0x4c, &dw);
+ dw |= 0x1000000;
+ pci_write_config_dword (osdev, 0x4c, dw);
+ break;
+ case NVIDIA_DEVICE_NFORCE3:
+ devc->model = NVIDIA_NFORCE2;
+ devc->chip_name = "Nvidia nForce3";
+ pci_read_config_dword (osdev, 0x4c, &dw);
+ dw |= 0x1000000;
+ pci_write_config_dword (osdev, 0x4c, dw);
+ break;
+ case NVIDIA_DEVICE_CK8S:
+ devc->model = NVIDIA_NFORCE2;
+ devc->chip_name = "Nvidia CK8S";
+ pci_read_config_dword (osdev, 0x4c, &dw);
+ dw |= 0x1000000;
+ pci_write_config_dword (osdev, 0x4c, dw);
+ break;
+ case NVIDIA_DEVICE_NFORCE4:
+ devc->model = NVIDIA_NFORCE2;
+ devc->chip_name = "Nvidia nForce4";
+ pci_read_config_dword (osdev, 0x4c, &dw);
+ dw |= 0x1000000;
+ pci_write_config_dword (osdev, 0x4c, dw);
+ break;
+ case NVIDIA_DEVICE_CK8:
+ devc->model = NVIDIA_NFORCE2;
+ devc->chip_name = "Nvidia CK8";
+ pci_read_config_dword (osdev, 0x4c, &dw);
+ dw |= 0x1000000;
+ pci_write_config_dword (osdev, 0x4c, dw);
+ break;
+ case NVIDIA_DEVICE_MCP51:
+ devc->model = NVIDIA_NFORCE2;
+ devc->chip_name = "Nvidia MCP51";
+ pci_read_config_dword (osdev, 0x4c, &dw);
+ dw |= 0x1000000;
+ pci_write_config_dword (osdev, 0x4c, dw);
+ break;
+ case NVIDIA_DEVICE_MCP4:
+ devc->model = NVIDIA_NFORCE2;
+ devc->chip_name = "Nvidia MCP4";
+ pci_read_config_dword (osdev, 0x4c, &dw);
+ dw |= 0x1000000;
+ pci_write_config_dword (osdev, 0x4c, dw);
+ break;
+ case AMD_DEVICE_768:
+ devc->model = AMD_768;
+ devc->chip_name = "AMD 768";
+ break;
+ case AMD_DEVICE_8111:
+ devc->model = AMD_8111;
+ devc->chip_name = "AMD 8111";
+ break;
+ default:
+ devc->chip_name = "Unknown ICH chip";
+ }
+
+ if (((pci_ioaddr1 == 0) || (intelpci_force_mmio)) &&
+ (devc->model == INTEL_ICH4))
+ {
+ unsigned int ioaddr;
+
+ /* read bar2 and bar3 for getting mmap address */
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_2, &ioaddr);
+ devc->ac97_membar_addr = ioaddr;
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_3, &ioaddr);
+ devc->membar_addr = ioaddr;
+
+ /* get virtual address */
+ devc->ac97_membar_virt =
+ (char *) MAP_PCI_MEM (devc->osdev, 2, devc->ac97_membar_addr, 512);
+ devc->membar_virt =
+ (char *) MAP_PCI_MEM (devc->osdev, 3, devc->membar_addr, 256);
+ devc->mem_mode = MMAP_MODE;
+ }
+ else
+ devc->mem_mode = IO_MODE;
+
+ if (devc->mem_mode == IO_MODE)
+ {
+ if (devc->model == INTEL_ICH4)
+ {
+ /*
+ * enable the IOSE bit in 0x41 for legacy
+ * mode for ICH4/ICH5
+ */
+ pci_write_config_byte (osdev, 0x41, 1);
+
+ /* Set the secondary codec ID */
+ pci_write_config_byte (osdev, 0x40, 0x39);
+ }
+ /* Remove I/O space marker in bit 0. */
+ devc->ac97_base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr0);
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 1, pci_ioaddr1);
+ devc->ac97_base &= ~0xF;
+ devc->base &= ~0xF;
+ }
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ devc->irq = pci_irq_line;
+
+ if (devc->mem_mode != IO_MODE)
+ {
+ devc->base = devc->membar_addr;
+ }
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if (oss_register_interrupts (devc->osdev, 0, ichintr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Unable to install interrupt handler\n");
+ return 0;
+ }
+
+ return ich_init (devc); /* Detected */
+}
+
+int
+oss_ich_detach (oss_device_t * osdev)
+{
+ ich_devc *devc = (ich_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ /* disable interrupts */
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x0b);
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x1b);
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x2b);
+ ich_OUTB (devc, 0x00, CTL_BASE, 0x7b);
+ oss_unregister_interrupts (devc->osdev);
+
+ /* disable S/PDIF */
+ if (devc->mixer_dev)
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 0);
+
+ if (devc->bdlBuffer)
+ CONTIG_FREE (devc->osdev, devc->bdlBuffer, 4 * 32 * 32, devc->bldbuf_dma_handle);
+ devc->bdlBuffer = NULL;
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+
+ if ((devc->mem_mode == MMAP_MODE) && (devc->membar_addr != 0))
+ {
+ UNMAP_PCI_MEM (devc->osdev, 2, devc->ac97_membar_addr,
+ devc->ac97_membar_virt, 512);
+ UNMAP_PCI_MEM (devc->osdev, 3, devc->membar_addr, devc->membar_virt,
+ 256);
+ devc->membar_addr = 0;
+ devc->ac97_membar_addr = 0;
+ }
+ else
+ {
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+ UNMAP_PCI_IOADDR (devc->osdev, 1);
+ }
+ oss_unregister_device (osdev);
+ return 1;
+}
+
+#ifdef OSS_POWER_MANAGE
+/* Not activated in .config at this moment */
+int
+oss_ich_power (oss_device_t *osdev, int component, int level)
+{
+// cmn_err(CE_CONT, "oss_ich_power(%d, %d)\n", component, level);
+
+ return 0; /* Failed */
+}
+#endif
+
+#ifdef OSS_SUSPEND_RESUME
+int
+oss_ich_suspend(oss_device_t *osdev)
+{
+//cmn_err(CE_CONT, "oss_ich_suspend()\n");
+ return 0; /* Failed */
+}
+
+int
+oss_ich_resume(oss_device_t *osdev)
+{
+//cmn_err(CE_CONT, "oss_ich_resume()\n");
+ return 0; /* Failed */
+}
+#endif
diff --git a/kernel/drv/oss_ich/oss_ich.man b/kernel/drv/oss_ich/oss_ich.man
new file mode 100644
index 0000000..ee15abf
--- /dev/null
+++ b/kernel/drv/oss_ich/oss_ich.man
@@ -0,0 +1,34 @@
+NAME
+oss_ich - Intel ICH/SiS7012/Nvidia/AMD audio device driver.
+
+DESCRIPTION
+Open Sound System driver for Intel ICH, nVidia Nforce, AMD and SiS 7012
+devices.
+
+OPTIONS
+
+o intelpci_rate_tuning=<NNN> (default is 240)
+ Some Compaq Deskpro models (EN and EX at least) and certain Dell models
+ play and record audio at a higher speed than what is expected. If you have
+ an Intel815 motherboard with an AD1885 you can try setting the parameter
+ to 240, 280 or 330 and see which works for your system. The way to figure
+ out the the right intelpci_rate_tuning value is using the osstest application.
+ It reports a sample rate drift value ("Sample rate drift" or "srate drift").
+ Use the following formula (round the result to the nearest integer):
+
+ <intelpci_rate_tuning = (240*(drift+100))/100>
+
+o intelpci_force_mmio=<0|1> (default is 0=Disable)
+ This option can be used to force the ICH4/ICH5 and ICH6 controllers to
+ run in memory mapped mode to free up I/O address space.
+
+o ich_jacksense=<0|1> (default is 0)
+ Force use of jacksensing on some AD198x mixers.
+
+FILES
+CONFIGFILEPATH/oss_ich.conf Device configuration file.
+
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_imux/.config b/kernel/drv/oss_imux/.config
new file mode 100644
index 0000000..b7929da
--- /dev/null
+++ b/kernel/drv/oss_imux/.config
@@ -0,0 +1,2 @@
+bus=VIRTUAL
+cflags=-O
diff --git a/kernel/drv/oss_imux/.devices b/kernel/drv/oss_imux/.devices
new file mode 100644
index 0000000..be685da
--- /dev/null
+++ b/kernel/drv/oss_imux/.devices
@@ -0,0 +1 @@
+oss_imux oss_imux OSS Input Multiplexer
diff --git a/kernel/drv/oss_imux/.name b/kernel/drv/oss_imux/.name
new file mode 100644
index 0000000..88f4996
--- /dev/null
+++ b/kernel/drv/oss_imux/.name
@@ -0,0 +1 @@
+OSS Input Multiplexer (IMUX)
diff --git a/kernel/drv/oss_imux/.params b/kernel/drv/oss_imux/.params
new file mode 100644
index 0000000..c52896c
--- /dev/null
+++ b/kernel/drv/oss_imux/.params
@@ -0,0 +1,24 @@
+/*
+ * IMUX supports multiple instances, please consult the man page
+ */
+
+int imux_devices=5;
+/*
+ * Number of IMUX client side devices to configure.
+ * Values: 2-48 Default: 5.
+ */
+
+int imux_masterdev=-1;
+/*
+ * Master physical device to use (ie attach IMUX to a specific soundcard)
+ * -1 means automatically detect the device. Use the device index numbers
+ * reported by ossinfo -a.
+ * Values: 0-N Default: -1 (autodetec)
+ */
+
+int imux_rate=48000;
+/*
+ * Select the base sampling rate for the IMUX device. The base rate must be
+ * one supported by the actual physical device (as reported by audioinfo -a -v2).
+ * Values: 8000-192000 Default: 48000
+ */
diff --git a/kernel/drv/oss_imux/oss_imux.c b/kernel/drv/oss_imux/oss_imux.c
new file mode 100644
index 0000000..e712436
--- /dev/null
+++ b/kernel/drv/oss_imux/oss_imux.c
@@ -0,0 +1,1072 @@
+/*
+ * Purpose: Pseudo driver for sharing one input device between multiple apps.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define MAX_IMUX_INSTANCES 16
+#define MAX_IMUX_DEV 48
+#define SUPPORTED_FORMATS (AFMT_S16_NE|AFMT_S16_OE)
+
+#include "oss_imux_cfg.h"
+
+static unsigned long long used_masterdevs = 0LL;
+
+typedef struct
+{
+ int audio_dev;
+ int port_number;
+ int is_opened, is_prepared, is_triggered;
+ int speed, channels, fmt;
+ int ch_index;
+ int left_igain, right_igain;
+ oss_peaks_t peaks;
+}
+imux_portc;
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_device_t *master_osdev;
+ oss_mutex_t mutex;
+ int installed_ok;
+ int hw_dev;
+ int hw_speed, hw_channels, hw_fmt, sw_fmt;
+ int hw_fragsize;
+
+ int device_started;
+ struct fileinfo finfo;
+
+ int nr_devices, open_count;
+ imux_portc portc[MAX_IMUX_DEV];
+ int fragsize;
+ int prev_fragment;
+
+/*
+ * Mixer
+ */
+ int mixer_dev;
+ int autoreset; /* Autoreset igain sliders to 100 during open */
+
+/*
+ * Startup info
+ */
+ int imux_devices;
+ int imux_rate;
+ int imux_masterdev;
+ int instance_no;
+}
+imux_devc;
+
+static imux_devc imux_info[MAX_IMUX_INSTANCES] = { {0} };
+static int nimuxdevs = 0;
+
+/*ARGSUSED*/
+static int
+imux_set_rate (int dev, int arg)
+{
+ imux_devc *devc = audio_engines[dev]->devc;
+ return devc->hw_speed;
+}
+
+/*ARGSUSED*/
+static short
+imux_set_channels (int dev, short arg)
+{
+ imux_portc *portc = audio_engines[dev]->portc;
+ return portc->channels = 2;
+}
+
+/*ARGSUSED*/
+static unsigned int
+imux_set_format (int dev, unsigned int arg)
+{
+ imux_devc *devc = audio_engines[dev]->devc;
+
+ return devc->sw_fmt;
+}
+
+
+static int
+imux_igain (int dev, int ctrl, unsigned int cmd, int value)
+{
+/*
+ * Access function for IMUX input gain
+ */
+ int left, right;
+ imux_devc *devc = mixer_devs[dev]->devc;
+ imux_portc *portc;
+
+ if (ctrl != 100 && (ctrl < 0 || ctrl >= devc->imux_devices))
+ return OSS_EINVAL;
+
+ portc = &devc->portc[ctrl];
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (ctrl == 100)
+ return devc->autoreset;
+ return (portc->left_igain & 0x00ff) |
+ ((portc->right_igain & 0x00ff) << 8);
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ if (ctrl == 100)
+ return devc->autoreset = !!value;
+
+ left = value & 0x00ff;
+ right = (value >> 8) & 0x00ff;
+ if (left < 0)
+ left = 0;
+ if (left > 100)
+ left = 100;
+ if (right < 0)
+ right = 0;
+ if (right > 100)
+ right = 100;
+
+ portc->left_igain = left;
+ portc->right_igain = right;
+ return left | (right << 8);
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+imux_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ imux_devc *devc = audio_engines[dev]->devc;
+ imux_portc *portc = audio_engines[dev]->portc;
+ int value, i, n, p;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_SET_RECSRC:
+ {
+ value = *arg;
+ if (value <= 0 || value >= devc->hw_channels - 1)
+ return OSS_EINVAL;
+ portc->ch_index = value;
+ }
+
+ case SNDCTL_DSP_GET_RECSRC:
+ return *arg = portc->ch_index;
+ break;
+
+ case SNDCTL_DSP_GET_RECSRC_NAMES:
+ {
+ oss_mixer_enuminfo *ei = (oss_mixer_enuminfo *) arg;
+
+ memset (ei, 0, sizeof (*ei));
+
+ n = ei->nvalues = devc->hw_channels - 1;
+ p = 0;
+
+ if (n <= 1) /* Only one alternative */
+ {
+ ei->nvalues = 1;
+ ei->strindex[0] = 0;
+ sprintf (ei->strings, "default");
+
+ }
+ else
+ /* Multiple alternatives */
+ for (i = 0; i < n; i++)
+ {
+ ei->strindex[i] = p;
+
+ sprintf (&ei->strings[p], "CH%d/%d", i + 1, i + 2);
+
+ p += strlen (&ei->strings[p]) + 1;
+ }
+
+ return 0;
+ }
+ break;
+
+ case SNDCTL_DSP_SETRECVOL:
+ value = *arg;
+ return *arg = imux_igain (audio_engines[dev]->mixer_dev,
+ portc->ch_index, SNDCTL_MIX_WRITE, value);
+ break;
+
+ case SNDCTL_DSP_GETRECVOL:
+ return *arg = imux_igain (audio_engines[dev]->mixer_dev,
+ portc->ch_index, SNDCTL_MIX_READ, 0);
+ break;
+
+ case SNDCTL_DSP_GETIPEAKS:
+ memset (arg, 0, sizeof (oss_peaks_t));
+ memcpy (arg, portc->peaks, sizeof (portc->peaks));
+ memset (portc->peaks, 0, sizeof (portc->peaks));
+ return 0;
+ break;
+ }
+ return OSS_EINVAL;
+}
+
+static void imux_trigger (int dev, int state);
+
+static void
+imux_reset (int dev)
+{
+ imux_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static void
+bufcpy16ne (imux_devc * devc, imux_portc * portc, unsigned char *tbuf,
+ unsigned char *buf, int nbytes, int frame_size, int hw_framesize)
+{
+ int ns, i, hw_channels;
+ short *p1, *p2;
+
+ ns = nbytes / frame_size;
+
+ hw_channels = hw_framesize / sizeof (*p2);
+
+ p1 = (short *) tbuf;
+ p2 = (short *) (buf + portc->ch_index * frame_size / 2);
+
+ for (i = 0; i < ns; i++)
+ {
+ int v;
+
+ /* Left channel */
+ v = *p2++;
+ v = v * portc->left_igain / 100;
+ *p1++ = v;
+ if (v < 0)
+ v = -v;
+ if (v > portc->peaks[0])
+ portc->peaks[0] = v;
+
+ /* Right channel */
+ v = *p2++;
+ v = v * portc->right_igain / 100;
+ *p1++ = v;
+ if (v < 0)
+ v = -v;
+ if (v > portc->peaks[1])
+ portc->peaks[1] = v;
+
+ if (hw_channels > 2)
+ p2 += hw_channels - 2;
+ }
+}
+
+/*ARGSUSED*/
+static void
+bufcpy16oe (imux_devc * devc, imux_portc * portc, unsigned char *tbuf,
+ unsigned char *buf, int nbytes, int frame_size, int hw_framesize)
+{
+ int ns, i, hw_channels;
+ short *p1, *p2;
+
+ ns = nbytes / frame_size;
+
+ hw_channels = hw_framesize / sizeof (*p2);
+
+ p1 = (short *) tbuf;
+ p2 = (short *) (buf + portc->ch_index * frame_size / 2);
+
+ for (i = 0; i < ns; i++)
+ {
+ int v;
+
+ /* Left channel */
+ v = *p2++;
+ v = ((v >> 8) & 0xff) | ((v & 0xff) << 8);
+ v = v * portc->left_igain / 100;
+ *p1++ = v;
+ if (v < 0)
+ v = -v;
+ if (v > portc->peaks[0])
+ portc->peaks[0] = v;
+
+ /* Right channel */
+ v = *p2++;
+ v = ((v >> 8) & 0xff) | ((v & 0xff) << 8);
+ v = v * portc->right_igain / 100;
+ *p1++ = v;
+ if (v < 0)
+ v = -v;
+ if (v > portc->peaks[1])
+ portc->peaks[1] = v;
+
+ if (hw_channels > 2)
+ p2 += hw_channels - 2;
+ }
+}
+
+/*ARGSUSED*/
+static void
+imux_callback (int dev, int parm)
+{
+ dmap_t *dmap;
+ unsigned char *buf, *tbuf;
+ int i, len, frag, tail, next, n;
+ imux_devc *devc = NULL;
+
+ for (i = 0; i < nimuxdevs && devc == NULL; i++)
+ {
+ if (imux_info[i].hw_dev == dev)
+ devc = &imux_info[i];
+ }
+
+ if (devc == NULL)
+ {
+ cmn_err (CE_WARN, "IMUX error\n");
+ return;
+ }
+
+ dmap = audio_engines[dev]->dmap_in;
+
+ frag = dmap_get_qhead (dmap);
+ tail = dmap_get_qtail (dmap);
+ next = (frag + 1) % dmap->nfrags;
+
+ n = 0;
+ while (n++ < 2 && frag != tail && next != tail
+ && devc->prev_fragment != frag)
+ {
+ devc->prev_fragment = frag;
+ buf = &dmap->dmabuf[frag * dmap->fragment_size];
+ len = dmap->fragment_size;
+
+ dmap->user_counter += dmap->fragment_size;
+
+ for (i = 0; i < devc->nr_devices; i++)
+ {
+ dmap_t *client_dmap;
+
+ imux_portc *portc = &devc->portc[i];
+ client_dmap = audio_engines[portc->audio_dev]->dmap_in;
+
+ if (!portc->is_opened || !portc->is_triggered)
+ continue;
+
+ if (client_dmap->fragment_size != (2 * len) / devc->hw_channels)
+ {
+ DDB (cmn_err (CE_WARN, "Fragment warning (%d, %d, %d-%d)\n",
+ client_dmap->fragment_size, len,
+ audio_engines[portc->audio_dev]->min_block,
+ audio_engines[portc->audio_dev]->max_block));
+#if 1
+ /* Make automatic adjustments */
+ client_dmap->fragment_size = (2 * len) / devc->hw_channels;
+ client_dmap->nfrags =
+ client_dmap->buffsize / client_dmap->fragment_size;
+ client_dmap->bytes_in_use =
+ client_dmap->nfrags * client_dmap->fragment_size;
+#else
+ continue;
+#endif
+ }
+
+ tbuf =
+ &client_dmap->dmabuf[dmap_get_qtail (client_dmap) *
+ client_dmap->fragment_size];
+
+ if (devc->hw_fmt == AFMT_S16_NE) /* Native 16 bits */
+ {
+ bufcpy16ne (devc, portc, tbuf, buf,
+ client_dmap->fragment_size,
+ client_dmap->frame_size, dmap->frame_size);
+ }
+ else if (devc->hw_fmt == AFMT_S16_OE) /* Native 16 bits */
+ {
+ bufcpy16oe (devc, portc, tbuf, buf,
+ client_dmap->fragment_size,
+ client_dmap->frame_size, dmap->frame_size);
+ }
+ else
+ memcpy (tbuf, buf, len);
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Imux: copy f=%d/%d to ch=%d t=%d/%d", frag, tail,
+ i, dmap_get_qtail (client_dmap),
+ dmap_get_qhead (client_dmap));
+#endif
+ oss_audio_inputintr (portc->audio_dev, 0);
+
+ }
+ frag = dmap_get_qhead (dmap);
+ tail = dmap_get_qtail (dmap);
+ next = (frag + 1) % dmap->nfrags;
+ }
+
+
+}
+
+static int
+start_device (imux_devc * devc)
+{
+ int i, err, dev, trig, nc;
+ /* int frags = 0x7fff0008; fragment size of 256 bytes */
+
+ if (devc->hw_dev < 0 || devc->hw_dev >= num_audio_engines)
+ {
+ devc->hw_dev = 0;
+ }
+
+ if (devc->hw_dev < 0 || devc->hw_dev >= num_audio_engines)
+ {
+ cmn_err (CE_WARN, "No audio hardware available\n");
+ return OSS_ENXIO;
+ }
+
+ if (devc->device_started)
+ {
+ return 1;
+ }
+
+ devc->finfo.mode = OPEN_READ;
+ devc->finfo.acc_flags = 0;
+ devc->prev_fragment = -1;
+
+ DDB (cmn_err (CE_NOTE,
+ "Instance %d: Will use audio device %d as the master\n",
+ devc->instance_no, devc->hw_dev));
+
+ if (devc->hw_dev >= devc->portc[0].audio_dev
+ && devc->hw_dev <= devc->portc[devc->imux_devices - 1].audio_dev)
+ {
+ cmn_err (CE_WARN, "Bad master device %d\n", devc->hw_dev);
+ return OSS_ENXIO;
+ }
+
+ if (!(audio_engines[devc->hw_dev]->iformat_mask & SUPPORTED_FORMATS))
+ {
+ cmn_err (CE_CONT,
+ "Audio device %d doesn't support compatible sample formats.\n",
+ devc->hw_dev);
+ return OSS_EIO;
+ }
+ if ((err =
+ oss_audio_open_engine (devc->hw_dev, OSS_DEV_DSP, &devc->finfo, 1, 0,
+ NULL)) < 0)
+ {
+ return err;
+ }
+ audio_engines[devc->hw_dev]->cooked_enable = 0;
+ strcpy (audio_engines[devc->hw_dev]->cmd, "IMUX");
+ audio_engines[devc->hw_dev]->pid = 0;
+
+ devc->hw_fmt =
+ oss_audio_set_format (devc->hw_dev, devc->hw_fmt,
+ audio_engines[devc->hw_dev]->iformat_mask);
+ devc->device_started = 1;
+ devc->hw_channels = 2;
+
+ devc->hw_channels =
+ oss_audio_set_channels (devc->hw_dev, devc->hw_channels);
+
+/*
+ * TODO: Turn off OPT_SHADOW flag from the virtual devices if the master device
+ * works in multi channel mode.
+ */
+ devc->hw_speed = oss_audio_set_rate (devc->hw_dev, devc->hw_speed);
+
+#if 0
+ oss_audio_ioctl (devc->hw_dev, NULL, SNDCTL_DSP_SETFRAGMENT,
+ (ioctl_arg) & frags);
+#endif
+ oss_audio_ioctl (devc->hw_dev, NULL, SNDCTL_DSP_GETBLKSIZE,
+ (ioctl_arg) & devc->fragsize);
+
+ if (!(devc->hw_fmt & SUPPORTED_FORMATS))
+ {
+ oss_audio_release (devc->hw_dev, &devc->finfo);
+ cmn_err (CE_WARN,
+ "This device doesn't support any known sample formats (%x)\n",
+ devc->hw_fmt);
+ return OSS_EIO;
+ }
+
+ switch (devc->hw_fmt)
+ {
+ case AFMT_S16_NE:
+ devc->sw_fmt = AFMT_S16_NE;
+ break;
+
+ case AFMT_S16_OE:
+ devc->sw_fmt = AFMT_S16_NE;
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Bad sample format %x\n", devc->hw_fmt);
+ }
+
+ nc = devc->hw_channels;
+ if (nc < 2)
+ {
+ oss_audio_release (devc->hw_dev, &devc->finfo);
+ cmn_err (CE_WARN, "A 2 channel soundcard (or better) is required\n");
+ return OSS_EIO;
+ }
+
+ DDB (cmn_err (CE_CONT, "Started audio device %d, s=%d, c=%d, bits=%d\n",
+ devc->hw_dev, devc->hw_speed, devc->hw_channels,
+ devc->hw_fmt));
+
+ trig = 0;
+ oss_audio_ioctl (devc->hw_dev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & trig);
+ trig = PCM_ENABLE_INPUT;
+ oss_audio_ioctl (devc->hw_dev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & trig);
+
+ devc->hw_fragsize = audio_engines[devc->hw_dev]->dmap_out->fragment_size;
+
+ for (i = 0; i < devc->nr_devices; i++)
+ {
+ int bz = (2 * devc->hw_fragsize) / devc->hw_channels;
+ dev = devc->portc[i].audio_dev;
+ audio_engines[dev]->fixed_rate = devc->hw_speed;
+ audio_engines[dev]->min_block = bz;
+ audio_engines[dev]->max_block = bz;
+ }
+ audio_engines[devc->hw_dev]->dmap_in->audio_callback = imux_callback;
+
+ return 1;
+}
+
+static void
+stop_device (imux_devc * devc)
+{
+ if (!devc->device_started)
+ return;
+
+ oss_audio_ioctl (devc->hw_dev, NULL, SNDCTL_DSP_HALT, 0);
+ oss_audio_release (devc->hw_dev, &devc->finfo);
+ audio_engines[devc->hw_dev]->pid = -1;
+ memset (audio_engines[devc->hw_dev]->cmd, 0,
+ sizeof (audio_engines[devc->hw_dev]->cmd));
+ audio_engines[devc->hw_dev]->flags &= ~ADEV_NOSRC;
+
+ devc->device_started = 0;
+}
+
+/*ARGSUSED*/
+static int
+imux_open (int dev, int mode, int open_flags)
+{
+ imux_portc *portc = audio_engines[dev]->portc;
+ imux_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ int bz, err;
+
+ if (devc->hw_dev < 0)
+ {
+ cmn_err (CE_NOTE, "No master device allocated\n");
+ return OSS_EIO;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->is_opened)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->is_opened = 1;
+ portc->is_prepared = 0;
+ portc->is_triggered = 0;
+ portc->channels = 2;
+ portc->ch_index = 0;
+ memset (portc->peaks, 0, sizeof (portc->peaks));
+ portc->fmt = AFMT_S16_NE;
+ audio_engines[dev]->rate_source = audio_engines[devc->hw_dev]->rate_source;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ if (!devc->device_started)
+ if ((err = start_device (devc)) < 0)
+ {
+ portc->is_opened = 0;
+ return err;
+ }
+
+ bz = (2 * devc->hw_fragsize) / devc->hw_channels;
+ audio_engines[dev]->min_block = audio_engines[dev]->max_block = bz;
+ portc->ch_index = portc->port_number % (devc->hw_channels / 2);
+ portc->speed = devc->hw_speed;
+
+ if (devc->autoreset)
+ {
+ portc->left_igain = 100;
+ portc->right_igain = 100;
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->open_count++;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+imux_close (int dev, int mode)
+{
+ imux_portc *portc = audio_engines[dev]->portc;
+ imux_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ int count;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->is_triggered = 0;
+ count = --devc->open_count;
+ /* MUTEX_EXIT_IRQRESTORE (devc->mutex, flags); */
+
+ if (count == 0) /* Last one? */
+ stop_device (devc);
+
+ /* MUTEX_ENTER_IRQDISABLE (devc->mutex, flags); */
+ portc->is_opened = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static void
+imux_output_block (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+imux_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+static void
+imux_trigger (int dev, int state)
+{
+ imux_portc *portc = audio_engines[dev]->portc;
+
+ if (state & PCM_ENABLE_INPUT)
+ portc->is_triggered = 1;
+ else
+ portc->is_triggered = 0;
+}
+
+/*ARGSUSED*/
+static int
+imux_prepare_for_input (int dev, int bsize, int bcount)
+{
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+imux_prepare_for_output (int dev, int bsize, int bcount)
+{
+ return OSS_EIO;
+}
+
+/*ARGSUSED*/
+static int
+imux_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+#define MY_BUFFSIZE (64*1024)
+ if (dmap->dmabuf != NULL)
+ return 0;
+ dmap->dmabuf_phys = 0; /* Not mmap() capable */
+ dmap->dmabuf = KERNEL_MALLOC (MY_BUFFSIZE);
+ if (dmap->dmabuf == NULL)
+ return OSS_ENOSPC;
+ dmap->buffsize = MY_BUFFSIZE;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+imux_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ if (dmap->dmabuf == NULL)
+ return 0;
+ KERNEL_FREE (dmap->dmabuf);
+
+ dmap->dmabuf = NULL;
+ return 0;
+}
+
+#if 0
+static int
+imux_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+}
+#endif
+
+static audiodrv_t imux_driver = {
+ imux_open,
+ imux_close,
+ imux_output_block,
+ imux_start_input,
+ imux_ioctl,
+ imux_prepare_for_input,
+ imux_prepare_for_output,
+ imux_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ imux_trigger,
+ imux_set_rate,
+ imux_set_format,
+ imux_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ imux_alloc_buffer,
+ imux_free_buffer,
+ NULL,
+ NULL,
+ NULL /* imux_get_buffer_pointer */
+};
+
+/*ARGSUSED*/
+static int
+imux_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static mixer_driver_t imux_mixer_driver = {
+ imux_mixer_ioctl
+};
+
+static const unsigned char peak_cnv[256] = {
+ 0, 18, 29, 36, 42, 47, 51, 54, 57, 60, 62, 65, 67, 69, 71, 72,
+ 74, 75, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 89, 90,
+ 91, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 100, 101,
+ 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
+ 108,
+ 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 113, 113, 113, 114, 114,
+ 114,
+ 115, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119,
+ 119,
+ 119, 119, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 122, 122, 123,
+ 123,
+ 123, 123, 124, 124, 124, 124, 125, 125, 125, 125, 125, 126, 126, 126, 126,
+ 126,
+ 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 129, 129, 129, 129, 129,
+ 130,
+ 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132,
+ 132,
+ 132, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 135,
+ 135,
+ 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 137, 137, 137,
+ 137,
+ 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139,
+ 139,
+ 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141,
+ 141,
+ 141, 141, 141, 141, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143,
+ 143,
+ 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, 144, 144, 144,
+ 144,
+};
+
+/*ARGSUSED*/
+static int
+imux_vu (int dev, int ctrl, unsigned int cmd, int value)
+{
+/*
+ * Access function for PCM VU meters
+ */
+ int left, right;
+ imux_devc *devc = mixer_devs[dev]->devc;
+
+ if (ctrl < 0 || ctrl >= devc->imux_devices)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ imux_portc *portc = &devc->portc[ctrl];
+ left = peak_cnv[(portc->peaks[0] * 144) / 32768];
+ right = peak_cnv[(portc->peaks[1] * 144) / 32768];
+ memset (portc->peaks, 0, sizeof (portc->peaks));
+ return left | (right << 8);
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+imux_mix_init (int dev)
+{
+ int group;
+ imux_devc *devc = mixer_devs[dev]->devc;
+ int i;
+ int err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "CLIENT")) < 0)
+ return group;
+
+ for (i = 0; i < devc->imux_devices; i++)
+ {
+ char tmp[32];
+
+ sprintf (tmp, "@pcm%d", devc->portc[i].audio_dev);
+
+ if ((err = mixer_ext_create_control (dev, group, i, imux_igain,
+ MIXT_STEREOSLIDER,
+ tmp, 100,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, i, imux_vu,
+ MIXT_STEREOPEAK,
+ "-", 144, MIXF_READABLE)) < 0)
+ return err;
+ }
+
+ if ((err = mixer_ext_create_control (dev, group, 100, imux_igain,
+ MIXT_ONOFF,
+ "autoreset", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ return 0;
+}
+
+static int
+find_master_device (imux_devc * devc)
+{
+/*
+ * Find a suitable master device.
+ *
+ * Return 1 if found and 0 if not.
+ */
+ int dev;
+ adev_p adev;
+
+ if (num_audio_devfiles < 1)
+ return 0;
+
+ if (devc->imux_masterdev >= 0)
+ {
+/*
+ * imux_masterdev property was given. Use the given /dev/dsp# number
+ * as the master device.
+ */
+ if (devc->imux_masterdev >= num_audio_devfiles)
+ return 0; /* Device not attached yet */
+ devc->hw_dev = audio_devfiles[devc->imux_masterdev]->engine_num;
+ adev = audio_engines[devc->hw_dev];
+
+ if (adev->flags & (ADEV_NOINPUT))
+ {
+ cmn_err (CE_NOTE,
+ "Audio device %d cannot be used as an IMUX master device\n",
+ devc->imux_masterdev);
+ devc->hw_dev = -1;
+ return 0;
+ }
+
+ devc->hw_dev = adev->engine_num;
+ /* TODO: Prevent the other virtual drivers from picking this one */
+ }
+ else
+ {
+/*
+ * Try to find if some of the devices currently available is suitable
+ * master device.
+ */
+ devc->hw_dev = -1;
+
+ for (dev = 0; dev < num_audio_engines; dev++)
+ {
+ adev = audio_engines[dev];
+
+ if (adev->flags & ADEV_NOINPUT)
+ continue;
+
+ if (used_masterdevs & (1LL << dev))
+ continue;
+
+ devc->hw_dev = adev->engine_num;
+ break;
+ }
+ }
+
+ return (devc->hw_dev >= 0);
+}
+
+static int
+try_to_start (void *dc)
+{
+ int n, adev, opts;
+ char tmp[32];
+ imux_devc *devc = dc;
+ int my_mixer;
+
+ if (!find_master_device (devc))
+ return 0;
+
+/*
+ * If the situation is hopeless then just tell the caller to stop
+ * trying this operation.
+ */
+ if (devc->hw_dev < 0)
+ return 1;
+
+ if (used_masterdevs & (1LL << devc->hw_dev))
+ {
+ devc->hw_dev = -1;
+ cmn_err (CE_WARN,
+ "Selected master device % for IMUX instance %d already used for some other instance\n",
+ devc->osdev->instance, devc->hw_dev);
+ return 1;
+ }
+
+ used_masterdevs |= (1LL << devc->hw_dev);
+
+ opts =
+ ADEV_STEREOONLY | ADEV_16BITONLY | ADEV_VIRTUAL | ADEV_NOOUTPUT |
+ ADEV_FIXEDRATE | ADEV_NOMMAP;
+
+ devc->nr_devices = 0;
+ devc->open_count = 0;
+
+ devc->hw_speed = devc->imux_rate;
+ devc->master_osdev = audio_engines[devc->hw_dev]->osdev;
+ devc->installed_ok = 1;
+ devc->autoreset = 1;
+ MUTEX_INIT (devc->master_osdev, devc->mutex, MH_DRV + 4);
+
+ if ((my_mixer = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->master_osdev,
+ "IMUX Control panel",
+ &imux_mixer_driver,
+ sizeof (mixer_driver_t), devc)) >= 0)
+ {
+ mixer_ext_set_init_fn (my_mixer, imux_mix_init, 32);
+ }
+ else
+ my_mixer = -1;
+
+ devc->mixer_dev = my_mixer;
+
+ for (n = 0; n < devc->imux_devices; n++)
+ {
+ imux_portc *portc;
+
+ if (n > 0)
+ opts |= ADEV_SHADOW;
+
+ sprintf (tmp, "IMux%d audio record", devc->instance_no);
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->master_osdev,
+ tmp,
+ &imux_driver,
+ sizeof (audiodrv_t),
+ opts, AFMT_S16_NE, devc, -1)) < 0)
+ {
+ return 1;
+ }
+
+ portc = &devc->portc[n];
+
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = 192000;
+ portc->left_igain = 100;
+ portc->right_igain = 100;
+
+ portc->audio_dev = adev;
+ portc->is_opened = 0;
+ portc->is_prepared = 0;
+ portc->is_triggered = 0;
+ portc->speed = 48000;
+ portc->channels = 2;
+ portc->fmt = AFMT_S16_NE;
+ portc->port_number = n;
+
+ devc->nr_devices = n + 1;
+ }
+
+ return 1;
+}
+
+
+int
+oss_imux_attach (oss_device_t * osdev)
+{
+ extern int imux_devices;
+ extern int imux_masterdev;
+ extern int imux_rate;
+ imux_devc *devc;
+
+ if (imux_devices < 2)
+ imux_devices = 2;
+ if (imux_devices > MAX_IMUX_DEV)
+ imux_devices = MAX_IMUX_DEV;
+
+ if (nimuxdevs >= MAX_IMUX_INSTANCES)
+ {
+ cmn_err (CE_NOTE, "Only %d instances permitted\n", MAX_IMUX_INSTANCES);
+ return 0;
+ }
+
+ devc = &imux_info[nimuxdevs++];
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ devc->master_osdev = NULL;
+ devc->instance_no = osdev->instance;
+ devc->imux_devices = imux_devices;
+ devc->imux_rate = imux_rate;
+ devc->imux_masterdev = imux_masterdev;
+ imux_masterdev = -1;
+ devc->hw_dev = -1;
+ devc->sw_fmt = AFMT_S16_NE;
+
+ oss_register_device (osdev, "OSS IMUX driver");
+
+ if (!try_to_start (devc))
+ {
+ oss_audio_register_client (try_to_start, devc, devc->osdev);
+ }
+
+ return 1;
+}
+
+int
+oss_imux_detach (oss_device_t * osdev)
+{
+ imux_devc *devc = osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ if (devc->installed_ok)
+ {
+ MUTEX_CLEANUP (devc->mutex);
+ }
+
+ oss_unregister_device (devc->osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_imux/oss_imux.man b/kernel/drv/oss_imux/oss_imux.man
new file mode 100644
index 0000000..4d64206
--- /dev/null
+++ b/kernel/drv/oss_imux/oss_imux.man
@@ -0,0 +1,78 @@
+NAME
+oss_imux - Input Muplexer audio driver.
+
+DESCRIPTION
+IMUX is a virtual recording engine that permits up to 8 audio recording
+applications to run at the same time. Generally most soundcards permit only a
+single recording application to record the input source (via mic, line or CD).
+With IMUX, you can use up to 8 recording applications to record the same
+source in different sample rates, bits/sample and channels (mono/stereo).
+IMUX does all the rate and format conversion in software. The applications
+think that they are actually getting data from the physical device. For
+instance, if you want to record the input from a CDROM in .wav format at
+48Khz/8/Mono and at the same time you want to record the same stream in .mp3
+format in 44.1Khz 16 bit stereo, with IMUX, you can start the wave recording
+application on the first IMUX device and start the MP3 encoder on the second
+IMUX device and both applications will run simultaneously thinking that they
+are getting data from the physical soundcard.
+
+CONFIGURATION
+To add the IMUX driver you first need to ensure that there is a physical
+soundcard present and then you can run ossdetect -i to add it. You may want
+to select a master device by setting imux_masterdev, but the autodetection
+should provide a good default. After OSS restart, imux should be available.
+
+USAGE
+Connect an input source to the soundcard's line-in jack. Using the Mixer app
+like ossmix (or any OSS compliant mixer) set the recording source to Line-In
+(eg ossmix line.rec ON) Now you can start recording the input in multiple
+formats and at different sample rates. The simplest example is:
+
+ ossrecord -s48000 -b16 -c2 -d/dev/oss/oss_imux0/pcmin0 test1.wav &
+ ossrecord -s8000 -b8 -d/dev/oss/oss_imux0/pcmin0 test2.wav &
+
+After a few minutes of recording you can stop them by placing the command in
+forground mode (type fg %1 or fg %2) and press ^c to stop.
+
+You now have two wav format files. test1.wav is a 48KHz 16bit stereo file and
+test2.wav is a 8Khz 8bit Mono file.
+
+You can now playback the files as follows:
+o ossplay -v test1.wav and it should show you that the file is indeed
+48Khz 16bit stereo.
+
+o ossplay -v test2.wav - you should see that this file is indeed a
+8Khz 8bit mono file.
+
+What you have essentially accomplished is recording a single input stream into
+two different formats at the same time.
+
+You can now extend this analogy to record the input in mp3 format and RealAudio
+format simultaneously.
+
+The IMUX control panel can be displayed by typing ossxmix -d<imux mixer number>
+(for e.g. in the above example, IMUX mixer is #2 so we type ossxmix -d2
+
+There are record level control sliders for each input channel and it will show
+activity when a recording program is active on a particular channel.
+
+
+OPTIONS
+o imux_masterdev: Selects which physical device to use as the Master device
+for the IMUX driver.
+Values: -1: automatically selected by OSS, 1-N: Audio device index of the
+master device (as reported by ossinfo -a), Default: -1.
+
+o imux_rate: Specifies what is the base sampling rate used by the imux driver.
+Values: 5000-96000 Default: 48000
+
+o imux_devices: Specifies number of Input Multiplexer devices to setup.
+Values: 2-48 Default: 5
+
+
+FILES
+CONFIGFILEPATH/oss_imux.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_madi/.devices b/kernel/drv/oss_madi/.devices
new file mode 100644
index 0000000..c282a96
--- /dev/null
+++ b/kernel/drv/oss_madi/.devices
@@ -0,0 +1 @@
+oss_madi pci10ee,3fc6 RME MADI (not supported yet)
diff --git a/kernel/drv/oss_madi/.name b/kernel/drv/oss_madi/.name
new file mode 100644
index 0000000..a776e0b
--- /dev/null
+++ b/kernel/drv/oss_madi/.name
@@ -0,0 +1 @@
+RME MADI Digital Interface
diff --git a/kernel/drv/oss_madi/.params b/kernel/drv/oss_madi/.params
new file mode 100644
index 0000000..9a9907e
--- /dev/null
+++ b/kernel/drv/oss_madi/.params
@@ -0,0 +1,12 @@
+int madi_maxchannels=64;
+/*
+ * By default OSS will create device files for all 64 channels (32 stereo
+ * pairs). Number of channels can be decreased by changing this parameter.
+ */
+int madi_devsize=2;
+/*
+ * This parameter tells how the device files should be created for MADI
+ * channels. By default (2) a device file will be created for each stereo
+ * channel pair. Value of 1 means that separate device file will be
+ * created for each channel.
+ */
diff --git a/kernel/drv/oss_madi/madi.h b/kernel/drv/oss_madi/madi.h
new file mode 100644
index 0000000..3cdd172
--- /dev/null
+++ b/kernel/drv/oss_madi/madi.h
@@ -0,0 +1,246 @@
+/*
+ * Purpose: Internal definitions for RME MADI and AES32 audio interfaces
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+
+/*
+ * DMA buffer size (for one direction)
+ */
+#define MAX_CHANNELS 64
+#define CHBUF_SIZE (64*1024) // 64k / channel
+#define CHBUF_PAGES (CHBUF_SIZE/4096)
+#define DMABUF_SIZE (MAX_CHANNELS*CHBUF_SIZE) // 4 Mbytes (total)
+
+
+/*
+ * Monitor mixer channel
+ */
+#define MONITOR_CH 64 // ???
+
+/*
+ * Registers
+ */
+#define MADI_control 64
+#define MADI_interruptAck 96
+#define MADI_control2 256
+#define MADI_freq 256 /* AES32 only */
+#define MADI_midiOut0 352
+#define MADI_midiOut1 356
+#define MADI_eeprom 384 /* AES32 only */
+#define MADI_outputEnableStart 512
+#define MADI_inputEnableStart 768
+#define MADI_PlayPageTable 8192
+#define MADI_RecPageTable 12288 /* 12k */
+#define MADI_MATRIX_MIXER_SIZE 8192
+#define MADI_mixerStart 32768
+
+#define MADI_status 0
+#define MADI_status2 192
+#define MADI_timecode 128
+#define MADI_midiIn0 360
+#define MADI_midiIn1 364
+#define MADI_midiStatusOut0 384
+#define MADI_midiStatusOut1 388
+#define MADI_midiStatusIn0 392
+#define MADI_midiStatusIn1 396
+#define MADI_peakrmsStart 4096
+#define MADI_inpeaks (1024*4)
+#define MADI_playpeaks (MADI_inpeaks+64*4)
+#define MADI_outpeaks (MADI_playpeaks+64*4)
+
+/*
+ * Control register bits
+ */
+#define MADI_Start (1<<0)
+#define MADI_Latency0 (1<<1)
+#define MADI_Latency1 (1<<2)
+#define MADI_Latency2 (1<<3)
+#define MADI_ClockModeMaster (1<<4)
+#define MADI_AudioInterruptEnable (1<<5)
+
+#define MADI_Freq0 (1<<6)
+#define MADI_Freq1 (1<<7)
+#define MADI_DblSpeed (1<<8)
+#define MADI_QuadSpeed (1U<<31)
+
+#define MADI_ProBit (1<<9) // AES32
+
+#define MADI_TX_64ch_mode (1<<10) // MADI
+#define MADI_Emphasis (1<<10) // AES32
+
+#define MADI_AutoInput (1<<11) // MADI
+#define MADI_DataBit (1<<11) // AES32
+
+#define MADI_InputSrc0 (1<<14) // MADI
+#define MADI_InputSrc1 (1<<15)
+#define MADI_SyncSrc0 (1<<16)
+#define MADI_SyncSrc1 (1<<17) // AES32
+#define MADI_SyncSrc2 (1<<13) // AES32
+#define MADI_SyncSrc3 (1<<25) // AES32
+#define MADI_SMUX (1<<18) // MADI
+#define MADI_clr_tms (1<<19)
+
+#define MADI_taxi_reset (1<<20) // MADI
+#define MADI_WCK48 (1<<20) // AES32
+
+#define MADI_Midi0IntrEna (1<<22)
+#define MADI_Midi1IntrEna (1<<23)
+
+#define MADI_LineOut (1<<24)
+
+#define MADI_DS_2Wire (1<<26) // AES32
+#define MADI_QS_2Wire (1<<27) // AES32
+#define MADI_QS_4Wire (1<<28) // AES32
+
+#define MADI_wclk_sel (1<<30)
+
+/*
+ * Control2 register bits
+ */
+#define MADI_BIGENDIAN_MODE (1<<9)
+
+/*
+ * Helper macros for the command register
+ */
+#define MADI_FreqMask (MADI_Freq0|MADI_Freq1|\
+ MADI_DblSpeed|MADI_QuadSpeed)
+
+#define MADI_LatencyMask (MADI_Latency0|MADI_Latency1|MADI_Latency2)
+
+#define MADI_InputMask (MADI_InputSrc0|MADI_InputSrc1)
+#define MADI_InputOptical 0
+#define MADI_InputCoax (MADI_InputSrc0)
+#define MADI_SyncRefMask (MADI_SyncSrc0|MADI_SyncSrc1|\
+ MADI_SyncSrc2|MADI_SyncSrc3)
+#define MADI_SyncRef_Word 0
+#define MADI_SyncRef_MADI (MADI_SyncSrc0)
+
+/*
+ * Status register bits
+ */
+#define MADI_audioIntPending (1<<0)
+#define MADI_RX_64ch_mode (1<<1)
+#define MADI_AB_int (1<<2)
+#define MADI_LockStatus (1<<3)
+#define MADI_BufferPosMask 0x000FFC0
+#define MADI_madiSync (1<<18)
+#define MADI_DblSpeedStatus (1<<19)
+
+#define MADI_Freq0_status (1<<22)
+#define MADI_Freq1_status (1<<23)
+#define MADI_Freq2_status (1<<24)
+#define MADI_Freq3_status (1<<25)
+
+#define MADI_BufferHalf (1<<26)
+
+#define MADI_midi0IRQStatus (1<<30)
+#define MADI_midi1IRQStatus (1U<<31)
+
+#define UNITY_GAIN 32768
+#define MUTE_GAIN 0
+
+typedef struct
+{
+ int open_mode;
+ unsigned int trigger_bits;
+ int direction;
+#define DIR_IN PCM_ENABLE_INPUT
+#define DIR_OUT PCM_ENABLE_OUTPUT
+ int channel; /* Index to the first channel */
+
+ int audio_dev;
+
+ int max_channels;
+ int channels; /* Number of channels */
+} madi_portc_t;
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+ char *name;
+
+ int model;
+#define MDL_MADI 0
+#define MDL_AES32 1
+
+ char *registers;
+ oss_native_word physaddr;
+
+ unsigned int cmd, cmd2; // Cached control/control2 register values
+
+ /* Sample rate, etc. */
+ unsigned int rate, next_rate;
+ unsigned long long active_inputs, active_outputs; /* Bitmasks indexed by ch# */
+
+ /* Mixer */
+ int mixer_dev;
+
+ /* Shadow of the hw mixer gain registers */
+ unsigned short mixer_values[MAX_CHANNELS][2 * MAX_CHANNELS];
+
+ /* Playback */
+ unsigned char *playbuf;
+ oss_native_word playbuf_phys;
+ oss_dma_handle_t play_dma_handle;
+ int num_outputs;
+ madi_portc_t *out_portc[MAX_CHANNELS];
+ unsigned long long busy_play_channels;
+
+ /* Recording */
+ unsigned char *recbuf;
+ oss_native_word recbuf_phys;
+ oss_dma_handle_t rec_dma_handle;
+ int num_inputs;
+ madi_portc_t *in_portc[MAX_CHANNELS];
+ unsigned long long busy_rec_channels;
+
+ volatile int open_audiodevs; /* Number of audio input/output devices currently open */
+ int first_audiodev;
+} madi_devc_t;
+
+static __inline__ void
+madi_write (madi_devc_t * devc, int reg, unsigned int value)
+{
+ PCI_WRITEL (devc->osdev, devc->registers + reg, value);
+}
+
+static __inline__ unsigned int
+madi_read (madi_devc_t * devc, int reg)
+{
+ return PCI_READL (devc->osdev, devc->registers + reg);
+}
+
+static __inline__ void
+madi_control (madi_devc_t * devc, unsigned int value)
+{
+ madi_write (devc, MADI_control, value);
+ devc->cmd = value;
+}
+
+static __inline__ void
+madi_control2 (madi_devc_t * devc, unsigned int value)
+{
+ madi_write (devc, MADI_control2, value);
+ devc->cmd2 = value;
+}
+
+#define SRC_IN 0
+#define SRC_PLAY 64
+extern void madi_write_gain (madi_devc_t * devc, unsigned int chn,
+ unsigned int src, unsigned short value);
+extern int madi_read_gain (madi_devc_t * devc, unsigned int chn,
+ unsigned int src);
+extern int madi_install_mixer (madi_devc_t * devc);
+extern void madi_activate_mixer (madi_devc_t * devc);
diff --git a/kernel/drv/oss_madi/madi_mixer.c b/kernel/drv/oss_madi/madi_mixer.c
new file mode 100644
index 0000000..8882fa7
--- /dev/null
+++ b/kernel/drv/oss_madi/madi_mixer.c
@@ -0,0 +1,459 @@
+/*
+ * Purpose: Mixer/control panel for RME MADI and AES32 audio interfaces
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_madi_cfg.h"
+#include "oss_pci.h"
+#include "madi.h"
+
+extern int madi_maxchannels;
+
+static const unsigned char peak_cnv[256] = {
+ 0, 18, 29, 36, 42, 47, 51, 54, 57, 60, 62, 65, 67, 69, 71, 72,
+ 74, 75, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 89, 90,
+ 91, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 100, 101,
+ 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
+ 108,
+ 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 113, 113, 113, 114, 114,
+ 114,
+ 115, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119,
+ 119,
+ 119, 119, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 122, 122, 123,
+ 123,
+ 123, 123, 124, 124, 124, 124, 125, 125, 125, 125, 125, 126, 126, 126, 126,
+ 126,
+ 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 129, 129, 129, 129, 129,
+ 130,
+ 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132,
+ 132,
+ 132, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 135,
+ 135,
+ 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 137, 137, 137,
+ 137,
+ 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139,
+ 139,
+ 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141,
+ 141,
+ 141, 141, 141, 141, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143,
+ 143,
+ 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, 144, 144, 144,
+ 144,
+};
+
+void
+madi_write_gain (madi_devc_t * devc, unsigned int chn, unsigned int src,
+ unsigned short value)
+{
+/*
+ * Write gain value to a mixer register. Parameter chn selects the output
+ * channel. Parameter src is the signal source. If (src & SRC_PLAY) then set
+ * the audio (DMA) playback volume (pcm[src]->out[chn]). Otherwise set
+ * the input[src]->out[chn] volume
+ */
+
+ if (chn >= MAX_CHANNELS || src >= (SRC_PLAY + MAX_CHANNELS))
+ return;
+
+ madi_write (devc, MADI_mixerStart + (src + 128 * chn) * 4, value);
+ devc->mixer_values[chn][src] = value;
+}
+
+int
+madi_read_gain (madi_devc_t * devc, unsigned int chn, unsigned int src)
+{
+ if (chn >= MAX_CHANNELS || src >= (SRC_PLAY + MAX_CHANNELS))
+ return 0;
+
+ return devc->mixer_values[chn][src];
+}
+
+static int
+madi_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+#if 0
+/*
+ * Dummy mixer. Some broken applications require this.
+ */
+
+ if (cmd == SOUND_MIXER_READ_CAPS)
+ return *arg = SOUND_CAP_NOLEGACY;
+
+ if (cmd == SOUND_MIXER_READ_DEVMASK ||
+ cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC)
+ return *arg = 0;
+
+ if (cmd == SOUND_MIXER_READ_VOLUME || cmd == SOUND_MIXER_READ_PCM)
+ return *arg = 100 | (100 << 8);
+ if (cmd == SOUND_MIXER_WRITE_VOLUME || cmd == SOUND_MIXER_WRITE_PCM)
+ return *arg = 100 | (100 << 8);
+#endif
+ return OSS_EINVAL;
+}
+
+ /*ARGSUSED*/ static int
+get_peak (int dev, int ctrl, unsigned int cmd, int value)
+{
+ madi_devc_t *devc = mixer_devs[dev]->devc;
+ unsigned int v;
+
+ if (cmd != SNDCTL_MIX_READ)
+ return OSS_EINVAL;
+
+ v = madi_read (devc, ctrl) >> 24; // Left channel
+ value = peak_cnv[v & 0xff];
+
+ v = madi_read (devc, ctrl + 4) >> 24; // Right channel
+ value |= peak_cnv[v & 0xff] << 8;
+
+ return value;
+}
+
+ /*ARGSUSED*/ static int
+vol_slider (int dev, int ctrl, unsigned int cmd, int value)
+{
+ madi_devc_t *devc = mixer_devs[dev]->devc;
+ unsigned int v;
+ int chn, src;
+
+ chn = (ctrl >> 8) & 0xff;
+ src = ctrl & 0xff;
+
+ if (chn >= MAX_CHANNELS || src >= 2 * MAX_CHANNELS)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ // Left channel
+ v = devc->mixer_values[chn][src];
+ if (v > 0)
+ v--;
+ value = v & 0xffff;
+
+ // Right channel
+ v = devc->mixer_values[chn + 1][src + 1];
+ if (v > 0)
+ v--;
+ value |= (v & 0xffff) << 16;
+
+ return value;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ // Left channel
+ v = value & 0xffff;
+ if (v > UNITY_GAIN)
+ v = UNITY_GAIN;
+ if (v > 0)
+ v++;
+ madi_write_gain (devc, chn, src, v);
+
+ // Right channel
+ v = (value >> 16) & 0xffff;
+ if (v > UNITY_GAIN)
+ v = UNITY_GAIN;
+ if (v > 0)
+ v++;
+ madi_write_gain (devc, chn + 1, src + 1, v);
+
+ return value;
+ }
+
+ return OSS_EINVAL;
+}
+
+ /*ARGSUSED*/ static int
+madi_set_ctl (int dev, int ctrl, unsigned int cmd, int value)
+{
+ madi_devc_t *devc = mixer_devs[dev]->devc;
+ unsigned int status;
+
+ if (cmd == SNDCTL_MIX_READ)
+ switch (ctrl)
+ {
+ case 0: /* Buffer size */
+ return (devc->cmd & MADI_LatencyMask) >> 1;
+ break;
+
+ case 1: /* Sync locked status */
+ status = madi_read (devc, MADI_status);
+ return !!(status & MADI_LockStatus);
+ break;
+
+ case 2: /* Input source (Optical/Coax) */
+ return !!(devc->cmd & MADI_InputSrc0);
+ break;
+
+ case 3: /* Clock source */
+ return !(devc->cmd & MADI_ClockModeMaster);
+ break;
+
+ case 4: /* Preferred sync reference */
+ return !!(devc->cmd & MADI_SyncRef_MADI);
+ break;
+
+ case 5: /* Safe Mode (auto input) */
+ return !!(devc->cmd & MADI_AutoInput);
+ break;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ switch (ctrl)
+ {
+ case 0: /* Buffer size */
+ if (devc->busy_play_channels || devc->busy_rec_channels) /* Device busy */
+ return (devc->cmd & MADI_LatencyMask) >> 1;
+
+ if (value < 0 || value > 7)
+ return OSS_EINVAL;
+
+ devc->cmd &= ~MADI_LatencyMask;
+ devc->cmd |= value << 1;
+ madi_control (devc, devc->cmd);
+ return value;
+ break;
+
+ case 2: /* Input source (Optical/Coax) */
+ value = !!value;
+ if (value)
+ madi_control (devc, devc->cmd | MADI_InputSrc0);
+ else
+ madi_control (devc, devc->cmd & ~MADI_InputSrc0);
+ return value;
+ break;
+
+ case 3: /* Clock source */
+ value = !!value;
+ if (!value)
+ madi_control (devc, devc->cmd | MADI_ClockModeMaster);
+ else
+ madi_control (devc, devc->cmd & ~MADI_ClockModeMaster);
+ return value;
+ break;
+
+ case 4: /* Preferred sync reference */
+ value = !!value;
+ if (value)
+ madi_control (devc, devc->cmd | MADI_SyncRef_MADI);
+ else
+ madi_control (devc, devc->cmd & ~MADI_SyncRef_MADI);
+ return value;
+ break;
+
+ case 5: /* Safe Mode (auto input) */
+ if (value)
+ madi_control (devc, devc->cmd | MADI_AutoInput);
+ else
+ madi_control (devc, devc->cmd & ~MADI_AutoInput);
+ return value;
+ break;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+madi_mix_init (int dev)
+{
+ int i;
+ madi_devc_t *devc = mixer_devs[dev]->devc;
+ char tmp[16];
+ int err, ctl;
+ int group = 0;
+
+/*
+ * Common controls
+ */
+
+ if ((ctl = mixer_ext_create_control (dev, 0,
+ 3,
+ madi_set_ctl,
+ MIXT_ENUM, "clock", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "master autosync", 0);
+
+ if (devc->model == MDL_MADI)
+ {
+ if ((ctl = mixer_ext_create_control (dev, 0,
+ 4,
+ madi_set_ctl,
+ MIXT_ENUM, "syncref", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "WordClock MADI-in", 0);
+ }
+
+ if (devc->model == MDL_MADI)
+ {
+ if ((ctl = mixer_ext_create_control (dev, 0,
+ 2,
+ madi_set_ctl,
+ MIXT_ENUM, "input", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "optical coax", 0);
+ }
+
+ if (devc->model == MDL_MADI)
+ {
+ if ((ctl = mixer_ext_create_control (dev, 0,
+ 5,
+ madi_set_ctl,
+ MIXT_ONOFF, "safe-input", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ }
+
+ if ((ctl = mixer_ext_create_control (dev, 0,
+ 0,
+ madi_set_ctl,
+ MIXT_ENUM, "buffer", 8,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl, "64 128 256 512 1k 2k 4k 8k", 0);
+
+ if ((ctl = mixer_ext_create_control (dev, 0,
+ 1,
+ madi_set_ctl,
+ MIXT_VALUE, "lock", 2,
+ MIXF_OKFAIL | MIXF_READABLE |
+ MIXF_POLL)) < 0)
+ return ctl;
+
+ /*
+ * Input mixer
+ */
+
+ for (i = 0; i < madi_maxchannels; i += 2)
+ {
+ int offs = MADI_inpeaks + i * 4;
+ int ctl;
+
+ if (!(i % 32))
+ if ((group = mixer_ext_create_group (dev, 0, "in")) < 0)
+ return group;
+
+ ctl = (i << 8) | (SRC_IN | i);
+
+ sprintf (tmp, "%d-%d", i + 1, i + 2);
+ if ((err =
+ mixer_ext_create_control (dev, group, ctl, vol_slider,
+ MIXT_STEREOSLIDER16, tmp, UNITY_GAIN - 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ if ((err =
+ mixer_ext_create_control (dev, group, offs, get_peak,
+ MIXT_STEREOPEAK, "-", 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return err;
+ }
+
+ /*
+ * Playback (pcm) mixer
+ */
+ for (i = 0; i < devc->num_outputs; i++)
+ {
+ int offs = MADI_playpeaks;
+ int ctl, ch;
+ madi_portc_t *portc = devc->out_portc[i];
+
+ ch = portc->channel;
+ offs += ch * 4;
+
+ if (!(i % 16))
+ if ((group = mixer_ext_create_group (dev, 0, "play")) < 0)
+ return group;
+
+ ctl = (ch << 8) | (SRC_PLAY | ch);
+
+ if ((err =
+ mixer_ext_create_control (dev, group, offs, get_peak,
+ MIXT_STEREOPEAK, "-", 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return err;
+
+ sprintf (tmp, "@pcm%d", portc->audio_dev);
+ if ((err =
+ mixer_ext_create_control (dev, group, ctl, vol_slider,
+ MIXT_STEREOSLIDER16, tmp, UNITY_GAIN - 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+
+ /*
+ * Output mixer
+ */
+ for (i = 0; i < madi_maxchannels; i += 2)
+ {
+ int offs = MADI_outpeaks + i * 4;
+
+ if (!(i % 64))
+ if ((group = mixer_ext_create_group (dev, 0, "out")) < 0)
+ return group;
+
+ sprintf (tmp, "%d-%d", i + 1, i + 2);
+ if ((err =
+ mixer_ext_create_control (dev, group, offs, get_peak,
+ MIXT_STEREOPEAK, tmp, 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return err;
+ }
+
+#if 0
+ /*
+ * Analog monitor
+ */
+ {
+ int offs = MADI_outpeaks + MONITOR_CH * 4;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, offs, get_peak,
+ MIXT_STEREOPEAK, "mon", 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return err;
+ }
+#endif
+
+ return 0;
+}
+
+static mixer_driver_t madi_mixer_driver = {
+ madi_mixer_ioctl
+};
+
+int
+madi_install_mixer (madi_devc_t * devc)
+{
+ int my_mixer;
+
+ if ((my_mixer = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ devc->name,
+ &madi_mixer_driver,
+ sizeof (mixer_driver_t), devc)) < 0)
+ return my_mixer;
+
+ mixer_devs[my_mixer]->priority = -1; /* Don't use as the default mixer */
+
+ return my_mixer;
+}
+
+void
+madi_activate_mixer (madi_devc_t * devc)
+{
+ mixer_ext_set_init_fn (devc->mixer_dev, madi_mix_init, madi_maxchannels*5 + 30);
+ touch_mixer (devc->mixer_dev);
+}
diff --git a/kernel/drv/oss_madi/oss_madi.c b/kernel/drv/oss_madi/oss_madi.c
new file mode 100644
index 0000000..8f0f2fa
--- /dev/null
+++ b/kernel/drv/oss_madi/oss_madi.c
@@ -0,0 +1,975 @@
+/*
+ * Purpose: Driver for RME MADI and AES32 audio interfaces
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_madi_cfg.h"
+#include "oss_pci.h"
+#include "madi.h"
+
+#define RME_VENDOR_ID 0x10ee /* Xilinx actually */
+#define RME_MADI 0x3fc6
+
+#define HWINFO_SIZE 128
+
+extern int madi_devsize;
+extern int madi_maxchannels;
+
+#define LSWAP(x) x
+
+static void
+set_output_enable (madi_devc_t * devc, unsigned int chn, int enabled)
+{
+ madi_write (devc, MADI_outputEnableStart + 4 * chn, enabled);
+}
+
+static void
+set_input_enable (madi_devc_t * devc, unsigned int chn, int enabled)
+{
+ madi_write (devc, MADI_inputEnableStart + 4 * chn, enabled);
+}
+
+static void
+start_audio (madi_devc_t * devc)
+{
+ madi_control (devc, devc->cmd | (MADI_AudioInterruptEnable | MADI_Start));
+}
+
+static void
+stop_audio (madi_devc_t * devc)
+{
+ madi_control (devc, devc->cmd & ~(MADI_AudioInterruptEnable | MADI_Start));
+}
+
+static void
+audio_interrupt (madi_devc_t * devc, unsigned int status)
+{
+ int i;
+
+ for (i = 0; i < devc->num_outputs; i++)
+ {
+ madi_portc_t *portc = devc->out_portc[i];
+
+ if (!(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ continue;
+
+ oss_audio_outputintr (portc->audio_dev, 1);
+ }
+
+ for (i = 0; i < devc->num_inputs; i++)
+ {
+ madi_portc_t *portc = devc->in_portc[i];
+
+ if (!(portc->trigger_bits & PCM_ENABLE_INPUT))
+ continue;
+
+ oss_audio_inputintr (portc->audio_dev, 1);
+ }
+}
+
+static int
+madiintr (oss_device_t * osdev)
+{
+ madi_devc_t *devc = osdev->devc;
+ unsigned int status;
+
+ status = madi_read (devc, MADI_status);
+
+ if (status & MADI_audioIntPending)
+ audio_interrupt (devc, status);
+
+ madi_write (devc, MADI_interruptAck, 0);
+
+ return !!(status &
+ (MADI_audioIntPending | MADI_midi0IRQStatus | MADI_midi1IRQStatus))
+ != 0;
+}
+
+static void
+madi_change_hw_rate (madi_devc_t * devc)
+{
+ unsigned int rate_bits = 0;
+ unsigned long long v;
+
+ devc->rate = devc->next_rate;
+ /*
+ * Compute and set the sample rate in control2 register.
+ */
+
+ rate_bits = MADI_Freq1; // TODO
+
+ devc->cmd &= ~MADI_FreqMask;
+ devc->cmd |= rate_bits;
+
+ madi_control (devc, devc->cmd);
+
+ /*
+ * Compute and set the DDS value
+ */
+ v = 110100480000000ULL / (unsigned long long) devc->rate;
+ madi_write (devc, MADI_freq, (unsigned int) v);
+}
+
+static void
+initialize_hardware (madi_devc_t * devc)
+{
+ int chn, src;
+
+/*
+ * Intialize the control register
+ */
+ devc->cmd = MADI_ClockModeMaster | MADI_LatencyMask | MADI_LineOut;
+
+ if (devc->model == MDL_AES32)
+ devc->cmd |= MADI_SyncSrc0 | MADI_ProBit;
+ else
+ devc->cmd |=
+ MADI_InputCoax | MADI_SyncRef_MADI | MADI_TX_64ch_mode | MADI_AutoInput;
+
+ madi_control (devc, devc->cmd);
+
+/*
+ * Set all input and output engines to stoped
+ */
+ for (chn = 0; chn < MAX_CHANNELS; chn++)
+ {
+ set_output_enable (devc, chn, 0);
+ set_input_enable (devc, chn, 0);
+ }
+
+/*
+ * Init control2 register
+ */
+ if (devc->model == MDL_MADI)
+#ifdef OSS_BIG_ENDIAN
+ madi_control2 (devc, MADI_BIGENDIAN_MODE);
+#else
+ madi_control2 (devc, 0x0);
+#endif
+
+ madi_change_hw_rate (devc);
+
+/*
+ * Write all HW mixer registers
+ */
+
+ for (chn = 0; chn < MAX_CHANNELS; chn++)
+ for (src = 0; src < 2 * MAX_CHANNELS; src++)
+ madi_write_gain (devc, chn, src, devc->mixer_values[chn][src]);
+}
+
+static int
+madi_set_rate (int dev, int arg)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+
+ return devc->rate;
+}
+
+static __inline__ void
+reserve_rec_channels(madi_devc_t *devc, int c, int nc)
+{
+ int ch;
+
+ for (ch=c;ch < c+nc;ch++)
+ devc->busy_rec_channels |= (1ULL << ch);
+}
+
+static __inline__ void
+free_rec_channels(madi_devc_t *devc, int c, int nc)
+{
+ int ch;
+
+ for (ch=c;ch < c+nc;ch++)
+ devc->busy_rec_channels &= ~(1ULL << ch);
+}
+
+static __inline__ int
+rec_channels_avail(madi_devc_t *devc, int c, int nc)
+{
+ int ch;
+
+ for (ch=c;ch < c+nc;ch++)
+ if (devc->busy_rec_channels & (1ULL << ch))
+ return 0;
+
+ return 1;
+}
+
+static __inline__ void
+reserve_play_channels(madi_devc_t *devc, int c, int nc)
+{
+ int ch;
+
+ for (ch=c;ch < c+nc;ch++)
+ devc->busy_play_channels |= (1ULL << ch);
+}
+
+static __inline__ void
+free_play_channels(madi_devc_t *devc, int c, int nc)
+{
+ int ch;
+
+ for (ch=c;ch < c+nc;ch++)
+ devc->busy_play_channels &= ~(1ULL << ch);
+}
+
+static __inline__ int
+play_channels_avail(madi_devc_t *devc, int c, int nc)
+{
+ int ch;
+
+ for (ch=c;ch < c+nc;ch++)
+ if (devc->busy_play_channels & (1ULL << ch))
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+static short
+madi_set_channels (int dev, short arg)
+{
+ madi_portc_t *portc = audio_engines[dev]->portc;
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ int ok=1;
+
+ if (arg < 1)
+ return portc->channels;
+
+ if (arg != 1 && arg != 2 && arg != 4 && arg != 8 && arg != 16 && arg != 32
+ && arg != 64)
+ return portc->channels;
+
+ if (arg > portc->max_channels)
+ return portc->channels;
+
+ if (arg == portc->channels)
+ return portc->channels;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (arg > portc->channels) /* Needs more channels */
+ {
+ if (portc->direction == DIR_OUT)
+ {
+ if (!play_channels_avail(devc, portc->channel+portc->channels, arg - portc->channels))
+ ok=0;
+ }
+ else
+ {
+ if (!rec_channels_avail(devc, portc->channel+portc->channels, arg - portc->channels))
+ ok=0;
+ }
+ }
+ else
+ {
+ if (portc->direction == DIR_OUT)
+ {
+ free_play_channels(devc, portc->channel+arg, portc->channels-arg);
+ }
+ else
+ {
+ free_rec_channels(devc, portc->channel+arg, portc->channels-arg);
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (!ok)
+ return portc->channels;
+
+ return portc->channels = arg;
+}
+
+ /*ARGSUSED*/ static unsigned int
+madi_set_format (int dev, unsigned int arg)
+{
+ return AFMT_S32_LE;
+}
+
+static int
+madi_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void
+madi_trigger (int dev, int state)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ madi_portc_t *portc = audio_engines[dev]->portc;
+ int ch;
+
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if ((state & PCM_ENABLE_OUTPUT)
+ && !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ for (ch = 0; ch < portc->channels; ch++)
+ set_output_enable (devc, portc->channel + ch, 1);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ devc->active_outputs |= (1ULL << portc->channel);
+ }
+ else if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ {
+ for (ch = 0; ch < portc->channels; ch++)
+ set_output_enable (devc, portc->channel + ch, 0);
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ devc->active_outputs &= ~(1ULL << portc->channel);
+ }
+ }
+
+ if ((portc->open_mode & OPEN_READ)
+ && !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ for (ch = 0; ch < portc->channels; ch++)
+ set_input_enable (devc, portc->channel + ch, 1);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ devc->active_inputs |= (1ULL << portc->channel);
+ }
+ else if (portc->trigger_bits & PCM_ENABLE_INPUT)
+ {
+ for (ch = 0; ch < portc->channels; ch++)
+ set_input_enable (devc, portc->channel + ch, 0);
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ devc->active_inputs &= ~(1ULL << portc->channel);
+ }
+ }
+
+ if (devc->active_inputs || devc->active_outputs)
+ start_audio (devc);
+ else
+ stop_audio (devc);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static int
+madi_sync_control (int dev, int event, int mode)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ madi_portc_t *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+ int ch;
+
+ if (event == SYNC_PREPARE)
+ {
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if ((mode & PCM_ENABLE_OUTPUT) && portc->direction == DIR_OUT)
+ {
+ for (ch = 0; ch < portc->channels; ch++)
+ set_output_enable (devc, portc->channel + ch, 1);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ devc->active_outputs |= (1ULL << portc->channel);
+ }
+
+ if ((mode & PCM_ENABLE_INPUT) && portc->direction == DIR_IN)
+ {
+ for (ch = 0; ch < portc->channels; ch++)
+ set_input_enable (devc, portc->channel + ch, 1);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ devc->active_inputs |= (1ULL << portc->channel);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+
+ if (event == SYNC_TRIGGER)
+ {
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (devc->active_inputs || devc->active_outputs)
+ start_audio (devc);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+ }
+
+ return OSS_EIO;
+}
+
+static void
+madi_halt (int dev)
+{
+ madi_trigger (dev, 0);
+}
+
+ /*ARGSUSED*/ static int
+madi_open (int dev, int mode, int open_flags)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ madi_portc_t *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+ int ok=1;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode != 0)
+ ok=0;
+ else
+ if (portc->direction == DIR_OUT)
+ {
+ if (!play_channels_avail(devc, portc->channel, 2))
+ {
+ ok=0;
+ }
+ }
+ else
+ {
+ if (!rec_channels_avail(devc, portc->channel, 2))
+ {
+ ok=0;
+ }
+ }
+
+ if (!ok)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ devc->open_audiodevs++;
+
+ portc->channels = 2;
+ if (portc->direction == DIR_OUT)
+ reserve_play_channels(devc, portc->channel, 2);
+ else
+ reserve_rec_channels(devc, portc->channel, 2);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static void
+madi_close (int dev, int mode)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ madi_portc_t *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->open_mode = 0;
+ devc->open_audiodevs--;
+ if (portc->direction == DIR_OUT)
+ {
+ free_play_channels(devc, portc->channel, portc->channels);
+ }
+ else
+ {
+ free_rec_channels(devc, portc->channel, portc->channels);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+ /*ARGSUSED*/ static void
+madi_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+}
+
+ /*ARGSUSED*/ static void
+madi_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+ /*ARGSUSED*/ static int
+madi_prepare_for_input (int dev, int bsize, int bcount)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ madi_portc_t *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ int i;
+ int offs = portc->channel * CHBUF_PAGES;
+
+ for (i = 0; i < CHBUF_PAGES * portc->channels; i++)
+ madi_write (devc, MADI_RecPageTable + 4 * (offs + i),
+ LSWAP(dmap->dmabuf_phys + i * 4096));
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+madi_prepare_for_output (int dev, int bsize, int bcount)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ madi_portc_t *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ int i;
+ int offs = portc->channel * CHBUF_PAGES;
+
+ for (i = 0; i < CHBUF_PAGES * portc->channels; i++)
+ madi_write (devc, MADI_PlayPageTable + 4 * (offs + i),
+ LSWAP(dmap->dmabuf_phys + i * 4096));
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+madi_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ madi_portc_t *portc = audio_engines[dev]->portc;
+
+ if (direction == OPEN_READ)
+ {
+ dmap->dmabuf = devc->recbuf + portc->channel * CHBUF_SIZE;
+ dmap->dmabuf_phys = devc->recbuf_phys + portc->channel * CHBUF_SIZE;
+ dmap->buffsize = CHBUF_SIZE;
+ }
+ else
+ {
+ dmap->dmabuf = devc->playbuf + portc->channel * CHBUF_SIZE;
+ dmap->dmabuf_phys = devc->playbuf_phys + portc->channel * CHBUF_SIZE;
+ dmap->buffsize = CHBUF_SIZE;
+ }
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+madi_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ dmap->dmabuf = NULL;
+ dmap->dmabuf_phys = 0;
+ dmap->buffsize = 0;
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+madi_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ madi_portc_t *portc = audio_engines[dev]->portc;
+ unsigned int status;
+#if 1
+ /*
+ * Use only full/half buffer resolution.
+ */
+ int bytes;
+ bytes = ((devc->cmd & MADI_LatencyMask) >> 1) + 8;
+ bytes = 1 << bytes;
+ bytes *= portc->channels;
+
+ status = madi_read (devc, MADI_status);
+ return (status & MADI_BufferHalf) ? bytes : 0;
+#else
+ /*
+ * Use full resolution
+ */
+ status = madi_read (devc, MADI_status) & MADI_BufferPosMask;
+
+ return status * portc->channels;
+#endif
+}
+
+/*ARGSUSED*/
+static void
+madi_setup_fragments (int dev, dmap_t * dmap, int direction)
+{
+ madi_devc_t *devc = audio_engines[dev]->devc;
+ madi_portc_t *portc = audio_engines[dev]->portc;
+ int bytes;
+
+ bytes = ((devc->cmd & MADI_LatencyMask) >> 1) + 8;
+ bytes = 1 << bytes;
+
+ dmap->buffsize = portc->channels * CHBUF_SIZE;
+
+#if 1
+ /*
+ * Use two fragment (ping-pong) buffer that is also used by the hardware.
+ */
+ dmap->fragment_size = bytes * portc->channels;
+ dmap->nfrags = 2;
+#else
+/*
+ * Use 4 fragments instead of 2 to avoid clicking caused by accessing the
+ * DMA buffer too close to the active DMA position.
+ *
+ * This means that the DMA pointer will jump by 2 fregments every time there
+ * is a half/full bufferinterrupt.
+ */
+ dmap->fragment_size = (bytes * portc->channels) / 2;
+ dmap->nfrags = 4;
+#endif
+
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+}
+
+static audiodrv_t madi_driver = {
+ madi_open,
+ madi_close,
+ madi_output_block,
+ madi_start_input,
+ madi_ioctl,
+ madi_prepare_for_input,
+ madi_prepare_for_output,
+ madi_halt,
+ NULL, // madi_local_qlen,
+ NULL,
+ NULL, // madi_halt_input,
+ NULL, // madi_halt_output,
+ madi_trigger,
+ madi_set_rate,
+ madi_set_format,
+ madi_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ madi_alloc_buffer,
+ madi_free_buffer,
+ NULL,
+ NULL,
+ madi_get_buffer_pointer,
+ NULL,
+ madi_sync_control,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ madi_setup_fragments
+};
+
+static int
+create_output_device (madi_devc_t * devc, char *name, int chn)
+{
+ madi_portc_t *portc;
+ adev_t *adev;
+ int n;
+
+ if ((portc = PMALLOC (devc->osdev, sizeof (*portc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate portc structure\n");
+ return OSS_ENOMEM;
+ }
+ memset (portc, 0, sizeof (*portc));
+
+ n = devc->num_outputs++;;
+ portc->channel = chn;
+ portc->channels = 2;
+ portc->max_channels = 64 - chn;
+
+ devc->out_portc[n] = portc;
+
+ if ((portc->audio_dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ name,
+ &madi_driver,
+ sizeof (audiodrv_t),
+ ADEV_NOINPUT |
+ ADEV_NONINTERLEAVED |
+ ADEV_NOMMAP, AFMT_S32_LE,
+ devc, -1)) < 0)
+ {
+ return portc->audio_dev;
+ }
+
+ adev = audio_engines[portc->audio_dev];
+
+ if (devc->first_audiodev == -1)
+ devc->first_audiodev = portc->audio_dev;
+ adev->rate_source = devc->first_audiodev;
+
+ adev->mixer_dev = devc->mixer_dev;
+ adev->portc = portc;
+ adev->min_rate = devc->rate;
+ adev->max_rate = devc->rate;
+ adev->min_channels = 1;
+ adev->max_channels = portc->max_channels;
+ adev->min_block = CHBUF_SIZE / 2;
+ adev->max_block = CHBUF_SIZE / 2;
+
+ portc->direction = DIR_OUT;
+
+ return portc->audio_dev;
+}
+
+static int
+create_input_device (madi_devc_t * devc, char *name, int chn)
+{
+ madi_portc_t *portc;
+ adev_t *adev;
+ int n;
+
+ if ((portc = PMALLOC (devc->osdev, sizeof (*portc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate portc structure\n");
+ return OSS_ENOMEM;
+ }
+ memset (portc, 0, sizeof (*portc));
+
+ n = devc->num_inputs++;;
+ portc->channel = chn;
+ portc->channels = 2;
+ portc->max_channels = 64 - chn;
+
+ devc->in_portc[n] = portc;
+
+ if ((portc->audio_dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ name,
+ &madi_driver,
+ sizeof (audiodrv_t),
+ ADEV_NOOUTPUT |
+ ADEV_NONINTERLEAVED |
+ ADEV_NOMMAP, AFMT_S32_LE,
+ devc, -1)) < 0)
+ {
+ return portc->audio_dev;
+ }
+
+ adev = audio_engines[portc->audio_dev];
+
+ if (devc->first_audiodev == -1)
+ devc->first_audiodev = portc->audio_dev;
+ adev->rate_source = devc->first_audiodev;
+
+ adev->mixer_dev = devc->mixer_dev;
+ adev->portc = portc;
+ adev->min_rate = devc->rate;
+ adev->max_rate = devc->rate;
+ adev->min_channels = 1;
+ adev->max_channels = portc->max_channels;
+ adev->min_block = CHBUF_SIZE / 2;
+ adev->max_block = CHBUF_SIZE / 2;
+
+ portc->direction = DIR_IN;
+
+ return portc->audio_dev;
+}
+
+int
+oss_madi_attach (oss_device_t * osdev)
+{
+ madi_devc_t *devc;
+ unsigned char pci_irq_line, pci_revision /*, pci_latency */ ;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ int i;
+ int err;
+ int my_mixer;
+
+ int chn, src;
+
+ DDB (cmn_err (CE_NOTE, "Entered RME MADI detect routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != RME_VENDOR_ID || device != RME_MADI)
+ return 0;
+
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &pci_ioaddr);
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "BAR0 not initialized by BIOS\n");
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osp, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate devc\n");
+ return 0;
+ }
+ memset (devc, 0, sizeof (*devc));
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->first_audiodev = -1;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+
+ DDB (cmn_err (CE_CONT, "RME HDSPM revision %d\n", pci_revision));
+
+ if (pci_revision < 230)
+ {
+ devc->name = "RME MADI";
+ devc->model = MDL_MADI;
+ }
+ else
+ {
+ devc->name = "RME AES32";
+ devc->model = MDL_AES32;
+ }
+
+ DDB (cmn_err (CE_CONT, "Card model is %s\n", devc->name));
+
+ devc->rate = devc->next_rate = 48000; // TODO: Also set the other rate control fields */
+
+ osdev->hw_info = PMALLOC (osdev, HWINFO_SIZE); /* Text buffer for additional device info */
+ sprintf (osdev->hw_info, "PCI revision %d", pci_revision);
+
+ oss_register_device (osdev, devc->name);
+
+ devc->physaddr = pci_ioaddr;
+ devc->registers = MAP_PCI_MEM (devc->osdev, 0, devc->physaddr, 65536);
+
+ if (devc->registers == NULL)
+ {
+ cmn_err (CE_WARN, "Can't map PCI registers (0x%08x)\n", devc->physaddr);
+ return 0;
+ }
+
+ devc->playbuf = CONTIG_MALLOC (devc->osdev, DMABUF_SIZE, MEMLIMIT_32BITS,
+ &devc->playbuf_phys, devc->play_dma_handle);
+ if (devc->playbuf == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate play DMA buffers\n");
+ return 0;
+ }
+
+ devc->recbuf = CONTIG_MALLOC (devc->osdev, DMABUF_SIZE, MEMLIMIT_32BITS,
+ &devc->recbuf_phys, devc->rec_dma_handle);
+ if (devc->recbuf == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate rec DMA buffers\n");
+ return 0;
+ }
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, madiintr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+
+ if (madi_maxchannels < 2) madi_maxchannels=2;
+ if (madi_maxchannels > MAX_CHANNELS)madi_maxchannels=MAX_CHANNELS;
+
+ if (madi_devsize < 1) madi_devsize = 1;
+
+ if (madi_devsize != 1 && madi_devsize != 2 && madi_devsize != 4)
+ madi_devsize = 2;
+
+ /*
+ * Set the hw mixer shadow values to sane levels so that
+ * initialize_hardware() can write them to the actual registers.
+ */
+
+ for (chn = 0; chn < MAX_CHANNELS; chn++)
+ for (src = 0; src < 2 * MAX_CHANNELS; src++)
+ devc->mixer_values[chn][src] = MUTE_GAIN; /* Set everything off */
+
+#if 0
+ for (src = 0; src < MAX_CHANNELS; src += 2)
+ {
+ /* Setup playback monitoring to analog out */
+ devc->mixer_values[MONITOR_CH][SRC_PLAY | src] = UNITY_GAIN / 10;
+ devc->mixer_values[MONITOR_CH + 1][SRC_PLAY | (src + 1)] =
+ UNITY_GAIN / 10;
+ }
+#endif
+
+ for (chn = 0; chn < MAX_CHANNELS; chn++)
+ devc->mixer_values[chn][SRC_PLAY | chn] = UNITY_GAIN; /* N->N outputs on */
+
+ initialize_hardware (devc);
+
+ if ((my_mixer = madi_install_mixer (devc)) < 0)
+ {
+ devc->mixer_dev = -1;
+ return 0;
+ }
+ else
+ {
+ devc->mixer_dev = my_mixer;
+ }
+
+ if (madi_devsize == 1)
+ {
+ for (i = 0; i < madi_maxchannels; i++)
+ {
+ char tmp[32];
+ sprintf (tmp, "%s out%d", devc->name, i+1);
+ create_output_device (devc, tmp, i);
+ }
+
+ for (i = 0; i < madi_maxchannels; i++)
+ {
+ char tmp[32];
+ sprintf (tmp, "%s in%d", devc->name, i+1);
+ create_input_device (devc, tmp, i);
+ }
+ }
+ else
+ {
+ for (i = 0; i < madi_maxchannels; i += madi_devsize)
+ {
+ char tmp[32];
+ sprintf (tmp, "%s out%d-%d", devc->name, i+1, i + madi_devsize);
+ create_output_device (devc, tmp, i);
+ }
+
+ for (i = 0; i < madi_maxchannels; i += madi_devsize)
+ {
+ char tmp[32];
+ sprintf (tmp, "%s in%d-%d", devc->name, i+1, i + madi_devsize);
+ create_input_device (devc, tmp, i);
+ }
+ }
+
+ madi_activate_mixer (devc);
+
+ return 1;
+}
+
+int
+oss_madi_detach (oss_device_t * osdev)
+{
+ madi_devc_t *devc = (madi_devc_t *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ stop_audio (devc);
+
+ /*
+ * Shut up the hardware
+ */
+ devc->cmd &= ~MADI_FreqMask;
+ madi_control (devc, devc->cmd);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+
+ if (devc->registers != NULL)
+ UNMAP_PCI_MEM (osdev, 0, devc->physaddr, devc->registers, 65536);
+ CONTIG_FREE (devc->osdev, devc->playbuf, DMABUF_SIZE,
+ devc->play_dma_handle);
+ CONTIG_FREE (devc->osdev, devc->recbuf, DMABUF_SIZE, devc->rec_dma_handle);
+
+ oss_unregister_device (devc->osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_madi/oss_madi.man b/kernel/drv/oss_madi/oss_madi.man
new file mode 100644
index 0000000..70239fc
--- /dev/null
+++ b/kernel/drv/oss_madi/oss_madi.man
@@ -0,0 +1,70 @@
+NAME
+oss_madi - RME HDSP MADI and AES32 audio driver
+
+DESCRIPTION
+Open Sound System driver for RME HDSP MADI and AES32 audio interfaces.
+
+This driver has been developed for RME HDSP MADI but it also supports
+HDSP AES32. The driver has been tested under Linux and Solaris under x86
+and Sparc.
+
+The internal engine of the card supports 64 playback channels and 64 recording
+channels. Only the first channels are connected to the actual input and
+output ports of the card.
+
+The mixer section of the card has recording level settings for all inputs.
+There is also an output mixer. Each output channel has mixer sliders for
+corresponding input channel and corresponding audio playback channel.
+
+There is a full 64x(64+64) mixing matrix supported by the hardware. For
+the time being this mixer matrix cannot be accessed directly by the
+applications. However support for the SNDCTL_MIX_MATRIX_WRITE and
+SNDCTL_MIX_MATRIX_READ ioctl calls can be added in the future.
+
+DEVICE FILES
+
+By default the driver will create input and output device files for
+each 32 stereo pairs. This can be changed by editing the settings in
+oss_madi.conf (see below).
+
+The application can set the devices to use 1, 2, 4, 8, 16, 32 or 64 channels.
+The device file being used selects the first channel slot within the available
+channels. For example pcm0 and pcmin0 sill select channel 0. Equally well
+pcm1 and pcmin1 will select channel slot 2 (assuming that madi_devsize option
+is set to 2). The first device (pcm0 and pcmin0) can be set to use up to 64
+channels. The last devices (pcm31 and pcmin31) only support 1 or 2 channel mode.
+The other device files support channel configurations where the last channel
+doesn't exceed the number of total channels (madi_maxchannels). Also the driver
+will not let two device files to share any of the channels with some other
+open device file.
+
+This channel allocation mechanism gives maximum flexibility to the user. It is
+possible to use some output channels by multi channel application while the
+others are available for other applications. This works as long the channel
+allocations by different applications don't overlap.
+
+OPTIONS
+
+o madi_maxchannels Number of channels supported by the driver. The default
+ is 64 which is also the maximum. This parameter can
+ be set to a lower value if full 64 channels are not
+ required. With less channels the mixer/control panel
+ interface will require less space on screen.
+o madi_devsize By default this parameter is set to 2 which means that
+ a device file will be created for each stereo channel
+ pair. Possible values are 1, 2, 4, 8, 16, 32 or 64.
+
+LIMITATIONS
+
+o The current driver doesn't support all control panel features of the card.
+For example sampling rate is fixed to 48 kHz. More features will be added
+on contract.
+
+o Use of mmap() is and will not be supported.
+o Virtual mixer is not supported (yet).
+
+FILES
+CONFIGFILEPATH/oss_madi.conf Device configuration file.
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_midiloop/.config b/kernel/drv/oss_midiloop/.config
new file mode 100644
index 0000000..c10d582
--- /dev/null
+++ b/kernel/drv/oss_midiloop/.config
@@ -0,0 +1 @@
+bus=VIRTUAL
diff --git a/kernel/drv/oss_midiloop/.devices b/kernel/drv/oss_midiloop/.devices
new file mode 100644
index 0000000..9389c68
--- /dev/null
+++ b/kernel/drv/oss_midiloop/.devices
@@ -0,0 +1 @@
+oss_midiloop oss_midiloop OSS MIDI Loopback driver
diff --git a/kernel/drv/oss_midiloop/.name b/kernel/drv/oss_midiloop/.name
new file mode 100644
index 0000000..1b2e06b
--- /dev/null
+++ b/kernel/drv/oss_midiloop/.name
@@ -0,0 +1 @@
+MIDI loopback pseudo device
diff --git a/kernel/drv/oss_midiloop/.params b/kernel/drv/oss_midiloop/.params
new file mode 100644
index 0000000..9e33e88
--- /dev/null
+++ b/kernel/drv/oss_midiloop/.params
@@ -0,0 +1,5 @@
+int midiloop_instances = 1; /* Number of loopback MIDI devs to install */
+/*
+ * midiloop_instances gives the number of MIDI loopback devices to be created.
+ * The default value is 1
+ */
diff --git a/kernel/drv/oss_midiloop/oss_midiloop.c b/kernel/drv/oss_midiloop/oss_midiloop.c
new file mode 100644
index 0000000..5c9082a
--- /dev/null
+++ b/kernel/drv/oss_midiloop/oss_midiloop.c
@@ -0,0 +1,412 @@
+/*
+ * Purpose: MIDI loopback driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_midiloop_cfg.h"
+#include "midi_core.h"
+
+#define MIDI_SYNTH_NAME "OSS loopback MIDI"
+#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
+
+#define MAX_INSTANCES 8
+#define CLIENT_NAME "MIDI loopback"
+#define SERVER_NAME "MIDI loopback server side"
+
+#define POLL_HZ (OSS_HZ/100)
+
+static int open_clients = 0;
+static int open_servers = 0;
+
+typedef struct midiloop_devc
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+
+ int instance_no;
+ int side;
+#define SIDE_SERVER 0
+#define SIDE_CLIENT 0
+ int midi_dev;
+ struct midiloop_devc *client, *server, *peer;
+
+ int open_mode;
+ oss_midi_inputbyte_t inputbyte_func;
+ oss_midi_inputbuf_t inputbuf_func;
+ oss_longname_t song_name;
+
+} midiloop_devc;
+
+static midiloop_devc midiloop_devs[2 * MAX_INSTANCES] = { {0} };
+static int ndevs = 0;
+
+static int
+midiloop_open_server (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags;
+ midiloop_devc *devc, *client_devc;
+ char *cmd;
+ int client_dev;
+
+ devc = midi_devs[dev]->devc;
+
+ client_devc = devc->client;
+
+ client_dev = client_devc->midi_dev;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (devc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode = mode;
+ devc->inputbyte_func = inputbyte;
+ devc->inputbuf_func = inputbuf;
+
+ open_servers++;
+
+ if ((cmd = midi_devs[dev]->cmd) != NULL)
+ {
+ sprintf (midi_devs[client_dev]->name, CLIENT_NAME " (%s)", cmd);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+midiloop_close_server (int dev, int mode)
+{
+ oss_native_word flags;
+ midiloop_devc *devc, *client_devc;
+ int client_dev;
+
+ devc = midi_devs[dev]->devc;
+ client_devc = devc->client;
+ client_dev = client_devc->midi_dev;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->open_mode = 0;
+ devc->inputbyte_func = NULL;
+ devc->inputbuf_func = NULL;
+ strcpy (midi_devs[client_dev]->name, CLIENT_NAME);
+ midi_devs[client_dev]->latency = -1; /* Not indicated */
+
+ open_servers--;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static int
+midiloop_open_client (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags;
+ midiloop_devc *devc;
+
+ devc = midi_devs[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (devc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode = mode;
+ devc->inputbyte_func = inputbyte;
+ devc->inputbuf_func = inputbuf;
+ open_clients++;
+
+ /* Notify the server */
+ if (devc->server->open_mode & OPEN_READ)
+ {
+ if (devc->server->inputbyte_func != NULL)
+ devc->server->inputbyte_func (devc->server->midi_dev, 0xfa); /* Start */
+
+ /* Restart the MTC timer of the server side (if necessary) */
+ if (midi_devs[devc->server->midi_dev]->mtc_timebase > -1)
+ {
+ int timebase = 25;
+ oss_midi_ioctl (devc->server->midi_dev, NULL, SNDCTL_MIDI_MTCINPUT,
+ (ioctl_arg) & timebase);
+ }
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+midiloop_close_client (int dev, int mode)
+{
+ oss_native_word flags;
+ midiloop_devc *devc;
+
+ devc = midi_devs[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->open_mode = 0;
+ devc->inputbyte_func = NULL;
+ devc->inputbuf_func = NULL;
+ open_clients--;
+
+ /* Notify the server */
+ if (devc->server->open_mode & OPEN_READ)
+ if (devc->server->inputbyte_func != NULL)
+ devc->server->inputbyte_func (devc->server->midi_dev, 0xfc); /* Stop */
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ /* Halt the MTC timer of the server side (if necessary) */
+ if (midi_devs[devc->server->midi_dev]->mtc_timebase > 0)
+ {
+ int timebase = 0;
+ oss_midi_ioctl (devc->server->midi_dev, NULL, SNDCTL_MIDI_MTCINPUT,
+ (ioctl_arg) & timebase);
+ }
+}
+
+static int
+midiloop_out (int dev, unsigned char midi_byte)
+{
+ midiloop_devc *devc;
+ oss_native_word flags;
+ int ok = 0;
+
+ devc = midi_devs[dev]->devc;
+
+ if (devc->peer->open_mode == 0)
+ return 1;
+ MUTEX_ENTER_IRQDISABLE (devc->peer->mutex, flags);
+ if (devc->peer->inputbyte_func != NULL)
+ {
+ ok = devc->peer->inputbyte_func (devc->peer->midi_dev, midi_byte);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->peer->mutex, flags);
+ return ok;
+}
+
+static int
+midiloop_bulk_out (int dev, unsigned char *buf, int len)
+{
+ midiloop_devc *devc;
+ oss_native_word flags;
+ int ok = 0;
+
+ devc = midi_devs[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->peer->mutex, flags);
+ if (devc->peer->open_mode == 0 || devc->peer->inputbuf_func == NULL)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->peer->mutex, flags);
+ return len;
+ }
+
+ ok = devc->peer->inputbuf_func (devc->peer->midi_dev, buf, len);
+ MUTEX_EXIT_IRQRESTORE (devc->peer->mutex, flags);
+ return ok;
+}
+
+static void
+midiloop_timer_setup (int dev /* Client dev */ )
+{
+ midiloop_devc *devc, *server_devc;
+ int client_dev;
+ int server_dev;
+
+ devc = midi_devs[dev]->devc;
+ server_devc = devc->server;
+ client_dev = devc->midi_dev;
+ server_dev = devc->server->midi_dev;
+
+ oss_midi_copy_timer (server_dev, client_dev);
+}
+
+static int
+midiloop_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ char *song_name;
+ oss_native_word flags;
+ midiloop_devc *devc, *client_devc;
+ int client_dev;
+
+ devc = midi_devs[dev]->devc;
+ client_devc = devc->client;
+ client_dev = client_devc->midi_dev;
+
+ switch (cmd)
+ {
+ case SNDCTL_SETSONG:
+ if (devc->side != SIDE_CLIENT)
+ return 0;
+
+ song_name = (char *) arg;
+ song_name[OSS_LONGNAME_SIZE - 1] = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ strcpy (devc->song_name, song_name);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ break;
+
+ case SNDCTL_SETNAME:
+ if (devc->side != SIDE_SERVER)
+ return 0;
+
+ song_name = (char *) arg;
+ song_name[OSS_LONGNAME_SIZE - 1] = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ strcpy (midi_devs[devc->client->midi_dev]->name, song_name);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ break;
+
+ case SNDCTL_GETSONG:
+ song_name = (char *) arg;
+ memset (song_name, 0, OSS_LONGNAME_SIZE);
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (devc->side == SIDE_SERVER)
+ strcpy (song_name, devc->peer->song_name);
+ else
+ strcpy (song_name, devc->song_name);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ break;
+
+ case SNDCTL_MIDI_SET_LATENCY:
+ if (devc->side != SIDE_SERVER)
+ return OSS_EINVAL;
+ if (*arg < -1 || *arg > 10000000)
+ return OSS_EINVAL;
+ midi_devs[devc->client->midi_dev]->latency = *arg;
+ break;
+ }
+ return OSS_EINVAL;
+}
+
+static midi_driver_t midiloop_client_driver = {
+ midiloop_open_client,
+ midiloop_close_client,
+ midiloop_ioctl,
+ midiloop_out,
+ midiloop_bulk_out,
+ MIDI_PAYLOAD_SIZE,
+ NULL,
+ NULL,
+ midiloop_timer_setup
+};
+
+static midi_driver_t midiloop_server_driver = {
+ midiloop_open_server,
+ midiloop_close_server,
+ midiloop_ioctl,
+ midiloop_out,
+ midiloop_bulk_out,
+ MIDI_PAYLOAD_SIZE
+};
+
+static void
+attach_midiloop_dev (oss_device_t * osdev)
+{
+ midiloop_devc *server_devc = NULL, *client_devc = NULL;
+
+ if (POLL_HZ < 1)
+ {
+ cmn_err (CE_CONT, "midiloop: Too low system timer resolution\n");
+ return;
+ }
+
+ if (ndevs >= MAX_INSTANCES)
+ {
+ cmn_err (CE_CONT, "MidiLoop: Too many instances\n");
+ return;
+ }
+
+ client_devc = &midiloop_devs[ndevs * 2];
+ client_devc->osdev = osdev;
+ MUTEX_INIT (client_devc->osdev, client_devc->mutex, MH_DRV);
+ client_devc->instance_no = ndevs;
+
+ client_devc->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "LOOP", CLIENT_NAME,
+ &midiloop_client_driver, sizeof (midi_driver_t),
+ MFLAG_VIRTUAL | MFLAG_CLIENT, client_devc,
+ client_devc->osdev);
+
+ server_devc = &midiloop_devs[ndevs * 2 + 1];
+ server_devc->osdev = osdev;
+ MUTEX_INIT (server_devc->osdev, server_devc->mutex, MH_DRV);
+ server_devc->instance_no = ndevs;
+
+ midi_devs[client_devc->midi_dev]->latency = 1000000;
+
+ server_devc->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "LOOP_S", SERVER_NAME,
+ &midiloop_server_driver, sizeof (midi_driver_t),
+ MFLAG_NOSEQUENCER | MFLAG_VIRTUAL | MFLAG_SERVER |
+ MFLAG_SELFTIMING, server_devc, server_devc->osdev);
+
+ client_devc->server = client_devc->peer = server_devc;
+ client_devc->client = client_devc;
+ client_devc->side = SIDE_CLIENT;
+
+ server_devc->client = server_devc->peer = client_devc;
+ server_devc->server = server_devc;
+ server_devc->side = SIDE_SERVER;
+
+ ndevs++;
+}
+
+int
+oss_midiloop_attach (oss_device_t * osdev)
+{
+ extern int midiloop_instances;
+ int i;
+
+ oss_register_device (osdev, "OSS MIDI loopback driver");
+
+ if (midiloop_instances > MAX_INSTANCES)
+ midiloop_instances = MAX_INSTANCES;
+ for (i = 0; i < midiloop_instances; i++)
+ {
+ attach_midiloop_dev (osdev);
+ }
+
+ return 1;
+}
+
+int
+oss_midiloop_detach (oss_device_t * osdev)
+{
+ int i, err;
+
+ if ((err = oss_disable_device (osdev)) < 0)
+ return 0;
+
+ for (i = 0; i < 2 * ndevs; i++)
+ {
+ midiloop_devc *devc;
+
+ devc = &midiloop_devs[i];
+ }
+
+ oss_unregister_device (osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_midiloop/oss_midiloop.man b/kernel/drv/oss_midiloop/oss_midiloop.man
new file mode 100644
index 0000000..a3ee97d
--- /dev/null
+++ b/kernel/drv/oss_midiloop/oss_midiloop.man
@@ -0,0 +1,44 @@
+NAME
+oss_midiloop - Loopback MIDI driver.
+
+DESCRIPTION
+The loopback midi driver makes it possible to create special purpose
+virtual midi devices based on user land server processes.
+
+INTRODUCTION
+MIDI loopback devices are like named pipes or pseudo terminals. They are
+grouped in client and server device pairs. The server side device must be open
+before the client side device can be opened.
+
+ SERVER SIDE DEVICE
+The server side device is used by some special application (such as a
+software based MIDI synthesizer) to receice MIDI events from the applications
+that want to play MIDI.
+
+ CLIENT SIDE DEVICE
+Client applications such as MIDI players open the client side device when they
+need to play some MIDI stream (file). The client side device behaves like any
+"ordinary" MIDI device. However it cannot be opened when there is no program
+connected to the server side.
+
+COMPATIBILITY ISSUES
+MIDI loopback devices differ from "normal" MIDI devices because an
+application is needed at the both ends of the loop. The loop device
+will return a "Connection reset by peer" error (ECONNRESET) error. Applications
+designed to be used as loopback based server applications can/should use this
+error (returned by read or write) as an end-of-stream indication.
+
+OPTIONS
+o midiloop_instances: Specifies how many loopback client/server MIDI device
+ pairs to be created.
+ Values: 1-16 Default: 1
+
+KNOWN PROBLEMS
+None
+
+FILES
+CONFIGFILEPATH/oss_midiloop.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_midimix/.config b/kernel/drv/oss_midimix/.config
new file mode 100644
index 0000000..c10d582
--- /dev/null
+++ b/kernel/drv/oss_midimix/.config
@@ -0,0 +1 @@
+bus=VIRTUAL
diff --git a/kernel/drv/oss_midimix/.name b/kernel/drv/oss_midimix/.name
new file mode 100644
index 0000000..543ecb8
--- /dev/null
+++ b/kernel/drv/oss_midimix/.name
@@ -0,0 +1 @@
+MIDI mixer pseudo device.
diff --git a/kernel/drv/oss_midimix/oss_midimix.c b/kernel/drv/oss_midimix/oss_midimix.c
new file mode 100644
index 0000000..9f7cc4c
--- /dev/null
+++ b/kernel/drv/oss_midimix/oss_midimix.c
@@ -0,0 +1,346 @@
+/*
+ * Purpose: MIDI mixer pseudo driver
+ *
+ * This driver creates a pseudo MIDI port device that can be used for
+ * real-time mixer volume changes. The pseudo MIDI device will return MIDI
+ * control change messages when a mixer setting changes. Application using the
+ * device may also do mixer changes (cross fading, etc) by sending (or
+ * playing back) control messages.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_midimix_cfg.h"
+#include "midi_core.h"
+#include "midiparser.h"
+
+#define MAX_INSTANCES 1
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+ int midi_dev;
+ int open_mode;
+ oss_midi_inputbuf_t inputbuf;
+ midiparser_common_p parser;
+ int modify_counters[16];
+ int update_counters[16][128];
+ timeout_id_t timeout_id;
+} midimix_devc;
+
+static midimix_devc midimix_devs[MAX_INSTANCES] = {{ 0 }};
+static int ndevs = 0;
+
+static void
+midimix_close (int dev, int mode)
+{
+ midimix_devc *devc = midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ midiparser_unalloc (devc->parser);
+ devc->parser = NULL;
+ untimeout (devc->timeout_id);
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->open_mode = 0;
+ devc->inputbuf = NULL;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+void
+parser_cb (void *context, int category, unsigned char msg, unsigned char ch,
+ unsigned char *parms, int len)
+{
+
+ if (category == CAT_CHN && msg == MIDI_CTL_CHANGE)
+ {
+ oss_mixext *ext;
+ oss_mixer_value rec;
+
+ int dev = ch;
+ int ctl = parms[0];
+ int val = parms[1];
+
+ if ((ext = mixer_find_ext (dev, ctl)) == NULL)
+ return; /* Not found */
+
+ if (!(ext->flags & MIXF_READABLE) || !(ext->flags & MIXF_WRITEABLE))
+ return; /* Not accessible */
+
+ if (ext->maxvalue > 127)
+ val = (val * ext->maxvalue + 63) / 127;
+
+ if (val < 0 || val > ext->maxvalue)
+ return; /* Value out of range */
+
+ switch (ext->type)
+ {
+ case MIXT_MONOSLIDER:
+ case MIXT_STEREOSLIDER:
+ val = val & 0xff;
+ val = val | (val << 8);
+ break;
+
+ case MIXT_ONOFF:
+ val = !!val;
+ break;
+
+ case MIXT_ENUM:
+ if (val >= ext->maxvalue)
+ return; /* Out of range */
+ break;
+
+ case MIXT_VALUE:
+ case MIXT_HEXVALUE:
+ case MIXT_SLIDER:
+ /* Accept as-is */
+ break;
+
+ default:
+ return; /* Type not supported */
+ }
+
+ memset (&rec, 0, sizeof (rec));
+ rec.dev = dev;
+ rec.ctrl = ctl;
+ rec.value = val;
+ rec.timestamp = ext->timestamp;
+ oss_mixer_ext (dev, OSS_DEV_MIXER, SNDCTL_MIX_WRITE, (ioctl_arg) & rec);
+ }
+
+}
+
+static void
+check_for_updates (midimix_devc * devc, int force)
+{
+ int dev, ctl;
+
+ for (dev = 0; dev < 16 && dev < num_mixers; dev++)
+ {
+ touch_mixer (dev);
+
+ if (force
+ || (mixer_devs[dev]->modify_counter > devc->modify_counters[dev]))
+ {
+ devc->modify_counters[dev] = mixer_devs[dev]->modify_counter;
+ for (ctl = 0; ctl < 128; ctl++)
+ {
+ oss_mixext *ext;
+ oss_mixer_value rec;
+ int val;
+ unsigned char midibuf[3];
+
+ if ((ext = mixer_find_ext (dev, ctl)) == NULL)
+ break; /* All controls processed I think */
+ if (!(ext->flags & MIXF_READABLE)
+ || !(ext->flags & MIXF_WRITEABLE))
+ continue; /* Not accessible */
+
+ if (!force
+ && devc->update_counters[dev][ctl] == ext->update_counter)
+ continue; /* No change */
+ devc->update_counters[dev][ctl] = ext->update_counter;
+
+ switch (ext->type)
+ {
+ case MIXT_MONOSLIDER:
+ case MIXT_STEREOSLIDER:
+ case MIXT_ONOFF:
+ case MIXT_ENUM:
+ case MIXT_VALUE:
+ case MIXT_HEXVALUE:
+ case MIXT_SLIDER:
+ /* Type OK */
+ break;
+
+ default:
+ continue; /* Type not supported */
+ }
+
+ memset (&rec, 0, sizeof (rec));
+ rec.dev = dev;
+ rec.ctrl = ctl;
+ rec.timestamp = ext->timestamp;
+
+ if (oss_mixer_ext
+ (dev, OSS_DEV_MIXER, SNDCTL_MIX_READ,
+ (ioctl_arg) & rec) < 0)
+ {
+ continue; /* Read failed */
+ }
+
+ val = rec.value & 0xff;
+ if (ext->maxvalue > 127)
+ val = (val * 127 + (ext->maxvalue / 2)) / ext->maxvalue;
+
+ if (val < 0)
+ val = 0;
+ if (val > 127)
+ val = 127;
+
+ midibuf[0] = 0xb0 | dev;
+ midibuf[1] = ctl;
+ midibuf[2] = val;
+
+ devc->inputbuf (devc->midi_dev, midibuf, 3);
+ }
+ }
+ }
+}
+
+static void
+timer_callback (void *arg)
+{
+ midimix_devc *devc = arg;
+ check_for_updates (devc, 0);
+ devc->timeout_id = timeout (timer_callback, devc, OSS_HZ / 10); /* 0.1s */
+}
+
+static int
+midimix_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf, oss_midi_outputintr_t outputintr)
+{
+ midimix_devc *devc = midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (devc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ devc->open_mode = mode;
+ devc->inputbuf = inputbuf;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if ((devc->parser = midiparser_create (parser_cb, devc)) == NULL)
+ {
+ devc->open_mode = 0;
+ devc->inputbuf = NULL;
+ cmn_err (CE_WARN, "Cannot create MIDI parser\n");
+ return OSS_ENOMEM;
+ }
+
+ devc->timeout_id = timeout (timer_callback, devc, OSS_HZ / 10); /* 0.1s */
+ return 0;
+}
+
+static int
+midimix_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static int
+midimix_out (int dev, unsigned char midi_byte)
+{
+ midimix_devc *devc = midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ midiparser_input (devc->parser, midi_byte);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 1;
+}
+
+static int
+midimix_bulk_out (int dev, unsigned char *buf, int len)
+{
+ midimix_devc *devc = midi_devs[dev]->devc;
+ int i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ for (i = 0; i < len; i++)
+ {
+ midiparser_input (devc->parser, buf[i]);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return len;
+}
+
+static void
+midimix_init_device (int dev)
+{
+ midimix_devc *devc = midi_devs[dev]->devc;
+
+ if (devc->open_mode & OPEN_READ)
+ check_for_updates (devc, 1);
+}
+
+static midi_driver_t midimix_driver = {
+ midimix_open,
+ midimix_close,
+ midimix_ioctl,
+ midimix_out,
+ midimix_bulk_out,
+ MIDI_PAYLOAD_SIZE,
+ NULL,
+ NULL,
+ NULL,
+ midimix_init_device
+};
+
+static void
+attach_midimix_dev (oss_device_t * osdev)
+{
+ midimix_devc *devc = &midimix_devs[ndevs++];
+
+ devc->osdev = osdev;
+
+ MUTEX_INIT (osdev, devc->mutex, MH_DRV);
+
+ devc->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "MIX",
+ "Mixer access MIDI device", &midimix_driver,
+ sizeof (midi_driver_t),
+ MFLAG_VIRTUAL | MFLAG_QUIET, devc, devc->osdev);
+}
+
+int
+oss_midimix_attach (oss_device_t * osdev)
+{
+ int midimix_instances = 1;
+ int i;
+
+ oss_register_device (osdev, "OSS MIDI mixer driver");
+
+ if (midimix_instances > MAX_INSTANCES)
+ midimix_instances = MAX_INSTANCES;
+ for (i = 0; i < midimix_instances; i++)
+ {
+ attach_midimix_dev (osdev);
+ }
+
+ return 1;
+}
+
+int
+oss_midimix_detach (oss_device_t * osdev)
+{
+ int i, err;
+
+ if ((err = oss_disable_device (osdev)) < 0)
+ return 0;
+
+ for (i = 0; i < ndevs; i++)
+ {
+ midimix_devc *devc;
+
+ devc = &midimix_devs[i];
+ }
+
+ oss_unregister_device (osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_midimix/oss_midimix.man b/kernel/drv/oss_midimix/oss_midimix.man
new file mode 100644
index 0000000..ac7e2ec
--- /dev/null
+++ b/kernel/drv/oss_midimix/oss_midimix.man
@@ -0,0 +1,40 @@
+NAME
+oss_midimix - Driver for controlling OSS mixer devices using MIDI messages
+
+DESCRIPTION
+The MIDI mixer device can be used by MIDI sequencer programs to control
+OSS mixer devices (volumes) in real time. A list of mixer devices available
+in the system can be found using the ossinfo(1) program with the -x option.
+
+ INTRODUCTION
+This driver uses MIDI channel numbers to select the mixer device. The first MIDI
+channel (#0) connects to the first mixer device in the system and so on. When
+any of the mixer controls (such as volume sliders) change their value the
+MIDI mixer device delivers a control change message to the application
+listening it. An application (such as a MIDI sequencer program) can record
+these mixer changes during recording and play them back during playback. In
+this way it's possible to repeat mixer changes with precise timing during
+playback.
+
+OPTIONS
+None
+
+KNOWN PROBLEMS
+o MIDI support is not included in OSS v4.0. It will be re-introduced in
+some future version of OSS.
+o The way how MIDI channel numbers are mapped to the mixer device numbers
+is system dependednt and may change depending on the order of devices are
+loaded in the system. The same is true with the MIDI controller numbers. For
+this reason recorded mixer changes may become obsolete if new devices are
+installed in the system or if the mixer layout changes in future OSS
+versions.
+o For the time being the MIDI controller numbers are mapped directly to
+the mixer control numbers. This means that only the first 128 controls in large
+mixers can be supported. This may change in future OSS versions.
+
+FILES
+None
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_sadasupport/.config b/kernel/drv/oss_sadasupport/.config
new file mode 100644
index 0000000..c8e8442
--- /dev/null
+++ b/kernel/drv/oss_sadasupport/.config
@@ -0,0 +1,3 @@
+bus=STREAMS
+targetos=SunOS
+depends=SADA
diff --git a/kernel/drv/oss_sadasupport/.devices b/kernel/drv/oss_sadasupport/.devices
new file mode 100644
index 0000000..236f38f
--- /dev/null
+++ b/kernel/drv/oss_sadasupport/.devices
@@ -0,0 +1 @@
+oss_sadasupport OSSAUDIOS SADA emulation layer for OSS
diff --git a/kernel/drv/oss_sadasupport/.name b/kernel/drv/oss_sadasupport/.name
new file mode 100644
index 0000000..c311b6a
--- /dev/null
+++ b/kernel/drv/oss_sadasupport/.name
@@ -0,0 +1 @@
+SADA emulation layer for OSS
diff --git a/kernel/drv/oss_sadasupport/.params b/kernel/drv/oss_sadasupport/.params
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel/drv/oss_sadasupport/.params
diff --git a/kernel/drv/oss_sadasupport/oss_sadasupport.c b/kernel/drv/oss_sadasupport/oss_sadasupport.c
new file mode 100644
index 0000000..43f5226
--- /dev/null
+++ b/kernel/drv/oss_sadasupport/oss_sadasupport.c
@@ -0,0 +1,1277 @@
+/*
+ * Purpose: Support for the legacy (SADA) /dev/audio interfaces of Solaris
+ *
+ * Description:
+ * This driver serves as a bridge between the OSS audio drivers and the
+ * native audio support framework of Solaris.
+ *
+ * **** This driver supports only one device instance ****
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_sadasupport_cfg.h"
+#include <oss_pci.h>
+#include <sys/note.h>
+#include <sys/audioio.h>
+#include <sys/audio.h>
+#include <sys/audiovar.h>
+#include <sys/audio/audio_trace.h>
+#include <sys/audio/audio_support.h>
+#include <sys/audio/audio_src.h>
+#include <sys/mixer.h>
+#include <sys/audio/audio_mixer.h>
+#ifdef SOL9
+#include <sys/audio/am_src1.h>
+#else
+#include <sys/sunldi.h>
+#endif
+
+int sadasupport_rate = 48000;
+
+static int do_byteswap = 0;
+
+#ifdef SOL9
+extern am_ad_src_entry_t am_src1;
+#else
+extern am_ad_src_entry_t am_src2;
+#endif
+
+#define AUDIOS_DEV_NAME "SUNW,oss"
+#define AUDIOS_DEV_CONFIG "onboard1"
+#define AUDIOS_DEV_VERSION "a"
+#define AUDIOS_NAME "oss"
+#define AUDIOS_IDNUM (0x6175)
+#define AUDIOS_MINPACKET (0)
+#define AUDIOS_MAXPACKET (1*1024)
+#define AUDIOS_HIWATER (64*1024)
+#define AUDIOS_LOWATER (32*1024)
+#define AUDIOS_BUFFSIZE (8*1024)
+
+#define AUDIOS_SAMPR5510 (5510)
+#define AUDIOS_SAMPR6620 (6620)
+#define AUDIOS_SAMPR8000 (8000)
+#define AUDIOS_SAMPR9600 (9600)
+#define AUDIOS_SAMPR11025 (11025)
+#define AUDIOS_SAMPR12000 (12000)
+#define AUDIOS_SAMPR16000 (16000)
+#define AUDIOS_SAMPR18900 (18900)
+#define AUDIOS_SAMPR22050 (22050)
+#define AUDIOS_SAMPR24000 (24000)
+#define AUDIOS_SAMPR27420 (27420)
+#define AUDIOS_SAMPR32000 (32000)
+#define AUDIOS_SAMPR33075 (33075)
+#define AUDIOS_SAMPR37800 (37800)
+#define AUDIOS_SAMPR44100 (44100)
+#define AUDIOS_SAMPR48000 (48000)
+
+#define AUDIOS_DEFAULT_SR AUDIOS_SAMPR8000
+#define AUDIOS_DEFAULT_CH AUDIO_CHANNELS_MONO
+#define AUDIOS_DEFAULT_PREC AUDIO_PRECISION_8
+#define AUDIOS_DEFAULT_ENC AUDIO_ENCODING_ULAW
+#define AUDIOS_DEFAULT_PGAIN (AUDIO_MAX_GAIN * 3 / 4)
+#define AUDIOS_DEFAULT_RGAIN (127)
+#define AUDIOS_DEFAULT_MONITOR_GAIN (0)
+#define AUDIOS_DEFAULT_BAL AUDIO_MID_BALANCE
+
+/*
+ * Entry point routine prototypes
+ */
+static int sadasupport_open (queue_t * q, dev_t * devp, int flag, int sflag,
+ cred_t * credp);
+static int sadasupport_close (queue_t * q, int flag, cred_t * credp);
+static int sadasupport_ad_set_config (audiohdl_t, int, int, int, int, int);
+static int sadasupport_ad_set_format (audiohdl_t, int, int, int, int, int,
+ int);
+static int sadasupport_ad_start_play (audiohdl_t, int);
+static void sadasupport_ad_pause_play (audiohdl_t, int);
+static void sadasupport_ad_stop_play (audiohdl_t, int);
+static int sadasupport_ad_start_record (audiohdl_t, int);
+static void sadasupport_ad_stop_record (audiohdl_t, int);
+
+/* now, only support stereo */
+static uint_t sadasupport_channels[] = {
+ AUDIO_CHANNELS_STEREO,
+ 0
+};
+
+static am_ad_cap_comb_t sadasupport_combinations[] = {
+ {AUDIO_PRECISION_16, AUDIO_ENCODING_LINEAR},
+ {0}
+};
+
+static uint_t sadasupport_mixer_srs[] = {
+ AUDIOS_SAMPR8000, AUDIOS_SAMPR48000, 0
+};
+
+#ifdef SOL9
+/* don't filter the higher sample rates, this causes the high to be lost */
+static am_ad_src1_info_t sadasupport_play_sample_rates_info[] = {
+ {AUDIOS_SAMPR8000, AUDIOS_SAMPR48000, 2, /* up 6, down 1 */
+ 3, (2 | AM_SRC1_FILTER), 0, 0, 1, 1, 0, 0, 3},
+ {AUDIOS_SAMPR9600, AUDIOS_SAMPR48000, 1, /* up 5, down 1 */
+ (5 | AM_SRC1_FILTER), 0, 0, 0, 1, 0, 0, 0, 3},
+ {AUDIOS_SAMPR11025, AUDIOS_SAMPR48000, 3, /* up 640, down 147 */
+ 10, 8, (8 | AM_SRC1_FILTER), 0, 7, 7, 3, 0, 3},
+ {AUDIOS_SAMPR12000, AUDIOS_SAMPR48000, 1, /* up 4, down 1 */
+ (4 | AM_SRC1_FILTER), 0, 0, 0, 1, 0, 0, 0, 3},
+ {AUDIOS_SAMPR16000, AUDIOS_SAMPR48000, 1, /* up 3, down 1 */
+ (3 | AM_SRC1_FILTER), 0, 0, 0, 1, 0, 0, 0, 3},
+ {AUDIOS_SAMPR18900, AUDIOS_SAMPR48000, 3, /* up 160, down 63 */
+ 8, 5, (4 | AM_SRC1_FILTER), 0, 7, 3, 3, 0, 3},
+ {AUDIOS_SAMPR22050, AUDIOS_SAMPR48000, 3, /* up 320, down 147 */
+ 10, 8, (4 | AM_SRC1_FILTER), 0, 7, 7, 3, 0, 3},
+ {AUDIOS_SAMPR24000, AUDIOS_SAMPR48000, 1, /* up 2, down 1 */
+ (2 | AM_SRC1_FILTER), 0, 0, 0, 1, 0, 0, 0, 3},
+ {AUDIOS_SAMPR32000, AUDIOS_SAMPR48000, 1, /* up 3, down 2 */
+ (3 | AM_SRC1_FILTER), 0, 0, 0, 2, 0, 0, 0, 3},
+ {AUDIOS_SAMPR33075, AUDIOS_SAMPR48000, 4, /* up 640, down 441 */
+ 8, 5, 4, 4, 7, 7, 3, 3, 3},
+ {AUDIOS_SAMPR37800, AUDIOS_SAMPR48000, 3, /* up 80, down 63 */
+ 5, 4, 4, 0, 7, 3, 3, 0, 3},
+ {AUDIOS_SAMPR44100, AUDIOS_SAMPR48000, 3, /* up 160, down 147 */
+ 8, 5, 4, 0, 7, 7, 3, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR48000, 1, /* up 1, down 1 */
+ 1, 0, 0, 0, 1, 0, 0, 0, 3},
+ {0}
+};
+
+static am_ad_src1_info_t sadasupport_record_sample_rates_info[] = {
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR8000, 1, /* up 1, down 6 */
+ 1, 0, 0, 0, 6, 0, 0, 0, 0},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR9600, 1, /* up 1, down 5 */
+ 1, 0, 0, 0, 5, 0, 0, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR11025, 3, /* up 147, down 640 */
+ 7, 7, (3 | AM_SRC1_FILTER), 0, 10, 8, 8, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR12000, 1, /* up 1, down 4 */
+ 1, 0, 0, 0, 4, 0, 0, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR16000, 1, /* up 1, down 3 */
+ 1, 0, 0, 0, 3, 0, 0, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR18900, 3, /* up 63, down 160 */
+ 7, 3, (3 | AM_SRC1_FILTER), 0, 8, 5, 4, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR22050, 3, /* up 147, down 320 */
+ 7, 7, (3 | AM_SRC1_FILTER), 0, 10, 8, 4, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR24000, 1, /* up 1, down 2 */
+ 1, 0, 0, 0, 2, 0, 0, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR32000, 1, /* up 2, down 3 */
+ (2 | AM_SRC1_FILTER), 0, 0, 0, 3, 0, 0, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR33075, 4, /* up 441, down 640 */
+ 7, 7, 3, 3, 8, 5, 4, 4, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR37800, 3, /* up 63, down 80 */
+ 7, 3, 3, 0, 5, 4, 4, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR44100, 3, /* up 147, down 160 */
+ 7, 7, 3, 0, 8, 5, 4, 0, 3},
+ {AUDIOS_SAMPR48000, AUDIOS_SAMPR48000, 3, /* up 1, down 1 */
+ 1, 0, 0, 0, 1, 0, 0, 0, 3},
+ {0}
+};
+#endif
+
+#if 0
+static uint_t sadasupport_compat_srs[] = {
+ AUDIOS_SAMPR5510, AUDIOS_SAMPR6620, AUDIOS_SAMPR8000,
+ AUDIOS_SAMPR9600, AUDIOS_SAMPR11025, AUDIOS_SAMPR12000,
+ AUDIOS_SAMPR16000, AUDIOS_SAMPR18900, AUDIOS_SAMPR22050,
+ AUDIOS_SAMPR24000, AUDIOS_SAMPR27420, AUDIOS_SAMPR32000,
+ AUDIOS_SAMPR33075, AUDIOS_SAMPR37800, AUDIOS_SAMPR44100,
+ AUDIOS_SAMPR48000, 0
+};
+#endif
+
+static am_ad_sample_rates_t sadasupport_mixer_sample_rates = {
+ MIXER_SRS_FLAG_SR_LIMITS,
+ sadasupport_mixer_srs
+};
+
+#if 0
+static am_ad_sample_rates_t sadasupport_compat_sample_rates = {
+ MIXER_SRS_FLAG_SR_NOT_LIMITS,
+ sadasupport_compat_srs
+};
+#endif
+
+typedef struct
+{
+ oss_device_t *osdev;
+ kmutex_t inst_lock;
+
+/*
+ * Fields related with the OSS audio device
+ */
+
+ volatile int audio_busy;
+ int audio_mode;
+ int oss_audiodev;
+ int play_frag;
+ int rec_frag;
+ int start_flags;
+ int sample_rate;
+ int mute; /* Play silence if mute is set */
+
+/*
+ * Fields related with the audiosup and mixer modules.
+ */
+ audiohdl_t audio_handle;
+ am_ad_info_t ad_info; /* audio device info state */
+ uint16_t vol_bits_mask; /* bits used to ctrl volume */
+
+ audio_info_t audios_defaults; /* default state for dev */
+ audio_device_t audios_dev_info; /* audio device info state */
+#ifndef SOL9
+ ldi_handle_t lh;
+ ldi_ident_t li;
+#endif
+} sadasupport_devc;
+
+static sadasupport_devc *devc = NULL;
+static struct fileinfo tmp_file = { 0 };
+
+static am_ad_entry_t sadasupport_entry = {
+ NULL, /* ad_setup() */
+ NULL, /* ad_teardown() */
+ sadasupport_ad_set_config, /* ad_set_config() */
+ sadasupport_ad_set_format, /* ad_set_format() */
+ sadasupport_ad_start_play, /* ad_start_play() */
+ sadasupport_ad_pause_play, /* ad_pause_play() */
+ sadasupport_ad_stop_play, /* ad_stop_play() */
+ sadasupport_ad_start_record, /* ad_start_record() */
+ sadasupport_ad_stop_record, /* ad_stop_record() */
+ NULL, /* ad_ioctl() */
+ NULL /* ad_iocdata() */
+};
+
+/*
+ * STREAMS structures
+ */
+
+/* STREAMS driver id and limit value struct */
+static struct module_info sadasupport_modinfo = {
+ AUDIOS_IDNUM, /* module ID number */
+ AUDIOS_NAME, /* module name */
+ AUDIOS_MINPACKET, /* minimum packet size */
+ AUDIOS_MAXPACKET, /* maximum packet size */
+ AUDIOS_HIWATER, /* high water mark */
+ AUDIOS_LOWATER, /* low water mark */
+};
+
+/* STREAMS queue processing procedures structures */
+/* read queue */
+static struct qinit sadasupport_rqueue = {
+ audio_sup_rput, /* put procedure */
+ audio_sup_rsvc, /* service procedure */
+ sadasupport_open, /* open procedure */
+ sadasupport_close, /* close procedure */
+ NULL, /* unused */
+ &sadasupport_modinfo, /* module parameters */
+ NULL /* module statistics */
+};
+
+/* write queue */
+static struct qinit sadasupport_wqueue = {
+ audio_sup_wput, /* write procedure */
+ audio_sup_wsvc, /* service procedure */
+ NULL, /* open procedure */
+ NULL, /* close procedure */
+ NULL, /* unused */
+ &sadasupport_modinfo, /* module parameters */
+ NULL /* module statistics */
+};
+
+/* STREAMS entity declaration structure */
+struct streamtab oss_sadasupport_str_info = {
+ &sadasupport_rqueue, /* read queue */
+ &sadasupport_wqueue, /* write queue */
+ NULL, /* mux lower read queue */
+ NULL, /* mux lower write queue */
+};
+
+/*ARGSUSED*/
+static void
+input_callback (int dev, int parm)
+{
+ dmap_p dmap;
+ adev_p adev;
+ unsigned char *buf;
+ int samples, i;
+ oss_native_word flags;
+
+ adev = audio_engines[dev];
+ dmap = adev->dmap_in;
+
+ if (dmap->dmabuf == NULL)
+ {
+ cmn_err (CE_WARN, "Dmabuf==NULL\n");
+ return;
+ }
+
+ MUTEX_ENTER (dmap->mutex, flags);
+
+ samples = dmap->fragment_size / 2; /* Number of 16 bit samples */
+
+ buf = dmap->dmabuf + devc->rec_frag * dmap->fragment_size;
+
+ if (dmap->nfrags == 0)
+ {
+ cmn_err (CE_WARN, "Nfrags==0\n");
+ MUTEX_EXIT (dmap->mutex, flags);
+ return;
+ }
+
+ devc->rec_frag = (devc->rec_frag + 1) % dmap->nfrags;
+ dmap->user_counter += dmap->fragment_size;
+ MUTEX_EXIT (dmap->mutex, flags);
+
+ /* Perform byte swapping (if necessary) */
+ if (do_byteswap)
+ for (i = 0; i < samples * 2; i += 2)
+ {
+ unsigned char tmp;
+
+ tmp = buf[i];
+ buf[i] = buf[i + 1];
+ buf[i + 1] = tmp;
+ }
+ am_send_audio (devc->audio_handle, buf, AUDIO_NO_CHANNEL, samples);
+
+}
+
+static int fill_play_buf (sadasupport_devc * devc);
+
+/*ARGSUSED*/
+static void
+output_callback (int dev, int parm)
+{
+ fill_play_buf (devc);
+}
+
+static int
+setup_device (sadasupport_devc * devc)
+{
+ int fmt = AFMT_S16_NE;
+ int ch = 2;
+ int rate = devc->sample_rate;
+ int mode;
+
+ devc->mute = 0; /* Unmute every time the device gets opened */
+
+ mode = 0;
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_COOKEDMODE,
+ (ioctl_arg) & mode);
+
+#if 0
+ int frag;
+
+ //frag=0x0002000d; /* Two 8k fragments */
+ frag = 0x0008000a; /* 1k fragments */
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SETFRAGMENT,
+ (ioctl_arg) & frag);
+#endif
+
+ do_byteswap = 0;
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SETFMT,
+ (ioctl_arg) & fmt);
+ if (fmt != AFMT_S16_NE)
+ {
+ fmt = AFMT_S16_OE;
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SETFMT,
+ (ioctl_arg) & fmt);
+ if (fmt != AFMT_S16_OE)
+ {
+ cmn_err (CE_WARN, "Internal error (format=%x)\n", fmt);
+ return AUDIO_FAILURE;
+ }
+ do_byteswap = 1;
+ }
+
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_CHANNELS,
+ (ioctl_arg) & ch);
+ if (ch != 2)
+ {
+ cmn_err (CE_WARN, "Internal error (channels=%d)\n", ch);
+ return AUDIO_FAILURE;
+ }
+
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SPEED,
+ (ioctl_arg) & rate);
+ if (rate != devc->sample_rate)
+ {
+/*
+ * Disabling SADA mixing/src may cause problems if the application wants
+ * to use rate that is not supported by the device itself. In that case
+ * we need to switch to the rate returned by the device.
+ */
+ cmn_err (CE_WARN, "Returned sample rate %d is different than requested %d)\n", rate,
+ devc->sample_rate);
+ cmn_err (CE_CONT, "Switching to %d\n", rate);
+ devc->sample_rate = rate;
+ // return AUDIO_FAILURE;
+ }
+
+ return AUDIO_SUCCESS;
+}
+
+#ifndef SOL9
+static int
+sadasupport_open (queue_t * q, dev_t * devp, int flag, int sflag,
+ cred_t * credp)
+{
+ int retval, i;
+ int devnum;
+ int dev = *devp;
+ char *cmd;
+ unsigned int bl_flags = 0;
+ int oss_mode = 0;
+
+ DDB (cmn_err
+ (CE_CONT, "sadasupport_open(dev=%x, flag=%x, sflag=%x)\n",
+ dev, flag, sflag));
+
+ if (devc == NULL)
+ return EIO;
+
+ oss_mode = OPEN_READWRITE;
+
+ mutex_enter (&devc->inst_lock);
+
+ if (devc->audio_busy++ == 0)
+ {
+ oss_audioinfo ai;
+ int err;
+
+ mutex_exit (&devc->inst_lock);
+
+ tmp_file.acc_flags = 0;
+ tmp_file.mode = oss_mode;
+
+ devc->audio_mode = tmp_file.mode;
+
+ DDB (cmn_err (CE_CONT, "Opening /dev/dsp (mode=%x)\n", tmp_file.mode));
+
+ if (ldi_ident_from_dev (dev, &devc->li) != 0)
+ {
+ cmn_err (CE_WARN, "ldi_ident_from_dev failed\n");
+ devc->audio_busy--;
+ return EIO;
+ }
+
+ if ((err =
+ ldi_open_by_name ("/dev/dsp", FWRITE | FREAD, credp, &devc->lh,
+ devc->li)) != 0)
+ {
+ cmn_err (CE_WARN,
+ "ldi_open_by_name(\"/dev/dsp\") failed, errno=%d\n", err);
+ devc->audio_busy--;
+ return -err;
+ }
+
+ ai.dev = -1;
+ if ((err =
+ ldi_ioctl (devc->lh, SNDCTL_ENGINEINFO, (intptr_t) & ai, FKIOCTL,
+ credp, &retval)) != 0)
+ {
+ ldi_close (devc->lh, FREAD | FWRITE, credp);
+ ldi_ident_release (devc->li);
+ cmn_err (CE_WARN, "ldi_ioctl(SNDCTL_AUDIOINFO) failed, err=%d\n",
+ err);
+ devc->audio_busy--;
+ return err;
+ }
+
+ devnum = ai.dev;
+
+ DDB (cmn_err
+ (CE_CONT, "Opened OSS audio engine %d:%s\n", devnum, ai.name));
+
+ if (devnum < 0 || devnum >= num_audio_engines)
+ {
+ cmn_err (CE_WARN, "OSS audio engine number %d is out of range.\n",
+ devnum);
+ ldi_close (devc->lh, FREAD | FWRITE, credp);
+ ldi_ident_release (devc->li);
+ devc->audio_busy--;
+ return ENXIO;
+ }
+
+ devc->oss_audiodev = devnum;
+
+ if (tmp_file.mode & OPEN_READ)
+ audio_engines[devnum]->dmap_in->audio_callback = input_callback;
+ if (tmp_file.mode & OPEN_WRITE)
+ audio_engines[devnum]->dmap_out->audio_callback = output_callback;
+ strcpy (audio_engines[devnum]->cmd, "SADA");
+ strcpy (audio_engines[devnum]->label, "SADA");
+ audio_engines[devnum]->pid = 0;
+
+ if ((retval = setup_device (devc)) != AUDIO_SUCCESS)
+ {
+ cmn_err (CE_NOTE, "setup_device failed\n");
+ mutex_enter (&devc->inst_lock);
+ if (--devc->audio_busy == 0)
+ {
+ ldi_close (devc->lh, FREAD | FWRITE, credp);
+ ldi_ident_release (devc->li);
+ mutex_exit (&devc->inst_lock);
+ }
+ else
+ mutex_exit (&devc->inst_lock);
+
+ return EIO;
+ }
+ }
+ else
+ {
+ if (oss_mode & ~devc->audio_mode)
+ {
+ cmn_err (CE_NOTE, "Conflicting access modes\n");
+
+ if (--devc->audio_busy == 0)
+ {
+ mutex_exit (&devc->inst_lock);
+ ldi_close (devc->lh, FREAD | FWRITE, credp);
+ ldi_ident_release (devc->li);
+ return EBUSY;
+ }
+
+ mutex_exit (&devc->inst_lock);
+ return EBUSY;
+ }
+
+ mutex_exit (&devc->inst_lock);
+
+ }
+
+ DDB (cmn_err (CE_CONT, "Open count %d\n", devc->audio_busy));
+
+ DDB (cmn_err
+ (CE_CONT, "audio_sup_open(q=%p, dev=%x, flag=%x, sflag=%x)\n", q, dev,
+ flag, sflag));
+ if ((retval = audio_sup_open (q, devp, flag, sflag, credp)) != 0)
+ {
+ cmn_err (CE_NOTE, "audio_sup_open() returned %d\n", retval);
+ mutex_enter (&devc->inst_lock);
+ if (--devc->audio_busy == 0)
+ {
+ mutex_exit (&devc->inst_lock);
+ ldi_close (devc->lh, FREAD | FWRITE, credp);
+ ldi_ident_release (devc->li);
+ }
+ else
+ mutex_exit (&devc->inst_lock);
+ }
+
+ return retval;
+}
+
+static int
+sadasupport_close (queue_t * q, int flag, cred_t * credp)
+{
+ int retval, count;
+
+ DDB (cmn_err (CE_CONT, "sadasupport_close(q=%p, flag=%x)\n", q, flag));
+
+ if (!devc->audio_busy)
+ cmn_err (CE_WARN, "Close while not busy.\n");
+
+ retval = audio_sup_close (q, flag, credp);
+
+ mutex_enter (&devc->inst_lock);
+ count = --devc->audio_busy;
+ mutex_exit (&devc->inst_lock);
+
+ DDB (cmn_err (CE_CONT, "Open count (close) %d\n", count));
+ if (count == 0)
+ {
+ DDB (cmn_err
+ (CE_CONT, "Closing OSS audiodev %d\n", devc->oss_audiodev));
+ ldi_close (devc->lh, FREAD | FWRITE, credp);
+ ldi_ident_release (devc->li);
+ devc->audio_mode = 0;
+ }
+
+ return retval;
+}
+#else
+#include "sadasupport_sol9.h"
+#endif
+
+static void
+set_port (sadasupport_devc * devc, int dir, int port)
+{
+ int recdev = SOUND_MASK_MIC;
+
+ if (dir == AUDIO_PLAY) /* Don't support this */
+ return;
+
+ switch (port)
+ {
+ case AUDIO_MICROPHONE:
+ recdev = SOUND_MASK_MIC;
+ break;
+ case AUDIO_LINE_IN:
+ recdev = SOUND_MASK_LINE;
+ break;
+ case AUDIO_CD:
+ recdev = SOUND_MASK_CD;
+ break;
+ }
+
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SOUND_MIXER_WRITE_RECSRC,
+ (ioctl_arg) & recdev);
+ /* Let's hope that worked */
+}
+
+static void
+set_gain (sadasupport_devc * devc, int dir, int gain, int channel)
+{
+ int cmd;
+ int val;
+
+ if (gain < 0)
+ gain = 0;
+ if (gain > 255)
+ gain = 255;
+
+ gain = (gain * 100) / 255;
+
+ if (dir == AUDIO_PLAY)
+ cmd = SNDCTL_DSP_GETPLAYVOL;
+ else
+ cmd = SNDCTL_DSP_GETRECVOL;
+
+ if (oss_audio_ioctl (devc->oss_audiodev, NULL, cmd, (ioctl_arg) & val) < 0)
+ return;
+
+ switch (channel)
+ {
+ case 0: /* Left channel */
+ val = (val & 0xff00) | gain;
+ break;
+
+ case 1: /* Right channel */
+ val = (val & 0x00ff) | (gain << 8);
+ break;
+ }
+
+ if (dir == AUDIO_PLAY)
+ cmd = SNDCTL_DSP_SETPLAYVOL;
+ else
+ cmd = SNDCTL_DSP_SETRECVOL;
+
+ oss_audio_ioctl (devc->oss_audiodev, NULL, cmd, (ioctl_arg) & val);
+}
+
+/*ARGSUSED*/
+static void
+set_monitor_gain (sadasupport_devc * devc, int gain)
+{
+ /* NOP. SADA applications are not allowed to change monitor gain. */
+}
+
+/*ARGSUSED*/
+static int
+sadasupport_ad_set_config (audiohdl_t ahandle, int stream, int command,
+ int dir, int arg1, int arg2)
+{
+/*
+ * We do not support most gain settings. They are incompatible with the way
+ * how OSS 4.0 (and later) works.
+ */
+
+#if 0
+ typedef struct
+ {
+ uint_t cmd;
+ char *name;
+ } cmds_t;
+
+ static const cmds_t cmds[] = {
+ {AM_SET_GAIN, "AM_SET_GAIN"},
+ {AM_SET_GAIN_BAL, "AM_SET_GAIN_BAL"},
+ {AM_SET_PORT, "AM_SET_PORT"},
+ {AM_SET_MONITOR_GAIN, "AM_SET_MONITOR_GAIN"},
+ {AM_OUTPUT_MUTE, "AM_OUTPUT_MUTE"},
+ {AM_MONO_MIC, "AM_MONO_MIC"},
+ {AM_MIC_BOOST, "AM_MIC_BOOST"},
+ {AM_BASS_BOOST, "AM_BASS_BOOST"},
+ {AM_MID_BOOST, "AM_MID_BOOST"},
+ {AM_TREBLE_BOOST, "AM_TREBLE_BOOST"},
+ {AM_LOUDNESS, "AM_LOUDNESS"},
+ {AM_SET_DIAG_MODE, "AM_SET_DIAG_MODE"},
+ {0, NULL}
+ };
+#endif
+
+ if (devc->audio_mode == 0)
+ return AUDIO_SUCCESS;
+
+ switch (command)
+ {
+ case AM_SET_PORT:
+ set_port (devc, dir, arg1);
+ break;
+
+ case AM_SET_GAIN_BAL:
+ return AUDIO_FAILURE;
+ break;
+
+ case AM_SET_GAIN:
+ set_gain (devc, dir, arg1, arg2);
+ break;
+
+ case AM_SET_MONITOR_GAIN:
+ set_monitor_gain (devc, arg1);
+ break;
+
+ case AM_OUTPUT_MUTE:
+ devc->mute = arg1;
+ break;
+
+ default:
+#if 0
+ int i;
+
+ cmn_err (CE_CONT,
+ "sadasupport_ad_set_config(stream=%d, cmd=%x, dir=%d, arg1=%x, arg2=%x)\n",
+ stream, command, dir, arg1, arg2);
+
+ for (i = 0; cmds[i].cmd != 0; i++)
+ if (cmds[i].cmd == command)
+ {
+ cmn_err (CE_CONT, " Unsupported mixer command =%s\n",
+ cmds[i].name);
+ break;
+ }
+#endif
+ break;
+ }
+ return AUDIO_SUCCESS;
+}
+
+/*ARGSUSED*/
+static int
+sadasupport_ad_set_format (audiohdl_t ahandle, int stream, int dir,
+ int sample_rate, int channels, int precision,
+ int encoding)
+{
+
+ DDB (cmn_err (CE_CONT,
+ "sadasupport_ad_set_format(stream=%d, dir=%d, sr=%d, ch=%d, prec=%d, enc=%d)\n",
+ stream, dir, sample_rate, channels, precision, encoding));
+
+ if (precision != AUDIO_PRECISION_16)
+ {
+ cmn_err (CE_WARN, "Sample size must be 16 bits.\n");
+ return AUDIO_FAILURE;
+ }
+
+ if (channels != AUDIO_CHANNELS_STEREO)
+ {
+ cmn_err (CE_WARN, "Channels must be stereo.\n");
+ return AUDIO_FAILURE;
+ }
+
+ if (encoding != AUDIO_ENCODING_LINEAR)
+ {
+ cmn_err (CE_WARN, "Channels must be stereo.\n");
+ return AUDIO_FAILURE;
+ }
+
+ devc->sample_rate = sample_rate;
+
+ return AUDIO_SUCCESS;
+}
+
+static int
+fill_play_buf (sadasupport_devc * devc)
+{
+ int rs;
+ int dev;
+ dmap_p dmap;
+ adev_p adev;
+ unsigned char *buf;
+ int samples, i;
+ oss_native_word flags;
+
+ dev = devc->oss_audiodev;
+
+ adev = audio_engines[dev];
+ dmap = adev->dmap_out;
+
+ if (dmap->dmabuf == NULL)
+ {
+ cmn_err (CE_WARN, "Dmabuf==NULL\n");
+ return AUDIO_FAILURE;
+ }
+
+ MUTEX_ENTER (dmap->mutex, flags);
+
+ samples = dmap->fragment_size / 2; /* Number of 16 bit samples */
+
+ buf = dmap->dmabuf + devc->play_frag * dmap->fragment_size;
+
+ if (dmap->nfrags == 0)
+ {
+ cmn_err (CE_WARN, "Nfrags==0\n");
+ MUTEX_EXIT (dmap->mutex, flags);
+ return AUDIO_FAILURE;
+ }
+
+ rs = am_get_audio (devc->audio_handle, buf, AUDIO_NO_CHANNEL, samples);
+
+ if (devc->mute || rs == 0) /* Device paused or muted */
+ {
+ memset (buf, 0, dmap->fragment_size);
+ }
+ else
+ {
+ /* Perform byte swapping (if necessary) */
+ if (do_byteswap)
+ for (i = 0; i < samples * 2; i += 2)
+ {
+ unsigned char tmp;
+
+ tmp = buf[i];
+ buf[i] = buf[i + 1];
+ buf[i + 1] = tmp;
+ }
+ }
+
+ devc->play_frag = (devc->play_frag + 1) % dmap->nfrags;
+ dmap->user_counter += dmap->fragment_size;
+ MUTEX_EXIT (dmap->mutex, flags);
+
+ return rs;
+}
+
+/*ARGSUSED*/
+static int
+sadasupport_ad_start_play (audiohdl_t ahandle, int stream)
+{
+ int dev;
+ dmap_p dmap;
+ adev_p adev;
+
+ dev = devc->oss_audiodev;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ {
+ cmn_err (CE_CONT, "Bad oss_audiodev %d\n", dev);
+ return AUDIO_FAILURE;
+ }
+
+ adev = audio_engines[dev];
+ dmap = adev->dmap_out;
+
+ mutex_enter (&devc->inst_lock);
+/*
+ * Already playing?
+ */
+ if (devc->start_flags & PCM_ENABLE_OUTPUT)
+ {
+ mutex_exit (&devc->inst_lock);
+ return 0; /* All buffers are full at this moment */
+ }
+
+ DDB (cmn_err (CE_CONT, "sadasupport_ad_start_play(stream=%d)\n", stream));
+
+/*
+ * Skip the first fragment (fill with silence) to avoid underruns
+ */
+ devc->play_frag = 1;
+ dmap->user_counter = dmap->fragment_size;
+
+/*
+ * Trigger the play engine
+ */
+ dmap->dma_mode = PCM_ENABLE_OUTPUT;
+ devc->start_flags &= ~PCM_ENABLE_OUTPUT;
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & devc->start_flags);
+ devc->start_flags |= PCM_ENABLE_OUTPUT;
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & devc->start_flags);
+
+ //dmap->user_counter += dmap->fragment_size;
+ devc->audios_defaults.play.buffer_size = dmap->fragment_size;
+ devc->ad_info.ad_play.ad_bsize = dmap->fragment_size;
+
+ mutex_exit (&devc->inst_lock);
+ return fill_play_buf (devc);
+}
+
+/*ARGSUSED*/
+static void
+sadasupport_ad_stop_play (audiohdl_t ahandle, int stream)
+{
+ DDB (cmn_err (CE_CONT, "sadasupport_ad_stop_play (stream=%d)\n", stream));
+ mutex_enter (&devc->inst_lock);
+ devc->start_flags &= ~PCM_ENABLE_OUTPUT;
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & devc->start_flags);
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_HALT_OUTPUT,
+ (ioctl_arg) NULL);
+ mutex_exit (&devc->inst_lock);
+}
+
+static void
+sadasupport_ad_pause_play (audiohdl_t ahandle, int stream)
+{
+ DDB (cmn_err (CE_CONT, "sadasupport_ad_pause_play\n"));
+
+ sadasupport_ad_stop_play (ahandle, stream);
+}
+
+/*ARGSUSED*/
+static int
+sadasupport_ad_start_record (audiohdl_t ahandle, int stream)
+{
+ int dev;
+ dmap_p dmap;
+ adev_p adev;
+
+ dev = devc->oss_audiodev;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ {
+ cmn_err (CE_CONT, "Bad oss_audiodev %d\n", dev);
+ return AUDIO_FAILURE;
+ }
+
+ mutex_enter (&devc->inst_lock);
+ adev = audio_engines[dev];
+ dmap = adev->dmap_in;
+
+/*
+ * Already Recording?
+ */
+ if (devc->start_flags & PCM_ENABLE_INPUT)
+ {
+ mutex_exit (&devc->inst_lock);
+ return AUDIO_SUCCESS; /* All buffers are full at this moment */
+ }
+
+ DDB (cmn_err (CE_CONT, "sadasupport_ad_start_record(stream=%d)\n", stream));
+
+/*
+ * Skip the first fragment (fill with silence) to avoid underruns
+ */
+ devc->rec_frag = 0;
+ dmap->user_counter = 0;
+
+/*
+ * Trigger the rec engine
+ */
+ dmap->dma_mode = PCM_ENABLE_INPUT;
+ devc->start_flags &= ~PCM_ENABLE_INPUT;
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & devc->start_flags);
+ devc->start_flags |= PCM_ENABLE_INPUT;
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & devc->start_flags);
+
+ devc->audios_defaults.record.buffer_size = dmap->fragment_size;
+ devc->ad_info.ad_record.ad_bsize = dmap->fragment_size;
+
+ mutex_exit (&devc->inst_lock);
+ return AUDIO_SUCCESS;
+}
+
+/*ARGSUSED*/
+static void
+sadasupport_ad_stop_record (audiohdl_t ahandle, int stream)
+{
+ DDB (cmn_err (CE_CONT, "sadasupport_ad_stop_record(stream=%d)\n", stream));
+ mutex_enter (&devc->inst_lock);
+ devc->start_flags &= ~PCM_ENABLE_INPUT;
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & devc->start_flags);
+ oss_audio_ioctl (devc->oss_audiodev, NULL, SNDCTL_DSP_HALT_INPUT,
+ (ioctl_arg) NULL);
+ mutex_exit (&devc->inst_lock);
+}
+
+static int
+sadasupport_init_state (sadasupport_devc * devc, dev_info_t * dip)
+{
+ int rints = 175;
+ int pints = 175;
+ int cdrom;
+ int mode;
+
+ devc->vol_bits_mask = 5;
+
+ cdrom = ddi_prop_get_int (DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+ "cdrom", 0);
+
+ /* get the mode from the .conf file */
+ if (ddi_prop_get_int (DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+ "mixer-mode", 1))
+ {
+ mode = AM_MIXER_MODE;
+ }
+ else
+ {
+ mode = AM_COMPAT_MODE;
+ }
+
+ /* fill in the device default state */
+ devc->audios_defaults.play.sample_rate = AUDIOS_DEFAULT_SR;
+ devc->audios_defaults.play.channels = AUDIOS_DEFAULT_CH;
+ devc->audios_defaults.play.precision = AUDIOS_DEFAULT_PREC;
+ devc->audios_defaults.play.encoding = AUDIOS_DEFAULT_ENC;
+ devc->audios_defaults.play.gain = AUDIOS_DEFAULT_PGAIN;
+ devc->audios_defaults.play.port = AUDIO_SPEAKER | AUDIO_LINE_OUT;
+ devc->audios_defaults.play.avail_ports = AUDIO_SPEAKER | AUDIO_LINE_OUT;
+ devc->audios_defaults.play.mod_ports = AUDIO_SPEAKER | AUDIO_LINE_OUT;
+ devc->audios_defaults.play.buffer_size = AUDIOS_BUFFSIZE;
+ devc->audios_defaults.play.balance = AUDIOS_DEFAULT_BAL;
+
+ devc->audios_defaults.record.sample_rate = AUDIOS_DEFAULT_SR;
+ devc->audios_defaults.record.channels = AUDIOS_DEFAULT_CH;
+ devc->audios_defaults.record.precision = AUDIOS_DEFAULT_PREC;
+ devc->audios_defaults.record.encoding = AUDIOS_DEFAULT_ENC;
+ devc->audios_defaults.record.gain = AUDIOS_DEFAULT_PGAIN;
+ devc->audios_defaults.record.port = AUDIO_MICROPHONE;
+ devc->audios_defaults.record.avail_ports =
+ AUDIO_MICROPHONE | AUDIO_LINE_IN | AUDIO_CD;
+ devc->audios_defaults.record.mod_ports =
+ AUDIO_MICROPHONE | AUDIO_LINE_IN | AUDIO_CD;
+ devc->audios_defaults.record.buffer_size = AUDIOS_BUFFSIZE;
+ devc->audios_defaults.record.balance = AUDIOS_DEFAULT_BAL;
+
+ devc->audios_defaults.monitor_gain = AUDIOS_DEFAULT_MONITOR_GAIN;
+ devc->audios_defaults.output_muted = B_FALSE;
+ devc->audios_defaults.ref_cnt = B_FALSE;
+ devc->audios_defaults.hw_features =
+ AUDIO_HWFEATURE_DUPLEX | AUDIO_HWFEATURE_PLAY |
+ AUDIO_HWFEATURE_IN2OUT | AUDIO_HWFEATURE_RECORD;
+ devc->audios_defaults.sw_features = AUDIO_SWFEATURE_MIXER;
+
+ if (cdrom)
+ {
+ devc->audios_defaults.record.avail_ports |= AUDIO_CD;
+ devc->audios_defaults.record.mod_ports |= AUDIO_CD;
+ }
+
+#if 0
+ devc->audios_psample_rate = devc->audios_defaults.play.sample_rate;
+ devc->audios_pchannels = devc->audios_defaults.play.channels;
+ devc->audios_pprecision = devc->audios_defaults.play.precision;
+ devc->audios_csample_rate = devc->audios_defaults.record.sample_rate;
+ devc->audios_cchannels = devc->audios_defaults.record.channels;
+ devc->audios_cprecision = devc->audios_defaults.record.precision;
+#endif
+
+ /*
+ * fill in the ad_info structure
+ */
+ devc->ad_info.ad_mode = mode;
+ devc->ad_info.ad_int_vers = AM_VERSION;
+ devc->ad_info.ad_add_mode = NULL;
+ devc->ad_info.ad_codec_type = AM_TRAD_CODEC;
+ devc->ad_info.ad_defaults = &devc->audios_defaults;
+ devc->ad_info.ad_play_comb = sadasupport_combinations;
+ devc->ad_info.ad_rec_comb = sadasupport_combinations;
+ devc->ad_info.ad_entry = &sadasupport_entry;
+ devc->ad_info.ad_dev_info = &devc->audios_dev_info;
+ devc->ad_info.ad_diag_flags = AM_DIAG_INTERNAL_LOOP;
+ devc->ad_info.ad_diff_flags =
+ AM_DIFF_SR | AM_DIFF_CH | AM_DIFF_PREC | AM_DIFF_ENC;
+ devc->ad_info.ad_assist_flags = AM_ASSIST_MIC;
+ devc->ad_info.ad_misc_flags = AM_MISC_RP_EXCL | AM_MISC_MONO_DUP;
+ devc->ad_info.ad_translate_flags =
+ AM_MISC_8_P_TRANSLATE | AM_MISC_8_R_TRANSLATE;
+ devc->ad_info.ad_num_mics = 1;
+
+ /* play capabilities */
+ devc->ad_info.ad_play.ad_mixer_srs = sadasupport_mixer_sample_rates;
+
+ devc->ad_info.ad_play.ad_compat_srs = sadasupport_mixer_sample_rates;
+
+#ifdef SOL9
+ devc->ad_info.ad_play.ad_conv = &am_src1;
+ devc->ad_info.ad_play.ad_sr_info = sadasupport_play_sample_rates_info;
+#else
+ devc->ad_info.ad_play.ad_conv = &am_src2;
+ devc->ad_info.ad_play.ad_sr_info = NULL;
+#endif
+ devc->ad_info.ad_play.ad_chs = sadasupport_channels;
+ devc->ad_info.ad_play.ad_int_rate = pints;
+ devc->ad_info.ad_play.ad_max_chs = 32;
+ devc->ad_info.ad_play.ad_bsize = AUDIOS_BUFFSIZE;
+
+ /* record capabilities */
+ devc->ad_info.ad_record.ad_mixer_srs = sadasupport_mixer_sample_rates;
+ devc->ad_info.ad_record.ad_compat_srs = sadasupport_mixer_sample_rates;
+#ifdef SOL9
+ devc->ad_info.ad_record.ad_conv = &am_src1;
+ devc->ad_info.ad_record.ad_sr_info = sadasupport_record_sample_rates_info;
+#else
+ devc->ad_info.ad_record.ad_conv = &am_src2;
+ devc->ad_info.ad_record.ad_sr_info = NULL;
+#endif
+ devc->ad_info.ad_record.ad_chs = sadasupport_channels;
+ devc->ad_info.ad_record.ad_int_rate = rints;
+ devc->ad_info.ad_record.ad_max_chs = 32;
+ devc->ad_info.ad_record.ad_bsize = AUDIOS_BUFFSIZE;
+
+ /* fill in device info strings */
+ (void) strcpy (devc->audios_dev_info.name, AUDIOS_DEV_NAME);
+ (void) strcpy (devc->audios_dev_info.config, AUDIOS_DEV_CONFIG);
+ (void) strcpy (devc->audios_dev_info.version, AUDIOS_DEV_VERSION);
+
+#if 0
+ devc->play_buf_size = AUDIOS_SAMPR48000 * AUDIO_CHANNELS_STEREO *
+ (AUDIO_PRECISION_16 >> AUDIO_PRECISION_SHIFT) / pints;
+ devc->play_buf_size += AUDIOS_MOD_SIZE -
+ (devc->play_buf_size % AUDIOS_MOD_SIZE);
+ devc->record_buf_size = AUDIOS_SAMPR48000 * AUDIO_CHANNELS_STEREO *
+ (AUDIO_PRECISION_16 >> AUDIO_PRECISION_SHIFT) / rints;
+ devc->record_buf_size += AUDIOS_MOD_SIZE -
+ (devc->record_buf_size % AUDIOS_MOD_SIZE);
+#endif
+ return (AUDIO_SUCCESS);
+
+} /* sadasupport_init_state */
+
+int
+oss_sadasupport_attach (oss_device_t * osdev)
+{
+#ifndef SOL9
+ audio_sup_reg_data_t data;
+#endif
+ int instance;
+ /* extern struct cb_ops ossdrv_streams_cb_ops; */
+
+ sadasupport_mixer_srs[1] = sadasupport_rate; /* Set the maximum rate */
+
+ instance = ddi_get_instance (osdev->dip);
+
+ DDB (cmn_err (CE_CONT, "sadasupport_attach\n"));
+
+ if (devc != NULL)
+ {
+ cmn_err (CE_WARN, "Multiple instances are not permitted\n");
+ return 0;
+ }
+
+ devc = PMALLOC (osdev, sizeof (*devc));
+ devc->osdev = osdev;
+ devc->oss_audiodev = -1;
+ devc->start_flags = 0;
+ mutex_init (&devc->inst_lock, NULL, MUTEX_DRIVER, NULL);
+
+ osdev->devc = devc;
+
+#ifdef SOL9
+ if ((devc->audio_handle =
+ audio_sup_attach (osdev->dip, DDI_ATTACH)) == NULL)
+ {
+ audio_sup_log (NULL, CE_WARN,
+ "!%s%d: attach() audio_sup_attach () failed",
+ DRIVER_NICK, instance);
+ return 0;
+ }
+ DDB (cmn_err (CE_CONT, "audio_sup_attach() OK, handle=%p\n",
+ devc->audio_handle));
+#else
+ data.asrd_version = AUDIOSUP_VERSION;
+ data.asrd_key = NULL;
+
+ if ((devc->audio_handle = audio_sup_register (osdev->dip, &data)) == NULL)
+ {
+ audio_sup_log (NULL, CE_WARN,
+ "!%s%d: attach() audio_sup_register() failed",
+ DRIVER_NICK, instance);
+ return 0;
+ }
+ DDB (cmn_err (CE_CONT, "audio_sup_register() OK, handle=%x\n",
+ devc->audio_handle));
+#endif
+ /* Save private data */
+ audio_sup_set_private (devc->audio_handle, devc);
+
+ if ((sadasupport_init_state (devc, osdev->dip)) != AUDIO_SUCCESS)
+ {
+ audio_sup_log (devc->audio_handle, CE_WARN,
+ "!attach() init state structure failed");
+ return 0;
+ }
+
+ /* call the mixer attach() routine */
+ if (am_attach (devc->audio_handle, DDI_ATTACH, &devc->ad_info) !=
+ AUDIO_SUCCESS)
+ {
+ audio_sup_log (devc->audio_handle, CE_WARN,
+ "!attach() am_attach() failed");
+ return 0;
+ }
+
+ oss_register_device (osdev, "SADA compatibility layer");
+ ddi_report_dev (osdev->dip);
+
+/*
+ * Take a copy of the callback options and replace the open/close
+ * entry points with our own version.
+ */
+
+ return 1;
+}
+
+int
+oss_sadasupport_detach (oss_device_t * osdev)
+{
+ /* int instance; */
+ sadasupport_devc *devc = osdev->devc;
+
+ if (devc != NULL && devc->audio_busy)
+ return 0;
+
+ /* instance = ddi_get_instance (osdev->dip); */
+
+#if 0
+ /* stop DMA engines */
+ mutex_enter (&devc->inst_lock);
+ sadasupport_stop_dma (devc);
+ mutex_exit (&devc->inst_lock);
+
+ /* remove the interrupt handler */
+ ddi_remove_intr (dip, 0, devc->intr_iblock);
+
+ /* free DMA memory */
+ sadasupport_free_sample_buf (devc, &devc->play_buf);
+ sadasupport_free_sample_buf (devc, &devc->record_buf);
+
+ /* free the kernel statistics structure */
+ if (devc->audios_ksp)
+ {
+ kstat_delete (devc->audios_ksp);
+ }
+#endif
+ /* detach audio mixer */
+ (void) am_detach (devc->audio_handle, DDI_DETACH);
+
+ /*
+ * call the audio support module's detach routine to remove this
+ * driver completely from the audio driver architecture.
+ */
+#ifdef SOL9
+ (void) audio_sup_detach (devc->audio_handle, DDI_DETACH);
+#else
+ (void) audio_sup_unregister (devc->audio_handle);
+#endif
+ mutex_destroy (&devc->inst_lock);
+ devc = NULL;
+
+ return 1;
+}
diff --git a/kernel/drv/oss_sadasupport/oss_sadasupport.man b/kernel/drv/oss_sadasupport/oss_sadasupport.man
new file mode 100644
index 0000000..4cce53e
--- /dev/null
+++ b/kernel/drv/oss_sadasupport/oss_sadasupport.man
@@ -0,0 +1,26 @@
+NAME
+oss_sadasupport - Open Sound System to Sun "devaudio" converter driver.
+
+DESCRIPTION
+Open Sound System driver Solaris "devaudio" or "SADA" compatibility.
+This driver is a shim driver between SADA's audio core and amsrc2 (mixer)
+and the OSS audio core. Currently playback, recording and mixer controls
+of SADA/devaudio are supported by this driver. This driver essentially
+translates between SADA audio and OSS audio. It relies on SADA to keep
+track of complete audio information and then takes that information and
+translates it into OSS API. This way, OSS drivers can achieve a 99.9%
+emulation of SADA APIs.
+
+OPTIONS
+No configuration options defined for the current version.
+
+KNOWN PROBLEMS
+Mixer volume control (/dev/audioctl) emulation is very limited. It is only
+possible to change the playback volume. Use native OSS mixers such as
+ossxmix(1) for volume control and control panel functions.
+
+FILES
+CONFIGFILEPATH/oss_sadasupport.conf Device configuration file
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_sadasupport/sadasupport_sol9.h b/kernel/drv/oss_sadasupport/sadasupport_sol9.h
new file mode 100644
index 0000000..6bf7518
--- /dev/null
+++ b/kernel/drv/oss_sadasupport/sadasupport_sol9.h
@@ -0,0 +1,187 @@
+/*
+ * Purpose: Solaris 9 compatible version of sadasupport_open/close
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+static int
+sadasupport_open (queue_t * q, dev_t * devp, int flag, int sflag,
+ cred_t * credp)
+{
+ int retval, i;
+ int tmpdev;
+ int dev = *devp;
+ char *cmd;
+ unsigned int bl_flags = 0;
+ int oss_mode = 0;
+#ifndef SOL9
+ extern void oss_forceload_drivers (int dev, cred_t * cred_p);
+#endif
+
+ DDB (cmn_err
+ (CE_CONT, "sadasupport_open(q=%x, dev=%x, flag=%x, sflag=%x)\n", q,
+ dev, flag, sflag));
+
+ cmd = oss_get_procname ();
+ DDB (cmn_err (CE_CONT, "Command %s\n", cmd));
+
+ if (devc == NULL)
+ return EIO;
+
+ oss_mode = OPEN_READWRITE;
+
+ mutex_enter (&devc->inst_lock);
+
+ if (devc->audio_busy++ == 0)
+ {
+ mutex_exit (&devc->inst_lock);
+
+ tmp_file.acc_flags = 0;
+ tmp_file.mode = oss_mode;
+
+ tmpdev = 0;
+ devc->audio_mode = tmp_file.mode;
+#if 0
+ DDB (cmn_err (CE_CONT, "Opening OSS audio device file %d (mode=%x)\n",
+ devc->masterdev, tmp_file.mode));
+
+ if (devc->masterdev >= 0 && devc->masterdev < num_audio_devfiles)
+#endif
+ {
+ /* Open /dev/dsp# */
+ tmp_file.mode = oss_mode = OPEN_READ | OPEN_WRITE;
+ if ((retval =
+ oss_audio_open_devfile (0, OSS_DEV_DSP,
+ &tmp_file, 1, OF_DEVAUDIO,
+ &tmpdev)) < 0)
+ {
+ mutex_enter (&devc->inst_lock);
+ devc->audio_busy = 0;
+ mutex_exit (&devc->inst_lock);
+ return -retval;
+ }
+ }
+#if 0
+ else
+
+ {
+ /* Open /dev/dsp */
+
+ if ((retval =
+ oss_open_vdsp (0, OSS_DEV_VDSP, &tmp_file, 1, OF_DEVAUDIO,
+ &tmpdev)) < 0)
+ {
+ mutex_enter (&devc->inst_lock);
+ devc->audio_busy = 0;
+ mutex_exit (&devc->inst_lock);
+ return -retval;
+ }
+ }
+#endif
+ DDB (cmn_err
+ (CE_CONT, "Opened OSS audio engine %d, minor=%d\n", retval,
+ tmpdev));
+
+ devc->oss_audiodev = retval;
+
+ if (tmp_file.mode & OPEN_READ)
+ audio_engines[retval]->dmap_in->audio_callback = input_callback;
+ if (tmp_file.mode & OPEN_WRITE)
+ audio_engines[retval]->dmap_out->audio_callback = output_callback;
+ strcpy (audio_engines[retval]->cmd, "SADA");
+ strcpy (audio_engines[retval]->label, "SADA");
+ audio_engines[retval]->pid = 0;
+
+ if ((retval = setup_device (devc)) != AUDIO_SUCCESS)
+ {
+ cmn_err (CE_NOTE, "setup_device failed\n");
+ mutex_enter (&devc->inst_lock);
+ if (--devc->audio_busy == 0)
+ {
+ mutex_exit (&devc->inst_lock);
+ oss_audio_release (devc->oss_audiodev, &tmp_file);
+ }
+ else
+ mutex_exit (&devc->inst_lock);
+
+ return EIO;
+ }
+ }
+ else
+ {
+ if (oss_mode & ~devc->audio_mode)
+ {
+ cmn_err (CE_NOTE, "Conflicting access modes\n");
+
+ if (--devc->audio_busy == 0)
+ {
+ mutex_exit (&devc->inst_lock);
+ oss_audio_release (devc->oss_audiodev, &tmp_file);
+ return EBUSY;
+ }
+
+ mutex_exit (&devc->inst_lock);
+ return EBUSY;
+ }
+
+ mutex_exit (&devc->inst_lock);
+
+ }
+
+ DDB (cmn_err (CE_CONT, "Open count %d\n", devc->audio_busy));
+
+ DDB (cmn_err
+ (CE_CONT, "audio_sup_open(q=%x, dev=%x, flag=%x, sflag=%x)\n", q, dev,
+ flag, sflag));
+ if ((retval = audio_sup_open (q, devp, flag, sflag, credp)) != 0)
+ {
+ cmn_err (CE_NOTE, "audio_sup_open() returned %d\n", retval);
+ mutex_enter (&devc->inst_lock);
+ if (--devc->audio_busy == 0)
+ {
+ mutex_exit (&devc->inst_lock);
+ oss_audio_release (devc->oss_audiodev, &tmp_file);
+ }
+ else
+ mutex_exit (&devc->inst_lock);
+ }
+
+ return retval;
+}
+
+static int
+sadasupport_close (queue_t * q, int flag, cred_t * credp)
+{
+ int retval, count;
+
+ DDB (cmn_err (CE_CONT, "sadasupport_close(q=%x, flag=%x)\n", q, flag));
+
+ if (!devc->audio_busy)
+ cmn_err (CE_WARN, "Close while not busy.\n");
+
+ retval = audio_sup_close (q, flag, credp);
+
+ mutex_enter (&devc->inst_lock);
+ count = --devc->audio_busy;
+ mutex_exit (&devc->inst_lock);
+
+ DDB (cmn_err (CE_CONT, "Open count (close) %d\n", count));
+ if (count == 0)
+ {
+ DDB (cmn_err
+ (CE_CONT, "Closing OSS audiodev %d\n", devc->oss_audiodev));
+ oss_audio_release (devc->oss_audiodev, &tmp_file);
+ devc->audio_mode = 0;
+ }
+
+ return retval;
+}
diff --git a/kernel/drv/oss_sblive/.devices b/kernel/drv/oss_sblive/.devices
new file mode 100644
index 0000000..56d10f0
--- /dev/null
+++ b/kernel/drv/oss_sblive/.devices
@@ -0,0 +1,7 @@
+oss_sblive pci1102,2 Creative Sound Blaster Live
+oss_sblive pcs1102,8040 Creative Sound Blaster Live 1024/Platinum
+oss_sblive pcs1102,8061 Creative Sound Blaster Live 5.1/Platinum IR
+oss_sblive pci1102,4 Creative Sound Blaster Audigy/Audigy2
+oss_sblive pcs1102,51 Creative Sound Blaster Audigy Platinum
+oss_sblive pci1102,8 Creative Sound Blaster Audigy2 Value/Audigy4
+oss_sblive pci1102,2001 Creative Sound Blaster Audigy2 ZS PCMCIA
diff --git a/kernel/drv/oss_sblive/.name b/kernel/drv/oss_sblive/.name
new file mode 100644
index 0000000..2bcb686
--- /dev/null
+++ b/kernel/drv/oss_sblive/.name
@@ -0,0 +1 @@
+Creative Sound Blaster Live/Audigy
diff --git a/kernel/drv/oss_sblive/.params b/kernel/drv/oss_sblive/.params
new file mode 100644
index 0000000..7720436
--- /dev/null
+++ b/kernel/drv/oss_sblive/.params
@@ -0,0 +1,25 @@
+int sblive_memlimit = 8;
+/*
+ * Amount of memory allocated to SBLive Synth.
+ * Values: 4-4096 (in megabytes). Default: 8MB
+ */
+
+int sblive_devices = 0;
+/*
+ * Specifies number of audio output engines for SBLive/Audigy.
+ * Changing this setting is not recommanded.
+ * Values: 0, 5-32
+ * Default: 0 (Use device dependent optimum value).
+ */
+
+int sblive_digital_din = 0;
+/*
+ * Sets the SPDIF/Analog combo output to audio or spdif mode
+ * Values: 1 = Digital, 0=Analog Default: 0
+ */
+
+int audigy_digital_din = 1;
+/*
+ * Sets the SPDIF/Analog combo output to analog or spdif mode
+ * Values: 1 = Digital, 0 = Analog Default: 1
+ */
diff --git a/kernel/drv/oss_sblive/emu10k1_dsp.h b/kernel/drv/oss_sblive/emu10k1_dsp.h
new file mode 100644
index 0000000..87b4b3b
--- /dev/null
+++ b/kernel/drv/oss_sblive/emu10k1_dsp.h
@@ -0,0 +1,989 @@
+/*
+ * Purpose: DSP firmware file for Live!
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+static unsigned char emu10k1_dsp[] = {
+ 0x01, 0x00, 0xe1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x96, 0x01, 0x00, 0x00,
+ 0x44, 0x00, 0x00, 0x00,
+ 0x40, 0x18, 0x44, 0x00, 0x44, 0x04, 0x00, 0x00, 0x40, 0x1c, 0x44, 0x00,
+ 0x02, 0x19, 0x04, 0x00,
+ 0x40, 0x20, 0x04, 0x00, 0x03, 0x1d, 0x04, 0x00, 0x40, 0x24, 0x04, 0x00,
+ 0x44, 0x08, 0x00, 0x00,
+ 0x40, 0x28, 0x44, 0x00, 0x44, 0x0c, 0x00, 0x00, 0x40, 0x2c, 0x44, 0x00,
+ 0x02, 0x29, 0x04, 0x00,
+ 0x40, 0x28, 0x04, 0x00, 0x03, 0x2d, 0x04, 0x00, 0x40, 0x2c, 0x04, 0x00,
+ 0x36, 0x21, 0x04, 0x00,
+ 0x40, 0x30, 0x04, 0x00, 0x36, 0x25, 0x04, 0x00, 0x40, 0x34, 0x04, 0x00,
+ 0x40, 0x30, 0x04, 0x00,
+ 0x0c, 0x41, 0x94, 0x00, 0x10, 0xdd, 0x04, 0x00, 0x37, 0xdd, 0xa4, 0x00,
+ 0x40, 0x34, 0x04, 0x00,
+ 0x0d, 0x41, 0x94, 0x00, 0x10, 0xe1, 0x04, 0x00, 0x38, 0xe1, 0xa4, 0x00,
+ 0x30, 0x49, 0x00, 0x00,
+ 0x0c, 0x31, 0x04, 0x00, 0x30, 0x4d, 0x00, 0x00, 0x0d, 0x35, 0x04, 0x00,
+ 0x30, 0x49, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0xc5, 0x04, 0x00,
+ 0x31, 0xc5, 0xa4, 0x00, 0x30, 0x4d, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0xc9, 0x04, 0x00, 0x32, 0xc9, 0xa4, 0x00,
+ 0x33, 0x41, 0x00, 0x00,
+ 0x0c, 0x31, 0x04, 0x00, 0x33, 0x45, 0x00, 0x00, 0x0d, 0x35, 0x04, 0x00,
+ 0x33, 0x41, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0xd1, 0x04, 0x00,
+ 0x34, 0xd1, 0xa4, 0x00, 0x33, 0x45, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0xd5, 0x04, 0x00, 0x35, 0xd5, 0xa4, 0x00,
+ 0x2d, 0x59, 0x00, 0x00,
+ 0x0c, 0x31, 0x04, 0x00, 0x2d, 0x5d, 0x00, 0x00, 0x0d, 0x35, 0x04, 0x00,
+ 0x2d, 0x59, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0xb9, 0x04, 0x00,
+ 0x2e, 0xb9, 0xa4, 0x00, 0x2d, 0x5d, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0xbd, 0x04, 0x00, 0x2f, 0xbd, 0xa4, 0x00,
+ 0x2d, 0x59, 0x00, 0x00,
+ 0x0c, 0x31, 0x04, 0x00, 0x2d, 0x5d, 0x00, 0x00, 0x0d, 0x35, 0x04, 0x00,
+ 0x39, 0x71, 0x00, 0x00,
+ 0x0c, 0x31, 0x04, 0x00, 0x39, 0x75, 0x00, 0x00, 0x0d, 0x35, 0x04, 0x00,
+ 0x39, 0x71, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0xe9, 0x04, 0x00,
+ 0x3a, 0xe9, 0xa4, 0x00, 0x39, 0x75, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0xed, 0x04, 0x00, 0x3b, 0xed, 0xa4, 0x00,
+ 0x04, 0x31, 0x04, 0x00,
+ 0x40, 0x30, 0x04, 0x00, 0x05, 0x35, 0x04, 0x00, 0x40, 0x34, 0x04, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x0c, 0xa5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x0c, 0xa1, 0x65, 0x00,
+ 0x16, 0xa5, 0x05, 0x00,
+ 0x40, 0xa4, 0x05, 0x00, 0x6e, 0xa5, 0x05, 0x00, 0x40, 0xa4, 0x05, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x82, 0x0d, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x81, 0x09, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x69, 0x05, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x85, 0x19, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x84, 0x15, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x10, 0x66, 0x00,
+ 0x26, 0x05, 0x06, 0x00,
+ 0x40, 0x10, 0x06, 0x00, 0x27, 0x09, 0x06, 0x00, 0x84, 0x11, 0x06, 0x00,
+ 0x28, 0x15, 0x06, 0x00,
+ 0x84, 0x11, 0x06, 0x00, 0x29, 0x0d, 0x06, 0x00, 0x84, 0x11, 0x06, 0x00,
+ 0x2a, 0x19, 0x06, 0x00,
+ 0x84, 0x11, 0x06, 0x00, 0x6c, 0x11, 0x06, 0x00, 0x40, 0x10, 0x46, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x84, 0xa5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x7c, 0xf5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x7b, 0xf1, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x69, 0xed, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x7f, 0x01, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x7e, 0xfd, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0xf8, 0x65, 0x00, 0x21, 0xed, 0x05, 0x00, 0x40, 0xf8, 0x05, 0x00,
+ 0x22, 0xf1, 0x05, 0x00,
+ 0x7e, 0xf9, 0x05, 0x00, 0x23, 0xfd, 0x05, 0x00, 0x7e, 0xf9, 0x05, 0x00,
+ 0x24, 0xf5, 0x05, 0x00,
+ 0x7e, 0xf9, 0x05, 0x00, 0x25, 0x01, 0x06, 0x00, 0x7e, 0xf9, 0x05, 0x00,
+ 0x6c, 0xf9, 0x05, 0x00,
+ 0x40, 0xf8, 0x45, 0x00, 0x40, 0x00, 0x01, 0x00, 0x7e, 0xa5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x76, 0xdd, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x75, 0xd9, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x69, 0xd5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x79, 0xe9, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x78, 0xe5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0xe0, 0x65, 0x00,
+ 0x1c, 0xd5, 0x05, 0x00,
+ 0x40, 0xe0, 0x05, 0x00, 0x1d, 0xd9, 0x05, 0x00, 0x78, 0xe1, 0x05, 0x00,
+ 0x1e, 0xe5, 0x05, 0x00,
+ 0x78, 0xe1, 0x05, 0x00, 0x1f, 0xdd, 0x05, 0x00, 0x78, 0xe1, 0x05, 0x00,
+ 0x20, 0xe9, 0x05, 0x00,
+ 0x78, 0xe1, 0x05, 0x00, 0x6c, 0xe1, 0x05, 0x00, 0x40, 0xe0, 0x45, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x78, 0xa5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x70, 0xc5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x6f, 0xc1, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x69, 0xbd, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x73, 0xd1, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x72, 0xcd, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0xc8, 0x65, 0x00, 0x17, 0xbd, 0x05, 0x00, 0x40, 0xc8, 0x05, 0x00,
+ 0x18, 0xc1, 0x05, 0x00,
+ 0x72, 0xc9, 0x05, 0x00, 0x19, 0xcd, 0x05, 0x00, 0x72, 0xc9, 0x05, 0x00,
+ 0x1a, 0xc5, 0x05, 0x00,
+ 0x72, 0xc9, 0x05, 0x00, 0x1b, 0xd1, 0x05, 0x00, 0x72, 0xc9, 0x05, 0x00,
+ 0x6c, 0xc9, 0x05, 0x00,
+ 0x40, 0xc8, 0x45, 0x00, 0x40, 0x00, 0x01, 0x00, 0x72, 0xa5, 0x65, 0x00,
+ 0x6d, 0xa5, 0x05, 0x00,
+ 0x6b, 0xa5, 0x45, 0x00, 0x2c, 0xa5, 0x05, 0x00, 0x40, 0x30, 0x44, 0x00,
+ 0x2b, 0xa1, 0x05, 0x00,
+ 0x0c, 0x31, 0x44, 0x00, 0x40, 0x00, 0x01, 0x00, 0x0d, 0xa5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x0d, 0xa1, 0x65, 0x00, 0x16, 0xa5, 0x05, 0x00, 0x40, 0xa4, 0x05, 0x00,
+ 0x6e, 0xa5, 0x05, 0x00,
+ 0x40, 0xa4, 0x05, 0x00, 0x40, 0x00, 0x01, 0x00, 0x9a, 0x6d, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x99, 0x69, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x69, 0x65, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x9d, 0x79, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x9c, 0x75, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x70, 0x66, 0x00, 0x26, 0x65, 0x06, 0x00, 0x40, 0x70, 0x06, 0x00,
+ 0x27, 0x69, 0x06, 0x00,
+ 0x9c, 0x71, 0x06, 0x00, 0x28, 0x75, 0x06, 0x00, 0x9c, 0x71, 0x06, 0x00,
+ 0x29, 0x6d, 0x06, 0x00,
+ 0x9c, 0x71, 0x06, 0x00, 0x2a, 0x79, 0x06, 0x00, 0x9c, 0x71, 0x06, 0x00,
+ 0x6c, 0x71, 0x06, 0x00,
+ 0x40, 0x70, 0x46, 0x00, 0x40, 0x00, 0x01, 0x00, 0x9c, 0xa5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x94, 0x55, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x93, 0x51, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x69, 0x4d, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x97, 0x61, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x96, 0x5d, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x58, 0x66, 0x00,
+ 0x21, 0x4d, 0x06, 0x00,
+ 0x40, 0x58, 0x06, 0x00, 0x22, 0x51, 0x06, 0x00, 0x96, 0x59, 0x06, 0x00,
+ 0x23, 0x5d, 0x06, 0x00,
+ 0x96, 0x59, 0x06, 0x00, 0x24, 0x55, 0x06, 0x00, 0x96, 0x59, 0x06, 0x00,
+ 0x25, 0x61, 0x06, 0x00,
+ 0x96, 0x59, 0x06, 0x00, 0x6c, 0x59, 0x06, 0x00, 0x40, 0x58, 0x46, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x96, 0xa5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x8e, 0x3d, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x8d, 0x39, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x69, 0x35, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x91, 0x49, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x90, 0x45, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x40, 0x66, 0x00, 0x1c, 0x35, 0x06, 0x00, 0x40, 0x40, 0x06, 0x00,
+ 0x1d, 0x39, 0x06, 0x00,
+ 0x90, 0x41, 0x06, 0x00, 0x1e, 0x45, 0x06, 0x00, 0x90, 0x41, 0x06, 0x00,
+ 0x1f, 0x3d, 0x06, 0x00,
+ 0x90, 0x41, 0x06, 0x00, 0x20, 0x49, 0x06, 0x00, 0x90, 0x41, 0x06, 0x00,
+ 0x6c, 0x41, 0x06, 0x00,
+ 0x40, 0x40, 0x46, 0x00, 0x40, 0x00, 0x01, 0x00, 0x90, 0xa5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x88, 0x25, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x87, 0x21, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x69, 0x1d, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x8b, 0x31, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x8a, 0x2d, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x28, 0x66, 0x00,
+ 0x17, 0x1d, 0x06, 0x00,
+ 0x40, 0x28, 0x06, 0x00, 0x18, 0x21, 0x06, 0x00, 0x8a, 0x29, 0x06, 0x00,
+ 0x19, 0x2d, 0x06, 0x00,
+ 0x8a, 0x29, 0x06, 0x00, 0x1a, 0x25, 0x06, 0x00, 0x8a, 0x29, 0x06, 0x00,
+ 0x1b, 0x31, 0x06, 0x00,
+ 0x8a, 0x29, 0x06, 0x00, 0x6c, 0x29, 0x06, 0x00, 0x40, 0x28, 0x46, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x8a, 0xa5, 0x65, 0x00, 0x6d, 0xa5, 0x05, 0x00, 0x6b, 0xa5, 0x45, 0x00,
+ 0x2c, 0xa5, 0x05, 0x00,
+ 0x40, 0x34, 0x44, 0x00, 0x2b, 0xa1, 0x05, 0x00, 0x0d, 0x35, 0x44, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x0c, 0x89, 0x60, 0x00, 0x40, 0x00, 0x01, 0x00, 0x0d, 0x8d, 0x60, 0x00,
+ 0x40, 0x30, 0x04, 0x00,
+ 0x0c, 0x41, 0x94, 0x00, 0x10, 0x99, 0x05, 0x00, 0x66, 0x99, 0xa5, 0x00,
+ 0x40, 0x34, 0x04, 0x00,
+ 0x0d, 0x41, 0x94, 0x00, 0x10, 0x9d, 0x05, 0x00, 0x67, 0x9d, 0xa5, 0x00,
+ 0x3c, 0x31, 0x04, 0x00,
+ 0x40, 0x80, 0x00, 0x00, 0x3d, 0x35, 0x04, 0x00, 0x40, 0x84, 0x00, 0x00,
+ 0x3c, 0x31, 0x04, 0x00,
+ 0x40, 0x98, 0x00, 0x00, 0x3d, 0x35, 0x04, 0x00, 0x40, 0x9c, 0x00, 0x00,
+ 0x3c, 0x31, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0xf9, 0x04, 0x00,
+ 0x3e, 0xf9, 0xa4, 0x00, 0x3d, 0x35, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0xfd, 0x04, 0x00, 0x3f, 0xfd, 0xa4, 0x00,
+ 0x49, 0x29, 0x04, 0x00,
+ 0x40, 0x28, 0x04, 0x00, 0x49, 0x2d, 0x04, 0x00, 0x40, 0x2c, 0x04, 0x00,
+ 0x40, 0x28, 0x04, 0x00,
+ 0x0a, 0x41, 0x94, 0x00, 0x10, 0x29, 0x05, 0x00, 0x4a, 0x29, 0xa5, 0x00,
+ 0x40, 0x2c, 0x04, 0x00,
+ 0x0b, 0x41, 0x94, 0x00, 0x10, 0x2d, 0x05, 0x00, 0x4b, 0x2d, 0xa5, 0x00,
+ 0x43, 0x49, 0x00, 0x00,
+ 0x0a, 0x29, 0x04, 0x00, 0x43, 0x4d, 0x00, 0x00, 0x0b, 0x2d, 0x04, 0x00,
+ 0x43, 0x49, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x11, 0x05, 0x00,
+ 0x44, 0x11, 0xa5, 0x00, 0x43, 0x4d, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x15, 0x05, 0x00, 0x45, 0x15, 0xa5, 0x00,
+ 0x46, 0x41, 0x00, 0x00,
+ 0x0a, 0x29, 0x04, 0x00, 0x46, 0x45, 0x00, 0x00, 0x0b, 0x2d, 0x04, 0x00,
+ 0x46, 0x41, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x1d, 0x05, 0x00,
+ 0x47, 0x1d, 0xa5, 0x00, 0x46, 0x45, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x21, 0x05, 0x00, 0x48, 0x21, 0xa5, 0x00,
+ 0x40, 0x59, 0x00, 0x00,
+ 0x0a, 0x29, 0x04, 0x00, 0x40, 0x5d, 0x00, 0x00, 0x0b, 0x2d, 0x04, 0x00,
+ 0x40, 0x59, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x05, 0x05, 0x00,
+ 0x41, 0x05, 0xa5, 0x00, 0x40, 0x5d, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x09, 0x05, 0x00, 0x42, 0x09, 0xa5, 0x00,
+ 0x4c, 0x71, 0x00, 0x00,
+ 0x0a, 0x29, 0x04, 0x00, 0x4c, 0x75, 0x00, 0x00, 0x0b, 0x2d, 0x04, 0x00,
+ 0x4c, 0x71, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x35, 0x05, 0x00,
+ 0x4d, 0x35, 0xa5, 0x00, 0x4c, 0x75, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x39, 0x05, 0x00, 0x4e, 0x39, 0xa5, 0x00,
+ 0x04, 0x29, 0x04, 0x00,
+ 0x40, 0x18, 0x04, 0x00, 0x05, 0x2d, 0x04, 0x00, 0x40, 0x1c, 0x04, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x06, 0xa5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0x06, 0xa1, 0x65, 0x00,
+ 0x16, 0xa5, 0x05, 0x00,
+ 0x40, 0xa4, 0x05, 0x00, 0x6e, 0xa5, 0x05, 0x00, 0x40, 0xa4, 0x05, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xb2, 0xcd, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0xb1, 0xc9, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x69, 0xc5, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0xb5, 0xd9, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xb4, 0xd5, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0xd0, 0x66, 0x00,
+ 0x26, 0xc5, 0x06, 0x00,
+ 0x40, 0xd0, 0x06, 0x00, 0x27, 0xc9, 0x06, 0x00, 0xb4, 0xd1, 0x06, 0x00,
+ 0x28, 0xd5, 0x06, 0x00,
+ 0xb4, 0xd1, 0x06, 0x00, 0x29, 0xcd, 0x06, 0x00, 0xb4, 0xd1, 0x06, 0x00,
+ 0x2a, 0xd9, 0x06, 0x00,
+ 0xb4, 0xd1, 0x06, 0x00, 0x6c, 0xd1, 0x06, 0x00, 0x40, 0xd0, 0x46, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xb4, 0xa5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0xac, 0xb5, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xab, 0xb1, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x69, 0xad, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xaf, 0xc1, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0xae, 0xbd, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0xb8, 0x66, 0x00, 0x21, 0xad, 0x06, 0x00, 0x40, 0xb8, 0x06, 0x00,
+ 0x22, 0xb1, 0x06, 0x00,
+ 0xae, 0xb9, 0x06, 0x00, 0x23, 0xbd, 0x06, 0x00, 0xae, 0xb9, 0x06, 0x00,
+ 0x24, 0xb5, 0x06, 0x00,
+ 0xae, 0xb9, 0x06, 0x00, 0x25, 0xc1, 0x06, 0x00, 0xae, 0xb9, 0x06, 0x00,
+ 0x6c, 0xb9, 0x06, 0x00,
+ 0x40, 0xb8, 0x46, 0x00, 0x40, 0x00, 0x01, 0x00, 0xae, 0xa5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xa6, 0x9d, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0xa5, 0x99, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x69, 0x95, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0xa9, 0xa9, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xa8, 0xa5, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0xa0, 0x66, 0x00,
+ 0x1c, 0x95, 0x06, 0x00,
+ 0x40, 0xa0, 0x06, 0x00, 0x1d, 0x99, 0x06, 0x00, 0xa8, 0xa1, 0x06, 0x00,
+ 0x1e, 0xa5, 0x06, 0x00,
+ 0xa8, 0xa1, 0x06, 0x00, 0x1f, 0x9d, 0x06, 0x00, 0xa8, 0xa1, 0x06, 0x00,
+ 0x20, 0xa9, 0x06, 0x00,
+ 0xa8, 0xa1, 0x06, 0x00, 0x6c, 0xa1, 0x06, 0x00, 0x40, 0xa0, 0x46, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xa8, 0xa5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0xa0, 0x85, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x9f, 0x81, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x69, 0x7d, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xa3, 0x91, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0xa2, 0x8d, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x88, 0x66, 0x00, 0x17, 0x7d, 0x06, 0x00, 0x40, 0x88, 0x06, 0x00,
+ 0x18, 0x81, 0x06, 0x00,
+ 0xa2, 0x89, 0x06, 0x00, 0x19, 0x8d, 0x06, 0x00, 0xa2, 0x89, 0x06, 0x00,
+ 0x1a, 0x85, 0x06, 0x00,
+ 0xa2, 0x89, 0x06, 0x00, 0x1b, 0x91, 0x06, 0x00, 0xa2, 0x89, 0x06, 0x00,
+ 0x6c, 0x89, 0x06, 0x00,
+ 0x40, 0x88, 0x46, 0x00, 0x40, 0x00, 0x01, 0x00, 0xa2, 0xa5, 0x65, 0x00,
+ 0x6d, 0xa5, 0x05, 0x00,
+ 0x6b, 0xa5, 0x45, 0x00, 0x2c, 0xa5, 0x05, 0x00, 0x40, 0x18, 0x44, 0x00,
+ 0x2b, 0xa1, 0x05, 0x00,
+ 0x06, 0x19, 0x44, 0x00, 0x40, 0x00, 0x01, 0x00, 0x07, 0xa5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x07, 0xa1, 0x65, 0x00, 0x16, 0xa5, 0x05, 0x00, 0x40, 0xa4, 0x05, 0x00,
+ 0x6e, 0xa5, 0x05, 0x00,
+ 0x40, 0xa4, 0x05, 0x00, 0x40, 0x00, 0x01, 0x00, 0xca, 0x2d, 0x67, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xc9, 0x29, 0x67, 0x00, 0x40, 0x00, 0x01, 0x00, 0x69, 0x25, 0x67, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xcd, 0x39, 0x67, 0x00, 0x40, 0x00, 0x01, 0x00, 0xcc, 0x35, 0x67, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x30, 0x67, 0x00, 0x26, 0x25, 0x07, 0x00, 0x40, 0x30, 0x07, 0x00,
+ 0x27, 0x29, 0x07, 0x00,
+ 0xcc, 0x31, 0x07, 0x00, 0x28, 0x35, 0x07, 0x00, 0xcc, 0x31, 0x07, 0x00,
+ 0x29, 0x2d, 0x07, 0x00,
+ 0xcc, 0x31, 0x07, 0x00, 0x2a, 0x39, 0x07, 0x00, 0xcc, 0x31, 0x07, 0x00,
+ 0x6c, 0x31, 0x07, 0x00,
+ 0x40, 0x30, 0x47, 0x00, 0x40, 0x00, 0x01, 0x00, 0xcc, 0xa5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xc4, 0x15, 0x67, 0x00, 0x40, 0x00, 0x01, 0x00, 0xc3, 0x11, 0x67, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x69, 0x0d, 0x67, 0x00, 0x40, 0x00, 0x01, 0x00, 0xc7, 0x21, 0x67, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xc6, 0x1d, 0x67, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x18, 0x67, 0x00,
+ 0x21, 0x0d, 0x07, 0x00,
+ 0x40, 0x18, 0x07, 0x00, 0x22, 0x11, 0x07, 0x00, 0xc6, 0x19, 0x07, 0x00,
+ 0x23, 0x1d, 0x07, 0x00,
+ 0xc6, 0x19, 0x07, 0x00, 0x24, 0x15, 0x07, 0x00, 0xc6, 0x19, 0x07, 0x00,
+ 0x25, 0x21, 0x07, 0x00,
+ 0xc6, 0x19, 0x07, 0x00, 0x6c, 0x19, 0x07, 0x00, 0x40, 0x18, 0x47, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xc6, 0xa5, 0x65, 0x00, 0x40, 0x00, 0x01, 0x00, 0xbe, 0xfd, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xbd, 0xf9, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x69, 0xf5, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xc1, 0x09, 0x67, 0x00, 0x40, 0x00, 0x01, 0x00, 0xc0, 0x05, 0x67, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x67, 0x00, 0x1c, 0xf5, 0x06, 0x00, 0x40, 0x00, 0x07, 0x00,
+ 0x1d, 0xf9, 0x06, 0x00,
+ 0xc0, 0x01, 0x07, 0x00, 0x1e, 0x05, 0x07, 0x00, 0xc0, 0x01, 0x07, 0x00,
+ 0x1f, 0xfd, 0x06, 0x00,
+ 0xc0, 0x01, 0x07, 0x00, 0x20, 0x09, 0x07, 0x00, 0xc0, 0x01, 0x07, 0x00,
+ 0x6c, 0x01, 0x07, 0x00,
+ 0x40, 0x00, 0x47, 0x00, 0x40, 0x00, 0x01, 0x00, 0xc0, 0xa5, 0x65, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xb8, 0xe5, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0xb7, 0xe1, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x69, 0xdd, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0xbb, 0xf1, 0x66, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xba, 0xed, 0x66, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0xe8, 0x66, 0x00,
+ 0x17, 0xdd, 0x06, 0x00,
+ 0x40, 0xe8, 0x06, 0x00, 0x18, 0xe1, 0x06, 0x00, 0xba, 0xe9, 0x06, 0x00,
+ 0x19, 0xed, 0x06, 0x00,
+ 0xba, 0xe9, 0x06, 0x00, 0x1a, 0xe5, 0x06, 0x00, 0xba, 0xe9, 0x06, 0x00,
+ 0x1b, 0xf1, 0x06, 0x00,
+ 0xba, 0xe9, 0x06, 0x00, 0x6c, 0xe9, 0x06, 0x00, 0x40, 0xe8, 0x46, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0xba, 0xa5, 0x65, 0x00, 0x6d, 0xa5, 0x05, 0x00, 0x6b, 0xa5, 0x45, 0x00,
+ 0x2c, 0xa5, 0x05, 0x00,
+ 0x40, 0x1c, 0x44, 0x00, 0x2b, 0xa1, 0x05, 0x00, 0x07, 0x1d, 0x44, 0x00,
+ 0x4f, 0x19, 0x04, 0x00,
+ 0x40, 0xa0, 0x00, 0x00, 0x50, 0x1d, 0x04, 0x00, 0x40, 0xa4, 0x00, 0x00,
+ 0x4f, 0x19, 0x04, 0x00,
+ 0x40, 0xb4, 0x00, 0x00, 0x50, 0x1d, 0x04, 0x00, 0x40, 0xb8, 0x00, 0x00,
+ 0x41, 0x10, 0x00, 0x00,
+ 0x40, 0x48, 0x44, 0x00, 0x41, 0x14, 0x00, 0x00, 0x40, 0x4c, 0x44, 0x00,
+ 0x4f, 0x19, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x45, 0x05, 0x00,
+ 0x51, 0x45, 0xa5, 0x00, 0x50, 0x1d, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x49, 0x05, 0x00, 0x52, 0x49, 0xa5, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x12, 0x91, 0x60, 0x00, 0x40, 0x00, 0x01, 0x00, 0x13, 0x95, 0x60, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x12, 0xc5, 0x60, 0x00, 0x40, 0x00, 0x01, 0x00, 0x13, 0xc9, 0x60, 0x00,
+ 0x59, 0x41, 0x00, 0x00,
+ 0x40, 0x18, 0x04, 0x00, 0x59, 0x45, 0x00, 0x00, 0x40, 0x1c, 0x04, 0x00,
+ 0x59, 0x41, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x69, 0x05, 0x00,
+ 0x5a, 0x69, 0xa5, 0x00, 0x59, 0x45, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x6d, 0x05, 0x00, 0x5b, 0x6d, 0xa5, 0x00,
+ 0x53, 0x59, 0x00, 0x00,
+ 0x06, 0x19, 0x04, 0x00, 0x53, 0x5d, 0x00, 0x00, 0x07, 0x1d, 0x04, 0x00,
+ 0x53, 0x59, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x51, 0x05, 0x00,
+ 0x54, 0x51, 0xa5, 0x00, 0x53, 0x5d, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x55, 0x05, 0x00, 0x55, 0x55, 0xa5, 0x00,
+ 0x56, 0x49, 0x00, 0x00,
+ 0x06, 0x19, 0x04, 0x00, 0x56, 0x4d, 0x00, 0x00, 0x07, 0x1d, 0x04, 0x00,
+ 0x56, 0x49, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x5d, 0x05, 0x00,
+ 0x57, 0x5d, 0xa5, 0x00, 0x56, 0x4d, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x61, 0x05, 0x00, 0x58, 0x61, 0xa5, 0x00,
+ 0x5c, 0x21, 0x04, 0x00,
+ 0x06, 0x19, 0x04, 0x00, 0x5c, 0x25, 0x04, 0x00, 0x07, 0x1d, 0x04, 0x00,
+ 0x5c, 0x21, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x75, 0x05, 0x00,
+ 0x5d, 0x75, 0xa5, 0x00, 0x5c, 0x25, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x79, 0x05, 0x00, 0x5e, 0x79, 0xa5, 0x00,
+ 0x5f, 0x71, 0x00, 0x00,
+ 0x06, 0x19, 0x04, 0x00, 0x5f, 0x75, 0x00, 0x00, 0x07, 0x1d, 0x04, 0x00,
+ 0x5f, 0x71, 0x00, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x81, 0x05, 0x00,
+ 0x60, 0x81, 0xa5, 0x00, 0x5f, 0x75, 0x00, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x85, 0x05, 0x00, 0x61, 0x85, 0xa5, 0x00,
+ 0x62, 0x19, 0x04, 0x00,
+ 0x40, 0xa8, 0x00, 0x00, 0x63, 0x1d, 0x04, 0x00, 0x40, 0xac, 0x00, 0x00,
+ 0x62, 0x19, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00, 0x11, 0x41, 0x94, 0x00,
+ 0x10, 0x91, 0x05, 0x00,
+ 0x64, 0x91, 0xa5, 0x00, 0x63, 0x1d, 0x04, 0x00, 0x40, 0x44, 0x04, 0x00,
+ 0x40, 0x44, 0x04, 0x00,
+ 0x11, 0x41, 0x94, 0x00, 0x10, 0x95, 0x05, 0x00, 0x65, 0x95, 0xa5, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x40, 0x00, 0x01, 0x00,
+ 0x40, 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00,
+ 0x30, 0x00, 0x00, 0x00,
+ 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00, 0x45, 0x51, 0x55, 0x41,
+ 0x4c, 0x49, 0x5a, 0x45,
+ 0x52, 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, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x52, 0x45, 0x53, 0x43, 0x41, 0x4c, 0x45,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00,
+ 0x4c, 0x4f, 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, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00,
+ 0x4d, 0x49, 0x44, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x1c, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x48, 0x49, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x10,
+ 0x80, 0x00, 0x00, 0x00, 0x58, 0x48, 0x49, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x10,
+ 0x80, 0x00, 0x00, 0x00,
+ 0x42, 0x59, 0x50, 0x41, 0x53, 0x53, 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, 0x00,
+ 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x52, 0x4f, 0x4e,
+ 0x54, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x50, 0x44, 0x49,
+ 0x46, 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, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x49, 0x47, 0x43, 0x44, 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, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x31, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0x39, 0x37,
+ 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, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x55, 0x58, 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, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x3c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3e, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x55, 0x52, 0x52,
+ 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x53, 0x50, 0x44, 0x49, 0x46, 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, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x49, 0x47, 0x43,
+ 0x44, 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, 0x00, 0x00,
+ 0x43, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0x39, 0x37, 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, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x47, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x43, 0x4d, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x49, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x55, 0x58, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x4d, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x53, 0x50, 0x44, 0x49, 0x46, 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, 0x00, 0x00,
+ 0x53, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0x47, 0x43,
+ 0x44, 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, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x43, 0x39, 0x37, 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, 0x00, 0x00, 0x00,
+ 0x59, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5a, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x43, 0x4d, 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, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x55, 0x58, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x5f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x60, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00,
+ 0x64, 0x64, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x08, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x6b, 0x00, 0x00, 0x00,
+ 0x2c, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x6d, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
diff --git a/kernel/drv/oss_sblive/emu10k1_dsp_be.h b/kernel/drv/oss_sblive/emu10k1_dsp_be.h
new file mode 100644
index 0000000..ea8769b
--- /dev/null
+++ b/kernel/drv/oss_sblive/emu10k1_dsp_be.h
@@ -0,0 +1,989 @@
+/*
+ * Purpose: DSP firmware file for Live! (big endian machines)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+static unsigned char emu10k1_dsp[] = {
+ 0x00, 0xe1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x96,
+ 0x00, 0x00, 0x00, 0x44,
+ 0x00, 0x44, 0x18, 0x40, 0x00, 0x00, 0x04, 0x44, 0x00, 0x44, 0x1c, 0x40,
+ 0x00, 0x04, 0x19, 0x02,
+ 0x00, 0x04, 0x20, 0x40, 0x00, 0x04, 0x1d, 0x03, 0x00, 0x04, 0x24, 0x40,
+ 0x00, 0x00, 0x08, 0x44,
+ 0x00, 0x44, 0x28, 0x40, 0x00, 0x00, 0x0c, 0x44, 0x00, 0x44, 0x2c, 0x40,
+ 0x00, 0x04, 0x29, 0x02,
+ 0x00, 0x04, 0x28, 0x40, 0x00, 0x04, 0x2d, 0x03, 0x00, 0x04, 0x2c, 0x40,
+ 0x00, 0x04, 0x21, 0x36,
+ 0x00, 0x04, 0x30, 0x40, 0x00, 0x04, 0x25, 0x36, 0x00, 0x04, 0x34, 0x40,
+ 0x00, 0x04, 0x30, 0x40,
+ 0x00, 0x94, 0x41, 0x0c, 0x00, 0x04, 0xdd, 0x10, 0x00, 0xa4, 0xdd, 0x37,
+ 0x00, 0x04, 0x34, 0x40,
+ 0x00, 0x94, 0x41, 0x0d, 0x00, 0x04, 0xe1, 0x10, 0x00, 0xa4, 0xe1, 0x38,
+ 0x00, 0x00, 0x49, 0x30,
+ 0x00, 0x04, 0x31, 0x0c, 0x00, 0x00, 0x4d, 0x30, 0x00, 0x04, 0x35, 0x0d,
+ 0x00, 0x00, 0x49, 0x30,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x04, 0xc5, 0x10,
+ 0x00, 0xa4, 0xc5, 0x31, 0x00, 0x00, 0x4d, 0x30, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x04, 0xc9, 0x10, 0x00, 0xa4, 0xc9, 0x32,
+ 0x00, 0x00, 0x41, 0x33,
+ 0x00, 0x04, 0x31, 0x0c, 0x00, 0x00, 0x45, 0x33, 0x00, 0x04, 0x35, 0x0d,
+ 0x00, 0x00, 0x41, 0x33,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x04, 0xd1, 0x10,
+ 0x00, 0xa4, 0xd1, 0x34, 0x00, 0x00, 0x45, 0x33, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x04, 0xd5, 0x10, 0x00, 0xa4, 0xd5, 0x35,
+ 0x00, 0x00, 0x59, 0x2d,
+ 0x00, 0x04, 0x31, 0x0c, 0x00, 0x00, 0x5d, 0x2d, 0x00, 0x04, 0x35, 0x0d,
+ 0x00, 0x00, 0x59, 0x2d,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x04, 0xb9, 0x10,
+ 0x00, 0xa4, 0xb9, 0x2e, 0x00, 0x00, 0x5d, 0x2d, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x04, 0xbd, 0x10, 0x00, 0xa4, 0xbd, 0x2f,
+ 0x00, 0x00, 0x59, 0x2d,
+ 0x00, 0x04, 0x31, 0x0c, 0x00, 0x00, 0x5d, 0x2d, 0x00, 0x04, 0x35, 0x0d,
+ 0x00, 0x00, 0x71, 0x39,
+ 0x00, 0x04, 0x31, 0x0c, 0x00, 0x00, 0x75, 0x39, 0x00, 0x04, 0x35, 0x0d,
+ 0x00, 0x00, 0x71, 0x39,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x04, 0xe9, 0x10,
+ 0x00, 0xa4, 0xe9, 0x3a, 0x00, 0x00, 0x75, 0x39, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x04, 0xed, 0x10, 0x00, 0xa4, 0xed, 0x3b,
+ 0x00, 0x04, 0x31, 0x04,
+ 0x00, 0x04, 0x30, 0x40, 0x00, 0x04, 0x35, 0x05, 0x00, 0x04, 0x34, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0x0c, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa1, 0x0c,
+ 0x00, 0x05, 0xa5, 0x16,
+ 0x00, 0x05, 0xa4, 0x40, 0x00, 0x05, 0xa5, 0x6e, 0x00, 0x05, 0xa4, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x0d, 0x82, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x09, 0x81,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x05, 0x69, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x19, 0x85,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x15, 0x84, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x10, 0x40,
+ 0x00, 0x06, 0x05, 0x26,
+ 0x00, 0x06, 0x10, 0x40, 0x00, 0x06, 0x09, 0x27, 0x00, 0x06, 0x11, 0x84,
+ 0x00, 0x06, 0x15, 0x28,
+ 0x00, 0x06, 0x11, 0x84, 0x00, 0x06, 0x0d, 0x29, 0x00, 0x06, 0x11, 0x84,
+ 0x00, 0x06, 0x19, 0x2a,
+ 0x00, 0x06, 0x11, 0x84, 0x00, 0x06, 0x11, 0x6c, 0x00, 0x46, 0x10, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0x84, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xf5, 0x7c,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xf1, 0x7b, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xed, 0x69,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x01, 0x7f, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xfd, 0x7e,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xf8, 0x40, 0x00, 0x05, 0xed, 0x21, 0x00, 0x05, 0xf8, 0x40,
+ 0x00, 0x05, 0xf1, 0x22,
+ 0x00, 0x05, 0xf9, 0x7e, 0x00, 0x05, 0xfd, 0x23, 0x00, 0x05, 0xf9, 0x7e,
+ 0x00, 0x05, 0xf5, 0x24,
+ 0x00, 0x05, 0xf9, 0x7e, 0x00, 0x06, 0x01, 0x25, 0x00, 0x05, 0xf9, 0x7e,
+ 0x00, 0x05, 0xf9, 0x6c,
+ 0x00, 0x45, 0xf8, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0x7e,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xdd, 0x76, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xd9, 0x75,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xd5, 0x69, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xe9, 0x79,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xe5, 0x78, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xe0, 0x40,
+ 0x00, 0x05, 0xd5, 0x1c,
+ 0x00, 0x05, 0xe0, 0x40, 0x00, 0x05, 0xd9, 0x1d, 0x00, 0x05, 0xe1, 0x78,
+ 0x00, 0x05, 0xe5, 0x1e,
+ 0x00, 0x05, 0xe1, 0x78, 0x00, 0x05, 0xdd, 0x1f, 0x00, 0x05, 0xe1, 0x78,
+ 0x00, 0x05, 0xe9, 0x20,
+ 0x00, 0x05, 0xe1, 0x78, 0x00, 0x05, 0xe1, 0x6c, 0x00, 0x45, 0xe0, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0x78, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xc5, 0x70,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xc1, 0x6f, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xbd, 0x69,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xd1, 0x73, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xcd, 0x72,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xc8, 0x40, 0x00, 0x05, 0xbd, 0x17, 0x00, 0x05, 0xc8, 0x40,
+ 0x00, 0x05, 0xc1, 0x18,
+ 0x00, 0x05, 0xc9, 0x72, 0x00, 0x05, 0xcd, 0x19, 0x00, 0x05, 0xc9, 0x72,
+ 0x00, 0x05, 0xc5, 0x1a,
+ 0x00, 0x05, 0xc9, 0x72, 0x00, 0x05, 0xd1, 0x1b, 0x00, 0x05, 0xc9, 0x72,
+ 0x00, 0x05, 0xc9, 0x6c,
+ 0x00, 0x45, 0xc8, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0x72,
+ 0x00, 0x05, 0xa5, 0x6d,
+ 0x00, 0x45, 0xa5, 0x6b, 0x00, 0x05, 0xa5, 0x2c, 0x00, 0x44, 0x30, 0x40,
+ 0x00, 0x05, 0xa1, 0x2b,
+ 0x00, 0x44, 0x31, 0x0c, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0x0d,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa1, 0x0d, 0x00, 0x05, 0xa5, 0x16, 0x00, 0x05, 0xa4, 0x40,
+ 0x00, 0x05, 0xa5, 0x6e,
+ 0x00, 0x05, 0xa4, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x6d, 0x9a,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x69, 0x99, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x65, 0x69,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x79, 0x9d, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x75, 0x9c,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x70, 0x40, 0x00, 0x06, 0x65, 0x26, 0x00, 0x06, 0x70, 0x40,
+ 0x00, 0x06, 0x69, 0x27,
+ 0x00, 0x06, 0x71, 0x9c, 0x00, 0x06, 0x75, 0x28, 0x00, 0x06, 0x71, 0x9c,
+ 0x00, 0x06, 0x6d, 0x29,
+ 0x00, 0x06, 0x71, 0x9c, 0x00, 0x06, 0x79, 0x2a, 0x00, 0x06, 0x71, 0x9c,
+ 0x00, 0x06, 0x71, 0x6c,
+ 0x00, 0x46, 0x70, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0x9c,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x55, 0x94, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x51, 0x93,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x4d, 0x69, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x61, 0x97,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x5d, 0x96, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x58, 0x40,
+ 0x00, 0x06, 0x4d, 0x21,
+ 0x00, 0x06, 0x58, 0x40, 0x00, 0x06, 0x51, 0x22, 0x00, 0x06, 0x59, 0x96,
+ 0x00, 0x06, 0x5d, 0x23,
+ 0x00, 0x06, 0x59, 0x96, 0x00, 0x06, 0x55, 0x24, 0x00, 0x06, 0x59, 0x96,
+ 0x00, 0x06, 0x61, 0x25,
+ 0x00, 0x06, 0x59, 0x96, 0x00, 0x06, 0x59, 0x6c, 0x00, 0x46, 0x58, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0x96, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x3d, 0x8e,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x39, 0x8d, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x35, 0x69,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x49, 0x91, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x45, 0x90,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x40, 0x40, 0x00, 0x06, 0x35, 0x1c, 0x00, 0x06, 0x40, 0x40,
+ 0x00, 0x06, 0x39, 0x1d,
+ 0x00, 0x06, 0x41, 0x90, 0x00, 0x06, 0x45, 0x1e, 0x00, 0x06, 0x41, 0x90,
+ 0x00, 0x06, 0x3d, 0x1f,
+ 0x00, 0x06, 0x41, 0x90, 0x00, 0x06, 0x49, 0x20, 0x00, 0x06, 0x41, 0x90,
+ 0x00, 0x06, 0x41, 0x6c,
+ 0x00, 0x46, 0x40, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0x90,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x25, 0x88, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x21, 0x87,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x1d, 0x69, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x31, 0x8b,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x2d, 0x8a, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x28, 0x40,
+ 0x00, 0x06, 0x1d, 0x17,
+ 0x00, 0x06, 0x28, 0x40, 0x00, 0x06, 0x21, 0x18, 0x00, 0x06, 0x29, 0x8a,
+ 0x00, 0x06, 0x2d, 0x19,
+ 0x00, 0x06, 0x29, 0x8a, 0x00, 0x06, 0x25, 0x1a, 0x00, 0x06, 0x29, 0x8a,
+ 0x00, 0x06, 0x31, 0x1b,
+ 0x00, 0x06, 0x29, 0x8a, 0x00, 0x06, 0x29, 0x6c, 0x00, 0x46, 0x28, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0x8a, 0x00, 0x05, 0xa5, 0x6d, 0x00, 0x45, 0xa5, 0x6b,
+ 0x00, 0x05, 0xa5, 0x2c,
+ 0x00, 0x44, 0x34, 0x40, 0x00, 0x05, 0xa1, 0x2b, 0x00, 0x44, 0x35, 0x0d,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x60, 0x89, 0x0c, 0x00, 0x01, 0x00, 0x40, 0x00, 0x60, 0x8d, 0x0d,
+ 0x00, 0x04, 0x30, 0x40,
+ 0x00, 0x94, 0x41, 0x0c, 0x00, 0x05, 0x99, 0x10, 0x00, 0xa5, 0x99, 0x66,
+ 0x00, 0x04, 0x34, 0x40,
+ 0x00, 0x94, 0x41, 0x0d, 0x00, 0x05, 0x9d, 0x10, 0x00, 0xa5, 0x9d, 0x67,
+ 0x00, 0x04, 0x31, 0x3c,
+ 0x00, 0x00, 0x80, 0x40, 0x00, 0x04, 0x35, 0x3d, 0x00, 0x00, 0x84, 0x40,
+ 0x00, 0x04, 0x31, 0x3c,
+ 0x00, 0x00, 0x98, 0x40, 0x00, 0x04, 0x35, 0x3d, 0x00, 0x00, 0x9c, 0x40,
+ 0x00, 0x04, 0x31, 0x3c,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x04, 0xf9, 0x10,
+ 0x00, 0xa4, 0xf9, 0x3e, 0x00, 0x04, 0x35, 0x3d, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x04, 0xfd, 0x10, 0x00, 0xa4, 0xfd, 0x3f,
+ 0x00, 0x04, 0x29, 0x49,
+ 0x00, 0x04, 0x28, 0x40, 0x00, 0x04, 0x2d, 0x49, 0x00, 0x04, 0x2c, 0x40,
+ 0x00, 0x04, 0x28, 0x40,
+ 0x00, 0x94, 0x41, 0x0a, 0x00, 0x05, 0x29, 0x10, 0x00, 0xa5, 0x29, 0x4a,
+ 0x00, 0x04, 0x2c, 0x40,
+ 0x00, 0x94, 0x41, 0x0b, 0x00, 0x05, 0x2d, 0x10, 0x00, 0xa5, 0x2d, 0x4b,
+ 0x00, 0x00, 0x49, 0x43,
+ 0x00, 0x04, 0x29, 0x0a, 0x00, 0x00, 0x4d, 0x43, 0x00, 0x04, 0x2d, 0x0b,
+ 0x00, 0x00, 0x49, 0x43,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x11, 0x10,
+ 0x00, 0xa5, 0x11, 0x44, 0x00, 0x00, 0x4d, 0x43, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x15, 0x10, 0x00, 0xa5, 0x15, 0x45,
+ 0x00, 0x00, 0x41, 0x46,
+ 0x00, 0x04, 0x29, 0x0a, 0x00, 0x00, 0x45, 0x46, 0x00, 0x04, 0x2d, 0x0b,
+ 0x00, 0x00, 0x41, 0x46,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x1d, 0x10,
+ 0x00, 0xa5, 0x1d, 0x47, 0x00, 0x00, 0x45, 0x46, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x21, 0x10, 0x00, 0xa5, 0x21, 0x48,
+ 0x00, 0x00, 0x59, 0x40,
+ 0x00, 0x04, 0x29, 0x0a, 0x00, 0x00, 0x5d, 0x40, 0x00, 0x04, 0x2d, 0x0b,
+ 0x00, 0x00, 0x59, 0x40,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x05, 0x10,
+ 0x00, 0xa5, 0x05, 0x41, 0x00, 0x00, 0x5d, 0x40, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x09, 0x10, 0x00, 0xa5, 0x09, 0x42,
+ 0x00, 0x00, 0x71, 0x4c,
+ 0x00, 0x04, 0x29, 0x0a, 0x00, 0x00, 0x75, 0x4c, 0x00, 0x04, 0x2d, 0x0b,
+ 0x00, 0x00, 0x71, 0x4c,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x35, 0x10,
+ 0x00, 0xa5, 0x35, 0x4d, 0x00, 0x00, 0x75, 0x4c, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x39, 0x10, 0x00, 0xa5, 0x39, 0x4e,
+ 0x00, 0x04, 0x29, 0x04,
+ 0x00, 0x04, 0x18, 0x40, 0x00, 0x04, 0x2d, 0x05, 0x00, 0x04, 0x1c, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0x06, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa1, 0x06,
+ 0x00, 0x05, 0xa5, 0x16,
+ 0x00, 0x05, 0xa4, 0x40, 0x00, 0x05, 0xa5, 0x6e, 0x00, 0x05, 0xa4, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xcd, 0xb2, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xc9, 0xb1,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xc5, 0x69, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xd9, 0xb5,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xd5, 0xb4, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xd0, 0x40,
+ 0x00, 0x06, 0xc5, 0x26,
+ 0x00, 0x06, 0xd0, 0x40, 0x00, 0x06, 0xc9, 0x27, 0x00, 0x06, 0xd1, 0xb4,
+ 0x00, 0x06, 0xd5, 0x28,
+ 0x00, 0x06, 0xd1, 0xb4, 0x00, 0x06, 0xcd, 0x29, 0x00, 0x06, 0xd1, 0xb4,
+ 0x00, 0x06, 0xd9, 0x2a,
+ 0x00, 0x06, 0xd1, 0xb4, 0x00, 0x06, 0xd1, 0x6c, 0x00, 0x46, 0xd0, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0xb4, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xb5, 0xac,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xb1, 0xab, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xad, 0x69,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xc1, 0xaf, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xbd, 0xae,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xb8, 0x40, 0x00, 0x06, 0xad, 0x21, 0x00, 0x06, 0xb8, 0x40,
+ 0x00, 0x06, 0xb1, 0x22,
+ 0x00, 0x06, 0xb9, 0xae, 0x00, 0x06, 0xbd, 0x23, 0x00, 0x06, 0xb9, 0xae,
+ 0x00, 0x06, 0xb5, 0x24,
+ 0x00, 0x06, 0xb9, 0xae, 0x00, 0x06, 0xc1, 0x25, 0x00, 0x06, 0xb9, 0xae,
+ 0x00, 0x06, 0xb9, 0x6c,
+ 0x00, 0x46, 0xb8, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0xae,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x9d, 0xa6, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x99, 0xa5,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x95, 0x69, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xa9, 0xa9,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xa5, 0xa8, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xa0, 0x40,
+ 0x00, 0x06, 0x95, 0x1c,
+ 0x00, 0x06, 0xa0, 0x40, 0x00, 0x06, 0x99, 0x1d, 0x00, 0x06, 0xa1, 0xa8,
+ 0x00, 0x06, 0xa5, 0x1e,
+ 0x00, 0x06, 0xa1, 0xa8, 0x00, 0x06, 0x9d, 0x1f, 0x00, 0x06, 0xa1, 0xa8,
+ 0x00, 0x06, 0xa9, 0x20,
+ 0x00, 0x06, 0xa1, 0xa8, 0x00, 0x06, 0xa1, 0x6c, 0x00, 0x46, 0xa0, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0xa8, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x85, 0xa0,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x81, 0x9f, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x7d, 0x69,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x91, 0xa3, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0x8d, 0xa2,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0x88, 0x40, 0x00, 0x06, 0x7d, 0x17, 0x00, 0x06, 0x88, 0x40,
+ 0x00, 0x06, 0x81, 0x18,
+ 0x00, 0x06, 0x89, 0xa2, 0x00, 0x06, 0x8d, 0x19, 0x00, 0x06, 0x89, 0xa2,
+ 0x00, 0x06, 0x85, 0x1a,
+ 0x00, 0x06, 0x89, 0xa2, 0x00, 0x06, 0x91, 0x1b, 0x00, 0x06, 0x89, 0xa2,
+ 0x00, 0x06, 0x89, 0x6c,
+ 0x00, 0x46, 0x88, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0xa2,
+ 0x00, 0x05, 0xa5, 0x6d,
+ 0x00, 0x45, 0xa5, 0x6b, 0x00, 0x05, 0xa5, 0x2c, 0x00, 0x44, 0x18, 0x40,
+ 0x00, 0x05, 0xa1, 0x2b,
+ 0x00, 0x44, 0x19, 0x06, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0x07,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa1, 0x07, 0x00, 0x05, 0xa5, 0x16, 0x00, 0x05, 0xa4, 0x40,
+ 0x00, 0x05, 0xa5, 0x6e,
+ 0x00, 0x05, 0xa4, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x67, 0x2d, 0xca,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x67, 0x29, 0xc9, 0x00, 0x01, 0x00, 0x40, 0x00, 0x67, 0x25, 0x69,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x67, 0x39, 0xcd, 0x00, 0x01, 0x00, 0x40, 0x00, 0x67, 0x35, 0xcc,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x67, 0x30, 0x40, 0x00, 0x07, 0x25, 0x26, 0x00, 0x07, 0x30, 0x40,
+ 0x00, 0x07, 0x29, 0x27,
+ 0x00, 0x07, 0x31, 0xcc, 0x00, 0x07, 0x35, 0x28, 0x00, 0x07, 0x31, 0xcc,
+ 0x00, 0x07, 0x2d, 0x29,
+ 0x00, 0x07, 0x31, 0xcc, 0x00, 0x07, 0x39, 0x2a, 0x00, 0x07, 0x31, 0xcc,
+ 0x00, 0x07, 0x31, 0x6c,
+ 0x00, 0x47, 0x30, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0xcc,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x67, 0x15, 0xc4, 0x00, 0x01, 0x00, 0x40, 0x00, 0x67, 0x11, 0xc3,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x67, 0x0d, 0x69, 0x00, 0x01, 0x00, 0x40, 0x00, 0x67, 0x21, 0xc7,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x67, 0x1d, 0xc6, 0x00, 0x01, 0x00, 0x40, 0x00, 0x67, 0x18, 0x40,
+ 0x00, 0x07, 0x0d, 0x21,
+ 0x00, 0x07, 0x18, 0x40, 0x00, 0x07, 0x11, 0x22, 0x00, 0x07, 0x19, 0xc6,
+ 0x00, 0x07, 0x1d, 0x23,
+ 0x00, 0x07, 0x19, 0xc6, 0x00, 0x07, 0x15, 0x24, 0x00, 0x07, 0x19, 0xc6,
+ 0x00, 0x07, 0x21, 0x25,
+ 0x00, 0x07, 0x19, 0xc6, 0x00, 0x07, 0x19, 0x6c, 0x00, 0x47, 0x18, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0xc6, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xfd, 0xbe,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xf9, 0xbd, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xf5, 0x69,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x67, 0x09, 0xc1, 0x00, 0x01, 0x00, 0x40, 0x00, 0x67, 0x05, 0xc0,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x67, 0x00, 0x40, 0x00, 0x06, 0xf5, 0x1c, 0x00, 0x07, 0x00, 0x40,
+ 0x00, 0x06, 0xf9, 0x1d,
+ 0x00, 0x07, 0x01, 0xc0, 0x00, 0x07, 0x05, 0x1e, 0x00, 0x07, 0x01, 0xc0,
+ 0x00, 0x06, 0xfd, 0x1f,
+ 0x00, 0x07, 0x01, 0xc0, 0x00, 0x07, 0x09, 0x20, 0x00, 0x07, 0x01, 0xc0,
+ 0x00, 0x07, 0x01, 0x6c,
+ 0x00, 0x47, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x65, 0xa5, 0xc0,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xe5, 0xb8, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xe1, 0xb7,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xdd, 0x69, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xf1, 0xbb,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x66, 0xed, 0xba, 0x00, 0x01, 0x00, 0x40, 0x00, 0x66, 0xe8, 0x40,
+ 0x00, 0x06, 0xdd, 0x17,
+ 0x00, 0x06, 0xe8, 0x40, 0x00, 0x06, 0xe1, 0x18, 0x00, 0x06, 0xe9, 0xba,
+ 0x00, 0x06, 0xed, 0x19,
+ 0x00, 0x06, 0xe9, 0xba, 0x00, 0x06, 0xe5, 0x1a, 0x00, 0x06, 0xe9, 0xba,
+ 0x00, 0x06, 0xf1, 0x1b,
+ 0x00, 0x06, 0xe9, 0xba, 0x00, 0x06, 0xe9, 0x6c, 0x00, 0x46, 0xe8, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x65, 0xa5, 0xba, 0x00, 0x05, 0xa5, 0x6d, 0x00, 0x45, 0xa5, 0x6b,
+ 0x00, 0x05, 0xa5, 0x2c,
+ 0x00, 0x44, 0x1c, 0x40, 0x00, 0x05, 0xa1, 0x2b, 0x00, 0x44, 0x1d, 0x07,
+ 0x00, 0x04, 0x19, 0x4f,
+ 0x00, 0x00, 0xa0, 0x40, 0x00, 0x04, 0x1d, 0x50, 0x00, 0x00, 0xa4, 0x40,
+ 0x00, 0x04, 0x19, 0x4f,
+ 0x00, 0x00, 0xb4, 0x40, 0x00, 0x04, 0x1d, 0x50, 0x00, 0x00, 0xb8, 0x40,
+ 0x00, 0x00, 0x10, 0x41,
+ 0x00, 0x44, 0x48, 0x40, 0x00, 0x00, 0x14, 0x41, 0x00, 0x44, 0x4c, 0x40,
+ 0x00, 0x04, 0x19, 0x4f,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x45, 0x10,
+ 0x00, 0xa5, 0x45, 0x51, 0x00, 0x04, 0x1d, 0x50, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x49, 0x10, 0x00, 0xa5, 0x49, 0x52,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x60, 0x91, 0x12, 0x00, 0x01, 0x00, 0x40, 0x00, 0x60, 0x95, 0x13,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x60, 0xc5, 0x12, 0x00, 0x01, 0x00, 0x40, 0x00, 0x60, 0xc9, 0x13,
+ 0x00, 0x00, 0x41, 0x59,
+ 0x00, 0x04, 0x18, 0x40, 0x00, 0x00, 0x45, 0x59, 0x00, 0x04, 0x1c, 0x40,
+ 0x00, 0x00, 0x41, 0x59,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x69, 0x10,
+ 0x00, 0xa5, 0x69, 0x5a, 0x00, 0x00, 0x45, 0x59, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x6d, 0x10, 0x00, 0xa5, 0x6d, 0x5b,
+ 0x00, 0x00, 0x59, 0x53,
+ 0x00, 0x04, 0x19, 0x06, 0x00, 0x00, 0x5d, 0x53, 0x00, 0x04, 0x1d, 0x07,
+ 0x00, 0x00, 0x59, 0x53,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x51, 0x10,
+ 0x00, 0xa5, 0x51, 0x54, 0x00, 0x00, 0x5d, 0x53, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x55, 0x10, 0x00, 0xa5, 0x55, 0x55,
+ 0x00, 0x00, 0x49, 0x56,
+ 0x00, 0x04, 0x19, 0x06, 0x00, 0x00, 0x4d, 0x56, 0x00, 0x04, 0x1d, 0x07,
+ 0x00, 0x00, 0x49, 0x56,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x5d, 0x10,
+ 0x00, 0xa5, 0x5d, 0x57, 0x00, 0x00, 0x4d, 0x56, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x61, 0x10, 0x00, 0xa5, 0x61, 0x58,
+ 0x00, 0x04, 0x21, 0x5c,
+ 0x00, 0x04, 0x19, 0x06, 0x00, 0x04, 0x25, 0x5c, 0x00, 0x04, 0x1d, 0x07,
+ 0x00, 0x04, 0x21, 0x5c,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x75, 0x10,
+ 0x00, 0xa5, 0x75, 0x5d, 0x00, 0x04, 0x25, 0x5c, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x79, 0x10, 0x00, 0xa5, 0x79, 0x5e,
+ 0x00, 0x00, 0x71, 0x5f,
+ 0x00, 0x04, 0x19, 0x06, 0x00, 0x00, 0x75, 0x5f, 0x00, 0x04, 0x1d, 0x07,
+ 0x00, 0x00, 0x71, 0x5f,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x81, 0x10,
+ 0x00, 0xa5, 0x81, 0x60, 0x00, 0x00, 0x75, 0x5f, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x85, 0x10, 0x00, 0xa5, 0x85, 0x61,
+ 0x00, 0x04, 0x19, 0x62,
+ 0x00, 0x00, 0xa8, 0x40, 0x00, 0x04, 0x1d, 0x63, 0x00, 0x00, 0xac, 0x40,
+ 0x00, 0x04, 0x19, 0x62,
+ 0x00, 0x04, 0x44, 0x40, 0x00, 0x04, 0x44, 0x40, 0x00, 0x94, 0x41, 0x11,
+ 0x00, 0x05, 0x91, 0x10,
+ 0x00, 0xa5, 0x91, 0x64, 0x00, 0x04, 0x1d, 0x63, 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x04, 0x44, 0x40,
+ 0x00, 0x94, 0x41, 0x11, 0x00, 0x05, 0x95, 0x10, 0x00, 0xa5, 0x95, 0x65,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x01, 0x00, 0x40,
+ 0x00, 0x61, 0x00, 0x40, 0x00, 0x01, 0x00, 0x40, 0x00, 0x61, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x30,
+ 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x64, 0x64,
+ 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x64, 0x64, 0x45, 0x51, 0x55, 0x41,
+ 0x4c, 0x49, 0x5a, 0x45,
+ 0x52, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x52, 0x45, 0x53, 0x43, 0x41, 0x4c, 0x45,
+ 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, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64,
+ 0x4c, 0x4f, 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, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x4d, 0x49, 0x44, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1c,
+ 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x49, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
+ 0x10, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x80, 0x58, 0x48, 0x49, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x80,
+ 0x42, 0x59, 0x50, 0x41, 0x53, 0x53, 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, 0x00,
+ 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x52, 0x4f, 0x4e,
+ 0x54, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x50, 0x44, 0x49,
+ 0x46, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x49, 0x47, 0x43, 0x44, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0x39, 0x37,
+ 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x37,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x41, 0x55, 0x58, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x64, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3e,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x53, 0x55, 0x52, 0x52,
+ 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x53, 0x50, 0x44, 0x49, 0x46, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x49, 0x47, 0x43,
+ 0x44, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0x39, 0x37, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x43, 0x4d, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x55, 0x58, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4f,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x64, 0x64, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x53, 0x50, 0x44, 0x49, 0x46, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x54,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0x47, 0x43,
+ 0x44, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x43, 0x39, 0x37, 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, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5a,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x50, 0x43, 0x4d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x55, 0x58, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x64, 0x64, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x08,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x6b,
+ 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x6d,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x6e, 0x04, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
diff --git a/kernel/drv/oss_sblive/emu10k2_dsp.h b/kernel/drv/oss_sblive/emu10k2_dsp.h
new file mode 100644
index 0000000..233a7be
--- /dev/null
+++ b/kernel/drv/oss_sblive/emu10k2_dsp.h
@@ -0,0 +1,989 @@
+/*
+ * Purpose: DSP firmware file for Audigy
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+static unsigned char emu10k2_dsp[] = {
+ 0x02, 0x00, 0xe1, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00,
+ 0xc1, 0x00, 0x00, 0x00,
+ 0xc0, 0x60, 0x40, 0x04, 0xc1, 0x10, 0x00, 0x00, 0xc0, 0x70, 0x40, 0x04,
+ 0x02, 0x64, 0x40, 0x00,
+ 0xc0, 0x80, 0x40, 0x00, 0x03, 0x74, 0x40, 0x00, 0xc0, 0x90, 0x40, 0x00,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x14, 0x60, 0x41, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x15, 0x70, 0x41, 0x06,
+ 0xc0, 0x60, 0x00, 0x00,
+ 0x02, 0xa0, 0x40, 0x06, 0xc0, 0x70, 0x00, 0x00, 0x03, 0xb0, 0x40, 0x06,
+ 0xc1, 0x40, 0x00, 0x00,
+ 0xc0, 0x20, 0x41, 0x04, 0xc1, 0x50, 0x00, 0x00, 0xc0, 0x30, 0x41, 0x04,
+ 0x02, 0xa4, 0x40, 0x00,
+ 0xc0, 0xa0, 0x40, 0x00, 0x03, 0xb4, 0x40, 0x00, 0xc0, 0xb0, 0x40, 0x00,
+ 0x38, 0x84, 0x40, 0x00,
+ 0xc0, 0xc0, 0x40, 0x00, 0x38, 0x94, 0x40, 0x00, 0xc0, 0xd0, 0x40, 0x00,
+ 0xc0, 0xc0, 0x40, 0x00,
+ 0x0c, 0x04, 0x41, 0x09, 0x10, 0x94, 0x43, 0x00, 0x39, 0x94, 0x43, 0x0a,
+ 0xc0, 0xd0, 0x40, 0x00,
+ 0x0d, 0x04, 0x41, 0x09, 0x10, 0xa4, 0x43, 0x00, 0x3a, 0xa4, 0x43, 0x0a,
+ 0x32, 0x24, 0x04, 0x00,
+ 0x0c, 0xc4, 0x40, 0x00, 0x32, 0x34, 0x04, 0x00, 0x0d, 0xd4, 0x40, 0x00,
+ 0x32, 0x24, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x34, 0x43, 0x00,
+ 0x33, 0x34, 0x43, 0x0a, 0x32, 0x34, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x44, 0x43, 0x00, 0x34, 0x44, 0x43, 0x0a,
+ 0x35, 0x04, 0x04, 0x00,
+ 0x0c, 0xc4, 0x40, 0x00, 0x35, 0x14, 0x04, 0x00, 0x0d, 0xd4, 0x40, 0x00,
+ 0x35, 0x04, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x64, 0x43, 0x00,
+ 0x36, 0x64, 0x43, 0x0a, 0x35, 0x14, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x74, 0x43, 0x00, 0x37, 0x74, 0x43, 0x0a,
+ 0x2f, 0x44, 0x04, 0x00,
+ 0x0c, 0xc4, 0x40, 0x00, 0x2f, 0x54, 0x04, 0x00, 0x0d, 0xd4, 0x40, 0x00,
+ 0x2f, 0x44, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x04, 0x43, 0x00,
+ 0x30, 0x04, 0x43, 0x0a, 0x2f, 0x54, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x14, 0x43, 0x00, 0x31, 0x14, 0x43, 0x0a,
+ 0x2f, 0x44, 0x04, 0x00,
+ 0x0c, 0xc4, 0x40, 0x00, 0x2f, 0x54, 0x04, 0x00, 0x0d, 0xd4, 0x40, 0x00,
+ 0x3b, 0xc4, 0x04, 0x00,
+ 0x0c, 0xc4, 0x40, 0x00, 0x3b, 0xd4, 0x04, 0x00, 0x0d, 0xd4, 0x40, 0x00,
+ 0x3b, 0xc4, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0xc4, 0x43, 0x00,
+ 0x3c, 0xc4, 0x43, 0x0a, 0x3b, 0xd4, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0xd4, 0x43, 0x00, 0x3d, 0xd4, 0x43, 0x0a,
+ 0x04, 0xc4, 0x40, 0x00,
+ 0xc0, 0xc0, 0x40, 0x00, 0x05, 0xd4, 0x40, 0x00, 0xc0, 0xd0, 0x40, 0x00,
+ 0x3e, 0x84, 0x04, 0x00,
+ 0x0e, 0xe4, 0x40, 0x00, 0x3e, 0x94, 0x04, 0x00, 0x0f, 0xf4, 0x40, 0x00,
+ 0x3e, 0x84, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0xf4, 0x43, 0x00,
+ 0x3f, 0xf4, 0x43, 0x0a, 0x3e, 0x94, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x04, 0x44, 0x00, 0x40, 0x04, 0x44, 0x0a,
+ 0x04, 0xc4, 0x40, 0x00,
+ 0xc0, 0xe0, 0x40, 0x00, 0x05, 0xd4, 0x40, 0x00, 0xc0, 0xf0, 0x40, 0x00,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x0c, 0x64, 0x47, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x0c, 0x54, 0x47, 0x06,
+ 0x18, 0x64, 0x47, 0x00,
+ 0xc0, 0x60, 0x47, 0x00, 0x7b, 0x64, 0x47, 0x00, 0xc0, 0x60, 0x47, 0x00,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x8f, 0x04, 0x49, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x8e, 0xf4, 0x48, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x76, 0xe4, 0x48, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x92, 0x34, 0x49, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x91, 0x24, 0x49, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x10, 0x49, 0x06,
+ 0x28, 0xe4, 0x48, 0x00,
+ 0xc0, 0x10, 0x49, 0x00, 0x29, 0xf4, 0x48, 0x00, 0x91, 0x14, 0x49, 0x00,
+ 0x2a, 0x24, 0x49, 0x00,
+ 0x91, 0x14, 0x49, 0x00, 0x2b, 0x04, 0x49, 0x00, 0x91, 0x14, 0x49, 0x00,
+ 0x2c, 0x34, 0x49, 0x00,
+ 0x91, 0x14, 0x49, 0x00, 0x79, 0x14, 0x49, 0x00, 0xc0, 0x10, 0x49, 0x04,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x91, 0x64, 0x47, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x89, 0xa4, 0x48, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x88, 0x94, 0x48, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x76, 0x84, 0x48, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x8c, 0xd4, 0x48, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x8b, 0xc4, 0x48, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0xb0, 0x48, 0x06, 0x23, 0x84, 0x48, 0x00, 0xc0, 0xb0, 0x48, 0x00,
+ 0x24, 0x94, 0x48, 0x00,
+ 0x8b, 0xb4, 0x48, 0x00, 0x25, 0xc4, 0x48, 0x00, 0x8b, 0xb4, 0x48, 0x00,
+ 0x26, 0xa4, 0x48, 0x00,
+ 0x8b, 0xb4, 0x48, 0x00, 0x27, 0xd4, 0x48, 0x00, 0x8b, 0xb4, 0x48, 0x00,
+ 0x79, 0xb4, 0x48, 0x00,
+ 0xc0, 0xb0, 0x48, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0x8b, 0x64, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x83, 0x44, 0x48, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x82, 0x34, 0x48, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x76, 0x24, 0x48, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x86, 0x74, 0x48, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x85, 0x64, 0x48, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x50, 0x48, 0x06,
+ 0x1e, 0x24, 0x48, 0x00,
+ 0xc0, 0x50, 0x48, 0x00, 0x1f, 0x34, 0x48, 0x00, 0x85, 0x54, 0x48, 0x00,
+ 0x20, 0x64, 0x48, 0x00,
+ 0x85, 0x54, 0x48, 0x00, 0x21, 0x44, 0x48, 0x00, 0x85, 0x54, 0x48, 0x00,
+ 0x22, 0x74, 0x48, 0x00,
+ 0x85, 0x54, 0x48, 0x00, 0x79, 0x54, 0x48, 0x00, 0xc0, 0x50, 0x48, 0x04,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x85, 0x64, 0x47, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x7d, 0xe4, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x7c, 0xd4, 0x47, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x76, 0xc4, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x80, 0x14, 0x48, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x7f, 0x04, 0x48, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0xf0, 0x47, 0x06, 0x19, 0xc4, 0x47, 0x00, 0xc0, 0xf0, 0x47, 0x00,
+ 0x1a, 0xd4, 0x47, 0x00,
+ 0x7f, 0xf4, 0x47, 0x00, 0x1b, 0x04, 0x48, 0x00, 0x7f, 0xf4, 0x47, 0x00,
+ 0x1c, 0xe4, 0x47, 0x00,
+ 0x7f, 0xf4, 0x47, 0x00, 0x1d, 0x14, 0x48, 0x00, 0x7f, 0xf4, 0x47, 0x00,
+ 0x79, 0xf4, 0x47, 0x00,
+ 0xc0, 0xf0, 0x47, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0x7f, 0x64, 0x47, 0x06,
+ 0x7a, 0x64, 0x47, 0x00,
+ 0x78, 0x64, 0x47, 0x04, 0x2e, 0x64, 0x47, 0x00, 0xc0, 0xc0, 0x40, 0x04,
+ 0x2d, 0x54, 0x47, 0x00,
+ 0x0c, 0xc4, 0x40, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0x0d, 0x64, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x0d, 0x54, 0x47, 0x06, 0x18, 0x64, 0x47, 0x00, 0xc0, 0x60, 0x47, 0x00,
+ 0x7b, 0x64, 0x47, 0x00,
+ 0xc0, 0x60, 0x47, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xa7, 0x84, 0x4a, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xa6, 0x74, 0x4a, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x76, 0x64, 0x4a, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xaa, 0xb4, 0x4a, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xa9, 0xa4, 0x4a, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x90, 0x4a, 0x06, 0x28, 0x64, 0x4a, 0x00, 0xc0, 0x90, 0x4a, 0x00,
+ 0x29, 0x74, 0x4a, 0x00,
+ 0xa9, 0x94, 0x4a, 0x00, 0x2a, 0xa4, 0x4a, 0x00, 0xa9, 0x94, 0x4a, 0x00,
+ 0x2b, 0x84, 0x4a, 0x00,
+ 0xa9, 0x94, 0x4a, 0x00, 0x2c, 0xb4, 0x4a, 0x00, 0xa9, 0x94, 0x4a, 0x00,
+ 0x79, 0x94, 0x4a, 0x00,
+ 0xc0, 0x90, 0x4a, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0xa9, 0x64, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xa1, 0x24, 0x4a, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xa0, 0x14, 0x4a, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x76, 0x04, 0x4a, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xa4, 0x54, 0x4a, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xa3, 0x44, 0x4a, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x30, 0x4a, 0x06,
+ 0x23, 0x04, 0x4a, 0x00,
+ 0xc0, 0x30, 0x4a, 0x00, 0x24, 0x14, 0x4a, 0x00, 0xa3, 0x34, 0x4a, 0x00,
+ 0x25, 0x44, 0x4a, 0x00,
+ 0xa3, 0x34, 0x4a, 0x00, 0x26, 0x24, 0x4a, 0x00, 0xa3, 0x34, 0x4a, 0x00,
+ 0x27, 0x54, 0x4a, 0x00,
+ 0xa3, 0x34, 0x4a, 0x00, 0x79, 0x34, 0x4a, 0x00, 0xc0, 0x30, 0x4a, 0x04,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xa3, 0x64, 0x47, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x9b, 0xc4, 0x49, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x9a, 0xb4, 0x49, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x76, 0xa4, 0x49, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x9e, 0xf4, 0x49, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x9d, 0xe4, 0x49, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0xd0, 0x49, 0x06, 0x1e, 0xa4, 0x49, 0x00, 0xc0, 0xd0, 0x49, 0x00,
+ 0x1f, 0xb4, 0x49, 0x00,
+ 0x9d, 0xd4, 0x49, 0x00, 0x20, 0xe4, 0x49, 0x00, 0x9d, 0xd4, 0x49, 0x00,
+ 0x21, 0xc4, 0x49, 0x00,
+ 0x9d, 0xd4, 0x49, 0x00, 0x22, 0xf4, 0x49, 0x00, 0x9d, 0xd4, 0x49, 0x00,
+ 0x79, 0xd4, 0x49, 0x00,
+ 0xc0, 0xd0, 0x49, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0x9d, 0x64, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x95, 0x64, 0x49, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x94, 0x54, 0x49, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x76, 0x44, 0x49, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x98, 0x94, 0x49, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x97, 0x84, 0x49, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x70, 0x49, 0x06,
+ 0x19, 0x44, 0x49, 0x00,
+ 0xc0, 0x70, 0x49, 0x00, 0x1a, 0x54, 0x49, 0x00, 0x97, 0x74, 0x49, 0x00,
+ 0x1b, 0x84, 0x49, 0x00,
+ 0x97, 0x74, 0x49, 0x00, 0x1c, 0x64, 0x49, 0x00, 0x97, 0x74, 0x49, 0x00,
+ 0x1d, 0x94, 0x49, 0x00,
+ 0x97, 0x74, 0x49, 0x00, 0x79, 0x74, 0x49, 0x00, 0xc0, 0x70, 0x49, 0x04,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x97, 0x64, 0x47, 0x06, 0x7a, 0x64, 0x47, 0x00, 0x78, 0x64, 0x47, 0x04,
+ 0x2e, 0x64, 0x47, 0x00,
+ 0xc0, 0xd0, 0x40, 0x04, 0x2d, 0x54, 0x47, 0x00, 0x0d, 0xd4, 0x40, 0x04,
+ 0x74, 0xc4, 0x40, 0x00,
+ 0xc0, 0x00, 0x06, 0x04, 0x74, 0xd4, 0x40, 0x00, 0xc0, 0x10, 0x06, 0x04,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x16, 0x04, 0x4e, 0x06, 0xc1, 0xc0, 0x4d, 0x00, 0xd7, 0x70, 0x0d, 0x0f,
+ 0xe0, 0x94, 0x0c, 0x00,
+ 0xc0, 0x00, 0x4e, 0x06, 0xc0, 0xd0, 0x4d, 0x00, 0xe0, 0x04, 0x4e, 0x08,
+ 0x73, 0x04, 0x4e, 0x00,
+ 0xc0, 0xe0, 0x4d, 0x04, 0xc1, 0x10, 0x0c, 0x00, 0x73, 0xf4, 0x4d, 0x08,
+ 0xdf, 0xc4, 0x40, 0x00,
+ 0xc0, 0xf0, 0x4d, 0x04, 0xc0, 0xf0, 0x4d, 0x00, 0xde, 0x04, 0x06, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x17, 0x04, 0x4e, 0x06, 0xc1, 0xc0, 0x4d, 0x00, 0xd7, 0x70, 0x0d, 0x0f,
+ 0xe0, 0x94, 0x0c, 0x00,
+ 0xc0, 0x00, 0x4e, 0x06, 0xc0, 0xd0, 0x4d, 0x00, 0xe0, 0x04, 0x4e, 0x08,
+ 0x73, 0x04, 0x4e, 0x00,
+ 0xc0, 0xe0, 0x4d, 0x04, 0xc1, 0x10, 0x0c, 0x00, 0x73, 0xf4, 0x4d, 0x08,
+ 0xdf, 0xd4, 0x40, 0x00,
+ 0xc0, 0xf0, 0x4d, 0x04, 0xc0, 0xf0, 0x4d, 0x00, 0xde, 0x14, 0x06, 0x06,
+ 0xc0, 0xc0, 0x40, 0x00,
+ 0x0c, 0x04, 0x41, 0x09, 0x10, 0x14, 0x47, 0x00, 0x71, 0x14, 0x47, 0x0a,
+ 0xc0, 0xd0, 0x40, 0x00,
+ 0x0d, 0x04, 0x41, 0x09, 0x10, 0x24, 0x47, 0x00, 0x72, 0x24, 0x47, 0x0a,
+ 0x41, 0xc4, 0x40, 0x00,
+ 0xc0, 0x80, 0x06, 0x00, 0x42, 0xd4, 0x40, 0x00, 0xc0, 0x90, 0x06, 0x00,
+ 0x41, 0xc4, 0x40, 0x00,
+ 0xc0, 0x40, 0x06, 0x00, 0x42, 0xd4, 0x40, 0x00, 0xc0, 0x50, 0x06, 0x00,
+ 0x41, 0xc4, 0x40, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x34, 0x44, 0x00,
+ 0x43, 0x34, 0x44, 0x0a, 0x42, 0xd4, 0x40, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x44, 0x44, 0x00, 0x44, 0x44, 0x44, 0x0a,
+ 0x4e, 0xa4, 0x40, 0x00,
+ 0xc0, 0xa0, 0x40, 0x00, 0x4e, 0xb4, 0x40, 0x00, 0xc0, 0xb0, 0x40, 0x00,
+ 0xc0, 0xa0, 0x40, 0x00,
+ 0x0a, 0x04, 0x41, 0x09, 0x10, 0xf4, 0x44, 0x00, 0x4f, 0xf4, 0x44, 0x0a,
+ 0xc0, 0xb0, 0x40, 0x00,
+ 0x0b, 0x04, 0x41, 0x09, 0x10, 0x04, 0x45, 0x00, 0x50, 0x04, 0x45, 0x0a,
+ 0x48, 0x24, 0x04, 0x00,
+ 0x0a, 0xa4, 0x40, 0x00, 0x48, 0x34, 0x04, 0x00, 0x0b, 0xb4, 0x40, 0x00,
+ 0x48, 0x24, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x94, 0x44, 0x00,
+ 0x49, 0x94, 0x44, 0x0a, 0x48, 0x34, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0xa4, 0x44, 0x00, 0x4a, 0xa4, 0x44, 0x0a,
+ 0x4b, 0x04, 0x04, 0x00,
+ 0x0a, 0xa4, 0x40, 0x00, 0x4b, 0x14, 0x04, 0x00, 0x0b, 0xb4, 0x40, 0x00,
+ 0x4b, 0x04, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0xc4, 0x44, 0x00,
+ 0x4c, 0xc4, 0x44, 0x0a, 0x4b, 0x14, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0xd4, 0x44, 0x00, 0x4d, 0xd4, 0x44, 0x0a,
+ 0x45, 0x44, 0x04, 0x00,
+ 0x0a, 0xa4, 0x40, 0x00, 0x45, 0x54, 0x04, 0x00, 0x0b, 0xb4, 0x40, 0x00,
+ 0x45, 0x44, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x64, 0x44, 0x00,
+ 0x46, 0x64, 0x44, 0x0a, 0x45, 0x54, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x74, 0x44, 0x00, 0x47, 0x74, 0x44, 0x0a,
+ 0x51, 0xc4, 0x04, 0x00,
+ 0x0a, 0xa4, 0x40, 0x00, 0x51, 0xd4, 0x04, 0x00, 0x0b, 0xb4, 0x40, 0x00,
+ 0x51, 0xc4, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x24, 0x45, 0x00,
+ 0x52, 0x24, 0x45, 0x0a, 0x51, 0xd4, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x34, 0x45, 0x00, 0x53, 0x34, 0x45, 0x0a,
+ 0x54, 0x84, 0x04, 0x00,
+ 0x0a, 0xa4, 0x40, 0x00, 0x54, 0x94, 0x04, 0x00, 0x0b, 0xb4, 0x40, 0x00,
+ 0x54, 0x84, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x54, 0x45, 0x00,
+ 0x55, 0x54, 0x45, 0x0a, 0x54, 0x94, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x64, 0x45, 0x00, 0x56, 0x64, 0x45, 0x0a,
+ 0x04, 0xa4, 0x40, 0x00,
+ 0xc0, 0x60, 0x40, 0x00, 0x05, 0xb4, 0x40, 0x00, 0xc0, 0x70, 0x40, 0x00,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x06, 0x64, 0x47, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x06, 0x54, 0x47, 0x06,
+ 0x18, 0x64, 0x47, 0x00,
+ 0xc0, 0x60, 0x47, 0x00, 0x7b, 0x64, 0x47, 0x00, 0xc0, 0x60, 0x47, 0x00,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xbf, 0x04, 0x4c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xbe, 0xf4, 0x4b, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x76, 0xe4, 0x4b, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc2, 0x34, 0x4c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc1, 0x24, 0x4c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x10, 0x4c, 0x06,
+ 0x28, 0xe4, 0x4b, 0x00,
+ 0xc0, 0x10, 0x4c, 0x00, 0x29, 0xf4, 0x4b, 0x00, 0xc1, 0x14, 0x4c, 0x00,
+ 0x2a, 0x24, 0x4c, 0x00,
+ 0xc1, 0x14, 0x4c, 0x00, 0x2b, 0x04, 0x4c, 0x00, 0xc1, 0x14, 0x4c, 0x00,
+ 0x2c, 0x34, 0x4c, 0x00,
+ 0xc1, 0x14, 0x4c, 0x00, 0x79, 0x14, 0x4c, 0x00, 0xc0, 0x10, 0x4c, 0x04,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc1, 0x64, 0x47, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xb9, 0xa4, 0x4b, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xb8, 0x94, 0x4b, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x76, 0x84, 0x4b, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xbc, 0xd4, 0x4b, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xbb, 0xc4, 0x4b, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0xb0, 0x4b, 0x06, 0x23, 0x84, 0x4b, 0x00, 0xc0, 0xb0, 0x4b, 0x00,
+ 0x24, 0x94, 0x4b, 0x00,
+ 0xbb, 0xb4, 0x4b, 0x00, 0x25, 0xc4, 0x4b, 0x00, 0xbb, 0xb4, 0x4b, 0x00,
+ 0x26, 0xa4, 0x4b, 0x00,
+ 0xbb, 0xb4, 0x4b, 0x00, 0x27, 0xd4, 0x4b, 0x00, 0xbb, 0xb4, 0x4b, 0x00,
+ 0x79, 0xb4, 0x4b, 0x00,
+ 0xc0, 0xb0, 0x4b, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0xbb, 0x64, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xb3, 0x44, 0x4b, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xb2, 0x34, 0x4b, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x76, 0x24, 0x4b, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xb6, 0x74, 0x4b, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xb5, 0x64, 0x4b, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x50, 0x4b, 0x06,
+ 0x1e, 0x24, 0x4b, 0x00,
+ 0xc0, 0x50, 0x4b, 0x00, 0x1f, 0x34, 0x4b, 0x00, 0xb5, 0x54, 0x4b, 0x00,
+ 0x20, 0x64, 0x4b, 0x00,
+ 0xb5, 0x54, 0x4b, 0x00, 0x21, 0x44, 0x4b, 0x00, 0xb5, 0x54, 0x4b, 0x00,
+ 0x22, 0x74, 0x4b, 0x00,
+ 0xb5, 0x54, 0x4b, 0x00, 0x79, 0x54, 0x4b, 0x00, 0xc0, 0x50, 0x4b, 0x04,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xb5, 0x64, 0x47, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xad, 0xe4, 0x4a, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xac, 0xd4, 0x4a, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x76, 0xc4, 0x4a, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xb0, 0x14, 0x4b, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xaf, 0x04, 0x4b, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0xf0, 0x4a, 0x06, 0x19, 0xc4, 0x4a, 0x00, 0xc0, 0xf0, 0x4a, 0x00,
+ 0x1a, 0xd4, 0x4a, 0x00,
+ 0xaf, 0xf4, 0x4a, 0x00, 0x1b, 0x04, 0x4b, 0x00, 0xaf, 0xf4, 0x4a, 0x00,
+ 0x1c, 0xe4, 0x4a, 0x00,
+ 0xaf, 0xf4, 0x4a, 0x00, 0x1d, 0x14, 0x4b, 0x00, 0xaf, 0xf4, 0x4a, 0x00,
+ 0x79, 0xf4, 0x4a, 0x00,
+ 0xc0, 0xf0, 0x4a, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0xaf, 0x64, 0x47, 0x06,
+ 0x7a, 0x64, 0x47, 0x00,
+ 0x78, 0x64, 0x47, 0x04, 0x2e, 0x64, 0x47, 0x00, 0xc0, 0x60, 0x40, 0x04,
+ 0x2d, 0x54, 0x47, 0x00,
+ 0x06, 0x64, 0x40, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0x07, 0x64, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x07, 0x54, 0x47, 0x06, 0x18, 0x64, 0x47, 0x00, 0xc0, 0x60, 0x47, 0x00,
+ 0x7b, 0x64, 0x47, 0x00,
+ 0xc0, 0x60, 0x47, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xd7, 0x84, 0x4d, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xd6, 0x74, 0x4d, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x76, 0x64, 0x4d, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xda, 0xb4, 0x4d, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xd9, 0xa4, 0x4d, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x90, 0x4d, 0x06, 0x28, 0x64, 0x4d, 0x00, 0xc0, 0x90, 0x4d, 0x00,
+ 0x29, 0x74, 0x4d, 0x00,
+ 0xd9, 0x94, 0x4d, 0x00, 0x2a, 0xa4, 0x4d, 0x00, 0xd9, 0x94, 0x4d, 0x00,
+ 0x2b, 0x84, 0x4d, 0x00,
+ 0xd9, 0x94, 0x4d, 0x00, 0x2c, 0xb4, 0x4d, 0x00, 0xd9, 0x94, 0x4d, 0x00,
+ 0x79, 0x94, 0x4d, 0x00,
+ 0xc0, 0x90, 0x4d, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0xd9, 0x64, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xd1, 0x24, 0x4d, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xd0, 0x14, 0x4d, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x76, 0x04, 0x4d, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xd4, 0x54, 0x4d, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xd3, 0x44, 0x4d, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x30, 0x4d, 0x06,
+ 0x23, 0x04, 0x4d, 0x00,
+ 0xc0, 0x30, 0x4d, 0x00, 0x24, 0x14, 0x4d, 0x00, 0xd3, 0x34, 0x4d, 0x00,
+ 0x25, 0x44, 0x4d, 0x00,
+ 0xd3, 0x34, 0x4d, 0x00, 0x26, 0x24, 0x4d, 0x00, 0xd3, 0x34, 0x4d, 0x00,
+ 0x27, 0x54, 0x4d, 0x00,
+ 0xd3, 0x34, 0x4d, 0x00, 0x79, 0x34, 0x4d, 0x00, 0xc0, 0x30, 0x4d, 0x04,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xd3, 0x64, 0x47, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xcb, 0xc4, 0x4c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xca, 0xb4, 0x4c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x76, 0xa4, 0x4c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xce, 0xf4, 0x4c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xcd, 0xe4, 0x4c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0xd0, 0x4c, 0x06, 0x1e, 0xa4, 0x4c, 0x00, 0xc0, 0xd0, 0x4c, 0x00,
+ 0x1f, 0xb4, 0x4c, 0x00,
+ 0xcd, 0xd4, 0x4c, 0x00, 0x20, 0xe4, 0x4c, 0x00, 0xcd, 0xd4, 0x4c, 0x00,
+ 0x21, 0xc4, 0x4c, 0x00,
+ 0xcd, 0xd4, 0x4c, 0x00, 0x22, 0xf4, 0x4c, 0x00, 0xcd, 0xd4, 0x4c, 0x00,
+ 0x79, 0xd4, 0x4c, 0x00,
+ 0xc0, 0xd0, 0x4c, 0x04, 0xc0, 0x00, 0x0c, 0x00, 0xcd, 0x64, 0x47, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc5, 0x64, 0x4c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc4, 0x54, 0x4c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x76, 0x44, 0x4c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc8, 0x94, 0x4c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc7, 0x84, 0x4c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x70, 0x4c, 0x06,
+ 0x19, 0x44, 0x4c, 0x00,
+ 0xc0, 0x70, 0x4c, 0x00, 0x1a, 0x54, 0x4c, 0x00, 0xc7, 0x74, 0x4c, 0x00,
+ 0x1b, 0x84, 0x4c, 0x00,
+ 0xc7, 0x74, 0x4c, 0x00, 0x1c, 0x64, 0x4c, 0x00, 0xc7, 0x74, 0x4c, 0x00,
+ 0x1d, 0x94, 0x4c, 0x00,
+ 0xc7, 0x74, 0x4c, 0x00, 0x79, 0x74, 0x4c, 0x00, 0xc0, 0x70, 0x4c, 0x04,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc7, 0x64, 0x47, 0x06, 0x7a, 0x64, 0x47, 0x00, 0x78, 0x64, 0x47, 0x04,
+ 0x2e, 0x64, 0x47, 0x00,
+ 0xc0, 0x70, 0x40, 0x04, 0x2d, 0x54, 0x47, 0x00, 0x07, 0x74, 0x40, 0x04,
+ 0x57, 0x64, 0x40, 0x00,
+ 0xc0, 0xe0, 0x06, 0x00, 0x58, 0x74, 0x40, 0x00, 0xc0, 0xf0, 0x06, 0x00,
+ 0x57, 0x64, 0x40, 0x00,
+ 0xc0, 0x60, 0x06, 0x00, 0x58, 0x74, 0x40, 0x00, 0xc0, 0x70, 0x06, 0x00,
+ 0x57, 0x64, 0x40, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x94, 0x45, 0x00,
+ 0x59, 0x94, 0x45, 0x0a, 0x58, 0x74, 0x40, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0xa4, 0x45, 0x00, 0x5a, 0xa4, 0x45, 0x0a,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x12, 0x24, 0x06, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x13, 0x34, 0x06, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0x12, 0xa4, 0x06, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0x13, 0xb4, 0x06, 0x06,
+ 0x61, 0x04, 0x04, 0x00,
+ 0xc0, 0x60, 0x40, 0x00, 0x61, 0x14, 0x04, 0x00, 0xc0, 0x70, 0x40, 0x00,
+ 0x61, 0x04, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x24, 0x46, 0x00,
+ 0x62, 0x24, 0x46, 0x0a, 0x61, 0x14, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x34, 0x46, 0x00, 0x63, 0x34, 0x46, 0x0a,
+ 0x5b, 0x44, 0x04, 0x00,
+ 0x06, 0x64, 0x40, 0x00, 0x5b, 0x54, 0x04, 0x00, 0x07, 0x74, 0x40, 0x00,
+ 0x5b, 0x44, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0xc4, 0x45, 0x00,
+ 0x5c, 0xc4, 0x45, 0x0a, 0x5b, 0x54, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0xd4, 0x45, 0x00, 0x5d, 0xd4, 0x45, 0x0a,
+ 0x5e, 0x24, 0x04, 0x00,
+ 0x06, 0x64, 0x40, 0x00, 0x5e, 0x34, 0x04, 0x00, 0x07, 0x74, 0x40, 0x00,
+ 0x5e, 0x24, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0xf4, 0x45, 0x00,
+ 0x5f, 0xf4, 0x45, 0x0a, 0x5e, 0x34, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x04, 0x46, 0x00, 0x60, 0x04, 0x46, 0x0a,
+ 0x64, 0x84, 0x40, 0x00,
+ 0x06, 0x64, 0x40, 0x00, 0x64, 0x94, 0x40, 0x00, 0x07, 0x74, 0x40, 0x00,
+ 0x64, 0x84, 0x40, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x54, 0x46, 0x00,
+ 0x65, 0x54, 0x46, 0x0a, 0x64, 0x94, 0x40, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x64, 0x46, 0x00, 0x66, 0x64, 0x46, 0x0a,
+ 0x67, 0xc4, 0x04, 0x00,
+ 0x06, 0x64, 0x40, 0x00, 0x67, 0xd4, 0x04, 0x00, 0x07, 0x74, 0x40, 0x00,
+ 0x67, 0xc4, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0x84, 0x46, 0x00,
+ 0x68, 0x84, 0x46, 0x0a, 0x67, 0xd4, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x94, 0x46, 0x00, 0x69, 0x94, 0x46, 0x0a,
+ 0x6a, 0x84, 0x04, 0x00,
+ 0x06, 0x64, 0x40, 0x00, 0x6a, 0x94, 0x04, 0x00, 0x07, 0x74, 0x40, 0x00,
+ 0x6a, 0x84, 0x04, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0xb4, 0x46, 0x00,
+ 0x6b, 0xb4, 0x46, 0x0a, 0x6a, 0x94, 0x04, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0xc4, 0x46, 0x00, 0x6c, 0xc4, 0x46, 0x0a,
+ 0x6d, 0x64, 0x40, 0x00,
+ 0xc0, 0x60, 0x07, 0x00, 0x6e, 0x74, 0x40, 0x00, 0xc0, 0x70, 0x07, 0x00,
+ 0x6d, 0x64, 0x40, 0x00,
+ 0xc0, 0x10, 0x41, 0x00, 0xc0, 0x10, 0x41, 0x00, 0x11, 0x04, 0x41, 0x09,
+ 0x10, 0xf4, 0x46, 0x00,
+ 0x6f, 0xf4, 0x46, 0x0a, 0x6e, 0x74, 0x40, 0x00, 0xc0, 0x10, 0x41, 0x00,
+ 0xc0, 0x10, 0x41, 0x00,
+ 0x11, 0x04, 0x41, 0x09, 0x10, 0x04, 0x47, 0x00, 0x70, 0x04, 0x47, 0x0a,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0xc0, 0x00, 0x0c, 0x00,
+ 0xc0, 0x00, 0x0c, 0x06, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x06,
+ 0x37, 0x00, 0x00, 0x00,
+ 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00, 0x45, 0x51, 0x55, 0x41,
+ 0x4c, 0x49, 0x5a, 0x45,
+ 0x52, 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, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x52, 0x45, 0x53, 0x43, 0x41, 0x4c, 0x45,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00,
+ 0x4c, 0x4f, 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, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00,
+ 0x4d, 0x49, 0x44, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x1e, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x48, 0x49, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x10,
+ 0x80, 0x00, 0x00, 0x00, 0x58, 0x48, 0x49, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x10,
+ 0x80, 0x00, 0x00, 0x00,
+ 0x42, 0x59, 0x50, 0x41, 0x53, 0x53, 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, 0x00,
+ 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x52, 0x4f, 0x4e,
+ 0x54, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x50, 0x44, 0x49,
+ 0x46, 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, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x49, 0x47, 0x43, 0x44, 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, 0x00, 0x00,
+ 0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x33, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0x39, 0x37,
+ 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, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x38, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x39, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x55, 0x58, 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, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x4d, 0x49, 0x43, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x3e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3f, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00,
+ 0x64, 0x64, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x53, 0x55, 0x52, 0x52, 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, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x53, 0x50, 0x44, 0x49,
+ 0x46, 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, 0x00, 0x00,
+ 0x45, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0x47, 0x43, 0x44, 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, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x49, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x43, 0x39, 0x37,
+ 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, 0x00, 0x00, 0x00,
+ 0x4b, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x55, 0x58, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x51, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x4d, 0x49, 0x43, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x55, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x57, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x53, 0x50, 0x44, 0x49, 0x46, 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, 0x00, 0x00,
+ 0x5b, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5c, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0x47, 0x43,
+ 0x44, 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, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x43, 0x39, 0x37, 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, 0x00, 0x00, 0x00,
+ 0x61, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x62, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x43, 0x4d, 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, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x55, 0x58, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x67, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x68, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x49, 0x43, 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, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6f, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x50, 0x41, 0x53,
+ 0x53, 0x54, 0x48, 0x52,
+ 0x4f, 0x55, 0x47, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
+ 0x02, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 0x00, 0x00,
+ 0x07, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x78, 0x00, 0x00, 0x00,
+ 0x2c, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x7a, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0xdc, 0x00, 0x00, 0x00,
+ 0x08, 0x10, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
diff --git a/kernel/drv/oss_sblive/emu10k2_dsp_be.h b/kernel/drv/oss_sblive/emu10k2_dsp_be.h
new file mode 100644
index 0000000..95447fa
--- /dev/null
+++ b/kernel/drv/oss_sblive/emu10k2_dsp_be.h
@@ -0,0 +1,989 @@
+/*
+ * Purpose: DSP firmware file for Audigy (big endian machines)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+static unsigned char emu10k2_dsp[] = {
+ 0x00, 0xe1, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0xc2,
+ 0x00, 0x00, 0x00, 0xc1,
+ 0x04, 0x40, 0x60, 0xc0, 0x00, 0x00, 0x10, 0xc1, 0x04, 0x40, 0x70, 0xc0,
+ 0x00, 0x40, 0x64, 0x02,
+ 0x00, 0x40, 0x80, 0xc0, 0x00, 0x40, 0x74, 0x03, 0x00, 0x40, 0x90, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x41, 0x60, 0x14, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x41, 0x70, 0x15,
+ 0x00, 0x00, 0x60, 0xc0,
+ 0x06, 0x40, 0xa0, 0x02, 0x00, 0x00, 0x70, 0xc0, 0x06, 0x40, 0xb0, 0x03,
+ 0x00, 0x00, 0x40, 0xc1,
+ 0x04, 0x41, 0x20, 0xc0, 0x00, 0x00, 0x50, 0xc1, 0x04, 0x41, 0x30, 0xc0,
+ 0x00, 0x40, 0xa4, 0x02,
+ 0x00, 0x40, 0xa0, 0xc0, 0x00, 0x40, 0xb4, 0x03, 0x00, 0x40, 0xb0, 0xc0,
+ 0x00, 0x40, 0x84, 0x38,
+ 0x00, 0x40, 0xc0, 0xc0, 0x00, 0x40, 0x94, 0x38, 0x00, 0x40, 0xd0, 0xc0,
+ 0x00, 0x40, 0xc0, 0xc0,
+ 0x09, 0x41, 0x04, 0x0c, 0x00, 0x43, 0x94, 0x10, 0x0a, 0x43, 0x94, 0x39,
+ 0x00, 0x40, 0xd0, 0xc0,
+ 0x09, 0x41, 0x04, 0x0d, 0x00, 0x43, 0xa4, 0x10, 0x0a, 0x43, 0xa4, 0x3a,
+ 0x00, 0x04, 0x24, 0x32,
+ 0x00, 0x40, 0xc4, 0x0c, 0x00, 0x04, 0x34, 0x32, 0x00, 0x40, 0xd4, 0x0d,
+ 0x00, 0x04, 0x24, 0x32,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x43, 0x34, 0x10,
+ 0x0a, 0x43, 0x34, 0x33, 0x00, 0x04, 0x34, 0x32, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x43, 0x44, 0x10, 0x0a, 0x43, 0x44, 0x34,
+ 0x00, 0x04, 0x04, 0x35,
+ 0x00, 0x40, 0xc4, 0x0c, 0x00, 0x04, 0x14, 0x35, 0x00, 0x40, 0xd4, 0x0d,
+ 0x00, 0x04, 0x04, 0x35,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x43, 0x64, 0x10,
+ 0x0a, 0x43, 0x64, 0x36, 0x00, 0x04, 0x14, 0x35, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x43, 0x74, 0x10, 0x0a, 0x43, 0x74, 0x37,
+ 0x00, 0x04, 0x44, 0x2f,
+ 0x00, 0x40, 0xc4, 0x0c, 0x00, 0x04, 0x54, 0x2f, 0x00, 0x40, 0xd4, 0x0d,
+ 0x00, 0x04, 0x44, 0x2f,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x43, 0x04, 0x10,
+ 0x0a, 0x43, 0x04, 0x30, 0x00, 0x04, 0x54, 0x2f, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x43, 0x14, 0x10, 0x0a, 0x43, 0x14, 0x31,
+ 0x00, 0x04, 0x44, 0x2f,
+ 0x00, 0x40, 0xc4, 0x0c, 0x00, 0x04, 0x54, 0x2f, 0x00, 0x40, 0xd4, 0x0d,
+ 0x00, 0x04, 0xc4, 0x3b,
+ 0x00, 0x40, 0xc4, 0x0c, 0x00, 0x04, 0xd4, 0x3b, 0x00, 0x40, 0xd4, 0x0d,
+ 0x00, 0x04, 0xc4, 0x3b,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x43, 0xc4, 0x10,
+ 0x0a, 0x43, 0xc4, 0x3c, 0x00, 0x04, 0xd4, 0x3b, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x43, 0xd4, 0x10, 0x0a, 0x43, 0xd4, 0x3d,
+ 0x00, 0x40, 0xc4, 0x04,
+ 0x00, 0x40, 0xc0, 0xc0, 0x00, 0x40, 0xd4, 0x05, 0x00, 0x40, 0xd0, 0xc0,
+ 0x00, 0x04, 0x84, 0x3e,
+ 0x00, 0x40, 0xe4, 0x0e, 0x00, 0x04, 0x94, 0x3e, 0x00, 0x40, 0xf4, 0x0f,
+ 0x00, 0x04, 0x84, 0x3e,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x43, 0xf4, 0x10,
+ 0x0a, 0x43, 0xf4, 0x3f, 0x00, 0x04, 0x94, 0x3e, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x44, 0x04, 0x10, 0x0a, 0x44, 0x04, 0x40,
+ 0x00, 0x40, 0xc4, 0x04,
+ 0x00, 0x40, 0xe0, 0xc0, 0x00, 0x40, 0xd4, 0x05, 0x00, 0x40, 0xf0, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0x0c, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x54, 0x0c,
+ 0x00, 0x47, 0x64, 0x18,
+ 0x00, 0x47, 0x60, 0xc0, 0x00, 0x47, 0x64, 0x7b, 0x00, 0x47, 0x60, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x49, 0x04, 0x8f, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x48, 0xf4, 0x8e,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x48, 0xe4, 0x76, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x49, 0x34, 0x92,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x49, 0x24, 0x91, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x49, 0x10, 0xc0,
+ 0x00, 0x48, 0xe4, 0x28,
+ 0x00, 0x49, 0x10, 0xc0, 0x00, 0x48, 0xf4, 0x29, 0x00, 0x49, 0x14, 0x91,
+ 0x00, 0x49, 0x24, 0x2a,
+ 0x00, 0x49, 0x14, 0x91, 0x00, 0x49, 0x04, 0x2b, 0x00, 0x49, 0x14, 0x91,
+ 0x00, 0x49, 0x34, 0x2c,
+ 0x00, 0x49, 0x14, 0x91, 0x00, 0x49, 0x14, 0x79, 0x04, 0x49, 0x10, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0x91, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x48, 0xa4, 0x89,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x48, 0x94, 0x88, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x48, 0x84, 0x76,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x48, 0xd4, 0x8c, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x48, 0xc4, 0x8b,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x48, 0xb0, 0xc0, 0x00, 0x48, 0x84, 0x23, 0x00, 0x48, 0xb0, 0xc0,
+ 0x00, 0x48, 0x94, 0x24,
+ 0x00, 0x48, 0xb4, 0x8b, 0x00, 0x48, 0xc4, 0x25, 0x00, 0x48, 0xb4, 0x8b,
+ 0x00, 0x48, 0xa4, 0x26,
+ 0x00, 0x48, 0xb4, 0x8b, 0x00, 0x48, 0xd4, 0x27, 0x00, 0x48, 0xb4, 0x8b,
+ 0x00, 0x48, 0xb4, 0x79,
+ 0x04, 0x48, 0xb0, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0x8b,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x48, 0x44, 0x83, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x48, 0x34, 0x82,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x48, 0x24, 0x76, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x48, 0x74, 0x86,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x48, 0x64, 0x85, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x48, 0x50, 0xc0,
+ 0x00, 0x48, 0x24, 0x1e,
+ 0x00, 0x48, 0x50, 0xc0, 0x00, 0x48, 0x34, 0x1f, 0x00, 0x48, 0x54, 0x85,
+ 0x00, 0x48, 0x64, 0x20,
+ 0x00, 0x48, 0x54, 0x85, 0x00, 0x48, 0x44, 0x21, 0x00, 0x48, 0x54, 0x85,
+ 0x00, 0x48, 0x74, 0x22,
+ 0x00, 0x48, 0x54, 0x85, 0x00, 0x48, 0x54, 0x79, 0x04, 0x48, 0x50, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0x85, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0xe4, 0x7d,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0xd4, 0x7c, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0xc4, 0x76,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x48, 0x14, 0x80, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x48, 0x04, 0x7f,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0xf0, 0xc0, 0x00, 0x47, 0xc4, 0x19, 0x00, 0x47, 0xf0, 0xc0,
+ 0x00, 0x47, 0xd4, 0x1a,
+ 0x00, 0x47, 0xf4, 0x7f, 0x00, 0x48, 0x04, 0x1b, 0x00, 0x47, 0xf4, 0x7f,
+ 0x00, 0x47, 0xe4, 0x1c,
+ 0x00, 0x47, 0xf4, 0x7f, 0x00, 0x48, 0x14, 0x1d, 0x00, 0x47, 0xf4, 0x7f,
+ 0x00, 0x47, 0xf4, 0x79,
+ 0x04, 0x47, 0xf0, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0x7f,
+ 0x00, 0x47, 0x64, 0x7a,
+ 0x04, 0x47, 0x64, 0x78, 0x00, 0x47, 0x64, 0x2e, 0x04, 0x40, 0xc0, 0xc0,
+ 0x00, 0x47, 0x54, 0x2d,
+ 0x04, 0x40, 0xc4, 0x0c, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0x0d,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x54, 0x0d, 0x00, 0x47, 0x64, 0x18, 0x00, 0x47, 0x60, 0xc0,
+ 0x00, 0x47, 0x64, 0x7b,
+ 0x00, 0x47, 0x60, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4a, 0x84, 0xa7,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4a, 0x74, 0xa6, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4a, 0x64, 0x76,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4a, 0xb4, 0xaa, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4a, 0xa4, 0xa9,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4a, 0x90, 0xc0, 0x00, 0x4a, 0x64, 0x28, 0x00, 0x4a, 0x90, 0xc0,
+ 0x00, 0x4a, 0x74, 0x29,
+ 0x00, 0x4a, 0x94, 0xa9, 0x00, 0x4a, 0xa4, 0x2a, 0x00, 0x4a, 0x94, 0xa9,
+ 0x00, 0x4a, 0x84, 0x2b,
+ 0x00, 0x4a, 0x94, 0xa9, 0x00, 0x4a, 0xb4, 0x2c, 0x00, 0x4a, 0x94, 0xa9,
+ 0x00, 0x4a, 0x94, 0x79,
+ 0x04, 0x4a, 0x90, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0xa9,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4a, 0x24, 0xa1, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4a, 0x14, 0xa0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4a, 0x04, 0x76, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4a, 0x54, 0xa4,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4a, 0x44, 0xa3, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4a, 0x30, 0xc0,
+ 0x00, 0x4a, 0x04, 0x23,
+ 0x00, 0x4a, 0x30, 0xc0, 0x00, 0x4a, 0x14, 0x24, 0x00, 0x4a, 0x34, 0xa3,
+ 0x00, 0x4a, 0x44, 0x25,
+ 0x00, 0x4a, 0x34, 0xa3, 0x00, 0x4a, 0x24, 0x26, 0x00, 0x4a, 0x34, 0xa3,
+ 0x00, 0x4a, 0x54, 0x27,
+ 0x00, 0x4a, 0x34, 0xa3, 0x00, 0x4a, 0x34, 0x79, 0x04, 0x4a, 0x30, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0xa3, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x49, 0xc4, 0x9b,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x49, 0xb4, 0x9a, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x49, 0xa4, 0x76,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x49, 0xf4, 0x9e, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x49, 0xe4, 0x9d,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x49, 0xd0, 0xc0, 0x00, 0x49, 0xa4, 0x1e, 0x00, 0x49, 0xd0, 0xc0,
+ 0x00, 0x49, 0xb4, 0x1f,
+ 0x00, 0x49, 0xd4, 0x9d, 0x00, 0x49, 0xe4, 0x20, 0x00, 0x49, 0xd4, 0x9d,
+ 0x00, 0x49, 0xc4, 0x21,
+ 0x00, 0x49, 0xd4, 0x9d, 0x00, 0x49, 0xf4, 0x22, 0x00, 0x49, 0xd4, 0x9d,
+ 0x00, 0x49, 0xd4, 0x79,
+ 0x04, 0x49, 0xd0, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0x9d,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x49, 0x64, 0x95, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x49, 0x54, 0x94,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x49, 0x44, 0x76, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x49, 0x94, 0x98,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x49, 0x84, 0x97, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x49, 0x70, 0xc0,
+ 0x00, 0x49, 0x44, 0x19,
+ 0x00, 0x49, 0x70, 0xc0, 0x00, 0x49, 0x54, 0x1a, 0x00, 0x49, 0x74, 0x97,
+ 0x00, 0x49, 0x84, 0x1b,
+ 0x00, 0x49, 0x74, 0x97, 0x00, 0x49, 0x64, 0x1c, 0x00, 0x49, 0x74, 0x97,
+ 0x00, 0x49, 0x94, 0x1d,
+ 0x00, 0x49, 0x74, 0x97, 0x00, 0x49, 0x74, 0x79, 0x04, 0x49, 0x70, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0x97, 0x00, 0x47, 0x64, 0x7a, 0x04, 0x47, 0x64, 0x78,
+ 0x00, 0x47, 0x64, 0x2e,
+ 0x04, 0x40, 0xd0, 0xc0, 0x00, 0x47, 0x54, 0x2d, 0x04, 0x40, 0xd4, 0x0d,
+ 0x00, 0x40, 0xc4, 0x74,
+ 0x04, 0x06, 0x00, 0xc0, 0x00, 0x40, 0xd4, 0x74, 0x04, 0x06, 0x10, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4e, 0x04, 0x16, 0x00, 0x4d, 0xc0, 0xc1, 0x0f, 0x0d, 0x70, 0xd7,
+ 0x00, 0x0c, 0x94, 0xe0,
+ 0x06, 0x4e, 0x00, 0xc0, 0x00, 0x4d, 0xd0, 0xc0, 0x08, 0x4e, 0x04, 0xe0,
+ 0x00, 0x4e, 0x04, 0x73,
+ 0x04, 0x4d, 0xe0, 0xc0, 0x00, 0x0c, 0x10, 0xc1, 0x08, 0x4d, 0xf4, 0x73,
+ 0x00, 0x40, 0xc4, 0xdf,
+ 0x04, 0x4d, 0xf0, 0xc0, 0x00, 0x4d, 0xf0, 0xc0, 0x06, 0x06, 0x04, 0xde,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4e, 0x04, 0x17, 0x00, 0x4d, 0xc0, 0xc1, 0x0f, 0x0d, 0x70, 0xd7,
+ 0x00, 0x0c, 0x94, 0xe0,
+ 0x06, 0x4e, 0x00, 0xc0, 0x00, 0x4d, 0xd0, 0xc0, 0x08, 0x4e, 0x04, 0xe0,
+ 0x00, 0x4e, 0x04, 0x73,
+ 0x04, 0x4d, 0xe0, 0xc0, 0x00, 0x0c, 0x10, 0xc1, 0x08, 0x4d, 0xf4, 0x73,
+ 0x00, 0x40, 0xd4, 0xdf,
+ 0x04, 0x4d, 0xf0, 0xc0, 0x00, 0x4d, 0xf0, 0xc0, 0x06, 0x06, 0x14, 0xde,
+ 0x00, 0x40, 0xc0, 0xc0,
+ 0x09, 0x41, 0x04, 0x0c, 0x00, 0x47, 0x14, 0x10, 0x0a, 0x47, 0x14, 0x71,
+ 0x00, 0x40, 0xd0, 0xc0,
+ 0x09, 0x41, 0x04, 0x0d, 0x00, 0x47, 0x24, 0x10, 0x0a, 0x47, 0x24, 0x72,
+ 0x00, 0x40, 0xc4, 0x41,
+ 0x00, 0x06, 0x80, 0xc0, 0x00, 0x40, 0xd4, 0x42, 0x00, 0x06, 0x90, 0xc0,
+ 0x00, 0x40, 0xc4, 0x41,
+ 0x00, 0x06, 0x40, 0xc0, 0x00, 0x40, 0xd4, 0x42, 0x00, 0x06, 0x50, 0xc0,
+ 0x00, 0x40, 0xc4, 0x41,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x44, 0x34, 0x10,
+ 0x0a, 0x44, 0x34, 0x43, 0x00, 0x40, 0xd4, 0x42, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x44, 0x44, 0x10, 0x0a, 0x44, 0x44, 0x44,
+ 0x00, 0x40, 0xa4, 0x4e,
+ 0x00, 0x40, 0xa0, 0xc0, 0x00, 0x40, 0xb4, 0x4e, 0x00, 0x40, 0xb0, 0xc0,
+ 0x00, 0x40, 0xa0, 0xc0,
+ 0x09, 0x41, 0x04, 0x0a, 0x00, 0x44, 0xf4, 0x10, 0x0a, 0x44, 0xf4, 0x4f,
+ 0x00, 0x40, 0xb0, 0xc0,
+ 0x09, 0x41, 0x04, 0x0b, 0x00, 0x45, 0x04, 0x10, 0x0a, 0x45, 0x04, 0x50,
+ 0x00, 0x04, 0x24, 0x48,
+ 0x00, 0x40, 0xa4, 0x0a, 0x00, 0x04, 0x34, 0x48, 0x00, 0x40, 0xb4, 0x0b,
+ 0x00, 0x04, 0x24, 0x48,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x44, 0x94, 0x10,
+ 0x0a, 0x44, 0x94, 0x49, 0x00, 0x04, 0x34, 0x48, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x44, 0xa4, 0x10, 0x0a, 0x44, 0xa4, 0x4a,
+ 0x00, 0x04, 0x04, 0x4b,
+ 0x00, 0x40, 0xa4, 0x0a, 0x00, 0x04, 0x14, 0x4b, 0x00, 0x40, 0xb4, 0x0b,
+ 0x00, 0x04, 0x04, 0x4b,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x44, 0xc4, 0x10,
+ 0x0a, 0x44, 0xc4, 0x4c, 0x00, 0x04, 0x14, 0x4b, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x44, 0xd4, 0x10, 0x0a, 0x44, 0xd4, 0x4d,
+ 0x00, 0x04, 0x44, 0x45,
+ 0x00, 0x40, 0xa4, 0x0a, 0x00, 0x04, 0x54, 0x45, 0x00, 0x40, 0xb4, 0x0b,
+ 0x00, 0x04, 0x44, 0x45,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x44, 0x64, 0x10,
+ 0x0a, 0x44, 0x64, 0x46, 0x00, 0x04, 0x54, 0x45, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x44, 0x74, 0x10, 0x0a, 0x44, 0x74, 0x47,
+ 0x00, 0x04, 0xc4, 0x51,
+ 0x00, 0x40, 0xa4, 0x0a, 0x00, 0x04, 0xd4, 0x51, 0x00, 0x40, 0xb4, 0x0b,
+ 0x00, 0x04, 0xc4, 0x51,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x45, 0x24, 0x10,
+ 0x0a, 0x45, 0x24, 0x52, 0x00, 0x04, 0xd4, 0x51, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x45, 0x34, 0x10, 0x0a, 0x45, 0x34, 0x53,
+ 0x00, 0x04, 0x84, 0x54,
+ 0x00, 0x40, 0xa4, 0x0a, 0x00, 0x04, 0x94, 0x54, 0x00, 0x40, 0xb4, 0x0b,
+ 0x00, 0x04, 0x84, 0x54,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x45, 0x54, 0x10,
+ 0x0a, 0x45, 0x54, 0x55, 0x00, 0x04, 0x94, 0x54, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x45, 0x64, 0x10, 0x0a, 0x45, 0x64, 0x56,
+ 0x00, 0x40, 0xa4, 0x04,
+ 0x00, 0x40, 0x60, 0xc0, 0x00, 0x40, 0xb4, 0x05, 0x00, 0x40, 0x70, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0x06, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x54, 0x06,
+ 0x00, 0x47, 0x64, 0x18,
+ 0x00, 0x47, 0x60, 0xc0, 0x00, 0x47, 0x64, 0x7b, 0x00, 0x47, 0x60, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4c, 0x04, 0xbf, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4b, 0xf4, 0xbe,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4b, 0xe4, 0x76, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4c, 0x34, 0xc2,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4c, 0x24, 0xc1, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4c, 0x10, 0xc0,
+ 0x00, 0x4b, 0xe4, 0x28,
+ 0x00, 0x4c, 0x10, 0xc0, 0x00, 0x4b, 0xf4, 0x29, 0x00, 0x4c, 0x14, 0xc1,
+ 0x00, 0x4c, 0x24, 0x2a,
+ 0x00, 0x4c, 0x14, 0xc1, 0x00, 0x4c, 0x04, 0x2b, 0x00, 0x4c, 0x14, 0xc1,
+ 0x00, 0x4c, 0x34, 0x2c,
+ 0x00, 0x4c, 0x14, 0xc1, 0x00, 0x4c, 0x14, 0x79, 0x04, 0x4c, 0x10, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0xc1, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4b, 0xa4, 0xb9,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4b, 0x94, 0xb8, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4b, 0x84, 0x76,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4b, 0xd4, 0xbc, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4b, 0xc4, 0xbb,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4b, 0xb0, 0xc0, 0x00, 0x4b, 0x84, 0x23, 0x00, 0x4b, 0xb0, 0xc0,
+ 0x00, 0x4b, 0x94, 0x24,
+ 0x00, 0x4b, 0xb4, 0xbb, 0x00, 0x4b, 0xc4, 0x25, 0x00, 0x4b, 0xb4, 0xbb,
+ 0x00, 0x4b, 0xa4, 0x26,
+ 0x00, 0x4b, 0xb4, 0xbb, 0x00, 0x4b, 0xd4, 0x27, 0x00, 0x4b, 0xb4, 0xbb,
+ 0x00, 0x4b, 0xb4, 0x79,
+ 0x04, 0x4b, 0xb0, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0xbb,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4b, 0x44, 0xb3, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4b, 0x34, 0xb2,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4b, 0x24, 0x76, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4b, 0x74, 0xb6,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4b, 0x64, 0xb5, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4b, 0x50, 0xc0,
+ 0x00, 0x4b, 0x24, 0x1e,
+ 0x00, 0x4b, 0x50, 0xc0, 0x00, 0x4b, 0x34, 0x1f, 0x00, 0x4b, 0x54, 0xb5,
+ 0x00, 0x4b, 0x64, 0x20,
+ 0x00, 0x4b, 0x54, 0xb5, 0x00, 0x4b, 0x44, 0x21, 0x00, 0x4b, 0x54, 0xb5,
+ 0x00, 0x4b, 0x74, 0x22,
+ 0x00, 0x4b, 0x54, 0xb5, 0x00, 0x4b, 0x54, 0x79, 0x04, 0x4b, 0x50, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0xb5, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4a, 0xe4, 0xad,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4a, 0xd4, 0xac, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4a, 0xc4, 0x76,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4b, 0x14, 0xb0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4b, 0x04, 0xaf,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4a, 0xf0, 0xc0, 0x00, 0x4a, 0xc4, 0x19, 0x00, 0x4a, 0xf0, 0xc0,
+ 0x00, 0x4a, 0xd4, 0x1a,
+ 0x00, 0x4a, 0xf4, 0xaf, 0x00, 0x4b, 0x04, 0x1b, 0x00, 0x4a, 0xf4, 0xaf,
+ 0x00, 0x4a, 0xe4, 0x1c,
+ 0x00, 0x4a, 0xf4, 0xaf, 0x00, 0x4b, 0x14, 0x1d, 0x00, 0x4a, 0xf4, 0xaf,
+ 0x00, 0x4a, 0xf4, 0x79,
+ 0x04, 0x4a, 0xf0, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0xaf,
+ 0x00, 0x47, 0x64, 0x7a,
+ 0x04, 0x47, 0x64, 0x78, 0x00, 0x47, 0x64, 0x2e, 0x04, 0x40, 0x60, 0xc0,
+ 0x00, 0x47, 0x54, 0x2d,
+ 0x04, 0x40, 0x64, 0x06, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0x07,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x54, 0x07, 0x00, 0x47, 0x64, 0x18, 0x00, 0x47, 0x60, 0xc0,
+ 0x00, 0x47, 0x64, 0x7b,
+ 0x00, 0x47, 0x60, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4d, 0x84, 0xd7,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4d, 0x74, 0xd6, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4d, 0x64, 0x76,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4d, 0xb4, 0xda, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4d, 0xa4, 0xd9,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4d, 0x90, 0xc0, 0x00, 0x4d, 0x64, 0x28, 0x00, 0x4d, 0x90, 0xc0,
+ 0x00, 0x4d, 0x74, 0x29,
+ 0x00, 0x4d, 0x94, 0xd9, 0x00, 0x4d, 0xa4, 0x2a, 0x00, 0x4d, 0x94, 0xd9,
+ 0x00, 0x4d, 0x84, 0x2b,
+ 0x00, 0x4d, 0x94, 0xd9, 0x00, 0x4d, 0xb4, 0x2c, 0x00, 0x4d, 0x94, 0xd9,
+ 0x00, 0x4d, 0x94, 0x79,
+ 0x04, 0x4d, 0x90, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0xd9,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4d, 0x24, 0xd1, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4d, 0x14, 0xd0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4d, 0x04, 0x76, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4d, 0x54, 0xd4,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4d, 0x44, 0xd3, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4d, 0x30, 0xc0,
+ 0x00, 0x4d, 0x04, 0x23,
+ 0x00, 0x4d, 0x30, 0xc0, 0x00, 0x4d, 0x14, 0x24, 0x00, 0x4d, 0x34, 0xd3,
+ 0x00, 0x4d, 0x44, 0x25,
+ 0x00, 0x4d, 0x34, 0xd3, 0x00, 0x4d, 0x24, 0x26, 0x00, 0x4d, 0x34, 0xd3,
+ 0x00, 0x4d, 0x54, 0x27,
+ 0x00, 0x4d, 0x34, 0xd3, 0x00, 0x4d, 0x34, 0x79, 0x04, 0x4d, 0x30, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0xd3, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4c, 0xc4, 0xcb,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4c, 0xb4, 0xca, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4c, 0xa4, 0x76,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4c, 0xf4, 0xce, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4c, 0xe4, 0xcd,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4c, 0xd0, 0xc0, 0x00, 0x4c, 0xa4, 0x1e, 0x00, 0x4c, 0xd0, 0xc0,
+ 0x00, 0x4c, 0xb4, 0x1f,
+ 0x00, 0x4c, 0xd4, 0xcd, 0x00, 0x4c, 0xe4, 0x20, 0x00, 0x4c, 0xd4, 0xcd,
+ 0x00, 0x4c, 0xc4, 0x21,
+ 0x00, 0x4c, 0xd4, 0xcd, 0x00, 0x4c, 0xf4, 0x22, 0x00, 0x4c, 0xd4, 0xcd,
+ 0x00, 0x4c, 0xd4, 0x79,
+ 0x04, 0x4c, 0xd0, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x47, 0x64, 0xcd,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4c, 0x64, 0xc5, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4c, 0x54, 0xc4,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4c, 0x44, 0x76, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4c, 0x94, 0xc8,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x4c, 0x84, 0xc7, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x4c, 0x70, 0xc0,
+ 0x00, 0x4c, 0x44, 0x19,
+ 0x00, 0x4c, 0x70, 0xc0, 0x00, 0x4c, 0x54, 0x1a, 0x00, 0x4c, 0x74, 0xc7,
+ 0x00, 0x4c, 0x84, 0x1b,
+ 0x00, 0x4c, 0x74, 0xc7, 0x00, 0x4c, 0x64, 0x1c, 0x00, 0x4c, 0x74, 0xc7,
+ 0x00, 0x4c, 0x94, 0x1d,
+ 0x00, 0x4c, 0x74, 0xc7, 0x00, 0x4c, 0x74, 0x79, 0x04, 0x4c, 0x70, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x47, 0x64, 0xc7, 0x00, 0x47, 0x64, 0x7a, 0x04, 0x47, 0x64, 0x78,
+ 0x00, 0x47, 0x64, 0x2e,
+ 0x04, 0x40, 0x70, 0xc0, 0x00, 0x47, 0x54, 0x2d, 0x04, 0x40, 0x74, 0x07,
+ 0x00, 0x40, 0x64, 0x57,
+ 0x00, 0x06, 0xe0, 0xc0, 0x00, 0x40, 0x74, 0x58, 0x00, 0x06, 0xf0, 0xc0,
+ 0x00, 0x40, 0x64, 0x57,
+ 0x00, 0x06, 0x60, 0xc0, 0x00, 0x40, 0x74, 0x58, 0x00, 0x06, 0x70, 0xc0,
+ 0x00, 0x40, 0x64, 0x57,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x45, 0x94, 0x10,
+ 0x0a, 0x45, 0x94, 0x59, 0x00, 0x40, 0x74, 0x58, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x45, 0xa4, 0x10, 0x0a, 0x45, 0xa4, 0x5a,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x06, 0x24, 0x12, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x06, 0x34, 0x13,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x06, 0xa4, 0x12, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x06, 0xb4, 0x13,
+ 0x00, 0x04, 0x04, 0x61,
+ 0x00, 0x40, 0x60, 0xc0, 0x00, 0x04, 0x14, 0x61, 0x00, 0x40, 0x70, 0xc0,
+ 0x00, 0x04, 0x04, 0x61,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x46, 0x24, 0x10,
+ 0x0a, 0x46, 0x24, 0x62, 0x00, 0x04, 0x14, 0x61, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x46, 0x34, 0x10, 0x0a, 0x46, 0x34, 0x63,
+ 0x00, 0x04, 0x44, 0x5b,
+ 0x00, 0x40, 0x64, 0x06, 0x00, 0x04, 0x54, 0x5b, 0x00, 0x40, 0x74, 0x07,
+ 0x00, 0x04, 0x44, 0x5b,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x45, 0xc4, 0x10,
+ 0x0a, 0x45, 0xc4, 0x5c, 0x00, 0x04, 0x54, 0x5b, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x45, 0xd4, 0x10, 0x0a, 0x45, 0xd4, 0x5d,
+ 0x00, 0x04, 0x24, 0x5e,
+ 0x00, 0x40, 0x64, 0x06, 0x00, 0x04, 0x34, 0x5e, 0x00, 0x40, 0x74, 0x07,
+ 0x00, 0x04, 0x24, 0x5e,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x45, 0xf4, 0x10,
+ 0x0a, 0x45, 0xf4, 0x5f, 0x00, 0x04, 0x34, 0x5e, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x46, 0x04, 0x10, 0x0a, 0x46, 0x04, 0x60,
+ 0x00, 0x40, 0x84, 0x64,
+ 0x00, 0x40, 0x64, 0x06, 0x00, 0x40, 0x94, 0x64, 0x00, 0x40, 0x74, 0x07,
+ 0x00, 0x40, 0x84, 0x64,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x46, 0x54, 0x10,
+ 0x0a, 0x46, 0x54, 0x65, 0x00, 0x40, 0x94, 0x64, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x46, 0x64, 0x10, 0x0a, 0x46, 0x64, 0x66,
+ 0x00, 0x04, 0xc4, 0x67,
+ 0x00, 0x40, 0x64, 0x06, 0x00, 0x04, 0xd4, 0x67, 0x00, 0x40, 0x74, 0x07,
+ 0x00, 0x04, 0xc4, 0x67,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x46, 0x84, 0x10,
+ 0x0a, 0x46, 0x84, 0x68, 0x00, 0x04, 0xd4, 0x67, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x46, 0x94, 0x10, 0x0a, 0x46, 0x94, 0x69,
+ 0x00, 0x04, 0x84, 0x6a,
+ 0x00, 0x40, 0x64, 0x06, 0x00, 0x04, 0x94, 0x6a, 0x00, 0x40, 0x74, 0x07,
+ 0x00, 0x04, 0x84, 0x6a,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x46, 0xb4, 0x10,
+ 0x0a, 0x46, 0xb4, 0x6b, 0x00, 0x04, 0x94, 0x6a, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x46, 0xc4, 0x10, 0x0a, 0x46, 0xc4, 0x6c,
+ 0x00, 0x40, 0x64, 0x6d,
+ 0x00, 0x07, 0x60, 0xc0, 0x00, 0x40, 0x74, 0x6e, 0x00, 0x07, 0x70, 0xc0,
+ 0x00, 0x40, 0x64, 0x6d,
+ 0x00, 0x41, 0x10, 0xc0, 0x00, 0x41, 0x10, 0xc0, 0x09, 0x41, 0x04, 0x11,
+ 0x00, 0x46, 0xf4, 0x10,
+ 0x0a, 0x46, 0xf4, 0x6f, 0x00, 0x40, 0x74, 0x6e, 0x00, 0x41, 0x10, 0xc0,
+ 0x00, 0x41, 0x10, 0xc0,
+ 0x09, 0x41, 0x04, 0x11, 0x00, 0x47, 0x04, 0x10, 0x0a, 0x47, 0x04, 0x70,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x0c, 0x00, 0xc0,
+ 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0xc0, 0x06, 0x0c, 0x00, 0xc0,
+ 0x00, 0x00, 0x00, 0x37,
+ 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x64, 0x64,
+ 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x64, 0x64, 0x45, 0x51, 0x55, 0x41,
+ 0x4c, 0x49, 0x5a, 0x45,
+ 0x52, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x52, 0x45, 0x53, 0x43, 0x41, 0x4c, 0x45,
+ 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, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64,
+ 0x4c, 0x4f, 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, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x19, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x4d, 0x49, 0x44, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1e,
+ 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x49, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23,
+ 0x10, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x80, 0x58, 0x48, 0x49, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x80,
+ 0x42, 0x59, 0x50, 0x41, 0x53, 0x53, 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, 0x00,
+ 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x46, 0x52, 0x4f, 0x4e,
+ 0x54, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x50, 0x44, 0x49,
+ 0x46, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x49, 0x47, 0x43, 0x44, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x33,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0x39, 0x37,
+ 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x41, 0x55, 0x58, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x4d, 0x49, 0x43, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3f,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x64, 0x64, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x53, 0x55, 0x52, 0x52, 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, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x53, 0x50, 0x44, 0x49,
+ 0x46, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0x47, 0x43, 0x44, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x43, 0x39, 0x37,
+ 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, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4b,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x43, 0x4d, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x55, 0x58, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x51,
+ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x4d, 0x49, 0x43, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x57,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x64, 0x64, 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59,
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x53, 0x50, 0x44, 0x49, 0x46, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0x47, 0x43,
+ 0x44, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x64, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x43, 0x39, 0x37, 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, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x62,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x50, 0x43, 0x4d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x55, 0x58, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x68,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x49, 0x43, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a,
+ 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x2d, 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, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x4f, 0x4c, 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,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x64, 0x64,
+ 0x2d, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6f,
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x50, 0x41, 0x53,
+ 0x53, 0x54, 0x48, 0x52,
+ 0x4f, 0x55, 0x47, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0x00, 0x00, 0x00, 0x02,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x78,
+ 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x7a,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x7b, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xdc,
+ 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0xdd, 0xff, 0xff, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
diff --git a/kernel/drv/oss_sblive/oss_sblive.c b/kernel/drv/oss_sblive/oss_sblive.c
new file mode 100644
index 0000000..b516746
--- /dev/null
+++ b/kernel/drv/oss_sblive/oss_sblive.c
@@ -0,0 +1,3985 @@
+/*
+ * Purpose: Driver for Creative SB Live/Audigy/2/4. Audio, MIDI and mixer services.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_sblive_cfg.h"
+#include "midi_core.h"
+#include "oss_pci.h"
+#include "remux.h"
+
+/*
+ * Include the DSP files for emu10k1 (Live!) and emu10k2 (Audigy)
+ * These headers have been generated using the emu10k tools (by 4Front).
+ * The _be.h files have been generated in a big endian system and the others
+ * in a litle endian (intel) system.
+ */
+#ifdef OSS_BIG_ENDIAN
+# include "emu10k1_dsp_be.h"
+# include "emu10k2_dsp_be.h"
+#else
+# include "emu10k1_dsp.h"
+# include "emu10k2_dsp.h"
+#endif
+
+#define NO_EMU10K1_SYNTH
+#undef TEST_3D
+
+#define BOGUS_MIXER_CONTROLS ( \
+ SOUND_MASK_SPEAKER | \
+ SOUND_MASK_ALTPCM | \
+ SOUND_MASK_VIDEO | \
+ SOUND_MASK_DEPTH | \
+ SOUND_MASK_MONO \
+ )
+
+#ifndef linux
+#define NO_EMU10K1_SYNTH
+#endif
+
+#include "ac97.h"
+#include "sblive.h"
+#include "eq1.h"
+
+#define MAX_SENDS 4
+
+#define SEND_L 0
+#define SEND_R 1
+#define SEND_SL 2
+#define SEND_SR 3
+#define SEND_C 4
+#define SEND_W 5
+#define SEND_RL 6
+#define SEND_RR 7
+
+#define SPDIF_L 20
+#define SPDIF_R 21
+
+static unsigned char default_routing[MAX_SENDS] =
+ { SEND_L, SEND_R, SEND_SL, SEND_SR };
+static unsigned char front_routing[MAX_SENDS] =
+ { SEND_L, SEND_R, 0x3f, 0x3f };
+static unsigned char surr_routing[MAX_SENDS] =
+ { SEND_SL, SEND_SR, 0x3f, 0x3f };
+static unsigned char center_lfe_routing[MAX_SENDS] =
+ { SEND_C, SEND_W, 0x3f, 0x3f };
+static unsigned char rear_routing[MAX_SENDS] =
+ { SEND_RL, SEND_RR, 0x3f, 0x3f };
+static unsigned char spdif_routing[MAX_SENDS] =
+ { SPDIF_L, SPDIF_R, 0x3f, 0x3f };
+
+typedef struct
+{
+ int speed;
+ int pitch;
+ int recbits;
+ int audigy_recbits;
+ int rom;
+}
+speed_ent;
+
+/* Note! with audigy speedsel=7 means 12 kHz */
+
+static speed_ent speed_tab[] = {
+ {8000, 0xb6a41b, 7, 8, ROM7},
+ {11025, 0xbe0b64, 6, 6, ROM6},
+ {16000, 0xc6a41b, 5, 5, ROM5},
+ {22050, 0xce0b64, 4, 3, ROM4},
+ {24000, 0xd00000, 3, 3, ROM3},
+ {32000, 0xd6a41b, 2, 2, ROM2},
+ {44100, 0xde0b64, 1, 1, ROM1},
+ {48000, 0xe00000, 0, 0, ROM0},
+ {0}
+};
+
+#define PCI_VENDOR_ID_CREATIVE 0x1102
+#define PCI_DEVICE_ID_SBLIVE 0x0002
+#define PCI_DEVICE_ID_AUDIGY 0x0004
+#define PCI_DEVICE_ID_AUDIGYVALUE 0x0008
+#define PCI_DEVICE_ID_AUDIGY_CARDBUS 0x2001
+
+#define LEFT_CH 0
+#define RIGHT_CH 1
+
+void sblive_init_voice (sblive_devc * devc, int chn);
+static void audigyuartintr (sblive_devc * devc);
+
+static int
+ac97_read (void *devc_, int wAddr)
+{
+ sblive_devc *devc = devc_;
+ int dtemp = 0, i;
+
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, wAddr, devc->base + 0x1e);
+ for (i = 0; i < 10000; i++)
+ if (INB (devc->osdev, devc->base + 0x1e) & 0x80)
+ break;
+ if (i == 1000)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO; /* Timeout */
+ }
+ dtemp = INW (devc->osdev, devc->base + 0x1c);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return dtemp & 0xffff;
+}
+
+static int
+ac97_write (void *devc_, int wAddr, int wData)
+{
+ sblive_devc *devc = devc_;
+ oss_native_word flags;
+ int i;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, wAddr, devc->base + 0x1e);
+ for (i = 0; i < 10000; i++)
+ if (INB (devc->osdev, devc->base + 0x1e) & 0x80)
+ break;
+ OUTW (devc->osdev, wData, devc->base + 0x1c);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return 0;
+}
+
+unsigned int
+sblive_read_reg (sblive_devc * devc, int reg, int chn)
+{
+ oss_native_word flags;
+ unsigned int ptr, ptr_addr_mask, val, mask, size, offset;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ ptr_addr_mask = (devc->feature_mask & SB_AUDIGY) ? 0x0fff0000 : 0x07ff0000;
+ ptr = ((reg << 16) & ptr_addr_mask) | (chn & 0x3f);
+ OUTL (devc->osdev, ptr, devc->base + 0x00); /* Pointer */
+ val = INL (devc->osdev, devc->base + 0x04); /* Data */
+ if (reg & 0xff000000)
+ {
+ size = (reg >> 24) & 0x3f;
+ offset = (reg >> 16) & 0x1f;
+ mask = ((1 << size) - 1) << offset;
+ val &= mask;
+ val >>= offset;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return val;
+}
+
+void
+sblive_write_reg (sblive_devc * devc, int reg, int chn, unsigned int value)
+{
+ oss_native_word flags;
+ unsigned int ptr, ptr_addr_mask, mask, size, offset;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ ptr_addr_mask = (devc->feature_mask & SB_AUDIGY) ? 0x0fff0000 : 0x07ff0000;
+ ptr = ((reg << 16) & ptr_addr_mask) | (chn & 0x3f);
+ OUTL (devc->osdev, ptr, devc->base + 0x00); /* Pointer */
+ if (reg & 0xff000000)
+ {
+ size = (reg >> 24) & 0x3f;
+ offset = (reg >> 16) & 0x1f;
+ mask = ((1 << size) - 1) << offset;
+ value <<= offset;
+ value &= mask;
+ value |= INL (devc->osdev, devc->base + 0x04) & ~mask; /* data */
+ }
+ OUTL (devc->osdev, value, devc->base + 0x04); /* Data */
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+
+static void
+write_efx (sblive_devc * devc, int reg, unsigned int value)
+{
+ sblive_write_reg (devc, reg, 0, value);
+}
+
+static void
+update_vu (sblive_devc * devc, sblive_portc * portc, dmap_p dmap, int frag)
+{
+ int left = 0, right = 0;
+ int i, l;
+
+ frag %= dmap->nfrags;
+ l = dmap->fragment_size / 2;
+
+ if (portc->format == AFMT_AC3) /* Raw S/PDIF mode */
+ {
+ if (devc->vu_tmp2 == 0)
+ devc->vu_tmp2 = 2;
+
+ portc->vu_left = devc->vu_tmp;
+ portc->vu_right = 144 - devc->vu_tmp;
+ devc->vu_tmp = devc->vu_tmp + devc->vu_tmp2;
+
+ if (devc->vu_tmp >= 144)
+ {
+ devc->vu_tmp2 = -2;
+ devc->vu_tmp = 144;
+ }
+
+ if (devc->vu_tmp <= 0)
+ {
+ devc->vu_tmp2 = 2;
+ devc->vu_tmp = 0;
+ }
+
+ return;
+ }
+
+ if (portc->format == AFMT_U8)
+ {
+ unsigned char *p;
+ int v;
+
+ p = dmap->dmabuf + (frag * dmap->fragment_size);
+
+ if (dmap->dmabuf != NULL)
+ for (i = 0; i < l; i++)
+ {
+ v = *p;
+ p++;
+ v -= 128;
+ if (v < 0)
+ v = -v;
+ if (v > left)
+ left = v;
+
+ v = *p;
+ p++;
+ v -= 128;
+ if (v < 0)
+ v = -v;
+ if (v > right)
+ right = v;
+ }
+ }
+ else
+ {
+ short *p;
+ int v;
+
+ l /= 2;
+ p = (short *) (dmap->dmabuf + (frag * dmap->fragment_size));
+
+ if (dmap->dmabuf != NULL)
+ for (i = 0; i < l; i++)
+ {
+ v = SSWAP (*p++) >> 8;
+ if (v < 0)
+ v = -v;
+ if (v > left)
+ left = v;
+
+ v = *p++ >> 8;
+ if (v < 0)
+ v = -v;
+ if (v > right)
+ right = v;
+ }
+ }
+
+ if (portc->channels == 1) /* Mono */
+ {
+ if (right > left)
+ left = right;
+ right = left;
+ }
+
+ if (left > portc->vu_left)
+ portc->vu_left = left;
+ if (right > portc->vu_right)
+ portc->vu_right = right;
+}
+
+static int
+sbliveintr (oss_device_t * osdev)
+{
+ int p;
+ unsigned int status;
+#ifndef NO_EMU10K1_SYNTH
+ extern int sblive_synth_enable;
+#endif
+
+ sblive_devc *devc = osdev->devc;
+
+ /*
+ * TODO: Fix mutexes and move the inputintr/outputintr calls outside the
+ * mutex block.
+ */
+ /* oss_native_word flags; */
+ /* MUTEX_ENTER (devc->mutex, flags); */
+
+ status = INL (devc->osdev, devc->base + 0x08);
+
+#if !defined(sparc)
+ if (status == 0)
+ {
+ /* MUTEX_EXIT (devc->mutex, flags); */
+ return 0;
+ }
+#endif
+
+ if (status & 0x00000080) /* MIDI RX interrupt */
+ {
+ if (devc->feature_mask & SB_AUDIGY)
+ audigyuartintr (devc);
+ else
+ uart401_irq (&devc->uart401devc);
+ }
+
+ if (status & 0x00008000) /* ADC buffer full intr */
+ {
+ /* Force the starting position to match this moment */
+ unsigned int pos;
+ pos = (INL (devc->osdev, devc->base + 0x10) >> 6) & 0xfffff;
+ devc->portc[0].rec_starttime = pos;
+ }
+
+ if (status & 0x00000240) /* Interval timer or channel loop interrupt */
+ {
+ for (p = 0; p < devc->n_audiodevs; p++)
+ {
+ sblive_portc *portc = &devc->portc[p];
+
+ if (portc->audiodev >= 0 && portc->audiodev < num_audio_engines
+ && portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ {
+ int pos, n;
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_out;
+
+ pos = sblive_read_reg (devc, QKBCA, portc->voice_chn) & 0x00ffffff; /* Curr pos */
+ pos <<= portc->out_sz;
+ pos -= dmap->driver_use_value;
+
+ if (dmap->fragment_size == 0)
+ {
+ cmn_err (CE_WARN, "dmap->fragment_size == 0\n");
+ continue;
+ }
+
+ pos /= dmap->fragment_size;
+ if (pos < 0 || pos >= dmap->nfrags)
+ pos = 0;
+
+ /*
+ * If this was a full/half loop interrupt then use forced pointer
+ */
+ if (sblive_get_voice_loopintr (devc, portc->voice_chn))
+ pos = 0; /* Full loop boundary */
+ else if (sblive_get_voice_halfloopintr (devc, portc->voice_chn))
+ pos = dmap->nfrags / 2; /* Half loop boundary */
+
+ n = 0;
+ while (dmap_get_qhead (dmap) != pos && n++ < dmap->nfrags)
+ {
+ update_vu (devc, portc, dmap, dmap_get_qhead (dmap));
+ oss_audio_outputintr (portc->audiodev, 0);
+ }
+ }
+
+ if (num_audio_engines > 0 && portc->audiodev < num_audio_engines
+ && portc->trigger_bits & PCM_ENABLE_INPUT)
+ {
+ int n;
+ unsigned int pos;
+
+ dmap_t *dmap = audio_engines[portc->audiodev]->dmap_in;
+
+ /* Compute current pos based on the wall clock register */
+ pos = (INL (devc->osdev, devc->base + 0x10) >> 6) & 0xfffff;
+ if (pos > portc->rec_starttime)
+ pos = pos - portc->rec_starttime;
+ else
+ pos = 0xfffff - (portc->rec_starttime - pos);
+ pos = (pos * (portc->speed / 25)) / (48000 / 25);
+ pos *= 2; /* 16 bit->bytes */
+ pos *= portc->channels;
+ pos = pos % dmap->bytes_in_use;
+ if (dmap->fragment_size == 0)
+ cmn_err (CE_WARN, "dmap->fragment_size==0\n");
+ else
+ {
+ pos /= dmap->fragment_size;
+ if (pos >= dmap->nfrags)
+ pos = 0;
+ n = 0;
+ while (dmap_get_qtail (dmap) != pos && n++ < dmap->nfrags)
+ {
+ oss_audio_inputintr (devc->recording_dev, 0);
+ }
+ }
+ }
+ }
+
+#ifndef NO_EMU10K1_SYNTH
+ if (sblive_synth_enable)
+ sblive_synth_interrupt (devc);
+#endif
+ }
+
+ OUTL (devc->osdev, status, devc->base + 0x08); /* Acknowledge them */
+
+ /* MUTEX_EXIT (devc->mutex, flags); */
+
+ return 1;
+}
+
+static int
+setup_passthrough (sblive_devc * devc, sblive_portc * portc, int pass)
+{
+ int ctrl = devc->passthrough_gpr;
+
+ if (ctrl < 0)
+ return 0;
+
+ if (pass == portc->uses_spdif)
+ return 1;
+
+ if (pass && devc->spdif_busy)
+ return 0;
+
+ portc->uses_spdif = pass;
+
+ sblive_write_reg (devc, ctrl + GPR0, 0, pass);
+ sblive_write_reg (devc, ctrl + GPR0 + 1, 0, !pass);
+ if (pass)
+ {
+ devc->spdif_busy = 1;
+ }
+ else
+ {
+ devc->spdif_busy = 0;
+ }
+
+ return 1;
+}
+
+static int
+sblive_audio_set_rate (int dev, int arg)
+{
+ sblive_portc *portc = audio_engines[dev]->portc;
+ int i, n = -1, dif, best = -1, bestdif = 0x7fffffff;
+
+ if (arg == 0)
+ return portc->speed;
+
+ for (i = 0; speed_tab[i].speed != 0 && n == -1; i++)
+ {
+ if (speed_tab[i].speed == arg) /* Exact match */
+ {
+ n = i;
+ break;
+ }
+
+ dif = arg - speed_tab[i].speed;
+ if (dif < 0)
+ dif = -dif;
+
+ if (dif < bestdif)
+ {
+ best = i;
+ bestdif = dif;
+ }
+ }
+
+ if (n == -1)
+ n = best;
+
+ if (n == -1)
+ n = 0;
+
+ portc->speed = speed_tab[n].speed;
+ portc->speedsel = n;
+
+ return portc->speed;
+}
+
+static short
+sblive_audio_set_channels (int dev, short arg)
+{
+ sblive_portc *portc = audio_engines[dev]->portc;
+
+ if ((arg != 1) && (arg != 2))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+sblive_audio_set_format (int dev, unsigned int arg)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->format;
+
+ if (portc->mode & OPEN_READ)
+ arg = AFMT_S16_LE;
+
+ if (arg != AFMT_U8 && arg != AFMT_S16_LE && arg != AFMT_AC3)
+ return portc->format;
+
+ /* Enforce stereo mode with AC3 */
+ if (arg == AFMT_AC3)
+ {
+ if (!setup_passthrough (devc, portc, 1))
+ return portc->format;
+ portc->channels = 2;
+ portc->speed = 48000;
+ }
+ else
+ if (portc->input_type != ITYPE_SPDIF && portc->uses_spdif
+ && arg != AFMT_AC3)
+ {
+ setup_passthrough (devc, portc, 0);
+ }
+
+ portc->format = arg;
+
+ return portc->format;
+}
+
+static int mixer_ext_init (int dev);
+static int create_efx_mixer (int dev);
+static int sblive_set_gpr (int dev, int ctrl, unsigned int cmd, int value);
+
+static int
+is_special_gpr (int gpr)
+{
+ if (gpr >= NEXT_FREE_GPR)
+ return 0;
+
+ if (SPECIAL_GPRS & (1 << gpr))
+ {
+ return 1;
+ }
+
+ if (gpr > 0)
+ if (SPECIAL_GPRS & (1 << (gpr - 1)))
+ {
+ return 1;
+ }
+ return 0;
+}
+
+static void update_output_device (sblive_devc * devc, sblive_portc * portc);
+
+static int
+sblive_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+ sblive_reg *reg = (sblive_reg *) arg;
+ gpr_info *gpr = (gpr_info *) arg;
+ const_info *consts = (const_info *) arg;
+ unsigned int *code = (unsigned int *) arg;
+ int i;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_GETCHANNELMASK:
+ return *arg =
+ DSP_BIND_FRONT | DSP_BIND_REAR | DSP_BIND_SURR | DSP_BIND_CENTER_LFE;
+ break;
+
+ case SNDCTL_DSP_BIND_CHANNEL:
+ {
+ int val;
+
+ val = *arg;
+ portc->speaker_mode = SMODE_BIND;
+ portc->binding = val;
+ return *arg = val;
+ }
+ break;
+
+ case SNDCTL_DSP_SETPLAYVOL:
+ {
+ int left, right, val;
+
+ val = *arg;
+
+ left = val & 0xff;
+ right = (val >> 8) & 0xff;
+ if (left < 0)
+ left = 0;
+ if (right < 0)
+ right = 0;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+
+#if 0
+ if (right > left)
+ left = right;
+#endif
+ portc->playvol = left;
+ update_output_device (devc, portc);
+
+ return *arg = left | (left << 8);
+ }
+ break;
+
+ case SNDCTL_DSP_GETPLAYVOL:
+ {
+ int vol;
+ vol = (portc->playvol << 8) | portc->playvol;
+ return *arg = vol;
+ }
+ break;
+
+ case SBLIVE_READREG:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ reg->value = sblive_read_reg (devc, reg->reg, reg->chn);
+ return 0;
+ break;
+
+ case SBLIVE_WRITEREG:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ sblive_write_reg (devc, reg->reg, reg->chn, reg->value);
+ return 0;
+ break;
+
+ case SBLIVE_READGPIO:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ return *arg = INW (devc->osdev, devc->base + 0x18);
+ break;
+
+ case SBLIVE_WRITEGPIO:
+ {
+ int val;
+ val = *arg;
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ OUTW (devc->osdev, val, devc->base + 0x18);
+
+ }
+ return 0;
+
+ case SBLIVE_WRITEPARMS:
+ {
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ if (gpr->ngpr >= MAX_GPR_PARMS)
+ return OSS_EIO;
+
+ for (i = 0; i < gpr->ngpr; i++)
+ {
+ gpr->gpr[i].name[GPR_NAME_SIZE - 1] = 0; /* Overflow protection */
+ if (strlen (gpr->gpr[i].name) >= 32) /* Name may be bad */
+ {
+ return OSS_EIO;
+ }
+
+ if (gpr->gpr[i].num >= MAX_GPR)
+ {
+ return OSS_EIO;
+ }
+
+/* cmn_err(CE_CONT, "Gpr %d = %s (vol %x) type=%x\n", gpr->gpr[i].num, gpr->gpr[i].name, gpr->gpr[i].def, gpr->gpr[i].type); */
+ if (gpr->gpr[i].type != MIXT_GROUP)
+ {
+ if (is_special_gpr (gpr->gpr[i].num))
+ sblive_set_gpr (devc->mixer_dev, gpr->gpr[i].num,
+ SNDCTL_MIX_WRITE,
+ devc->gpr_values[gpr->gpr[i].num]);
+ else
+ sblive_set_gpr (devc->mixer_dev, gpr->gpr[i].num,
+ SNDCTL_MIX_WRITE, gpr->gpr[i].def);
+ }
+ }
+
+
+ if (devc->gpr == NULL)
+ {
+ devc->gpr = PMALLOC (devc->osdev, sizeof (gpr_info));
+ if (devc->gpr == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory (gpr)\n");
+ return OSS_ENOSPC;
+ }
+ memset (devc->gpr, 0, sizeof (gpr_info));
+ }
+ memcpy (devc->gpr, gpr, sizeof (gpr_info));
+ create_efx_mixer (devc->mixer_dev);
+ }
+ return 0;
+ break;
+
+ case SBLIVE_WRITECONST:
+ {
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ if (consts->nconst >= MAX_CONST_PARMS)
+ return OSS_EIO;
+
+ for (i = 0; i < consts->nconst; i++)
+ {
+ if (consts->consts[i].gpr >= MAX_GPR)
+ {
+ return OSS_EIO;
+ }
+
+ sblive_write_reg (devc, consts->consts[i].gpr + GPR0, 0,
+ consts->consts[i].value);
+ }
+
+ }
+ return 0;
+ break;
+
+ case SBLIVE_WRITECODE1:
+ {
+ int pc;
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ for (pc = 0; pc < 512; pc++)
+ {
+ write_efx (devc, UC0 + pc, code[pc]);
+ }
+
+ }
+ sblive_write_reg (devc, DBG, 0, 0);
+ return 0;
+ break;
+
+ case SBLIVE_WRITECODE2:
+ {
+ int pc;
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ for (pc = 0; pc < 512; pc++)
+ {
+ write_efx (devc, UC0 + 512 + pc, code[pc]);
+ }
+ }
+ sblive_write_reg (devc, DBG, 0, 0);
+ return 0;
+ break;
+
+ case SBLIVE_GETCHIPTYPE:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ return *arg = devc->feature_mask & ~SB_AUDIGY2;
+ break;
+
+ }
+ return OSS_EINVAL;
+}
+
+static void sblive_audio_trigger (int dev, int state);
+
+static void
+sblive_audio_reset (int dev)
+{
+ sblive_audio_trigger (dev, 0);
+}
+
+static void
+sblive_audio_reset_input (int dev)
+{
+ sblive_portc *portc = audio_engines[dev]->portc;
+ sblive_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+sblive_audio_reset_output (int dev)
+{
+ sblive_portc *portc = audio_engines[dev]->portc;
+ sblive_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+static int sblive_set_vol (int dev, int ctrl, unsigned int cmd, int value);
+
+static void
+reset_portc_volume (sblive_devc * devc, sblive_portc * portc)
+{
+ int v;
+#ifdef TEST_3D
+ v = 100 | (50 << 8) | (0 << 16); /* vol=100, dist=50, angle=0 */
+#else
+ v = 100 | (100 < 8);
+#endif
+ sblive_set_vol (devc->mixer_dev, portc->port_number, SNDCTL_MIX_WRITE, v);
+}
+
+#if MAX_ADEV == 2
+static const unsigned int binding_map[MAX_ADEV] =
+ { DSP_BIND_FRONT, DSP_BIND_SURR };
+#else
+static const unsigned int binding_map[MAX_ADEV] = {
+ DSP_BIND_FRONT,
+ DSP_BIND_FRONT,
+ DSP_BIND_SURR,
+ DSP_BIND_CENTER_LFE,
+ DSP_BIND_REAR
+};
+#endif
+
+/*ARGSUSED*/
+static int
+sblive_audio_open (int dev, int mode, int open_flags)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->mode = mode;
+ portc->audio_active &= ~mode;
+
+ portc->resetvol = 0;
+
+ portc->speaker_mode = devc->speaker_mode;
+ portc->binding = binding_map[portc->port_number];
+ if (portc->binding == 0)
+ portc->binding = DSP_BIND_FRONT;
+ mixer_devs[devc->mixer_dev]->modify_counter++; /* Force update of mixer */
+
+ audio_engines[dev]->flags &= ~ADEV_FIXEDRATE;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (devc->autoreset || portc->resetvol)
+ reset_portc_volume (devc, portc);
+
+ if (portc->input_type == ITYPE_SPDIF)
+ {
+ if (!setup_passthrough (devc, portc, 1))
+ {
+ portc->mode = 0;
+ return OSS_EBUSY;
+ }
+ }
+ else
+ {
+ /* Enable AC3 format if possible */
+ if (!devc->spdif_busy)
+ audio_engines[dev]->oformat_mask |= AFMT_AC3;
+ else
+ audio_engines[dev]->oformat_mask &= ~AFMT_AC3;
+ }
+ return 0;
+}
+
+static void
+sblive_audio_close (int dev, int mode)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+
+ sblive_audio_reset (dev);
+ portc->mode = 0;
+ portc->audio_active &= ~mode;
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+ setup_passthrough (devc, portc, 0);
+ audio_engines[dev]->oformat_mask |= AFMT_AC3;
+}
+
+#ifdef TEST_3D
+/* Sin table for Q1 (*10000) */
+static const int sincos[] = {
+ 0, 174, 348, 523, 697, 871, 1045, 1218, 1391, 1564,
+ 1736, 1908, 2079, 2249, 2419, 2588, 2756, 2923, 3090, 3255,
+ 3420, 3583, 3746, 3907, 4067, 4226, 4383, 4539, 4694, 4848,
+ 5000, 5150, 5299, 5446, 5591, 5735, 5877, 6018, 6156, 6293,
+ 6427, 6560, 6691, 6819, 6946, 7071, 7193, 7313, 7431, 7547,
+ 7660, 7771, 7880, 7986, 8090, 8191, 8290, 8386, 8480, 8571,
+ 8660, 8746, 8829, 8910, 8987, 9063, 9135, 9205, 9271, 9335,
+ 9396, 9455, 9510, 9563, 9612, 9659, 9702, 9743, 9781, 9816,
+ 9848, 9876, 9902, 9925, 9945, 9961, 9975, 9986, 9993, 9998,
+ 10000,
+};
+
+static __inline__ int
+oss_sin (int angle)
+{
+ int a;
+ int f;
+
+ a = angle % 90;
+
+ if ((angle / 90) & 1)
+ a = 90 - a;
+
+ f = sincos[a];
+ if (angle >= 180)
+ f = -f;
+ return f;
+}
+
+static __inline__ int
+oss_cos (int angle)
+{
+ int a, q;
+ int f;
+
+ a = angle % 90;
+ q = angle / 90;
+
+ if (!(q & 1))
+ a = 90 - a;
+
+ f = sincos[a];
+ if (angle >= 90 && angle < 270)
+ f = -f;
+ return f;
+}
+
+static void
+compute_3d (sblive_devc * devc, sblive_portc * portc, int voice, int chn,
+ int *send)
+{
+ int angle = portc->playangle;
+ int dist, opening = 45;
+ int i;
+
+ /* left, right, rear_right, rear_left */
+ static int spk_angles[4] = { 315, 45, 135, 225 };
+ int gain = 50, leak = 0;
+ int v[4];
+
+ dist = portc->playdist;
+
+ if (dist < 0)
+ dist = 0;
+ if (dist > 100)
+ dist = 100;
+ portc->playdist = dist;
+
+ dist = 100 - dist; /* Invert distance */
+ opening = (90 * dist) / 100;
+
+ if (dist < 50)
+ { /* Attenuate distant sounds */
+ gain = dist;
+ }
+ else
+ {
+ /* "Expand" close sounds by leaking signal to silent channels */
+ leak = dist - 50;
+ }
+
+ if (portc->channels == 2)
+ {
+ if (chn == LEFT_CH)
+ angle -= opening;
+ else
+ angle += opening;
+ }
+
+ if (angle < 0)
+ angle += 360;
+
+ angle %= 360;
+
+ for (i = 0; i < 4; i++)
+ v[i] = (gain * portc->playvol * 255 + 25) / 50;
+
+ for (i = 0; i < 4; i++)
+ {
+ int a = spk_angles[i] - angle;
+
+ if (a < 0)
+ a = -a; /* ABS */
+ if (a > 180)
+ a = 360 - a;
+
+ if (a >= 90) /* Too far */
+ {
+ v[i] = 0; /* Muted speaker */
+ continue;
+ }
+ else
+ v[i] = ((v[i] * oss_cos (a) + 5000) / 10000) / 100;
+ }
+
+ if (leak > 0)
+ {
+ leak = (255 * portc->playvol * leak + 2500) / 5000;
+
+ for (i = 0; i < 4; i++)
+ if (v[i] < leak)
+ v[i] = leak;
+ }
+
+ send[0] = v[0]; /* Left */
+ send[1] = v[1]; /* Right */
+ send[2] = v[3]; /* Rear left */
+ send[3] = v[2]; /* Rear right */
+}
+#endif
+
+static void
+write_routing (sblive_devc * devc, int voice, unsigned char *routing)
+{
+ int i;
+
+ if (routing == NULL)
+ routing = default_routing;
+
+ if (devc->feature_mask & SB_AUDIGY)
+ {
+ unsigned int srda = 0;
+
+ for (i = 0; i < 4; i++)
+ srda |= routing[i] << (i * 8);
+
+ sblive_write_reg (devc, SRDA, voice, srda);
+ }
+ else
+ {
+ int fxrt = 0;
+
+ for (i = 0; i < 4; i++)
+ fxrt |= routing[i] << ((i * 4) + 16);
+ sblive_write_reg (devc, FXRT, voice, fxrt);
+ }
+}
+
+/*ARGSUSED*/
+static void
+compute_bind (sblive_devc * devc, sblive_portc * portc, unsigned char *send,
+ int chn)
+{
+ memset (send, 0, MAX_SENDS);
+
+ if (chn == LEFT_CH)
+ send[0] = (0xff * portc->playvol + 50) / 100;
+ else
+ send[1] = (0xff * portc->playvol + 50) / 100;
+
+ switch (portc->binding)
+ {
+ case DSP_BIND_FRONT:
+ portc->routing = front_routing;
+ break;
+ case DSP_BIND_SURR:
+ portc->routing = surr_routing;
+ break;
+ case DSP_BIND_CENTER_LFE:
+ portc->routing = center_lfe_routing;
+ break;
+ case DSP_BIND_REAR:
+ portc->routing = rear_routing;
+ break;
+ default:
+ portc->routing = default_routing;
+ }
+}
+
+static void
+update_output_volume (int dev, int voice, int chn)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+ int left, right;
+ unsigned int loop_start, loop_end, tmp;
+ unsigned char send[MAX_SENDS];
+
+ send[0] = 0xff; /* Max */
+ send[1] = 0xff; /* Max */
+ send[2] = 0xff; /* Max */
+ send[3] = 0xff; /* Max */
+
+ if (portc->input_type == ITYPE_SPDIF || portc->format == AFMT_AC3)
+ {
+ /* Digital voice */
+ send[2] = 0; /* Muted */
+ send[3] = 0; /* Muted */
+
+ /* sends are revered between Audigy2 and Audigy */
+ left = (devc->feature_mask & SB_AUDIGY2) ? 1 : 0;
+ right = !left;
+
+ if (portc->channels > 1)
+ {
+ if (chn == LEFT_CH)
+ {
+ send[left] = 0;
+ }
+ else
+ {
+ send[right] = 0;
+ }
+ }
+ }
+ else
+ {
+ /* Analog voice */
+
+ if (portc->channels > 1)
+ {
+ if (chn == LEFT_CH)
+ {
+ send[1] = 0;
+ }
+ else
+ {
+ send[0] = 0;
+ }
+ }
+ send[2] = send[0];
+ send[3] = send[1];
+
+#ifdef TEST_3D
+ if (portc->speaker_mode == SMODE_3D)
+ compute_3d (devc, portc, voice, chn, send);
+ else
+#endif
+ {
+ send[0] = (send[0] * portc->playvol + 50) / 100;
+ send[1] = (send[1] * portc->playvol + 50) / 100;
+ send[2] = (send[2] * portc->playvol + 50) / 100;
+ send[3] = (send[3] * portc->playvol + 50) / 100;
+
+ switch (portc->speaker_mode)
+ {
+ case SMODE_FRONT:
+ send[2] = send[3] = 0;
+ break;
+
+ case SMODE_SURR:
+ send[0] = send[1] = 0;
+ break;
+
+ case SMODE_FRONTREAR:
+ break;
+
+ case SMODE_BIND:
+ compute_bind (devc, portc, send, chn);
+ break;
+ }
+ }
+
+ /* Analog voice */
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ loop_end = sblive_read_reg (devc, SDL, voice) & 0xffffff;
+ sblive_write_reg (devc, SDL, voice, loop_end | (send[3] << 24));
+ loop_start = sblive_read_reg (devc, SCSA, voice) & 0xffffff;
+ sblive_write_reg (devc, SCSA, voice, loop_start | (send[2] << 24));
+ tmp = sblive_read_reg (devc, PTAB, voice) & 0xffff0000;
+ sblive_write_reg (devc, PTAB, voice, tmp | (send[0] << 8) | send[1]);
+ write_routing (devc, voice, portc->routing);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+setup_audio_voice (int dev, int voice, int chn)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ unsigned int nCRA = 0;
+
+ unsigned int loop_start, loop_end;
+
+ int sz = 1;
+ int start_pos;
+
+ sblive_write_reg (devc, VEDS, voice, 0x0); /* OFF */
+ sblive_write_reg (devc, VTFT, voice, 0xffff);
+ sblive_write_reg (devc, CVCF, voice, 0xffff);
+
+ if (devc->feature_mask & SB_AUDIGY)
+ sblive_write_reg (devc, SRDA, voice, 0x03020100);
+ else
+ sblive_write_reg (devc, FXRT, voice, 0x32100000);
+
+
+ sz =
+ (((portc->format == AFMT_S16_LE
+ || portc->format == AFMT_AC3)) ? 1 : 0) + ((portc->channels ==
+ 2) ? 1 : 0);
+
+ loop_start = dmap->driver_use_value >> sz;
+ loop_end = (dmap->driver_use_value + dmap->bytes_in_use) >> sz;
+
+ /* set mono/stereo */
+ sblive_write_reg (devc, CPF, voice, (portc->channels > 1) ? 0x8000 : 0);
+
+ nCRA = (portc->channels > 1) ? 28 : 30;
+ nCRA *= (portc->format == AFMT_S16_LE || portc->format == AFMT_AC3) ? 1 : 2;
+ start_pos = loop_start + nCRA;
+
+ /* SDL, ST, CA */
+ portc->out_sz = sz;
+
+ sblive_write_reg (devc, SDL, voice, loop_end);
+ sblive_write_reg (devc, SCSA, voice, loop_start);
+ sblive_write_reg (devc, PTAB, voice, 0);
+
+ update_output_volume (dev, voice, chn); /* Set volume */
+
+ if (portc->format == AFMT_S16_LE || portc->format == AFMT_AC3)
+ sblive_write_reg (devc, QKBCA, voice, start_pos);
+ else
+ sblive_write_reg (devc, QKBCA, voice, start_pos | BYTESIZE);
+
+ sblive_write_reg (devc, Z1, voice, 0);
+ sblive_write_reg (devc, Z2, voice, 0);
+
+ sblive_write_reg (devc, MAPA, voice, 0x1fff | (devc->silent_page_phys << 1)); /* This is really a physical address */
+ sblive_write_reg (devc, MAPB, voice, 0x1fff | (devc->silent_page_phys << 1)); /* This is really a physical address */
+
+ sblive_write_reg (devc, VTFT, voice, 0x0000ffff);
+ sblive_write_reg (devc, CVCF, voice, 0x0000ffff);
+ sblive_write_reg (devc, MEHA, voice, 0);
+ sblive_write_reg (devc, MEDS, voice, 0x7f);
+ sblive_write_reg (devc, MLV, voice, 0x8000);
+ sblive_write_reg (devc, VLV, voice, 0x8000);
+ sblive_write_reg (devc, VFM, voice, 0);
+ sblive_write_reg (devc, TMFQ, voice, 0);
+ sblive_write_reg (devc, VVFQ, voice, 0);
+ sblive_write_reg (devc, MEV, voice, 0x8000);
+ sblive_write_reg (devc, VEHA, voice, 0x7f7f); /* OK */
+ sblive_write_reg (devc, VEV, voice, 0x8000); /* No volume envelope delay (OK) */
+ sblive_write_reg (devc, PEFE_FILTERAMOUNT, voice, 0x7f);
+ sblive_write_reg (devc, PEFE_PITCHAMOUNT, voice, 0x00);
+}
+
+/*ARGSUSED*/
+static void
+update_output_device (sblive_devc * devc, sblive_portc * portc)
+{
+ int voiceL = portc->voice_chn, voiceR = portc->voice_chn + 1;
+
+ if (!(portc->audio_active & PCM_ENABLE_OUTPUT))
+ return;
+
+ update_output_volume (portc->audiodev, voiceL, LEFT_CH);
+ update_output_volume (portc->audiodev, voiceR, RIGHT_CH);
+}
+
+
+/*ARGSUSED*/
+static void
+sblive_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ sblive_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_active |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+sblive_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ sblive_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_active |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+void
+sblive_set_loop_stop (sblive_devc * devc, int voice, int s)
+{
+ unsigned int tmp;
+ int offs, bit;
+
+ offs = voice / 32;
+ bit = voice % 32;
+ s = !!s;
+
+ tmp = sblive_read_reg (devc, SOLL + offs, 0);
+ tmp &= ~(1 << bit);
+
+ if (s)
+ tmp |= (1 << bit);
+ sblive_write_reg (devc, SOLL + offs, 0, tmp);
+}
+
+int
+sblive_get_voice_loopintr (sblive_devc * devc, int voice)
+{
+ unsigned int tmp;
+ int offs, bit;
+
+ offs = voice / 32;
+ bit = voice % 32;
+
+ tmp = sblive_read_reg (devc, CLIPL + offs, 0);
+ tmp &= 1 << bit;
+ sblive_write_reg (devc, CLIPL + offs, 0, tmp); /* Ack the interrupt */
+
+ return !!tmp;
+}
+
+int
+sblive_get_voice_halfloopintr (sblive_devc * devc, int voice)
+{
+ unsigned int tmp;
+ int offs, bit;
+
+ offs = voice / 32;
+ bit = voice % 32;
+
+ tmp = sblive_read_reg (devc, HLIPL + offs, 0);
+ tmp &= 1 << bit;
+ sblive_write_reg (devc, HLIPL + offs, 0, tmp); /* Ack the interrupt */
+
+ return !!tmp;
+}
+
+void
+sblive_set_voice_intr (sblive_devc * devc, int voice, int s)
+{
+ unsigned int tmp;
+ int offs, bit;
+
+ offs = voice / 32;
+ bit = voice % 32;
+ s = !!s;
+
+ tmp = sblive_read_reg (devc, CLIEL + offs, 0);
+ tmp &= ~(1 << bit);
+ if (s)
+ tmp |= (1 << bit);
+ sblive_write_reg (devc, CLIEL + offs, 0, tmp);
+ sblive_write_reg (devc, HLIEL + offs, 0, tmp);
+}
+
+static unsigned int
+emu_rate_to_pitch (unsigned int rate)
+{
+ static unsigned int 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 */
+}
+
+static unsigned int
+emu_rate_to_linearpitch (unsigned int rate)
+{
+ rate = (rate << 8) / 375;
+ return (rate >> 1) + (rate & 1);
+}
+
+static void
+start_audio_voice (int dev, int voice, int chn)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+ unsigned int sample, initial_pitch, pitch_target;
+ unsigned int cra, cs, ccis, i;
+
+ /* setup CCR regs */
+ cra = 64;
+ cs = (portc->channels > 1) ? 4 : 2;
+ ccis = (portc->channels > 1) ? 28 : 30;
+ ccis *= (portc->format == AFMT_S16_LE || portc->format == AFMT_AC3) ? 1 : 2;
+ sample = (portc->format == AFMT_S16_LE
+ || portc->format == AFMT_AC3) ? 0x00000000 : 0x80808080;
+
+ for (i = 0; i < cs; i++)
+ sblive_write_reg (devc, CD0 + i, voice, sample);
+
+ sblive_write_reg (devc, CCR_CACHEINVALIDSIZE, voice, 0);
+ sblive_write_reg (devc, CCR_READADDRESS, voice, cra);
+ sblive_write_reg (devc, CCR_CACHEINVALIDSIZE, voice, ccis);
+
+ /* Set current pitch */
+ sblive_write_reg (devc, IFA, voice, 0xff00);
+ sblive_write_reg (devc, VTFT, voice, 0xffffffff);
+ sblive_write_reg (devc, CVCF, voice, 0xffffffff);
+ sblive_set_loop_stop (devc, voice, 0);
+
+ pitch_target = emu_rate_to_linearpitch (portc->speed);
+ initial_pitch = emu_rate_to_pitch (portc->speed) >> 8;
+ sblive_write_reg (devc, PTRX_PITCHTARGET, voice, pitch_target);
+ sblive_write_reg (devc, CPF_CURRENTPITCH, voice, pitch_target);
+ sblive_write_reg (devc, IP, voice, initial_pitch);
+
+ if (chn == LEFT_CH)
+ {
+ sblive_get_voice_loopintr (devc, voice);
+ sblive_get_voice_halfloopintr (devc, voice);
+ sblive_set_voice_intr (devc, voice, 1);
+ }
+ sblive_write_reg (devc, VEDS, voice, /*0x80 | */ 0x7f7f); /* Trigger (OK) */
+}
+
+/*ARGSUSED*/
+static void
+stop_audio_voice (int dev, int voice, int chn)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+
+ sblive_write_reg (devc, IFA, voice, 0xffff);
+ sblive_write_reg (devc, VTFT, voice, 0xffff);
+ sblive_write_reg (devc, PTRX_PITCHTARGET, voice, 0);
+ sblive_write_reg (devc, CPF_CURRENTPITCH, voice, 0);
+ sblive_write_reg (devc, IP, voice, 0);
+ sblive_set_loop_stop (devc, voice, 1);
+ sblive_set_voice_intr (devc, voice, 0);
+}
+
+static void
+sblive_audio_trigger (int dev, int state)
+{
+ sblive_portc *portc = audio_engines[dev]->portc;
+ sblive_devc *devc = audio_engines[dev]->devc;
+ int voiceL = portc->voice_chn, voiceR = portc->voice_chn + 1;
+
+ if (portc->mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_active & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ start_audio_voice (dev, voiceL, LEFT_CH);
+ /* sblive_dump_regs(devc, voiceL); */
+ if (portc->channels > 1)
+ start_audio_voice (dev, voiceR, RIGHT_CH);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_active & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ portc->audio_active &= ~PCM_ENABLE_OUTPUT;
+ stop_audio_voice (dev, voiceL, LEFT_CH);
+ stop_audio_voice (dev, voiceR, RIGHT_CH);
+ }
+ }
+ }
+
+ if (portc->mode & OPEN_READ && !(audio_engines[dev]->flags & ADEV_NOINPUT))
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_active & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ int tmp = sblive_read_reg (devc, ADCSR, 0);
+ unsigned int pos;
+
+ if (portc->input_type == ITYPE_SPDIF)
+ {
+ /* Start recording from S/PDIF input A */
+ sblive_write_reg (devc, SPRC, 0, portc->in_szbits | 0x00);
+ }
+ else
+ {
+ if (devc->feature_mask & SB_AUDIGY)
+ {
+ tmp |= 0x10; /* Left channel enable */
+ if (portc->channels > 1)
+ tmp |= 0x20; /* Right channel enable */
+ }
+ else
+ {
+ tmp |= 0x08; /* Left channel enable */
+ if (portc->channels > 1)
+ tmp |= 0x10; /* Right channel enable */
+ }
+ sblive_write_reg (devc, ADCBS, 0, portc->in_szbits);
+ sblive_write_reg (devc, ADCSR, 0, tmp); /* GO */
+ }
+
+ pos = (INL (devc->osdev, devc->base + 0x10) >> 6) & 0xfffff;
+ portc->rec_starttime = pos;
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_active & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ if (portc->input_type == ITYPE_SPDIF)
+ sblive_write_reg (devc, SPRC, 0, 0);
+ else
+ sblive_write_reg (devc, ADCSR, 0, 0);
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ portc->audio_active &= ~PCM_ENABLE_INPUT;
+ }
+ }
+ }
+
+}
+
+/*ARGSUSED*/
+static int
+sblive_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ int sz = -1;
+
+ if (audio_engines[dev]->flags & ADEV_NOINPUT)
+ {
+ cmn_err (CE_WARN, "Audio device %d is output only\n", dev);
+ return OSS_EIO;
+ }
+
+ if (dmap->buffsize > 65536)
+ {
+ cmn_err (CE_WARN, "Recording buffer bigger than 64k\n");
+ dmap->buffsize = 65536;
+ }
+
+#ifdef sun1
+ if (dmap->buffsize == 36864)
+ {
+ dmap->buffsize = 32768;
+ }
+#endif
+
+ switch (dmap->buffsize)
+ {
+ case 4096:
+ sz = 15;
+ break;
+ case 8192:
+ sz = 19;
+ break;
+ case 16384:
+ sz = 23;
+ break;
+ case 32768:
+ sz = 27;
+ break;
+ case 65536:
+ sz = 31;
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Unsupported input buffer size %d\n", dmap->buffsize);
+ return OSS_ENOSPC;
+ }
+
+ if (portc->input_type == ITYPE_SPDIF)
+ {
+ sblive_write_reg (devc, SPRA, 0, dmap->dmabuf_phys);
+ sblive_write_reg (devc, SPRC, 0, 0);
+ }
+ else
+ {
+ sblive_write_reg (devc, ADCBA, 0, dmap->dmabuf_phys);
+ sblive_write_reg (devc, ADCBS, 0, 0);
+ }
+ portc->in_szbits = sz;
+
+ sblive_write_reg (devc, ADCSR, 0, 0x0);
+
+ if (portc->input_type == ITYPE_ANALOG)
+ {
+ if (devc->feature_mask & SB_AUDIGY)
+ sblive_write_reg (devc, ADCSR, 0,
+ speed_tab[portc->speedsel].audigy_recbits);
+ else
+ sblive_write_reg (devc, ADCSR, 0, speed_tab[portc->speedsel].recbits);
+ }
+
+ devc->recording_dev = dev;
+
+ portc->audio_active |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+sblive_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+
+ int voiceL = portc->voice_chn, voiceR = portc->voice_chn + 1;
+
+ if (audio_engines[dev]->flags & ADEV_NOOUTPUT)
+ return OSS_EIO;
+
+ /* AC3 needs stereo too */
+ if (portc->format == AFMT_AC3 || portc->input_type == ITYPE_SPDIF)
+ {
+ portc->channels = 2;
+ portc->speed = 48000;
+ portc->routing = spdif_routing;
+ }
+ else
+ portc->routing = default_routing;
+
+ /* Left channel */
+ sblive_write_reg (devc, IFA, voiceL, 0xffff); /* Intial filter cutoff and attenuation */
+ sblive_write_reg (devc, VEDS, voiceL, 0x0); /* Volume envelope decay and sustain */
+ sblive_write_reg (devc, VTFT, voiceL, 0xffff); /* Volume target and Filter cutoff target */
+ sblive_write_reg (devc, PTAB, voiceL, 0x0); /* Pitch target and sends A and B */
+ /* The same for right channel */
+ sblive_write_reg (devc, IFA, voiceR, 0xffff);
+ sblive_write_reg (devc, VEDS, voiceR, 0x0);
+ sblive_write_reg (devc, VTFT, voiceR, 0xffff);
+ sblive_write_reg (devc, PTAB, voiceR, 0x0);
+
+ /* now setup the voices and go! */
+ setup_audio_voice (dev, voiceL, LEFT_CH);
+ if (portc->channels == 2)
+ setup_audio_voice (dev, voiceR, RIGHT_CH);
+
+ portc->audio_active |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ if (portc->uses_spdif)
+ {
+ if (portc->format == AFMT_AC3)
+ {
+ sblive_write_reg (devc, SCS0, 0, 0x2109206);
+ }
+ else
+ {
+ sblive_write_reg (devc, SCS0, 0, 0x2108504);
+ }
+ }
+ return 0;
+}
+
+static int
+sblive_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ int err, i, n;
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+ if ((err = oss_alloc_dmabuf (dev, dmap, direction)) < 0)
+ {
+ cmn_err (CE_WARN, "Cannot allocate DMA buffer\n");
+ return err;
+ }
+
+ if (dmap->buffsize > DMABUF_SIZE)
+ {
+ cmn_err (CE_NOTE, "DMA buffer was too large - truncated\n");
+ dmap->buffsize = DMABUF_SIZE;
+ }
+
+ if (devc->feature_mask & SB_LIVE)
+ if (dmap->dmabuf_phys & 0x80000000)
+ {
+ cmn_err (CE_CONT, "Got DMA buffer address beyond 2G limit.\n");
+ oss_free_dmabuf (dev, dmap);
+ dmap->dmabuf = NULL;
+
+ return OSS_ENOSPC;
+ }
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ dmap->driver_use_value = portc->memptr;
+ n = portc->memptr / 4096;
+
+/*
+ * Fill the page table
+ */
+ for (i = 0; i < dmap->buffsize / 4096; i++)
+ {
+ FILL_PAGE_MAP_ENTRY (n + i, dmap->dmabuf_phys + i * 4096);
+ }
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+sblive_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ if (dmap->dmabuf == NULL)
+ return 0;
+ oss_free_dmabuf (dev, dmap);
+
+ dmap->dmabuf = NULL;
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+sblive_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ sblive_devc *devc = audio_engines[dev]->devc;
+ sblive_portc *portc = audio_engines[dev]->portc;
+ int pos;
+
+ if (!(portc->trigger_bits & direction))
+ return 0;
+
+ if (direction == OPEN_WRITE)
+ {
+ pos = sblive_read_reg (devc, QKBCA, portc->voice_chn) & 0x00ffffff; /* Curr pos */
+ pos <<= portc->out_sz;
+ pos -= dmap->driver_use_value;
+ }
+ else
+ {
+ /* Compute current pos based on the wall clock register */
+ pos = (INL (devc->osdev, devc->base + 0x10) >> 6) & 0xfffff;
+ if (pos > portc->rec_starttime)
+ pos = pos - portc->rec_starttime;
+ else
+ pos = 0xfffff - (portc->rec_starttime - pos);
+ pos = (pos * (portc->speed / 25)) / (48000 / 25);
+ pos *= 2; /* 16 bit->bytes */
+ pos *= portc->channels;
+ pos = pos % dmap->bytes_in_use;
+ }
+
+ if (pos < 0)
+ pos = 0;
+
+ return pos;
+}
+
+static audiodrv_t sblive_audio_driver = {
+ sblive_audio_open,
+ sblive_audio_close,
+ sblive_audio_output_block,
+ sblive_audio_start_input,
+ sblive_audio_ioctl,
+ sblive_audio_prepare_for_input,
+ sblive_audio_prepare_for_output,
+ sblive_audio_reset,
+ NULL,
+ NULL,
+ sblive_audio_reset_input,
+ sblive_audio_reset_output,
+ sblive_audio_trigger,
+ sblive_audio_set_rate,
+ sblive_audio_set_format,
+ sblive_audio_set_channels,
+ NULL,
+ NULL,
+ NULL, /* sblive_check_input, */
+ NULL, /* sblive_check_output, */
+ sblive_alloc_buffer,
+ sblive_free_buffer,
+ NULL,
+ NULL,
+ sblive_get_buffer_pointer,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ sblive_audio_ioctl /* bind */
+};
+
+#define DATAPORT (devc->base)
+#define COMDPORT (devc->base+1)
+#define STATPORT (devc->base+1)
+
+static __inline__ int
+audigyuart_status (sblive_devc * devc)
+{
+ return sblive_read_reg (devc, MUASTAT, 0);
+}
+
+#define input_avail(devc) (!(audigyuart_status(devc)&INPUT_AVAIL))
+#define output_ready(devc) (!(audigyuart_status(devc)&OUTPUT_READY))
+static void
+audigyuart_cmd (sblive_devc * devc, unsigned char cmd)
+{
+ sblive_write_reg (devc, MUACMD, 0, cmd);
+}
+
+static __inline__ int
+audigyuart_read (sblive_devc * devc)
+{
+ return sblive_read_reg (devc, MUADAT, 0);
+}
+
+static __inline__ void
+audigyuart_write (sblive_devc * devc, unsigned char byte)
+{
+ sblive_write_reg (devc, MUADAT, 0, byte);
+}
+
+#define OUTPUT_READY 0x40
+#define INPUT_AVAIL 0x80
+#define MPU_ACK 0xFE
+#define MPU_RESET 0xFF
+#define UART_MODE_ON 0x3F
+
+static int reset_audigyuart (sblive_devc * devc);
+static void enter_uart_mode (sblive_devc * devc);
+
+typedef struct
+{
+ int keycode;
+ int action;
+ int local_action;
+} ir_code_t;
+
+static void
+sblive_key_action (sblive_devc * devc, ir_code_t * code)
+{
+ int value, left, right, dev;
+
+ dev = devc->mixer_dev;
+
+ switch (code->local_action)
+ {
+ case 1: /* Volume- */
+ value = sblive_set_gpr (dev, GPR_VOLUME, SNDCTL_MIX_READ, 0);
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ left -= 5;
+ if (left < 0)
+ left = 0;
+ right -= 5;
+ if (right < 0)
+ right = 0;
+ value = left | (right << 8);
+ sblive_set_gpr (dev, GPR_VOLUME, SNDCTL_MIX_WRITE, value);
+ mixer_devs[dev]->modify_counter++;
+ return;
+ break;
+
+ case 2: /* Volume+ */
+ value = sblive_set_gpr (dev, GPR_VOLUME, SNDCTL_MIX_READ, 0);
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ left += 5;
+ if (left > 100)
+ left = 100;
+ right += 5;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ sblive_set_gpr (dev, GPR_VOLUME, SNDCTL_MIX_WRITE, value);
+ mixer_devs[dev]->modify_counter++;
+ return;
+ break;
+ }
+}
+
+static void
+sblive_handle_ir (sblive_devc * devc, unsigned char c)
+{
+/*
+ * Receive a MIDI SysEx message and check if it's an IR remote command
+ */
+#if 1
+
+/*
+ * Sysex code sent by the Live!DRIVE IR unit
+ */
+ static unsigned char remote_id[] =
+ { 0xf0, 0x00, 0x20, 0x21, 0x60, 0x00, 0x02, 0x00, 0xf7 };
+
+ static ir_code_t codes[] = {
+ /* Creative RM-900B remote control unit */
+ {0x09017e}, /* 0 */
+ {0x0a512e}, /* 1 */
+ {0x0a710e}, /* 2 */
+ {0x090976}, /* 3 */
+ {0x09512e}, /* 4 */
+ {0x09215e}, /* 5 */
+ {0x091e61}, /* 6 */
+ {0x0a116e}, /* 7 */
+ {0x0a413e}, /* 8 */
+ {0x0a6e11}, /* 9 */
+ {0x0a1e61}, /* Play/Pause */
+ {0x0a215e}, /* Stop/Eject */
+ {0x0a3e41}, /* Slow */
+ {0x0a7e01}, /* Prev */
+ {0x095e21}, /* Next */
+ {0x097e01}, /* Step */
+ {0x097609}, /* Mute */
+ {0x0a4639, 0, 1}, /* Vol- */
+ {0x094639, 0, 2}, /* Vol+ */
+ /* Speaker ??? */
+ {0x09314e}, /* EAX */
+ {0x09413e}, /* Options */
+ {0x096e11}, /* Display */
+ {0x09710e}, /* Return */
+ {0x09116e}, /* Start */
+ {0x093e41}, /* Cancel */
+ {0x0a5e21}, /* Up */
+ {0x0a611e}, /* << */
+ {0x0a017e}, /* Select/OK */
+ {0x0a2e51}, /* >> */
+ {0x0a314e}, /* Down */
+
+/* Creative RM-1000 remote control unit */
+ {0x0a0679}, /* Power */
+ {0x0a0e71}, /* CMSS */
+ {0x0a4e31}, /* Rec */
+
+/* Creative Inspire 5.1 Digital 5700 remote */
+ {0x0a0778}, /* Power */
+ {0x097708}, /* Mute */
+ {0x0a7708}, /* Test */
+ {0x0a4738}, /* Vol- */
+ {0x094738}, /* Vol+ */
+ {0x0a0f70}, /* Effect */
+ {0x0a5728}, /* Analog */
+ {0x0a2758}, /* Pro logic */
+ {0x094f30}, /* Dynamic mode */
+ {0x093748}, /* Digital/PCM audio */
+ {0}
+ };
+#endif
+ if (c == 0xf0) /* Sysex start */
+ {
+ devc->sysex_buf[0] = c;
+ devc->sysex_p = 1;
+ return;
+ }
+
+ if (devc->sysex_p <= 0)
+ return;
+
+ if (devc->sysex_p >= 20) /* Too long */
+ {
+ devc->sysex_p = 0;
+ return;
+ }
+
+ if (c == 0xf7) /* Sysex end */
+ {
+ int i, l, v;
+ unsigned char *buf;
+
+ devc->sysex_buf[devc->sysex_p] = c;
+ devc->sysex_p++;
+ l = devc->sysex_p;
+
+ devc->sysex_p = 0;
+ buf = devc->sysex_buf;
+
+ if (l == 9)
+ {
+ int ok = 1;
+
+ for (i = 0; i < sizeof (remote_id); i++)
+ if (buf[i] != remote_id[i])
+ ok = 0;
+
+ if (ok)
+ {
+ /* cmn_err (CE_CONT, "Live!DRIVE IR detected\n"); */
+ return;
+ }
+
+ return;
+ }
+
+ if (l != 13) /* Wrong length */
+ return;
+
+ if (buf[0] != 0xf0 || buf[12] != 0xf7) /* Not sysex */
+ return;
+
+ /* Verify that this is an IR receiver sysex */
+ if (buf[1] != 0x00 || buf[2] != 0x20 || buf[3] != 0x21)
+ return;
+ if (buf[4] != 0x60 || buf[5] != 0x00 || buf[6] != 0x01)
+ return;
+#if 0
+ if (buf[7] != 0x09 && buf[7] != 0x0a) /* Remote ID */
+ return;
+#endif
+ if (buf[8] != 0x41 || buf[9] != 0x44)
+ return;
+
+ v = (buf[7] << 16) | (buf[10] << 8) | buf[11];
+
+ for (i = 0; codes[i].keycode != 0; i++)
+ if (codes[i].keycode == v)
+ {
+ sblive_key_action (devc, &codes[i]);
+ return;
+ }
+
+ return;
+ }
+
+ /* Ordinary byte */
+ devc->sysex_buf[devc->sysex_p] = c;
+ devc->sysex_p++;
+}
+
+static void
+sblive_ir_callback (int dev, unsigned char c)
+{
+ sblive_devc *devc;
+ oss_device_t *osdev = midi_devs[dev]->osdev;
+ devc = osdev->devc;
+
+ if (devc->midi_dev != dev)
+ return;
+
+ sblive_handle_ir (devc, c);
+}
+
+static void
+audigyuart_input_loop (sblive_devc * devc)
+{
+ int t = 0;
+
+ while (input_avail (devc) && t++ < 1000)
+ {
+ unsigned char c = audigyuart_read (devc);
+
+ sblive_handle_ir (devc, c);
+
+ if (c == MPU_ACK)
+ devc->input_byte = c;
+ else if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr (devc->midi_dev, c);
+ }
+}
+
+static void
+audigyuartintr (sblive_devc * devc)
+{
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ audigyuart_input_loop (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+audigyuart_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ sblive_devc *devc = (sblive_devc *) midi_devs[dev]->devc;
+
+ if (devc->midi_opened)
+ {
+ return OSS_EBUSY;
+ }
+
+ while (input_avail (devc))
+ audigyuart_read (devc);
+
+ devc->midi_input_intr = inputbyte;
+ devc->midi_opened = mode;
+ enter_uart_mode (devc);
+ devc->midi_disabled = 0;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+audigyuart_close (int dev, int mode)
+{
+ sblive_devc *devc = (sblive_devc *) midi_devs[dev]->devc;
+
+ reset_audigyuart (devc);
+ oss_udelay (10);
+ enter_uart_mode (devc);
+ reset_audigyuart (devc);
+ devc->midi_opened = 0;
+}
+
+static int
+audigyuart_out (int dev, unsigned char midi_byte)
+{
+ sblive_devc *devc = (sblive_devc *) midi_devs[dev]->devc;
+
+ if (devc->midi_disabled)
+ return 1;
+
+ if (!output_ready (devc))
+ {
+ return 0;
+ }
+
+ audigyuart_write (devc, midi_byte);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+audigyuart_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t audigy_midi_driver = {
+ audigyuart_open,
+ audigyuart_close,
+ audigyuart_ioctl,
+ audigyuart_out
+};
+
+static void
+enter_uart_mode (sblive_devc * devc)
+{
+ int ok, timeout;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+
+ devc->input_byte = 0;
+ audigyuart_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 (audigyuart_read (devc) == MPU_ACK)
+ ok = 1;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+void
+attach_audigyuart (sblive_devc * devc)
+{
+ enter_uart_mode (devc);
+
+ devc->midi_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "AUDIGY", "Audigy UART", &audigy_midi_driver, sizeof (midi_driver_t),
+ 0, devc, devc->osdev);
+ devc->midi_opened = 0;
+}
+
+static int
+reset_audigyuart (sblive_devc * devc)
+{
+ int ok, timeout, n;
+ oss_native_word flags;
+
+ /*
+ * Send the RESET command. Try again if no success at the first time.
+ */
+
+ ok = 0;
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ for (n = 0; n < 2 && !ok; n++)
+ {
+ for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+
+ devc->input_byte = 0;
+ audigyuart_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 (audigyuart_read (devc) == MPU_ACK)
+ ok = 1;
+
+ }
+
+
+
+ if (ok)
+ audigyuart_input_loop (devc); /*
+ * Flush input before enabling interrupts
+ */
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return ok;
+}
+
+int
+probe_audigyuart (sblive_devc * devc)
+{
+ int ok = 0;
+
+ DDB (cmn_err (CE_CONT, "Entered probe_audigyuart\n"));
+
+ devc->midi_input_intr = NULL;
+ devc->midi_opened = 0;
+ devc->input_byte = 0;
+
+ ok = reset_audigyuart (devc);
+
+ if (ok)
+ {
+ DDB (cmn_err (CE_CONT, "Reset UART401 OK\n"));
+ }
+ else
+ {
+ DDB (cmn_err
+ (CE_CONT, "Reset UART401 failed (no hardware present?).\n"));
+ DDB (cmn_err
+ (CE_CONT, "mpu401 status %02x\n", audigyuart_status (devc)));
+ }
+
+ DDB (cmn_err (CE_CONT, "audigyuart detected OK\n"));
+ return ok;
+}
+
+void
+unload_audigyuart (sblive_devc * devc)
+{
+ reset_audigyuart (devc);
+}
+
+static void
+attach_mpu (sblive_devc * devc)
+{
+ char tmp[128];
+ int ndevs = num_mididevs;
+ oss_native_word flags;
+
+ sprintf (tmp, "%s external MIDI", devc->card_name);
+
+ if (devc->feature_mask & SB_AUDIGY)
+ {
+ if (!probe_audigyuart (devc))
+ {
+ cmn_err (CE_NOTE, "MIDI UART was not detected\n");
+ return;
+ }
+ DDB (cmn_err (CE_CONT, "SB Audigy: MIDI UART detected - Good\n"));
+ devc->mpu_attached = 1;
+ attach_audigyuart (devc);
+ }
+ else
+ {
+ MUTEX_ENTER (devc->mutex, flags);
+ if (uart401_init (&devc->uart401devc, devc->osdev, devc->base + 0x18,
+ tmp) >= 0)
+ devc->mpu_attached = 1;
+ MUTEX_EXIT (devc->mutex, flags);
+
+ if (ndevs != num_mididevs)
+ {
+ devc->midi_dev = ndevs;
+ midi_devs[ndevs]->input_callback = sblive_ir_callback;
+ }
+ }
+}
+
+static void
+load_dsp (sblive_devc * devc, unsigned char *buf, int len)
+{
+ emu10k1_file *code;
+ int pc, i;
+
+ if (len != sizeof (*code))
+ {
+ cmn_err (CE_NOTE, "DSP file size mismatch\n");
+ return;
+ }
+
+ code = (emu10k1_file *) buf;
+
+ for (pc = 0; pc < 1024; pc++)
+ {
+ write_efx (devc, UC0 + pc, code->code[pc]);
+ }
+
+ if (code->parms.ngpr < MAX_GPR_PARMS)
+ for (i = 0; i < code->parms.ngpr; i++)
+ {
+ code->parms.gpr[i].name[GPR_NAME_SIZE - 1] = 0; /* Overflow protection */
+ if (strlen (code->parms.gpr[i].name) >= 32) /* Name may be bad */
+ {
+ return;
+ }
+
+/* cmn_err(CE_CONT, "Gpr %d = %s (vol %x) type=%x\n", gpr->gpr[i].num, gpr->gpr[i].name, gpr->gpr[i].def, gpr->gpr[i].type); */
+ if (code->parms.gpr[i].num < MAX_GPR)
+ if (code->parms.gpr[i].type != MIXT_GROUP)
+ {
+ if (is_special_gpr (code->parms.gpr[i].num))
+ sblive_set_gpr (devc->mixer_dev, code->parms.gpr[i].num,
+ SNDCTL_MIX_WRITE,
+ devc->gpr_values[code->parms.gpr[i].num]);
+ else
+ sblive_set_gpr (devc->mixer_dev, code->parms.gpr[i].num,
+ SNDCTL_MIX_WRITE, code->parms.gpr[i].def);
+ }
+ }
+
+
+ if (devc->gpr == NULL)
+ {
+ devc->gpr = PMALLOC (devc->osdev, sizeof (gpr_info));
+ if (devc->gpr == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory (gpr)\n");
+ return;
+ }
+ memset (devc->gpr, 0, sizeof (gpr_info));
+ }
+ memcpy (devc->gpr, &code->parms, sizeof (gpr_info));
+ create_efx_mixer (devc->mixer_dev);
+
+ if (code->consts.nconst >= MAX_CONST_PARMS)
+ return;
+
+ for (i = 0; i < code->consts.nconst; i++)
+ {
+ if (code->consts.consts[i].gpr >= MAX_GPR)
+ {
+ return;
+ }
+
+ sblive_write_reg (devc, code->consts.consts[i].gpr + GPR0, 0,
+ code->consts.consts[i].value);
+ }
+}
+
+#define LIVE_NOP() \
+ write_efx(devc, UC0+(pc*2), 0x10040); \
+ write_efx(devc, UC0+(pc*2+1), 0x610040);pc++
+#define LIVE_ACC3(r, a, x, y) /* z=w+x+y */ \
+ write_efx(devc, UC0+(pc*2), (x << 10) | y); \
+ write_efx(devc, UC0+(pc*2+1), (6 << 20) | (r << 10) | a);pc++
+
+#define AUDIGY_ACC3(r, a, x, y) /* z=w+x+y */ \
+ write_efx(devc, UC0+(pc*2), (x << 12) | y); \
+ write_efx(devc, UC0+(pc*2+1), (6 << 24) | (r << 12) | a);pc++
+#define AUDIGY_NOP() AUDIGY_ACC3(0xc0, 0xc0, 0xc0, 0xc0)
+
+static int
+init_effects (sblive_devc * devc)
+{
+ int i;
+ unsigned short pc;
+
+ if (devc->feature_mask & SB_AUDIGY)
+ {
+ pc = 0;
+ for (i = 0; i < 512; i++)
+ {
+ AUDIGY_NOP ();
+ }
+
+ for (i = 0; i < 256; i++)
+ write_efx (devc, GPR0 + i, 0);
+ sblive_write_reg (devc, AUDIGY_DBG, 0, 0);
+ load_dsp (devc, emu10k2_dsp, sizeof (emu10k2_dsp));
+ }
+ else
+ {
+ pc = 0;
+ for (i = 0; i < 512; i++)
+ {
+ LIVE_NOP ();
+ }
+
+ for (i = 0; i < 256; i++)
+ write_efx (devc, GPR0 + i, 0);
+ sblive_write_reg (devc, DBG, 0, 0);
+ load_dsp (devc, emu10k1_dsp, sizeof (emu10k1_dsp));
+ }
+
+ return 1;
+}
+
+static void
+init_emu10k1 (sblive_devc * devc)
+{
+ unsigned int tmp, i;
+ extern int sblive_memlimit;
+#ifndef NO_EMU10K1_SYNTH
+ extern int sblive_synth_enable;
+#endif
+ int xmem_mode = 0;
+ unsigned int reg, val;
+ extern int sblive_digital_din;
+ extern int audigy_digital_din;
+ oss_native_word phaddr;
+ unsigned int memlimit = MEMLIMIT_31BITS;
+
+ OUTL (devc->osdev, 0x00000000, devc->base + 0x0c); /* Intr disable */
+ OUTL (devc->osdev,
+ HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE,
+ devc->base + 0x14);
+
+ sblive_write_reg (devc, MBS, 0, 0x0);
+ sblive_write_reg (devc, MBA, 0, 0x0);
+ sblive_write_reg (devc, FXBS, 0, 0x0);
+ sblive_write_reg (devc, FXBA, 0, 0x0);
+ sblive_write_reg (devc, ADCBS, 0, 0x0);
+ sblive_write_reg (devc, ADCBA, 0, 0x0);
+
+ sblive_write_reg (devc, CLIEL, 0, 0x0);
+ sblive_write_reg (devc, CLIEH, 0, 0x0);
+ sblive_write_reg (devc, SOLL, 0, 0xffffffff);
+ sblive_write_reg (devc, SOLH, 0, 0xffffffff);
+
+
+ if (devc->feature_mask & SB_AUDIGY)
+ {
+ memlimit=MEMLIMIT_32BITS;
+ sblive_write_reg (devc, 0x5e, 0, 0xf00); /* ?? */
+ sblive_write_reg (devc, 0x5f, 0, 0x3); /* ?? */
+ }
+
+#ifndef NO_EMU10K1_SYNTH
+ if (!sblive_synth_enable)
+ sblive_memlimit = 0;
+#endif
+
+ if (sblive_memlimit < 4096) /* Given in megabytes */
+ sblive_memlimit *= (1024 * 1024);
+
+ devc->max_mem = sblive_memlimit;
+ if (devc->max_mem < 1024 * 1024)
+ devc->max_mem = 1024 * 1024;
+
+ devc->max_mem += AUDIO_MEMSIZE;
+
+ /* SB Live/Audigy supports at most 32M of memory) */
+ if (devc->max_mem > 32 * 1024 * 1024)
+ devc->max_mem = 32 * 1024 * 1024;
+
+ devc->max_pages = devc->max_mem / 4096;
+ if (devc->max_pages < 1024)
+ devc->max_pages = 1024;
+ devc->page_map =
+ (int *) CONTIG_MALLOC (devc->osdev, devc->max_pages * 4, memlimit,
+ &phaddr, devc->page_map_dma_handle);
+ devc->vpage_map =
+ KERNEL_MALLOC (devc->max_pages * sizeof (unsigned char *));
+ if (devc->page_map == NULL || devc->vpage_map == NULL)
+ {
+ cmn_err (CE_WARN, "Can't allocate the PTBA table\n");
+ return;
+ }
+ memset (devc->vpage_map, 0, devc->max_pages * 4);
+
+ tmp = phaddr;
+ if (devc->feature_mask & SB_LIVE)
+ {
+ if (tmp & 0x80000000)
+ {
+ cmn_err (CE_CONT,
+ "SB Live Error: Page table is beyond the 2G limit\n");
+ }
+ }
+ else
+ {
+ if (tmp & 0x80000000)
+ {
+ DDB (cmn_err (CE_CONT, "Audigy: Using 4G PCI addressing mode\n"));
+ xmem_mode = 1;
+ devc->emu_page_shift = 0;
+ if (devc->max_mem > 16 * 1024 * 1034)
+ {
+ devc->max_mem = 16 * 1024 * 1024;
+
+ DDB (cmn_err
+ (CE_NOTE,
+ "Max memory dropped to 16M due to need for extended PCI address mode.\n"));
+ }
+ }
+ }
+
+ devc->synth_memlimit = devc->max_mem - AUDIO_MEMSIZE;
+ devc->synth_membase = SYNTH_MEMBASE;
+ devc->synth_memtop = devc->synth_membase;
+ devc->synth_memptr = devc->synth_membase;
+
+ devc->silent_page =
+ (int *) CONTIG_MALLOC (devc->osdev, 4096, memlimit, &phaddr, devc->silent_page_dma_handle);
+ if (devc->silent_page == NULL)
+ {
+ cmn_err (CE_WARN, "Can't allocate a silent page\n");
+ return;
+ }
+
+ devc->silent_page_phys = phaddr;
+ if (devc->feature_mask & SB_LIVE)
+ if (devc->silent_page_phys & 0x80000000)
+ {
+ cmn_err (CE_CONT,
+ "SB Live warning: Silent page is beyond the 2G limit\n");
+ }
+
+ devc->audio_memptr = 4096; /* Skip the silence page */
+ memset (devc->silent_page, 0, 4096);
+
+ for (i = 0; i < devc->max_pages; i++)
+ {
+ FILL_PAGE_MAP_ENTRY (i, devc->silent_page_phys);
+ devc->vpage_map[i] = NULL;
+ }
+
+ for (i = 0; i < 64; i++)
+ sblive_init_voice (devc, i);
+
+ if (devc->feature_mask & SB_AUDIGY)
+ {
+ sblive_write_reg (devc, SCS0, 0, 0x2108504);
+ sblive_write_reg (devc, SCS1, 0, 0x2108504);
+ sblive_write_reg (devc, SCS2, 0, 0x2108504);
+ }
+ else
+ {
+ sblive_write_reg (devc, SCS0, 0, 0x2109204);
+ sblive_write_reg (devc, SCS1, 0, 0x2109204);
+ sblive_write_reg (devc, SCS2, 0, 0x2109204);
+ }
+
+ sblive_write_reg (devc, PTBA, 0, tmp);
+ tmp = sblive_read_reg (devc, PTBA, 0);
+
+ sblive_write_reg (devc, TCBA, 0, 0x0);
+ sblive_write_reg (devc, TCBS, 0, 0x4);
+
+ OUTL (devc->osdev, IE_RXA | IE_AB | IE_IT, devc->base + IE); /* Intr enable */
+
+/*
+ * SB Live 5.1 support. Turn on S/PDIF output
+ */
+ if (devc->subvendor == 0x80611102) /* Live 5.1 */
+ {
+ tmp = INL (devc->osdev, devc->base + 0x14);
+ tmp |= 0x00001000; /* Turn GPO0 pin on to enable S/PDIF outputs */
+ OUTL (devc->osdev, tmp, devc->base + 0x14);
+ }
+
+ if (devc->subvendor == 0x80661102)
+ {
+ sblive_write_reg (devc, AC97SLOT, 0,
+ AC97SLOT_CENTER | AC97SLOT_LFE | AC97SLOT_REAR_LEFT |
+ AC97SLOT_REAR_RIGHT);
+ }
+
+ if (devc->feature_mask & SB_AUDIGY2)
+ {
+ /* Enable analog outputs on Audigy2 */
+ int tmp;
+
+ /* Setup SRCMulti_I2S SamplingRate */
+ tmp = sblive_read_reg (devc, EHC, 0);
+ tmp &= 0xfffff1ff;
+ tmp |= (0x2 << 9);
+ sblive_write_reg (devc, EHC, 0, tmp);
+ /* sblive_write_reg (devc, SOC, 0, 0x00000000); */
+
+ /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
+ OUTL (devc->osdev, 0x600000, devc->base + 0x20);
+ OUTL (devc->osdev, 0x14, devc->base + 0x24);
+
+ /* Setup SRCMulti Input Audio Enable */
+ /* Setup SRCMulti Input Audio Enable */
+ if (devc->feature_mask & SB_AUDIGY2VAL)
+ OUTL (devc->osdev, 0x7B0000, devc->base + 0x20);
+ else
+ OUTL (devc->osdev, 0x6E0000, devc->base + 0x20);
+
+ OUTL (devc->osdev, 0xFF00FF00, devc->base + 0x24);
+
+ /* Setup I2S ASRC Enable (HC register) */
+ tmp = INL (devc->osdev, devc->base + 0x14);
+ tmp |= 0x00000070;
+ OUTL (devc->osdev, tmp, devc->base + 0x14);
+
+ /*
+ * Unmute Analog now. Set GPO6 to 1 for Apollo.
+ * This has to be done after init ALice3 I2SOut beyond 48KHz.
+ * So, sequence is important
+ */
+ tmp = INL (devc->osdev, devc->base + 0x18);
+ tmp |= 0x0040;
+ if (devc->feature_mask & SB_AUDIGY2VAL)
+ tmp |= 0x0060;
+
+ OUTL (devc->osdev, tmp, devc->base + 0x18);
+ }
+
+ sblive_write_reg (devc, SOLL, 0, 0xffffffff);
+ sblive_write_reg (devc, SOLH, 0, 0xffffffff);
+
+ if (devc->feature_mask & SB_AUDIGY)
+ {
+ unsigned int mode = 0;
+
+ if (devc->feature_mask & SB_AUDIGY2)
+ mode |= HCFG_AC3ENABLE_GPSPDIF | HCFG_AC3ENABLE_CDSPDIF;
+ if (xmem_mode)
+ {
+ OUTL (devc->osdev,
+ HCFG_AUDIOENABLE | HCFG_AUTOMUTE | HCFG_JOYENABLE |
+ A_HCFG_VMUTE | A_HCFG_AUTOMUTE | A_HCFG_XM | mode,
+ devc->base + 0x14);
+ }
+ else
+ OUTL (devc->osdev,
+ HCFG_AUDIOENABLE | HCFG_AUTOMUTE | HCFG_JOYENABLE | A_HCFG_VMUTE
+ | A_HCFG_AUTOMUTE | mode, devc->base + 0x14);
+
+ OUTL (devc->osdev, INL (devc->osdev, devc->base + 0x18) | 0x0004, devc->base + 0x18); /* GPIO (S/PDIF enable) */
+
+
+ /* enable IR port */
+ tmp = INL (devc->osdev, devc->base + 0x18);
+ OUTL (devc->osdev, tmp | A_IOCFG_GPOUT2, devc->base + 0x18);
+ oss_udelay (500);
+ OUTL (devc->osdev, tmp | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2,
+ devc->base + 0x18);
+ oss_udelay (100);
+ OUTL (devc->osdev, tmp, devc->base + 0x18);
+ }
+ else
+ OUTL (devc->osdev,
+ HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE |
+ HCFG_JOYENABLE, devc->base + 0x14);
+
+
+ /* enable IR port */
+ tmp = INL (devc->osdev, devc->base + 0x14);
+ OUTL (devc->osdev, tmp | HCFG_GPOUT2, devc->base + 0x14);
+ oss_udelay (500);
+ OUTL (devc->osdev, tmp | HCFG_GPOUT1 | HCFG_GPOUT2, devc->base + 0x14);
+ oss_udelay (100);
+ OUTL (devc->osdev, tmp, devc->base + 0x14);
+
+ /* Switch the shared SPDIF/OUT3 to DIGITAL or ANALOG mode */
+ /* depending on whether the port is SPDIF or analog */
+
+ if ((devc->feature_mask == SB_AUDIGY) ||
+ ((devc->feature_mask & SB_AUDIGY2) && (audigy_digital_din == 0)))
+ {
+ reg = INL (devc->osdev, devc->base + 0x18) & ~A_IOCFG_GPOUT0;
+ val = (audigy_digital_din) ? 0x4 : 0;
+ reg |= val;
+ OUTL (devc->osdev, reg, devc->base + 0x18);
+ }
+ if (devc->feature_mask & SB_LIVE) /* SBLIVE */
+ {
+ reg = INL (devc->osdev, devc->base + 0x14) & ~HCFG_GPOUT0;
+ val = (sblive_digital_din) ? HCFG_GPOUT0 : 0;
+ reg |= val;
+ OUTL (devc->osdev, reg, devc->base + 0x14);
+ }
+
+}
+
+void
+sblive_init_voice (sblive_devc * devc, int voice)
+{
+ sblive_set_loop_stop (devc, voice, 1);
+
+ sblive_write_reg (devc, VEDS, voice, 0x0);
+ sblive_write_reg (devc, IP, voice, 0x0);
+ sblive_write_reg (devc, VTFT, voice, 0xffff);
+ sblive_write_reg (devc, CVCF, voice, 0xffff);
+ sblive_write_reg (devc, PTAB, voice, 0x0);
+ sblive_write_reg (devc, CPF, voice, 0x0);
+ sblive_write_reg (devc, CCR, voice, 0x0);
+ sblive_write_reg (devc, SCSA, voice, 0x0);
+ sblive_write_reg (devc, SDL, voice, 0x10);
+ sblive_write_reg (devc, QKBCA, voice, 0x0);
+ sblive_write_reg (devc, Z1, voice, 0x0);
+ sblive_write_reg (devc, Z2, voice, 0x0);
+
+ if (devc->feature_mask & SB_AUDIGY)
+ sblive_write_reg (devc, SRDA, voice, 0x03020100);
+ sblive_write_reg (devc, FXRT, voice, 0x32100000);
+
+ sblive_write_reg (devc, MEHA, voice, 0x0);
+ sblive_write_reg (devc, MEDS, voice, 0x0);
+ sblive_write_reg (devc, IFA, voice, 0xffff);
+ sblive_write_reg (devc, PEFE, voice, 0x0);
+ sblive_write_reg (devc, VFM, voice, 0x0);
+ sblive_write_reg (devc, TMFQ, voice, 24);
+ sblive_write_reg (devc, VVFQ, voice, 24);
+ sblive_write_reg (devc, TMPE, voice, 0x0);
+ sblive_write_reg (devc, VLV, voice, 0x0);
+ sblive_write_reg (devc, MLV, voice, 0x0);
+ sblive_write_reg (devc, VEHA, voice, 0x0);
+ sblive_write_reg (devc, VEV, voice, 0x0);
+ sblive_write_reg (devc, MEV, voice, 0x0);
+
+ if (devc->feature_mask & SB_AUDIGY)
+ {
+ sblive_write_reg (devc, CSBA, voice, 0x0);
+ sblive_write_reg (devc, CSDC, voice, 0x0);
+ sblive_write_reg (devc, CSFE, voice, 0x0);
+ sblive_write_reg (devc, CSHG, voice, 0x0);
+ sblive_write_reg (devc, SRHE, voice, 0x3f3f3f3f);
+ }
+}
+
+#ifndef NO_EMU10K1_SYNTH
+extern void sblive_install_synth (sblive_devc * devc);
+extern void sblive_remove_synth (sblive_devc * devc);
+#endif
+
+static const unsigned char peak_cnv[256] = {
+ 0, 18, 29, 36, 42, 47, 51, 54, 57, 60, 62, 65, 67, 69, 71, 72,
+ 74, 75, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 89, 90,
+ 91, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 100, 101,
+ 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
+ 108,
+ 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 113, 113, 113, 114, 114,
+ 114,
+ 115, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119,
+ 119,
+ 119, 119, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 122, 122, 123,
+ 123,
+ 123, 123, 124, 124, 124, 124, 125, 125, 125, 125, 125, 126, 126, 126, 126,
+ 126,
+ 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 129, 129, 129, 129, 129,
+ 130,
+ 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132,
+ 132,
+ 132, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 135,
+ 135,
+ 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 137, 137, 137,
+ 137,
+ 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139,
+ 139,
+ 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141,
+ 141,
+ 141, 141, 141, 141, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143,
+ 143,
+ 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, 144, 144, 144,
+ 144,
+};
+
+static void
+set_equalizer (sblive_devc * devc, int ctrl, int band, int value)
+{
+ const unsigned int *row;
+ int i;
+
+ switch (band)
+ {
+ case 0:
+ row = (unsigned int *) &eq_band1_data[value][0];
+ break;
+ case 1:
+ row = (unsigned int *) &eq_band2_data[value][0];
+ break;
+ case 2:
+ row = (unsigned int *) &eq_band3_data[value][0];
+ break;
+ case 3:
+ row = (unsigned int *) &eq_band4_data[value][0];
+ break;
+
+ default:
+ cmn_err (CE_CONT, "%s: bad equalizer band %d\n", devc->card_name, band);
+ return;
+ }
+
+ for (i = 0; i < 5; i++)
+ {
+ sblive_write_reg (devc, ctrl + GPR0 + i, 0, row[i]);
+ }
+}
+
+static const int db2lin_101[101] = { 0x00000000,
+ 0x0024B53A, 0x002750CA, 0x002A1BC6, 0x002D198D, 0x00304DBA, 0x0033BC2A,
+ 0x00376901, 0x003B58AF, 0x003F8FF1, 0x004413DF, 0x0048E9EA, 0x004E17E9,
+ 0x0053A419, 0x0059952C, 0x005FF24E, 0x0066C32A, 0x006E0FFB, 0x0075E18D,
+ 0x007E414F, 0x0087395B, 0x0090D482, 0x009B1E5B, 0x00A6234F, 0x00B1F0A7,
+ 0x00BE94A1, 0x00CC1E7C, 0x00DA9E8D, 0x00EA2650, 0x00FAC881, 0x010C9931,
+ 0x011FADDC, 0x01341D87, 0x014A00D8, 0x01617235, 0x017A8DE6, 0x01957233,
+ 0x01B23F8D, 0x01D118B1, 0x01F222D4, 0x021585D1, 0x023B6C57, 0x0264041D,
+ 0x028F7E19, 0x02BE0EBD, 0x02EFEE33, 0x032558A2, 0x035E8E7A, 0x039BD4BC,
+ 0x03DD7551, 0x0423BF61, 0x046F07B5, 0x04BFA91B, 0x051604D5, 0x0572830D,
+ 0x05D59354, 0x063FAD27, 0x06B15080, 0x072B0673, 0x07AD61CD, 0x0838FFCA,
+ 0x08CE88D3, 0x096EB147, 0x0A1A3A53, 0x0AD1F2E0, 0x0B96B889, 0x0C6978A5,
+ 0x0D4B316A, 0x0E3CF31B, 0x0F3FE155, 0x10553469, 0x117E3AD9, 0x12BC5AEA,
+ 0x14111457, 0x157E0219, 0x1704DC5E, 0x18A77A97, 0x1A67D5B6, 0x1C480A87,
+ 0x1E4A5C45, 0x2071374D, 0x22BF3412, 0x25371A37, 0x27DBE3EF, 0x2AB0C18F,
+ 0x2DB91D6F, 0x30F89FFD, 0x34733433, 0x382D0C46, 0x3C2AA6BD, 0x4070D3D9,
+ 0x4504BB66, 0x49EBE2F1, 0x4F2C346F, 0x54CC0565, 0x5AD21E86, 0x6145C3E7,
+ 0x682EBDBD, 0x6F9561C4, 0x77829D4D,
+ 0x7fffffff
+};
+
+static __inline__ int
+convert_fixpoint (int val)
+{
+ if (val < 0)
+ val = 0;
+ if (val > 100)
+ val = 100;
+ return db2lin_101[val];
+}
+
+static int
+sblive_set_gpr (int dev, int ctrl, unsigned int cmd, int value)
+{
+ sblive_devc *devc = mixer_devs[dev]->hw_devc;
+ int typ, i;
+
+ if (devc == NULL)
+ return 0;
+
+ if (devc->gpr == NULL)
+ {
+ int left, right;
+
+ if (ctrl >= NEXT_FREE_GPR)
+ return 0;
+
+ if (cmd != SNDCTL_MIX_WRITE)
+ return 0;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ if (left < 0)
+ left = 0;
+ if (left > 100)
+ left = 100;
+ if (right < 0)
+ right = 0;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ devc->gpr_values[ctrl] = value;
+
+ left = convert_fixpoint (left);
+ sblive_write_reg (devc, ctrl + GPR0, 0, left);
+ right = convert_fixpoint (right);
+ sblive_write_reg (devc, ctrl + GPR0 + 1, 0, right);
+ return value;
+ }
+
+ if (ctrl < 0 || ctrl >= MAX_GPR)
+ return OSS_EIO;
+
+ typ = MIXT_SLIDER;
+ for (i = 0; i < devc->gpr->ngpr; i++)
+ if (devc->gpr->gpr[i].num == ctrl && devc->gpr->gpr[i].type != MIXT_GROUP)
+ typ = devc->gpr->gpr[i].type;
+
+ if (typ == MIXT_GROUP)
+ {
+ return OSS_EIO;
+ }
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if (typ == MIXT_STEREOPEAK || typ == MIXT_STEREOVU)
+ {
+ int v, l, r;
+
+ /* Get the sample values and scale them to 0-144 dB range */
+ v = sblive_read_reg (devc, ctrl + GPR0, 0);
+ l = v >> 23;
+
+ v = sblive_read_reg (devc, ctrl + GPR0 + 1, 0);
+ r = v >> 23;
+
+ if (l < 0)
+ l = -l;
+ if (r < 0)
+ r = -r;
+ l = peak_cnv[l];
+ r = peak_cnv[r];
+
+ /* Reset values back to 0 */
+ sblive_write_reg (devc, ctrl + GPR0, 0, 0);
+ sblive_write_reg (devc, ctrl + GPR0 + 1, 0, 0);
+
+ return l | (r << 8);
+ }
+ return devc->gpr_values[ctrl];
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (typ)
+ {
+ case MIXT_STEREOSLIDER:
+ {
+ int left, right;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ if (left < 0)
+ left = 0;
+ if (left > 100)
+ left = 100;
+ if (right < 0)
+ right = 0;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ devc->gpr_values[ctrl] = value;
+
+ left = convert_fixpoint (left);
+ sblive_write_reg (devc, ctrl + GPR0, 0, left);
+ right = convert_fixpoint (right);
+ sblive_write_reg (devc, ctrl + GPR0 + 1, 0, right);
+ }
+ break;
+
+ case MIXT_ONOFF:
+ {
+ value = !!value;
+ devc->gpr_values[ctrl] = value;
+
+ sblive_write_reg (devc, ctrl + GPR0, 0, value);
+ sblive_write_reg (devc, ctrl + GPR0 + 1, 0, !value);
+ }
+ break;
+
+ case EMU_MIXT_EQ1:
+ case EMU_MIXT_EQ2:
+ case EMU_MIXT_EQ3:
+ case EMU_MIXT_EQ4:
+ {
+ int band;
+
+ band = typ & 3;
+ value = value & 0xff;
+ set_equalizer (devc, ctrl, band, value);
+ devc->gpr_values[ctrl] = value;
+ }
+ break;
+
+ default:
+ {
+ int tmp;
+
+ value = value & 0xff;
+ if (value > 100)
+ value = 100;
+
+ devc->gpr_values[ctrl] = value;
+
+ tmp = convert_fixpoint (value);
+ sblive_write_reg (devc, ctrl + GPR0, 0, tmp);
+ }
+ }
+
+ return value;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+sblive_set_vol (int dev, int ctrl, unsigned int cmd, int value)
+{
+ sblive_devc *devc = mixer_devs[dev]->hw_devc;
+ sblive_portc *portc;
+
+ if (ctrl < 0 || ctrl >= devc->n_audiodevs)
+ return OSS_EINVAL;
+
+ portc = &devc->portc[ctrl];
+
+ if (portc->input_type == ITYPE_SPDIF)
+ {
+ mixer_devs[dev]->modify_counter++;
+ return 100 | (100 << 8);
+ }
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+#ifdef TEST_3D
+ return (devc->portc[ctrl].playvol & 0x00ff) |
+ ((devc->portc[ctrl].playangle & 0xffff) << 16) |
+ ((devc->portc[ctrl].playdist & 0xff) << 8);
+#else
+ return devc->portc[ctrl].playvol & 0xff;
+#endif
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+#ifdef TEST_3D
+ int angle, dist;
+ angle = (value >> 16) & 0xffff; /* Rotation angle */
+ dist = (value >> 8) & 0xff; /* Distance */
+ value &= 0x00ff; /* Volume */
+
+ if (value < 0)
+ value = 0;
+ if (value > 100)
+ value = 100;
+
+ switch (portc->speaker_mode)
+ {
+ case SMODE_FRONT:
+ angle = 0;
+ dist = 50;
+ break;
+
+ case SMODE_SURR:
+ angle = 180;
+ dist = 50;
+ break;
+
+ case SMODE_FRONTREAR:
+ angle = 0;
+ dist = 50;
+ break;
+
+ case SMODE_3D:
+ break;
+ }
+ devc->portc[ctrl].playvol = value;
+ devc->portc[ctrl].playdist = dist;
+ devc->portc[ctrl].playangle = angle;
+
+ update_output_device (devc, &devc->portc[ctrl]);
+ return (value & 0x00ff) | (angle << 16) | ((dist & 0xff) << 8);
+#else
+ value &= 0xff; /* Only left channel */
+
+ if (value < 0)
+ value = 0;
+ if (value > 100)
+ value = 100;
+ devc->portc[ctrl].playvol = value;
+
+ update_output_device (devc, &devc->portc[ctrl]);
+ return value;
+
+#endif
+ }
+
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static int
+sblive_get_peak (int dev, int ctrl, unsigned int cmd, int value)
+{
+ sblive_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (ctrl < 0 || ctrl >= devc->n_audiodevs)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ int l, r, vol;
+
+ l = devc->portc[ctrl].vu_left & 0xff;
+ r = devc->portc[ctrl].vu_right & 0xff;
+#if 1
+ vol = devc->portc[ctrl].playvol;
+ /* if (vol<1) vol=5; */
+ l = (l * vol + 50) / 100;
+ r = (r * vol + 50) / 100;
+#endif
+ devc->portc[ctrl].vu_left = 0;
+ devc->portc[ctrl].vu_right = 0;
+
+ return peak_cnv[l] | (peak_cnv[r] << 8);
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+sblive_set_parm (int dev, int ctrl, unsigned int cmd, int value)
+{
+ sblive_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ switch (ctrl)
+ {
+ case 1:
+ return devc->autoreset;
+ case 2:
+ return devc->speaker_mode;
+ }
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case 1:
+ return devc->autoreset = !!(value);
+ case 2:
+ if (devc->speaker_mode != value)
+ {
+ int i;
+ for (i = 0; i < devc->n_audiodevs; i++)
+ devc->portc[i].resetvol = 1;
+ }
+ return devc->speaker_mode = value;
+ break;
+
+ }
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+create_soft_mixer (int dev)
+{
+ sblive_devc *devc = mixer_devs[dev]->hw_devc;
+ int group = 0, err, i, n;
+ char tmp[100];
+
+ if ((err = mixer_ext_create_control (dev, 0,
+ 1,
+ sblive_set_parm,
+ MIXT_ONOFF,
+ "SBLIVE_AUTORESET",
+ 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+#ifdef TEST_3D
+ n = 5;
+#else
+ n = 4;
+#endif
+ if ((err = mixer_ext_create_control (dev, 0,
+ 2,
+ sblive_set_parm,
+ MIXT_ENUM,
+ "SBLIVE_SPKMODE",
+ n,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ for (i = 0; i < devc->n_audiodevs; i++)
+ {
+ if (devc->n_audiodevs > devc->min_audiodevs)
+ {
+ /*
+ * Use the traditional dspN naming system for sliders.
+ */
+ if ((i % 8) == 0)
+ if ((group = mixer_ext_create_group (dev, 0, "/dev")) < 0)
+ return group;
+
+ sprintf (tmp, "@pcm%d", devc->portc[i].audiodev);
+ }
+ else
+ {
+ /*
+ * Use front/rear/etc naming style
+ */
+ if ((i % 8) == 0)
+ if ((group = mixer_ext_create_group (dev, 0, "pcm")) < 0)
+ return group;
+
+ switch (i)
+ {
+ case 0:
+ strcpy (tmp, "main");
+ break; /* Duplex device */
+ case 1:
+ strcpy (tmp, "front");
+ break;
+ case 2:
+ strcpy (tmp, "side");
+ break;
+ case 3:
+ strcpy (tmp, "C/L");
+ break;
+ case 4:
+ strcpy (tmp, "rear");
+ break;
+ }
+ }
+
+
+ if ((err = mixer_ext_create_control (dev, group, i, sblive_set_vol,
+#ifdef TEST_3D
+ MIXT_3D,
+#else
+ MIXT_SLIDER,
+#endif
+ tmp,
+ 100,
+ MIXF_PCMVOL | MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+ if ((err = mixer_ext_create_control (dev, group,
+ i,
+ sblive_get_peak,
+ MIXT_STEREOPEAK,
+ "-", 144, MIXF_READABLE)) < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+create_efx_mixer (int dev)
+{
+ sblive_devc *devc = mixer_devs[dev]->hw_devc;
+ int group = 0, err = 0, i, mode;
+ int group_created = 0;
+ int typ, maxval;
+
+ if (!devc->extinfo_loaded)
+ {
+ return 0;
+ }
+
+ if (devc->gpr == NULL)
+ {
+ return 0;
+ }
+
+ if (devc->mixer_group >= 0)
+ mixer_ext_truncate (dev, devc->mixer_group);
+ devc->mixer_group = -1;
+
+ if (devc->gpr->ngpr >= MAX_GPR_PARMS)
+ return OSS_EINVAL;
+
+ for (i = 0; i < devc->gpr->ngpr; i++)
+ {
+ if (devc->gpr->gpr[i].num >= MAX_GPR)
+ continue;
+
+ typ = devc->gpr->gpr[i].type;
+
+ if (typ == MIXT_GROUP)
+ {
+ if ((group =
+ mixer_ext_create_group (dev, 0, devc->gpr->gpr[i].name)) < 0)
+ return group;
+
+ if (!group_created)
+ devc->mixer_group = group;
+ group_created = 1;
+ continue;
+ }
+
+#if 0
+ if (!group_created)
+ {
+ cmn_err (CE_WARN, "Mixer initialization sequence error\n");
+ return OSS_EINVAL;
+ }
+#endif
+ mode = MIXF_READABLE;
+ maxval = 144;
+
+ switch (typ)
+ {
+ case EMU_MIXT_EQ1:
+ case EMU_MIXT_EQ2:
+ case EMU_MIXT_EQ3:
+ case EMU_MIXT_EQ4:
+ {
+ mode |= MIXF_WRITEABLE;
+ maxval = 255;
+ typ = MIXT_SLIDER;
+ }
+ break;
+
+ case MIXT_STEREOSLIDER:
+ case MIXT_SLIDER:
+ case MIXT_MONOSLIDER:
+ {
+ mode |= MIXF_WRITEABLE;
+ maxval = 100;
+ }
+ break;
+
+ case MIXT_STEREOVU:
+ typ = MIXT_STEREOPEAK;
+ break;
+
+ case MIXT_ONOFF:
+ {
+ mode |= MIXF_WRITEABLE;
+ maxval = 1;
+ }
+ break;
+ }
+
+ if (devc->gpr->gpr[i].name[0] == '_')
+ {
+ /* Hidden control */
+ if (strcmp (devc->gpr->gpr[i].name, "_PASSTHROUGH") == 0)
+ {
+ int ctrl = devc->gpr->gpr[i].num;
+ devc->passthrough_gpr = ctrl;
+
+ sblive_write_reg (devc, ctrl + GPR0, 0, 1);
+ sblive_write_reg (devc, ctrl + GPR0 + 1, 0, 0);
+ }
+ }
+ else
+ {
+ /* Visible control */
+ if ((err = mixer_ext_create_control (dev, group,
+ devc->gpr->gpr[i].num,
+ sblive_set_gpr, typ,
+ devc->gpr->gpr[i].name,
+ maxval, mode)) < 0)
+ return err;
+ }
+
+ if (!group_created)
+ devc->mixer_group = err;
+ group_created = 1;
+
+ if (is_special_gpr (devc->gpr->gpr[i].num))
+ {
+ sblive_set_gpr (dev, devc->gpr->gpr[i].num, SNDCTL_MIX_WRITE,
+ devc->gpr_values[devc->gpr->gpr[i].num]);
+ }
+ else
+ {
+ sblive_set_gpr (dev, devc->gpr->gpr[i].num, SNDCTL_MIX_WRITE,
+ devc->gpr->gpr[i].def);
+ }
+ }
+ return 0;
+}
+
+static int
+mixer_ext_init (int dev)
+{
+ sblive_devc *devc = mixer_devs[dev]->hw_devc;
+
+ devc->extinfo_loaded = 1;
+ create_soft_mixer (dev);
+ create_efx_mixer (dev);
+ return 0;
+}
+
+static int
+mixer_override (int dev, int audiodev, unsigned int cmd, int val)
+{
+ sblive_devc *devc = mixer_devs[dev]->hw_devc;
+ switch (cmd)
+ {
+ case SOUND_MIXER_READ_VOLUME:
+ return sblive_set_gpr (dev, GPR_VOLUME, SNDCTL_MIX_READ, 0);
+ break;
+
+ case SOUND_MIXER_WRITE_VOLUME:
+ return sblive_set_gpr (dev, GPR_VOLUME, SNDCTL_MIX_WRITE, val);
+ break;
+
+ case SOUND_MIXER_READ_PCM:
+ if (audiodev >= 0 && audiodev < num_audio_engines)
+ {
+ sblive_portc *portc = NULL;
+ int i;
+
+ for (i = 0; i < devc->n_audiodevs && portc == NULL; i++)
+ if (devc->portc[i].audiodev == audiodev)
+ portc = &devc->portc[i];
+
+ if (portc == NULL)
+ return OSS_EIO;
+
+ return portc->playvol | (portc->playvol << 8);
+ }
+ return sblive_set_gpr (dev, GPR_PCM, SNDCTL_MIX_READ, 0);
+ break;
+
+ case SOUND_MIXER_WRITE_PCM:
+ if (audiodev >= 0 && audiodev < num_audio_engines)
+ {
+ sblive_portc *portc = NULL;
+ int i, left, right;
+
+ for (i = 0; i < devc->n_audiodevs && portc == NULL; i++)
+ if (devc->portc[i].audiodev == audiodev)
+ portc = &devc->portc[i];
+
+ if (portc == NULL)
+ return OSS_EIO;
+
+ left = val & 0xff;
+ right = (val >> 8) & 0xff;
+
+ if (left < 0)
+ left = 0;
+ if (right < 0)
+ right = 0;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+
+ if (right > left)
+ left = right;
+ portc->playvol = left;
+ mixer_devs[devc->mixer_dev]->modify_counter++; /* Force update of mixer */
+ update_output_device (devc, portc);
+
+ return portc->playvol | (portc->playvol << 8);
+ }
+ return sblive_set_gpr (dev, GPR_PCM, SNDCTL_MIX_WRITE, val);
+ break;
+ }
+
+ return 0;
+}
+
+static const char *port_names[] =
+ { "front out", "side out", "center/lfe out", "rear out" };
+
+static const __inline__ char *
+get_port_name (sblive_devc * devc, int n)
+{
+ int max_names = 3;
+
+ if (devc->feature_mask & SB_AUDIGY)
+ max_names = 3;
+ if (devc->feature_mask & SB_LIVE)
+ max_names = 2;
+
+ n = n - 1;
+
+ if (n > max_names)
+ return "extra out";
+
+ return port_names[n];
+}
+
+static void
+unload_mpu (sblive_devc * devc)
+{
+ if (devc == NULL)
+ return;
+
+ if (devc->feature_mask & SB_AUDIGY)
+ unload_audigyuart (devc);
+ else
+ uart401_disable (&devc->uart401devc);
+}
+
+int
+oss_sblive_attach (oss_device_t * osdev)
+{
+ sblive_devc *devc;
+ int i, err;
+ int frontdev = -1, ndevs = 0;
+ int first_dev = -1;
+ unsigned char pci_irq_line, pci_revision /*, pci_latency */ ;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ unsigned int subvendor;
+ adev_p adev;
+ extern int sblive_devices;
+
+ int audiodevs_to_create = sblive_devices;
+
+ char tmp[64];
+
+ DDB (cmn_err (CE_CONT, "sblive_attach entered\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != PCI_VENDOR_ID_CREATIVE)
+ {
+ cmn_err (CE_WARN, "Unrecognized SB live vendor %x\n", vendor);
+ return 0;
+ }
+
+ if (device != PCI_DEVICE_ID_SBLIVE
+ && device != PCI_DEVICE_ID_AUDIGY
+ && device != PCI_DEVICE_ID_AUDIGY_CARDBUS
+ && device != PCI_DEVICE_ID_AUDIGYVALUE)
+ {
+ cmn_err (CE_WARN, "Unrecognized SB live device %x:%x\n", vendor,
+ device);
+ return 0;
+ }
+
+#ifdef AUDIGY_ONLY
+ if (device == PCI_DEVICE_ID_SBLIVE)
+ {
+ cmn_err (CE_CONT,
+ "Error: Due to hardware limitations SB Live is not\n");
+ cmn_err (CE_CONT, "supported under this hardware architecture.\n");
+ cmn_err (CE_CONT,
+ "Consider upgrading to SB Audigy which is supported.\n");
+ return 0;
+ }
+#endif
+
+ pci_read_config_dword (osdev, 0x2c, &subvendor);
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ memset (devc, 0, sizeof (*devc));
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ MUTEX_INIT (osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (osdev, devc->low_mutex, MH_DRV + 1);
+
+ devc->emu_page_shift = 1; /* Default page shift */
+
+ devc->card_name = "Generic SB Live!";
+ devc->subvendor = subvendor;
+
+ devc->min_audiodevs = 5; /* Audigy supports 7.1 */
+
+ if (device == PCI_DEVICE_ID_AUDIGYVALUE)
+ {
+ /* SOLWAY subvendor id is 0x10211103 */
+ if ((devc->subvendor == 0x10211102) || (devc->subvendor == 0x10211103))
+ devc->card_name = "SB Audigy4";
+ else
+ devc->card_name = "SB Audigy2 Value";
+ devc->feature_mask = SB_AUDIGY | SB_AUDIGY2 | SB_AUDIGY2VAL;
+ }
+ else if (device == PCI_DEVICE_ID_AUDIGY)
+ {
+ if (devc->subvendor >= 0x10021102 && devc->subvendor <= 0x20051102)
+ {
+ devc->card_name = "SB Audigy2";
+ devc->feature_mask = SB_AUDIGY | SB_AUDIGY2;
+ }
+ else
+ {
+ devc->card_name = "SB Audigy";
+ devc->feature_mask = SB_AUDIGY;
+ }
+ }
+ else if (device == PCI_DEVICE_ID_AUDIGY_CARDBUS)
+ {
+ if (devc->subvendor >= 0x10021102 && devc->subvendor <= 0x20051102)
+ {
+ devc->card_name = "SB Audigy2 ZS Notebook";
+ devc->feature_mask = SB_AUDIGY | SB_AUDIGY2;
+ }
+ else
+ {
+ devc->card_name = "SB Audigy";
+ devc->feature_mask = SB_AUDIGY;
+ }
+ DDB (cmn_err (CE_CONT,
+ "emu10k2 chip rev %d, pcb rev %d\n", pci_revision,
+ sblive_read_reg (devc, 0x5f, 0)));
+ }
+ else
+ {
+ devc->card_name = "SB Live";
+ devc->feature_mask = SB_LIVE;
+ devc->min_audiodevs = 4; /* Just 5.1 */
+ }
+
+ if (audiodevs_to_create < devc->min_audiodevs)
+ audiodevs_to_create = devc->min_audiodevs;
+ if (audiodevs_to_create > MAX_ADEV)
+ audiodevs_to_create = MAX_ADEV;
+
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+ devc->base &= ~0x3;
+
+ devc->gpr = NULL;
+ oss_register_device (osdev, devc->card_name);
+
+ devc->irq = pci_irq_line;
+
+ devc->page_map = NULL;
+ devc->vpage_map = NULL;
+ devc->nr_pages = 0;
+ devc->max_pages = 0;
+ devc->max_mem = 0;
+ devc->silent_page = NULL;
+ devc->subvendor = subvendor;
+ devc->passthrough_gpr = -1;
+
+ if ((err = oss_register_interrupts (devc->osdev, 0, sbliveintr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't register interrupt handler, err=%d\n", err);
+ return 0;
+ }
+
+ devc->mixer_group = -1;
+ devc->extinfo_loaded = 0;
+ devc->autoreset = 1;
+ devc->speaker_mode = SMODE_FRONTREAR;
+
+/*
+ * Init mixer
+ */
+ devc->mixer_dev =
+ ac97_install (&devc->ac97devc, devc->card_name, ac97_read, ac97_write,
+ devc, devc->osdev);
+ if (devc->mixer_dev < 0)
+ {
+ cmn_err (CE_WARN, "Mixer install failed - cannot continue\n");
+ return 0;
+ }
+
+ devc->ac97devc.mixer_ext = 0;
+ devc->ac97devc.spdifout_support = 0;
+ devc->ac97devc.spdifin_support = 0;
+ if (ac97_init_ext
+ (devc->mixer_dev, &devc->ac97devc, mixer_ext_init, 100) < 0)
+ {
+ cmn_err (CE_WARN, "Mixer ext install failed\n");
+ }
+
+ /* first set the AC97 PCM to max - otherwise sound is too low */
+ ac97_mixer_set (&devc->ac97devc, SOUND_MIXER_PCM, 100 | (100 << 8));
+
+ ac97_remove_control (&devc->ac97devc, BOGUS_MIXER_CONTROLS, 0);
+ ac97_override_control (&devc->ac97devc, SOUND_MIXER_VOLUME,
+ mixer_override, 100 | (100 << 8));
+ ac97_override_control (&devc->ac97devc, SOUND_MIXER_PCM,
+ mixer_override, 100 | (100 << 8));
+
+ attach_mpu (devc);
+
+/*
+ * Audio initialization
+ */
+ init_emu10k1 (devc);
+
+ for (i = 0; i < audiodevs_to_create; i++)
+ {
+ sblive_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE;
+ int fmts = 0;
+ devc->n_audiodevs = i + 1;
+
+ portc->memptr = devc->audio_memptr;
+ devc->audio_memptr += (DMABUF_SIZE + 4095) & ~4095;
+
+ if (devc->audio_memptr > AUDIO_MEMSIZE)
+ {
+ cmn_err (CE_WARN, "Audio memory block exhausted (%d/%d)\n",
+ devc->audio_memptr, AUDIO_MEMSIZE);
+ return OSS_ENOSPC;
+ }
+
+ if (i == 0)
+ {
+ strcpy (tmp, devc->card_name);
+ sprintf (tmp, "%s main", devc->card_name);
+ caps |= ADEV_DUPLEX;
+ }
+ else
+ {
+ sprintf (tmp, "%s %s", devc->card_name, get_port_name (devc, i));
+ caps |= ADEV_NOINPUT;
+#if 0
+ if (i >= devc->min_audiodevs)
+ caps |= ADEV_HWMIX;
+#endif
+ if (i >= devc->min_audiodevs + 1)
+ caps |= ADEV_SHADOW;
+ }
+ if ((devc->feature_mask & SB_AUDIGY) && i == audiodevs_to_create - 1)
+ {
+ sprintf (tmp, "%s raw S/PDIF (output only)", devc->card_name);
+ caps &= ~(ADEV_SHADOW /* | ADEV_HWMIX*/);
+ caps |= ADEV_SPECIAL;
+ fmts |= AFMT_AC3;
+ }
+#if 0
+ if (devc->feature_mask & SB_AUDIGY)
+ caps |= ADEV_COLD;
+#endif
+ if ((portc->audiodev =
+ oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp,
+ &sblive_audio_driver,
+ sizeof (audiodrv_t), caps,
+ fmts | AFMT_U8 | AFMT_S16_LE, devc, -1)) < 0)
+ {
+ portc->audiodev = -1;
+ return (i > 0);
+ }
+ else
+ {
+ int x;
+
+ adev = audio_engines[portc->audiodev];
+ adev->nrates=0;
+ for (x = 0; speed_tab[x].speed != 0; x++)
+ adev->rates[adev->nrates++] = speed_tab[x].speed;
+
+ if (i == 0)
+ first_dev = portc->audiodev;
+ adev->devc = devc;
+ adev->portc = portc;
+ adev->rate_source = first_dev;
+ adev->mixer_dev = devc->mixer_dev;
+ adev->min_rate = 8000;
+ adev->max_rate = 48000;
+
+ if (!(devc->feature_mask & SB_AUDIGY))
+ {
+ /*
+ * SB Live supports only 31 PCI address bits
+ */
+ adev->dmabuf_maxaddr = MEMLIMIT_31BITS;
+ }
+
+ portc->mode = 0;
+ adev->oformat_mask |= AFMT_AC3;
+ portc->input_type = ITYPE_ANALOG;
+ if ((devc->feature_mask & SB_AUDIGY) && i == audiodevs_to_create - 1)
+ portc->input_type = ITYPE_SPDIF;
+ if (i == 1)
+ frontdev = portc->audiodev;
+ if (i > 0)
+ ndevs++;
+
+ portc->playvol = 100;
+ portc->playangle = 0;
+ portc->playdist = 50;
+ portc->vu_left = 0;
+ portc->vu_right = 0;
+ portc->audio_active = 0;
+ portc->voice_chn = i * 2;
+ portc->port_number = i;
+ devc->voice_busy[i * 2] = 1;
+ devc->voice_busy[i * 2 + 1] = 1;
+ portc->resetvol = 0;
+ if (devc->feature_mask & SB_LIVE)
+ {
+/*
+ * Do not enable vmix by default on Live! It would cause enormous
+ * latencies because emu10k1 doesn't have working full/half buffer DMA
+ * interrupts.
+ */
+ adev->vmix_flags = VMIX_MULTIFRAG;
+ adev->max_intrate = 50;
+ adev->min_block = 4096;
+ }
+ else
+ {
+ adev->max_fragments = 2;
+ }
+
+ /*
+ * Hide vmix main volume control and peak meters if no
+ * real HW mixing devices are enabled.
+ */
+#if 0
+ if (audiodevs_to_create <= devc->min_audiodevs)
+ adev->vmix_flags |= VMIX_NOMAINVOL;
+#endif
+ adev->iformat_mask = AFMT_S16_LE; /* No 8 bit recording */
+
+ if (i == 0)
+ {
+ if (devc->feature_mask & SB_LIVE)
+ adev->magic = EMU10K1_MAGIC;
+ else
+ adev->magic = EMU10K2_MAGIC;
+ }
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, first_dev, -1, 0);
+#endif
+ }
+ adev->mixer_dev = devc->mixer_dev;
+ }
+
+#ifdef USE_REMUX
+ /* Install Remux (only 5.1 support for the time being) */
+ sprintf (tmp, "%s 5.1 output device", devc->card_name);
+ if (frontdev > 0 && ndevs >= 3) /* Have enough devices for 5.1 */
+ remux_install (tmp, devc->osdev, frontdev, frontdev + 1, frontdev + 2,
+ -1);
+#endif
+
+#ifndef NO_EMU10K1_SYNTH
+ sblive_install_synth (devc);
+#endif
+
+ touch_mixer (devc->mixer_dev);
+ init_effects (devc);
+
+ return 1;
+}
+
+int
+oss_sblive_detach (oss_device_t * osdev)
+{
+ sblive_devc *devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ devc = osdev->devc;
+
+ OUTL (devc->osdev, 0, devc->base + 0x0c); /* Intr enable (all off) */
+ OUTL (devc->osdev,
+ HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK |
+ HCFG_MUTEBUTTONENABLE, devc->base + 0x14);
+
+ sblive_write_reg (devc, ADCSR, 0, 0x0);
+ sblive_write_reg (devc, ADCBA, 0, 0x0);
+ sblive_write_reg (devc, ADCBA, 0, 0x0);
+
+ sblive_write_reg (devc, PTBA, 0, 0);
+
+#ifndef NO_EMU10K1_SYNTH
+ sblive_remove_synth (devc);
+#endif
+ if (devc->page_map != NULL)
+ CONTIG_FREE (devc->osdev, devc->page_map, devc->max_pages * 4, devc->page_map_dma_handle);
+ if (devc->vpage_map != NULL)
+ KERNEL_FREE (devc->vpage_map);
+ if (devc->silent_page != NULL)
+ CONTIG_FREE (devc->osdev, devc->silent_page, 4096, devc->silent_page_dma_handle);
+ devc->max_pages = 0;
+ devc->max_mem = 0;
+ devc->page_map = NULL;
+ devc->vpage_map = NULL;
+ devc->silent_page = NULL;
+ unload_mpu (devc);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+ oss_unregister_device (osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_sblive/oss_sblive.man b/kernel/drv/oss_sblive/oss_sblive.man
new file mode 100644
index 0000000..067a341
--- /dev/null
+++ b/kernel/drv/oss_sblive/oss_sblive.man
@@ -0,0 +1,226 @@
+NAME
+ oss_sblive - Creative Labs Sound Blaster Live/Audigy family driver.
+
+DESCRIPTION
+ Open Sound System driver for Creative Labs Sound Blaster Live!, Audigy,
+ Audigy2, Audigy2-Value and sound cards.
+
+ The sblive driver supports:
+
+ o 8-48Khz Playback/Recording
+ o 8 or 16 bits
+ o SPDIF digital output and Input
+ o Multi channel 5.1 (Live!) and 7.1 (Audigy) output.
+
+ AC3 passthrough is only supported on Audigy series of the soundcards.
+
+OTHER SIMILAR CARDS
+There are several Sound Blaster cards that are also called as Live or
+Audigy. However these cards are based on entirely different hardware design
+and they are not compatible with this driver.
+
+o Sound Blaster Live 5.1 card is used in some Dell machines but it's
+ driven by the emu10k1x driver.
+o Sound Blaster AudigyLS and Live 7.1 models are driven by the audigyls
+ driver of OSS.
+
+ SBLIVE COMBO SPDIF AND AUDIO JACKS
+Most models of Live! and Audigy cards have an orange combo jack that is
+used both for the analog center/LFE output and for digital DIN (S/PDIF)
+output. The output mode is selected by a driver configuration option
+(seel below) which should be set to proper value depending on the actual
+speaker configuration.
+
+o Noisy analog center/LFE output. The orange combo jack at the rear plate
+ of the Live/Audigy card is shared between the digital DIN and the analog
+ center/LFE outputs. In digital DIN mode (default) you will hear very noisy
+ output from the speakers connected to this output jack. If you have analog
+ center/LFE (subwoofer) speakers connected then you need to turn off the
+ sblive_digital_din (or audigy_digital_din) option.
+
+o There is a new configuration option to enable/disable the "digital DIN"
+ output. By default the digital DIN interface is enabled which disables the
+ center/LFE analog output (uses the same combo jack). By setting the
+ sblive_digital_din (or audigy_digital_din) option to 0 you can enable the
+ analog C/LFE output feature. When digital DIN is disabled you can still get
+ S/PDIF (or AC3) output from the digital (optical/coax) outputs of the
+ optional livedrive unit.
+
+ SBLIVE MIXER
+SB Live cards have actually two mixer chips. In OSS both of them are
+controlled together. However only limited set of features can be controlled
+using ordinary mixer programs (such as the mixer applet included in OSS).
+Majority of features can only be accessed using the ossmix and ossxmix
+programs included in OSS.
+
+The AC97 mixer is used to control volumes of the back bracket inputs (mic and
+line in) and the _analog_ CD input connector on the soundcard. The 'mic'
+volume controls the level of the rear bracket microphone input sent directly
+to the front (only front) speakers. The 'line' and 'cd' controls do the same
+for the back bracket line in connector and the on board analog CD input
+connector. It's usually recommended to set these volumes to 0.
+
+Another function of the AC97 mixer is selecting the signal that is passed to
+the master mixer (for example for recording). One of the 'mic', 'line' or
+'cd' signals can be routed to the master mixer by selecting that device as
+the recording source in the AC97 mixer. The 'rec' volume control slider can
+be used to adjust the signal strength. The 'igain' control doesn't usually
+have any effect but some hardware revisions may use it for controlling the
+microphone recording level.
+
+
+ SBLIVE MASTER MIXER
+Other mixer functions are handled by the DSP engine of the EMU 10k1 chip.
+Most input signals (including all digital signals and LiveDrive inputs).
+
+There are only two master mixer settings that can be controlled using all
+mixer programs. The 'vol' setting is the master output volume that affects
+both the front and rear speakers and the headphone output (digital output
+volumes are not affected). The 'pcm' setting controls volumes of all PCM
+playback channels (/dev/dsp#).
+
+In addition to volume sliders most inputs have a stereo VU meter pair
+(only in ossxmix) that can be used to monitor the input and to adjust the
+input levels properly.
+
+The master mixer consists of several sections that are:
+
+o Primary section: This section has two settings. The "spkmode" setting
+ selects how front/rear speakers are used for PCM playback (outputs from
+ programs using /dev/dsp#). The possible settings are FRONT, REAR and
+ FRONT+REAR. The default is FRONT+REAR. Change this setting if you like to
+ get PCM playback only from front or rear speakers. The "autoreset" flag is
+ used to control the "/dev" section.
+
+o "/dev" section: This section controls the volumes of each /dev/dsp# device
+ file supported by the device (there are 8 of them at this moment). These
+ volumes will return back to maximum every time the device is opened. However
+ this can be disabled by setting the 'autoreset' option to OFF. The ossxmix
+ program has special ability to show the application using the particular
+ /dev/dsp device (for layout reasons only the first 4 characters of the
+ program name are shown).
+
+o The equalizer section: This section controls the graphic equalizer for
+ front speakers only.
+
+o The front rear, and record sections: These three identical sections control
+ the levels of external inputs and PCM playback (/dev/dsp# devices) to be
+ sent to the front/rear speakers and to the recording device.
+ The CD Analog audio will only be heard from the FRONT speakers.
+
+ SBLIVE RECORDING
+Before recording anything you need to set the volumes in the recording
+section properly. To enable recording from the AC97 connected inputs
+(mic, line in and analog CD) use the AC97 mixer to select the desired input
+and then tune the input level using the rec (and igain) setting.
+
+Finally set the 'ac97' slider in the record section of the master mixer so
+that the recording level is suitable.
+
+The OSS drivers permit recording any application that's currently playing.
+
+To record audio that's playing on any of the SB Live channels:
+
+o Turn down the AC97 control in the "record" section. This prevents any audio
+ being fed to the soundcard from MIC/Line-in/CD-in from getting mixed with
+ the audio produced by the application that's currently playing.
+
+o Type ossrecord -s<sampling rate> -b<bits/sample> -c<channels> test.wav
+
+o To stop recording press <Ctrl-c> and then you can play back the test.wav
+ file using ossplay command.
+
+
+ RECORDING ISSUES:
+In most cases noise is caused by the microphone input or some other
+(unused) input. Use the ossxmix program to turn off all unused inputs and
+finally save the current mixer settings (see below).
+
+Hint: Look at the VU meter panels of ossxmix. It's usually very easy to
+locate the noise source by looking which input has some signal coming from
+it.
+
+WARNING! If you turn off some of the signals in recording section or the
+AC97 mixer section this affects all subsequent recordings. Remember
+to raise the volume prior doing any recording. After that decrease
+the volumes again if necessary.
+
+
+ SBLIVE HARDWARE MIXING
+You can use /dev/oss/oss_sblive0/ pcm0-pcm7 to play multiple audio programs
+using the hardware mixing.
+Simply specify the device name with the application. A simple test is
+to do the following:
+ ossplay -d/dev/oss/oss_sblive0/pcm0 <file1.wav> &
+ ossplay -d/dev/oss/oss_sblive0/pcm1 <file2.wav> &
+ ossplay -d/dev/oss/oss_sblive0/pcm2 <file3.wav> &
+
+You should hear all three wav files playing simultaneously.
+
+NOTE: Some apps may desire the old /dev/dspN names. e.g. /dev/dsp0 - /dev/dsp7.
+
+NOTE: You can increase the number of output devices from the standard 8 devices
+to 32 device. For this, run soundconf, select Set configuration options and
+look for the entry "sblive_device", now type any number between 1 and 32
+for the number of channels you wish. You can also do this manually by editing
+oss_sblive.conf and inserting sblive_devices=XX entry,
+ e.g.: sblive_devices=27
+
+ CDROM CONNNECTIONS
+There are two alternative ways to connect audio signal from a CD-ROM drive tor
+the SB Live soundcard. You can use a (three wire) analog cable or a (2 wire)
+digital cable. OSS now supports both of these choices. Note that there are
+separate mixer settings for both of these connections.
+
+The analog CD-ROM wire is connected to the AC97 code chip and this method
+works in most cases. To route the analog CD -input to the (front) speakers
+you need to raise the volume of the 'cd' control in mixer. However if you
+like to hear the analog CD input both from the front and rears speakers you
+need to do this in slightly different way (please read the description of
+the mixer above).
+
+The digital connection works only with CD-ROM drives that has support for it.
+Note that some CD-ROM drives having this digital output connector use a
+different signal level than the one required by SB Live. This means that the
+digital connection doesn't work with all CD-ROM drives (no sound). If you
+have problems with the digital connection you should use the analog one.
+When using the the digital CD input you may need to adjust the 'digcd'
+volumes using ossxmix (or ossmix).
+
+It should be noted that SB Live works internally at 48 kHz. This means that
+all S/PDIF input signals are automatically sample rate converted to 48 kHz.
+If you record from a 44.1 kHz (CD-ROM) and save the result to a 44.1 kHz
+file the signal will be sample rate converted twice. First from the 44.1 kHz
+input to internal 48 kHz and then back to 44.1 kHz. While the sample rate
+converter of SB Live is very precise this will cause some change. This should
+not be any problem when doing audio recordings but it may cause unwanted
+results when transferring digital data (such as AC3/DTS) using the S/PDIF
+the interface.
+
+CONFIGURATION OPTIONS
+o sblive_digital_din=<0|1> - This option is to enable/disable the "digital DIN"
+ output of SB Live. By default the digital DIN interface is disabled which
+ enables the center/LFE analog output (uses the same combo jack). By
+ setting the sblive_digital_din option to 0 you can enable the analog
+ Center/LFE output feature. When digital DIN is disabled you can still
+ get S/PDIF (or AC3) output from the digital (optical/coax) outputs of the
+ optional livedrive unit. Default: 0=analog output.
+
+o audigy_digital_din=<0|1> - same as "sblive_digital_din" option except for
+ the Audigy soundcards. Default: 1=digital output.
+
+o sblive_devices=<1..32> - Number of audio devices to be configured.
+
+
+LIMITATION
+o SB Live! devices will not work in Sparc systems due to PCI addressing
+ limitations. Only Audigy/Audigy2 models work under Sparc.
+o EMU Wavetable MIDI synthesizer is not supported
+o AC3 passthrough only supported on Audigy/Audigy but not on SB Live! devices.
+
+FILES
+CONFIGFILEPATH/oss_sblive.conf Device configuration file
+
+AUTHOR
+ 4Front Technologies
+
diff --git a/kernel/drv/oss_sblive/sblive.h b/kernel/drv/oss_sblive/sblive.h
new file mode 100644
index 0000000..a6a2ca7
--- /dev/null
+++ b/kernel/drv/oss_sblive/sblive.h
@@ -0,0 +1,535 @@
+/*
+ * Purpose: Global definitions for the SB Live/Audigy driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 USERLAND
+#include "uart401.h"
+#endif
+
+#define EMU10K1_MAGIC 0xe10001
+#define EMU10K2_MAGIC 0xe10002
+
+/* Audio */
+
+#if defined(OSR5) || defined(__bsdi__)
+#define MAX_ADEV 2
+#else
+#define MAX_ADEV 32 /* How many devices */
+#endif
+
+#define DMABUF_SIZE (64*1024) /* Maximum DMA buffer size supported */
+#define AUDIO_MAXVOICE (2*MAX_ADEV)
+#define AUDIO_MEMSIZE (MAX_ADEV*DMABUF_SIZE+4096) /* Audio buffer + silent page */
+#define SYNTH_MEMBASE AUDIO_MEMSIZE
+
+/* Synth */
+#define MAX_PATCH 256
+#define MAX_SAMPLE 512
+#define MAX_VOICE 64
+
+#define SYNTH_FIRSTVOICE AUDIO_MAXVOICE
+#define SYNTH_LASTVOICE (MAX_VOICE-1)
+
+/* Synth memory allocation */
+#define SBLIVE_MEMBLOCK_SIZE (128*1024) /* Default synth mem alloc chunk size */
+#define MIN_BLOCK_SIZE (8*1024)
+#define SBLIVE_MAX_MEMBLOCKS 1024 /* Max number of mem chunks to allocate */
+
+/* Hardware config register */
+
+#define HCFG_CODECFORMAT_MASK 0x00070000 /* CODEC format */
+#define HCFG_CODECFORMAT_AC97 0x00000000 /* AC97 CODEC format -- Primary Output */
+#define HCFG_CODECFORMAT_I2S 0x00010000 /* I2S CODEC format -- Secondary (Rear) Output */
+#define HCFG_GPINPUT0 0x00004000 /* External pin112 */
+#define HCFG_GPINPUT1 0x00002000 /* External pin110 */
+#define HCFG_GPOUTPUT_MASK 0x00001c00 /* External pins which may be controlled */
+#define HCFG_GPOUT0 0x00001000 /* set to enable digital out on 5.1 cards */
+#define HCFG_GPOUT1 0x00000800 /* IR */
+#define HCFG_GPOUT2 0x00000400 /* IR */
+#define HCFG_JOYENABLE 0x00000200 /* Internal joystick enable */
+#define HCFG_PHASETRACKENABLE 0x00000100 /* Phase tracking enable */
+ /* 1 = Force all 3 async digital inputs to use */
+ /* the same async sample rate tracker (ZVIDEO) */
+#define HCFG_AC3ENABLE_MASK 0x0x0000e0 /* AC3 async input control - Not implemented */
+#define HCFG_AC3ENABLE_ZVIDEO 0x00000080 /* Channels 0 and 1 replace ZVIDEO */
+#define HCFG_AC3ENABLE_CDSPDIF 0x00000040 /* Channels 0 and 1 replace CDSPDIF */
+#define HCFG_AC3ENABLE_GPSPDIF 0x00000020 /* Channels 0 and 1 replace GPSPDIF */
+#define HCFG_AUTOMUTE 0x00000010 /* When set, the async sample rate convertors */
+ /* will automatically mute their output when */
+ /* they are not rate-locked to the external */
+ /* async audio source */
+#define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */
+ /* NOTE: This should generally never be used. */
+#define HCFG_LOCKTANKCACHE_MASK 0x00000004 /* 1 = Cancel bustmaster accesses to tankcache */
+ /* NOTE: This should generally never be used. */
+#define HCFG_LOCKTANKCACHE 0x01020014
+#define HCFG_MUTEBUTTONENABLE 0x00000002 /* 1 = Master mute button sets AUDIOENABLE = 0. */
+ /* NOTE: This is a 'cheap' way to implement a */
+ /* master mute function on the mute button, and */
+ /* in general should not be used unless a more */
+ /* sophisticated master mute function has not */
+ /* been written. */
+#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
+ /* Should be set to 1 when the EMU10K1 is */
+ /* completely initialized. */
+#define A_HCFG_VMUTE 0x00004000
+#define A_HCFG_AUTOMUTE 0x00008000
+#define A_HCFG_XM 0x00040000 /* Xtended address mode */
+
+/*
+ * GPIO bit definitions (global register 0x18) for Audigy.
+ */
+
+#define A_IOCFG_GPOUT0 0x0044 /* analog/digital? */
+#define A_IOCFG_GPOUT1 0x0002 /* IR */
+#define A_IOCFG_GPOUT2 0x0001 /* IR */
+
+/* Status bits (read only) */
+#define GPIO_VERSAPLUGGED 0x2000 /* Center/LFE/digital */
+#define GPIO_FRONTPLUGGED 0x4000
+#define GPIO_REARPLUGGED 0x8000
+#define GPIO_HEADPHPLUGGED 0x0100
+#define GPIO_ANALOG_MUTE 0x0040
+#define GPIO_DIGITAL_ENABLE 0x0004 /* Center/lfe (0) or digital (1) switch */
+
+#define FILL_PAGE_MAP_ENTRY(e, v) devc->page_map[e] = LSWAP (((v) << devc->emu_page_shift) | (e));
+/*
+ * Audio block registers
+ */
+
+#define CPF 0x000 /* DW:cnl Current pitch and fraction */
+#define CPF_CURRENTPITCH_MASK 0xffff0000 /* Current pitch (linear, 0x4000 == unity pitch shift) */
+#define CPF_CURRENTPITCH 0x10100000
+#define CPF_STEREO_MASK 0x00008000 /* 1 = Even channel interleave, odd channel locked */
+#define CPF_STOP_MASK 0x00004000 /* 1 = Current pitch forced to 0 */
+#define CPF_FRACADDRESS_MASK 0x00003fff /* Linear fractional address of the current channel */
+
+
+#define PTAB 0x001 /* DW:cnl Pitch target and sends A and B */
+#define PTRX_PITCHTARGET_MASK 0xffff0000 /* Pitch target of specified channel */
+#define PTRX_PITCHTARGET 0x10100001
+#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00 /* Linear level of channel output sent to FX send bus A */
+#define PTRX_FXSENDAMOUNT_A 0x08080001
+#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff /* Linear level of channel output sent to FX send bus B */
+#define PTRX_FXSENDAMOUNT_B 0x08000001
+
+
+#define CVCF 0x002 /* DW:cnl Curr vol and curr filter cutoff */
+#define VTFT 0x003 /* DW:cnl Volume tgt and filter cutoff tgt */
+#define Z2 0x004 /* DW:cnl Filter delay memory 2 */
+#define Z1 0x005 /* DW:cnl Filter delay memory 1 */
+#define SCSA 0x006 /* DW:cnl Send C and Start addr */
+#define SDL 0x007 /* DW:cnl Send D and Loop addr */
+#define QKBCA 0x008 /* DW:cnl Filter Q, ROM, etc */
+#undef CCR
+#define CCR 0x009
+#define CCR_CACHEINVALIDSIZE 0x07190009
+#define CCR_CACHEINVALIDSIZE_MASK 0xfe000000 /* Number of invalid samples cache for this channel */
+#define CCR_CACHELOOPFLAG 0x01000000 /* 1 = Cache has a loop service pending */
+#define CCR_INTERLEAVEDSAMPLES 0x00800000 /* 1 = A cache service will fetch interleaved samples */
+#define CCR_WORDSIZEDSAMPLES 0x00400000 /* 1 = A cache service will fetch word sized samples */
+#define CCR_READADDRESS 0x06100009
+#define CCR_READADDRESS_MASK 0x003f0000 /* Location of cache just beyond current cache service */
+#define CCR_LOOPINVALSIZE 0x0000fe00 /* Number of invalid samples in cache prior to loop */
+ /* NOTE: This is valid only if CACHELOOPFLAG is set */
+#define CCR_LOOPFLAG 0x00000100 /* Set for a single sample period when a loop occurs */
+#define CCR_CACHELOOPADDRHI 0x000000ff /* DSL_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set */
+
+#define CLP 0x00a
+#define SRHE 0x07c
+#define STHE 0x07d
+#define SRDA 0x07e
+#define STDA 0x07f
+#define L_FXRT 0x00b
+#define FXRT ((devc->feature_mask&SB_AUDIGY)? 0x7d:0x00b) /* W:cnl */
+#define MAPA 0x00c
+#define MAPB 0x00d
+#define VEV 0x010 /* W:cnl */
+#define VEHA 0x011 /* W:cnl */
+#define VEDS 0x012 /* W:cnl */
+#define MLV 0x013 /* W:cnl */
+#define MEV 0x014 /* W:cnl */
+#define MEHA 0x015 /* W:cnl */
+#define MEDS 0x016 /* W:cnl */
+#define VLV 0x017 /* W:cnl */
+#define IP 0x018 /* W:cnl */
+#define IFA 0x019 /* W:cnl */
+#define PEFE 0x01a /* W:cnl */
+#define PEFE_PITCHAMOUNT_MASK 0x0000ff00 /* Pitch envlope amount */
+#define PEFE_PITCHAMOUNT 0x0808001a
+#define PEFE_FILTERAMOUNT_MASK 0x000000ff /* Filter envlope amount */
+#define PEFE_FILTERAMOUNT 0x0800001a
+
+#define VFM 0x01b /* W:cnl */
+#define TMFQ 0x01c /* W:cnl */
+#define VVFQ 0x01d /* W:cnl */
+#define TMPE 0x01e /* W:cnl */
+#define CD0 0x020 /* DW:cnl (16 registers) */
+#define PTBA 0x040 /* DW:nocnl */
+#define TCBA 0x041 /* DW:nocnl */
+#define ADCSR 0x042 /* B:nocnl */
+#define FXWC 0x043 /* DW:nocnl */
+#define TCBS 0x044 /* B:nocnl */
+#define MBA 0x045 /* DW:nocnl */
+#define ADCBA 0x046 /* DW:nocnl */
+#define FXBA 0x047 /* DW:nocnl */
+
+#define MBS 0x049 /* B:nocnl */
+#define ADCBS 0x04a /* B:nocnl */
+#define FXBS 0x04b /* B:nocnl */
+#define CSBA 0x4c
+#define CSDC 0x4d
+#define CSFE 0x4e
+#define CSHG 0x4f
+#define CDCS 0x050 /* DW:nocnl */
+#define GPSCS 0x051 /* DW:nocnl */
+#define DBG 0x052 /* DW:nocnl */
+#define AUDIGY_DBG 0x053 /* DW:nocnl */
+#define SCS0 0x054 /* DW:nocnl */
+#define SCS1 0x055 /* DW:nocnl */
+#define SCS2 0x056 /* DW:nocnl */
+#define CLIEL 0x058 /* DW:nocnl */
+#define CLIEH 0x059 /* DW:nocnl */
+#define CLIPL 0x05a /* DW:nocnl */
+#define CLIPH 0x05b /* DW:nocnl */
+#define SOLL 0x05c /* DW:nocnl */
+#define SOLH 0x05d /* DW:nocnl */
+#define SOC 0x05e /* DW:nocnl */
+#define AC97SLOT 0x05f
+#define AC97SLOT_REAR_RIGHT 0x01
+#define AC97SLOT_REAR_LEFT 0x02
+#define AC97SLOT_CENTER 0x10
+#define AC97SLOT_LFE 0x20
+#define CDSRCS 0x060 /* DW:nocnl */
+#define GPSRCS 0x061 /* DW:nocnl */
+#define ZVSRCS 0x062 /* DW:nocnl */
+#define ADCIDX 0x063 /* W:nocnl */
+#define MIDX 0x064 /* W:nocnl */
+#define FXIDX 0x065 /* W:nocnl */
+
+/* Half loop interrupt registers (audigy only) */
+#define HLIEL 0x066 /* DW:nocnl */
+#define HLIEH 0x067 /* DW:nocnl */
+#define HLIPL 0x068 /* DW:nocnl */
+#define HLIPH 0x069 /* DW:nocnl */
+#define GPR0 ((devc->feature_mask&SB_LIVE)? 0x100:0x400) /* DW:nocnl */
+#define TMA0 0x300 /* Tank memory */
+#define UC0 ((devc->feature_mask&SB_LIVE) ? 0x400:0x600) /* DSM microcode memory */
+
+/* Interrupt enable register */
+#define IE 0x0c
+# define IE_RXA 0x00000001
+# define IE_IT 0x00000004
+# define IE_AB 0x00000040
+
+/* EMU10K2 MIDI UART */
+#define MUADAT 0x070
+#define MUACMD 0x071
+#define MUASTAT MUACMD
+
+/* EMU10K2 S/PDIF recording buffer */
+#define SPRI 0x6a
+#define SPRA 0x6b
+#define SPRC 0x6c
+
+#define EHC 0x76 /* Audigy 2 */
+
+#define SRHE 0x07c
+#define STHE 0x07d
+#define SRDA 0x07e
+
+#define HCFG_GPOUT0 0x00001000 /* set to enable digital out on 5.1 cards */
+#define HCFG_GPOUT1 0x00000800 /* IR on SBLive */
+#define HCFG_GPOUT2 0x00000400 /* IR on SBLive */
+#define HCFG_JOYENABLE 0x00000200 /* Internal joystick enable */
+
+#define A_IOCFG_GPOUT0 0x0044 /* analog/digital? */
+#define A_IOCFG_GPOUT1 0x0002 /* IR on Audigy */
+#define A_IOCFG_GPOUT2 0x0001 /* IR on Audigy */
+
+#define ROM0 0x00000000 /* interpolation ROM 0 */
+#define ROM1 0x02000000 /* interpolation ROM 1 */
+#define ROM2 0x04000000 /* interpolation ROM 2 */
+#define ROM3 0x06000000 /* interpolation ROM 3 */
+#define ROM4 0x08000000 /* interpolation ROM 4 */
+#define ROM5 0x0A000000 /* interpolation ROM 5 */
+#define ROM6 0x0C000000 /* interpolation ROM 6 */
+#define ROM7 0x0E000000 /* interpolation ROM 7 */
+#define BYTESIZE 0x01000000 /* byte sound memory */
+
+#define MAX_GPR 256
+#define MAX_GPR_PARMS 60
+#define MAX_CONST_PARMS 128
+#define GPR_NAME_SIZE 32
+typedef struct
+{
+ char name[GPR_NAME_SIZE];
+ unsigned int num;
+ int type;
+ int def;
+}
+gpr_t;
+
+typedef struct
+{
+ unsigned int gpr;
+ int value;
+}
+const_t;
+
+typedef struct
+{
+ unsigned int ngpr;
+
+ gpr_t gpr[MAX_GPR_PARMS];
+}
+gpr_info;
+
+typedef struct
+{
+ unsigned int nconst;
+
+ const_t consts[MAX_CONST_PARMS];
+}
+const_info;
+
+typedef struct sblive_portc
+{
+ int audiodev;
+ int mode;
+ int input_type;
+#define ITYPE_ANALOG 0
+#define ITYPE_SPDIF 1
+ int uses_spdif; /* This device uses the S/PDIF passthrough channel */
+ int audio_active;
+ volatile int trigger_bits;
+ int format, speed, channels;
+ int speedsel;
+
+ int voice_chn;
+ int port_number;
+ int out_sz; /* Output sample size */
+ int in_szbits;
+ unsigned long rec_starttime;
+
+ /* 3D soft mixer */
+ int playvol, playangle, playdist;
+ int vu_left, vu_right;
+ int speaker_mode;
+#define SMODE_FRONT 0 /* Front speakers only */
+#define SMODE_SURR 1 /* Rear speakers only */
+#define SMODE_FRONTREAR 2 /* Front and rear speakers */
+#define SMODE_BIND 3 /* Use channel bindings */
+#define SMODE_3D 4 /* 3D positioning */
+ int binding;
+ unsigned char *routing;
+ int resetvol;
+ int memptr;
+}
+sblive_portc;
+
+typedef struct
+{
+ int active;
+ int program;
+ int sample;
+ int note_num, note_freq, orig_freq;
+ int velosity;
+ struct patch_info *patch;
+ int sample_ptr;
+ int fixed_pitch;
+ int main_vol, expression_vol, panning, frontrear, bender, bender_range;
+}
+sblive_voice_t;
+
+typedef struct sblive_devc
+{
+ oss_native_word base;
+ int irq;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+ oss_device_t *osdev;
+ char *card_name;
+
+ /*
+ * Device feature mask tells which kind of features are suported by the
+ * hardware. Audigy2/2val have multiple bits set while Live! has just
+ * the SB_LIVE bits. So Features of Audigy will be reported by Audigy2/val
+ * too.
+ */
+ int feature_mask;
+#define SB_LIVE 1
+#define SB_AUDIGY 2
+#define SB_AUDIGY2 4
+#define SB_AUDIGY2VAL 8
+ int mpu_attached;
+
+ int *page_map; /* Table for up to 8k pointers to pages of 4k */
+ unsigned char **vpage_map; /* Virtual address map */
+ oss_dma_handle_t page_map_dma_handle;
+ int emu_page_shift;
+ int max_mem, max_pages, nr_pages;
+ unsigned int subvendor;
+/*
+ * Mixer
+ */
+ int mixer_dev;
+ ac97_devc ac97devc;
+ int input_routing_pc;
+ int input_sel; /* 0=AC97 */
+ gpr_info *gpr;
+ int mixer_group;
+ int gpr_values[MAX_GPR];
+ int extinfo_loaded;
+ int passthrough_gpr;
+ int vu_tmp, vu_tmp2;
+
+/*
+ * Audio
+ */
+
+ int n_audiodevs;
+ int min_audiodevs;
+ int audio_memptr;
+ int *silent_page;
+ oss_dma_handle_t silent_page_dma_handle;
+ oss_native_word silent_page_phys;
+
+ sblive_portc portc[MAX_ADEV + 2];
+ int recording_dev;
+ int spdif_busy;
+
+ int autoreset;
+ int speaker_mode;
+
+/*
+ * Wave table RAM alloc structures
+ */
+ int memblock_size; /* Size of blocks to be allocated */
+ int num_memblocks;
+ void *memblocks[SBLIVE_MAX_MEMBLOCKS];
+ int memblock_sizes[SBLIVE_MAX_MEMBLOCKS];
+ int total_memblock_size;
+
+/*
+ * Audigy UART
+ */
+ oss_midi_inputbyte_t midi_input_intr;
+ int midi_opened, midi_disabled;
+ volatile unsigned char input_byte;
+ int midi_dev;
+ int sysex_p;
+ unsigned char sysex_buf[20];
+ uart401_devc uart401devc;
+
+/*
+ * Wave table
+ */
+
+ int synthdev;
+ int synth_open;
+ int synth_membase, synth_memlimit, synth_memptr, synth_memtop;
+ unsigned int voice_busy[2];
+ int free_sample;
+ struct patch_info *samples;
+ long sample_ptrs[MAX_SAMPLE + 1];
+ int programs[MAX_PATCH];
+
+ sblive_voice_t voices[MAX_VOICE];
+
+}
+sblive_devc;
+
+/*
+ * Private ioctl() interface
+ */
+
+typedef struct
+{
+ unsigned int reg;
+ unsigned int chn;
+ unsigned int value;
+}
+sblive_reg;
+
+typedef struct
+{
+ int magic;
+ int feature_mask;
+ int size; /* # of instructions */
+ unsigned int code[1024];
+ gpr_info parms;
+ const_info consts;
+}
+emu10k1_file;
+
+typedef unsigned int sblive_code[512];
+
+#define SBLIVE_READREG __SIOWR('L', 1, sblive_reg)
+#define SBLIVE_WRITEREG __SIOW ('L', 2, sblive_reg)
+#define SBLIVE_WRITECODE1 __SIOW ('L', 3, sblive_code)
+#define SBLIVE_WRITECODE2 __SIOW ('L', 4, sblive_code)
+#define SBLIVE_WRITEPARMS __SIOW ('L', 5, gpr_info)
+#define SBLIVE_WRITECONST __SIOW ('L', 6, const_info)
+#define SBLIVE_GETCHIPTYPE __SIOR ('L', 7, int)
+#define SBLIVE_WRITEGPIO __SIOW ('L', 8, int)
+#define SBLIVE_READGPIO __SIOR ('L', 9, int)
+
+#define EMU_MIXT_EQ1 0x10000000
+#define EMU_MIXT_EQ2 0x10000001
+#define EMU_MIXT_EQ3 0x10000002
+#define EMU_MIXT_EQ4 0x10000003
+
+/*
+ * Overridden mixer controls (GPR registers)
+ * Note that these definitions heve to be kept in sync with
+ * init_compiler() routine of sndkit/sblive/asm10k1.c and the
+ * mixer_override() routine of sblive.c.
+ */
+#define GPR_DUMMY 0 /* 2 locations reserved for NULL control */
+#define GPR_PCM 2 /* 2 locations required for stereo slider */
+#define GPR_VOLUME 4 /* 2 locations required for stereo slider */
+#define NEXT_FREE_GPR 6 /* Needs to be 32 or below so that SPECIAL_GPRS works */
+#define SPECIAL_GPRS ((1<<GPR_PCM) | (1<<GPR_VOLUME))
+
+#ifdef OSS_BIG_ENDIAN
+static __inline__ unsigned int
+swap_int (unsigned int x)
+{
+ return ((x & 0x000000ff) << 24) |
+ ((x & 0x0000ff00) << 8) |
+ ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
+}
+
+static __inline__ unsigned short
+swap_short (unsigned short x)
+{
+ return ((x | 0xff) << 8) | ((x >> 8) & 0xff);
+}
+
+#define LSWAP(x) swap_int(x)
+#define SSWAP(x) swap_short(x)
+#else
+#define LSWAP(x) x
+#define SSWAP(x) x
+#endif
+extern void sblive_set_loop_stop (sblive_devc * devc, int voice, int s);
+extern void sblive_set_voice_intr (sblive_devc * devc, int voice, int s);
+extern void sblive_write_reg (sblive_devc * devc, int reg, int chn,
+ unsigned int value);
+extern unsigned int sblive_read_reg (sblive_devc * devc, int reg, int chn);
+extern void sblive_init_voice (sblive_devc * devc, int chn);
+extern void sblive_synth_interrupt (sblive_devc * devc);
+extern int sblive_get_voice_loopintr (sblive_devc * devc, int voice);
+extern int sblive_get_voice_halfloopintr (sblive_devc * devc, int voice);
diff --git a/kernel/drv/oss_sbpci/.devices b/kernel/drv/oss_sbpci/.devices
new file mode 100644
index 0000000..4a38255
--- /dev/null
+++ b/kernel/drv/oss_sbpci/.devices
@@ -0,0 +1,5 @@
+oss_sbpci pci1102,8938 Creative Ectiva EV1938
+oss_sbpci pci1274,1371 Creative AudioPCI97 (ES1371/ES1373)
+oss_sbpci pci1274,5880 Creative Sound Blaster PCI128 (5880B)
+oss_sbpci pci1274,8001 Creative Sound Blaster PCI128 (CT5880)
+oss_sbpci pci1274,8002 Creative Sound Blaster PCI128 (5880A)
diff --git a/kernel/drv/oss_sbpci/.name b/kernel/drv/oss_sbpci/.name
new file mode 100644
index 0000000..36ff069
--- /dev/null
+++ b/kernel/drv/oss_sbpci/.name
@@ -0,0 +1 @@
+Creative AudioPCI97 (ES1371/ES1373/EV1938)
diff --git a/kernel/drv/oss_sbpci/.params b/kernel/drv/oss_sbpci/.params
new file mode 100644
index 0000000..5d4d7b5
--- /dev/null
+++ b/kernel/drv/oss_sbpci/.params
@@ -0,0 +1,12 @@
+int apci_latency=0;
+/*
+ * Set the latency to 32, 64, 96, 128 clocks - some APCI97 devices exhibit
+ * garbled audio in some cases and setting the latency to higer values fixes it
+ * Values: 32, 64, 96, 128 - Default: 64 (or defined by bios)
+ */
+
+int apci_spdif=0;
+/*
+ * Enable SPDIF port on SoundBlaster 128D or Sound Blaster Digital-4.1 models
+ * Values: 1=Enable 0=Disable Default: 0
+ */
diff --git a/kernel/drv/oss_sbpci/oss_sbpci.c b/kernel/drv/oss_sbpci/oss_sbpci.c
new file mode 100644
index 0000000..c4bea9f
--- /dev/null
+++ b/kernel/drv/oss_sbpci/oss_sbpci.c
@@ -0,0 +1,1404 @@
+/*
+ * Purpose: Creative/Ensoniq AudioPCI97 driver (ES1371/ES1373)
+ *
+ * This driver is used with the original Ensoniq AudioPCI97 card and many
+ * PCI based Sound Blaster cards by Creative Technologies. For example
+ * Sound Blaster PCI128 and Creative/Ectiva EV1938.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_sbpci_cfg.h"
+#include "midi_core.h"
+#include "sbpci.h"
+#include "ac97.h"
+#include "oss_pci.h"
+
+
+extern int apci_latency;
+extern int apci_spdif;
+
+#define ENSONIQ_VENDOR_ID 0x1274
+#define ECTIVA_VENDOR_ID 0x1102
+#define ENSONIQ_ES1371 0x1371
+#define ENSONIQ_ES5880 0x8001
+#define ENSONIQ_ES5880A 0x8002
+#define ENSONIQ_ES5880B 0x5880
+#define ECTIVA_ES1938 0x8938
+
+#define MAX_PORTC 2
+
+typedef struct apci97_portc
+{
+
+ /* Audio parameters */
+ int audiodev;
+ int open_mode;
+ int trigger_bits;
+ int audio_enabled;
+ int speed, bits, channels;
+ int atype; /* 0=DAC/ADC, 1=Synth */
+}
+apci97_portc;
+
+typedef struct apci97_devc
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex, low_mutex;
+ oss_native_word base;
+ int irq;
+ char *chip_name;
+ int revision;
+
+ apci97_portc portc[MAX_PORTC];
+/*
+ * Mixer
+ */
+ ac97_devc ac97devc;
+
+/*
+ * MIDI
+ */
+ int midi_opened;
+ int midi_dev;
+ oss_midi_inputbyte_t midi_input_intr;
+}
+apci97_devc;
+
+
+void SRCRegWrite (apci97_devc * devc, unsigned short reg, unsigned short val);
+void SRCSetRate (apci97_devc * devc, unsigned char base, unsigned short rate);
+
+
+static int
+ac97_read (void *devc_, int wAddr)
+{
+ apci97_devc *devc = devc_;
+ int i, dtemp, dinit;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ dtemp = INL (devc->osdev, devc->base + CONC_dCODECCTL_OFF);
+ /* wait for WIP to go away saving the current state for later */
+ for (i = 0; i < 0x100UL; ++i)
+ if (!(INL (devc->osdev, devc->base + CONC_dCODECCTL_OFF) & (1UL << 30)))
+ break;
+
+ /* write addr w/data=0 and assert read request ... */
+
+ /* save the current state for later */
+ dinit = INL (devc->osdev, devc->base + CONC_dSRCIO_OFF);
+
+ /* enable SRC state data in SRC mux */
+ for (i = 0; i < 0x100UL; ++i)
+ if (!
+ ((dtemp =
+ INL (devc->osdev, devc->base + CONC_dSRCIO_OFF)) & SRC_BUSY))
+ break;
+ OUTL (devc->osdev, (dtemp & SRC_CTLMASK) | 0x00010000UL,
+ devc->base + CONC_dSRCIO_OFF);
+
+ /* wait for a SAFE time to write a read request and then do it, dammit */
+
+ for (i = 0; i < 0x100UL; ++i)
+ {
+ if ((INL (devc->osdev, devc->base + CONC_dSRCIO_OFF) & 0x00070000UL) ==
+ 0x00010000UL)
+ break;
+ }
+
+ OUTL (devc->osdev,
+ ((int) wAddr << 16) | (1UL << 23), devc->base + CONC_dCODECCTL_OFF);
+
+ /* restore SRC reg */
+ for (i = 0; i < 0x100UL; ++i)
+ if (!
+ ((dtemp =
+ INL (devc->osdev, devc->base + CONC_dSRCIO_OFF)) & SRC_BUSY))
+ break;
+ OUTL (devc->osdev, dinit, devc->base + CONC_dSRCIO_OFF);
+
+ /* now wait for the stinkin' data (RDY) */
+ for (i = 0; i < 0x100UL; ++i)
+ if (INL (devc->osdev, devc->base + CONC_dCODECCTL_OFF) & (1UL << 31))
+ break;
+ dtemp = INL (devc->osdev, devc->base + CONC_dCODECCTL_OFF);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return dtemp & 0xffff;
+}
+
+static int
+ac97_write (void *devc_, int wAddr, int wData)
+{
+ apci97_devc *devc = devc_;
+ int i, dtemp, dinit;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ /* wait for WIP to go away */
+ for (i = 0; i < 0x100UL; ++i)
+ if (!(INL (devc->osdev, devc->base + CONC_dCODECCTL_OFF) & (1UL << 30)))
+ break;
+
+ /* save the current state for later */
+ dinit = INL (devc->osdev, devc->base + CONC_dSRCIO_OFF);
+
+ dtemp = INL (devc->osdev, devc->base + CONC_dSRCIO_OFF);
+ /* enable SRC state data in SRC mux */
+ for (i = 0; i < 0x100UL; ++i)
+ if (!
+ ((dtemp =
+ INL (devc->osdev, devc->base + CONC_dSRCIO_OFF)) & SRC_BUSY))
+ break;
+ OUTL (devc->osdev, (dtemp & SRC_CTLMASK) | 0x00010000UL,
+ devc->base + CONC_dSRCIO_OFF);
+
+ /* wait for a SAFE time to write addr/data and then do it, dammit */
+ for (i = 0; i < 0x100UL; ++i)
+ {
+ if ((INL (devc->osdev, devc->base + CONC_dSRCIO_OFF) & 0x00070000UL) ==
+ 0x00010000UL)
+ break;
+ }
+
+ OUTL (devc->osdev, ((int) wAddr << 16) | wData,
+ devc->base + CONC_dCODECCTL_OFF);
+
+ /* restore SRC reg */
+ for (i = 0; i < 0x100UL; ++i)
+ if (!(INL (devc->osdev, devc->base + CONC_dSRCIO_OFF) & SRC_BUSY))
+ break;
+ OUTL (devc->osdev, dinit, devc->base + CONC_dSRCIO_OFF);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return 0;
+}
+
+
+void
+SRCInit (apci97_devc * devc)
+{
+ int i;
+
+ /* Clear all SRC RAM then init - keep SRC disabled until done */
+ for (i = 0; i < SRC_IOPOLL_COUNT; ++i)
+ if (!(INL (devc->osdev, devc->base + CONC_dSRCIO_OFF) & SRC_BUSY))
+ break;
+ OUTL (devc->osdev, SRC_DISABLE, devc->base + CONC_dSRCIO_OFF);
+
+ for (i = 0; i < 0x80; ++i)
+ SRCRegWrite (devc, (unsigned short) i, 0U);
+
+ SRCRegWrite (devc, SRC_SYNTH_BASE + SRC_TRUNC_N_OFF, 16 << 4);
+ SRCRegWrite (devc, SRC_SYNTH_BASE + SRC_INT_REGS_OFF, 16 << 10);
+ SRCRegWrite (devc, SRC_DAC_BASE + SRC_TRUNC_N_OFF, 16 << 4);
+ SRCRegWrite (devc, SRC_DAC_BASE + SRC_INT_REGS_OFF, 16 << 10);
+ SRCRegWrite (devc, SRC_SYNTH_VOL_L, 1 << 12);
+ SRCRegWrite (devc, SRC_SYNTH_VOL_R, 1 << 12);
+ SRCRegWrite (devc, SRC_DAC_VOL_L, 1 << 12);
+ SRCRegWrite (devc, SRC_DAC_VOL_R, 1 << 12);
+ SRCRegWrite (devc, SRC_ADC_VOL_L, 1 << 12);
+ SRCRegWrite (devc, SRC_ADC_VOL_R, 1 << 12);
+
+ /* default some rates */
+ SRCSetRate (devc, SRC_SYNTH_BASE, 8000);
+ SRCSetRate (devc, SRC_DAC_BASE, 8000);
+ SRCSetRate (devc, SRC_ADC_BASE, 8000);
+
+ /* now enable the whole deal */
+ for (i = 0; i < SRC_IOPOLL_COUNT; ++i)
+ if (!(INL (devc->osdev, devc->base + CONC_dSRCIO_OFF) & SRC_BUSY))
+ break;
+ OUTL (devc->osdev, 0, devc->base + CONC_dSRCIO_OFF);
+
+ return;
+}
+
+unsigned short
+SRCRegRead (apci97_devc * devc, unsigned short reg)
+{
+ int i, dtemp;
+
+ dtemp = INL (devc->osdev, devc->base + CONC_dSRCIO_OFF);
+ /* wait for ready */
+ for (i = 0; i < SRC_IOPOLL_COUNT; ++i)
+ if (!
+ ((dtemp =
+ INL (devc->osdev, devc->base + CONC_dSRCIO_OFF)) & SRC_BUSY))
+ break;
+
+ /* assert a read request */
+ OUTL (devc->osdev,
+ (dtemp & SRC_CTLMASK) | ((int) reg << 25),
+ devc->base + CONC_dSRCIO_OFF);
+
+ /* now wait for the data */
+ for (i = 0; i < SRC_IOPOLL_COUNT; ++i)
+ if (!
+ ((dtemp =
+ INL (devc->osdev, devc->base + CONC_dSRCIO_OFF)) & SRC_BUSY))
+ break;
+
+ return (unsigned short) dtemp;
+}
+
+
+void
+SRCRegWrite (apci97_devc * devc, unsigned short reg, unsigned short val)
+{
+ int i, dtemp;
+ int writeval;
+
+ dtemp = INL (devc->osdev, devc->base + CONC_dSRCIO_OFF);
+ /* wait for ready */
+ for (i = 0; i < SRC_IOPOLL_COUNT; ++i)
+ if (!
+ ((dtemp =
+ INL (devc->osdev, devc->base + CONC_dSRCIO_OFF)) & SRC_BUSY))
+ break;
+
+ /* assert the write request */
+ writeval = (dtemp & SRC_CTLMASK) | SRC_WENABLE | ((int) reg << 25) | val;
+ OUTL (devc->osdev, writeval, devc->base + CONC_dSRCIO_OFF);
+
+ return;
+}
+
+typedef struct
+{
+ unsigned char base;
+ unsigned short rate;
+}
+SRC_RATE_REC;
+
+#define SRC_RATE_RECS (3)
+SRC_RATE_REC theSRCRates[SRC_RATE_RECS] = {
+ {SRC_SYNTH_BASE, 0},
+ {SRC_DAC_BASE, 0},
+ {SRC_ADC_BASE, 0}
+};
+
+/*ARGSUSED*/
+unsigned short
+SRCGetRate (apci97_devc * devc, unsigned char base)
+{
+ unsigned short i;
+
+ for (i = 0; i < SRC_RATE_RECS; i++)
+ if (theSRCRates[i].base == base)
+ return theSRCRates[i].rate;
+
+ return 0;
+}
+
+void
+SRCSetRate (apci97_devc * devc, unsigned char base, unsigned short rate)
+{
+ int i, freq, dtemp;
+ unsigned short N, truncM, truncStart;
+
+
+ for (i = 0; i < SRC_RATE_RECS; i++)
+ if (theSRCRates[i].base == base)
+ {
+ theSRCRates[i].rate = rate;
+ break;
+ }
+
+ if (base != SRC_ADC_BASE)
+ {
+ /* freeze the channel */
+ dtemp = base == SRC_SYNTH_BASE ? SRC_SYNTHFREEZE : SRC_DACFREEZE;
+ for (i = 0; i < SRC_IOPOLL_COUNT; ++i)
+ if (!(INL (devc->osdev, devc->base + CONC_dSRCIO_OFF) & SRC_BUSY))
+ break;
+ OUTL (devc->osdev,
+ (INL (devc->osdev, devc->base + CONC_dSRCIO_OFF) & SRC_CTLMASK) |
+ dtemp, devc->base + CONC_dSRCIO_OFF);
+
+ /* calculate new frequency and write it - preserve accum */
+ freq = ((int) rate << 16) / 3000U;
+ SRCRegWrite (devc, (unsigned short) base + SRC_INT_REGS_OFF,
+ (SRCRegRead
+ (devc,
+ (unsigned short) base +
+ SRC_INT_REGS_OFF) & 0x00ffU) | ((unsigned short) (freq >>
+ 6) &
+ 0xfc00));
+ SRCRegWrite (devc, (unsigned short) base + SRC_VFREQ_FRAC_OFF,
+ (unsigned short) freq >> 1);
+
+ /* un-freeze the channel */
+ for (i = 0; i < SRC_IOPOLL_COUNT; ++i)
+ if (!(INL (devc->osdev, devc->base + CONC_dSRCIO_OFF) & SRC_BUSY))
+ break;
+ OUTL (devc->osdev,
+ (INL (devc->osdev, devc->base + CONC_dSRCIO_OFF) & SRC_CTLMASK) &
+ ~dtemp, devc->base + CONC_dSRCIO_OFF);
+ }
+ else
+ {
+ /* derive oversample ratio */
+ N = rate / 3000U;
+ if (N == 15 || N == 13 || N == 11 || N == 9)
+ --N;
+
+ /* truncate the filter and write n/trunc_start */
+ truncM = (21 * N - 1) | 1;
+ if (rate >= 24000U)
+ {
+ if (truncM > 239)
+ truncM = 239;
+ truncStart = (239 - truncM) >> 1;
+
+ SRCRegWrite (devc, base + SRC_TRUNC_N_OFF,
+ (truncStart << 9) | (N << 4));
+ }
+ else
+ {
+ if (truncM > 119)
+ truncM = 119;
+ truncStart = (119 - truncM) >> 1;
+
+ SRCRegWrite (devc, base + SRC_TRUNC_N_OFF,
+ 0x8000U | (truncStart << 9) | (N << 4));
+ }
+
+ /* calculate new frequency and write it - preserve accum */
+ freq = ((48000UL << 16) / rate) * N;
+ SRCRegWrite (devc, base + SRC_INT_REGS_OFF,
+ (SRCRegRead
+ (devc,
+ (unsigned short) base +
+ SRC_INT_REGS_OFF) & 0x00ff) | ((unsigned short) (freq >>
+ 6) &
+ 0xfc00));
+ SRCRegWrite (devc, base + SRC_VFREQ_FRAC_OFF,
+ (unsigned short) freq >> 1);
+
+ SRCRegWrite (devc, SRC_ADC_VOL_L, N << 8);
+ SRCRegWrite (devc, SRC_ADC_VOL_R, N << 8);
+
+ }
+
+ return;
+}
+
+static void
+apci97_writemem (apci97_devc * devc, int page, int offs, int data)
+{
+ int tmp;
+
+ tmp = INL (devc->osdev, devc->base + 0xc);
+ OUTL (devc->osdev, page, devc->base + 0xc); /* Select memory page */
+ OUTL (devc->osdev, data, devc->base + offs);
+ OUTL (devc->osdev, tmp, devc->base + 0xc); /* Select the original memory page */
+}
+
+static unsigned int
+apci97_readmem (apci97_devc * devc, int page, int offs)
+{
+ unsigned int val;
+
+ OUTL (devc->osdev, page, devc->base + 0xc); /* Select memory page */
+ val = INL (devc->osdev, devc->base + offs);
+ return val;
+}
+
+static int
+apci97intr (oss_device_t * osdev)
+{
+ int stats, i;
+ int tmp;
+ unsigned char ackbits = 0;
+ unsigned char uart_stat;
+ apci97_devc *devc = (apci97_devc *) osdev->devc;
+ apci97_portc *portc;
+ int served = 0;
+
+ stats = INL (devc->osdev, devc->base + 0x04);
+ /*cmn_err (CE_WARN, "AudioPCI97 intr status %08x\n", stats); */
+
+ if (!(stats & 0x80000000)) /* No interrupt pending */
+ return served;
+
+ served = 1;
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+
+ if (stats & 0x00000010) /* CCB interrupt */
+ {
+ cmn_err (CE_WARN, "CCB interrupt\n");
+ }
+
+ if ((stats & 0x00000004) && (portc->atype)) /* DAC1 (synth) interrupt */
+ {
+ ackbits |= CONC_SERCTL_DAC1IE;
+ if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ oss_audio_outputintr (portc->audiodev, 0);
+
+ }
+
+ if ((stats & 0x00000002) && (!portc->atype)) /* DAC2 interrupt */
+ {
+ ackbits |= CONC_SERCTL_DAC2IE;
+ if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ oss_audio_outputintr (portc->audiodev, 0);
+ }
+
+ if ((stats & 0x00000001) && (!portc->atype)) /* ADC interrupt */
+ {
+ ackbits |= CONC_SERCTL_ADCIE;
+ if (portc->trigger_bits & PCM_ENABLE_INPUT)
+ {
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+
+ if (stats & 0x00000008) /* UART interrupt */
+ {
+ uart_stat = INB (devc->osdev, devc->base + CONC_bUARTCSTAT_OFF);
+
+ while (uart_stat & CONC_UART_RXRDY)
+ {
+ unsigned char d;
+ d = INB (devc->osdev, devc->base + CONC_bUARTDATA_OFF);
+
+ if (devc->midi_opened & OPEN_READ && devc->midi_input_intr)
+ devc->midi_input_intr (devc->midi_dev, d);
+ uart_stat = INB (devc->osdev, devc->base + CONC_bUARTCSTAT_OFF);
+ }
+
+ }
+ /* Ack the interrupt */
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF);
+ OUTB (devc->osdev, (tmp & ~ackbits), devc->base + CONC_bSERCTL_OFF); /* Clear bits */
+ OUTB (devc->osdev, tmp | ackbits, devc->base + CONC_bSERCTL_OFF); /* Return them back on */
+ }
+
+ return served;
+}
+
+/*
+ * Audio routines
+ */
+
+static int
+apci97_audio_set_rate (int dev, int arg)
+{
+ apci97_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+apci97_audio_set_channels (int dev, short arg)
+{
+ apci97_portc *portc = audio_engines[dev]->portc;
+
+ if ((arg != 1) && (arg != 2))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+apci97_audio_set_format (int dev, unsigned int arg)
+{
+ apci97_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE | AFMT_AC3)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+apci97_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void apci97_audio_trigger (int dev, int state);
+
+static void
+apci97_audio_reset (int dev)
+{
+ apci97_audio_trigger (dev, 0);
+}
+
+static void
+apci97_audio_reset_input (int dev)
+{
+ apci97_portc *portc = audio_engines[dev]->portc;
+ apci97_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+apci97_audio_reset_output (int dev)
+{
+ apci97_portc *portc = audio_engines[dev]->portc;
+ apci97_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+apci97_audio_open (int dev, int mode, int open_flags)
+{
+ apci97_portc *portc = audio_engines[dev]->portc;
+ apci97_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ portc->open_mode = mode;
+ portc->audio_enabled = ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+apci97_audio_close (int dev, int mode)
+{
+ apci97_portc *portc = audio_engines[dev]->portc;
+
+ apci97_audio_reset (dev);
+ portc->open_mode = 0;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+apci97_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ apci97_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+}
+
+/*ARGSUSED*/
+static void
+apci97_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ apci97_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+apci97_audio_trigger (int dev, int state)
+{
+ apci97_devc *devc = audio_engines[dev]->devc;
+ apci97_portc *portc = audio_engines[dev]->portc;
+ int tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ if (portc->atype)
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp |= CONC_DEVCTL_DAC1_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ }
+ else
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp |= CONC_DEVCTL_DAC2_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ }
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ if (portc->atype)
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp &= ~CONC_DEVCTL_DAC1_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF);
+ tmp &= ~CONC_SERCTL_DAC1IE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ }
+ else
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp &= ~CONC_DEVCTL_DAC2_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF);
+ tmp &= ~CONC_SERCTL_DAC2IE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+
+ }
+ }
+ }
+ }
+
+ if ((portc->open_mode & OPEN_READ)
+ && !(audio_engines[dev]->flags & ADEV_NOINPUT))
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp |= CONC_DEVCTL_ADC_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF);
+ tmp &= ~CONC_DEVCTL_ADC_EN;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF);
+ tmp &= ~CONC_SERCTL_ADCIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ }
+ }
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+apci97_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ apci97_devc *devc = audio_engines[dev]->devc;
+ apci97_portc *portc = audio_engines[dev]->portc;
+ int tmp = 0x00;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ /* Set physical address of the DMA buffer */
+
+ apci97_writemem (devc, CONC_ADCCTL_PAGE, CONC_dADCPADDR_OFF,
+ dmap->dmabuf_phys);
+
+ /* Set ADC rate */
+ SRCSetRate (devc, SRC_ADC_BASE, portc->speed);
+
+ /* Set format */
+ tmp = INB (devc->osdev, devc->base + CONC_bSERFMT_OFF);
+ tmp &= ~(CONC_PCM_ADC_STEREO | CONC_PCM_ADC_16BIT);
+ if (portc->channels == 2)
+ tmp |= CONC_PCM_ADC_STEREO;
+ if (portc->bits == 16)
+ {
+ tmp |= CONC_PCM_ADC_16BIT;
+ OUTB (devc->osdev, 0x10, devc->base + CONC_bSKIPC_OFF); /* Skip count register */
+ }
+ else
+ {
+ OUTB (devc->osdev, 0x08, devc->base + CONC_bSKIPC_OFF); /* Skip count register */
+ }
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERFMT_OFF);
+
+ /* Set the frame count */
+ apci97_writemem (devc, CONC_ADCCTL_PAGE, CONC_wADCFC_OFF,
+ (dmap->bytes_in_use / 4) - 1);
+
+ /* Set # of samples between interrupts */
+ OUTW (devc->osdev,
+ (dmap->fragment_size / ((portc->channels * portc->bits) / 8)) - 1,
+ devc->base + CONC_wADCIC_OFF);
+
+ /* Enable the wave interrupt */
+ tmp = INB (devc->osdev, devc->base + CONC_bSERCTL_OFF) & ~CONC_SERCTL_ADCIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ tmp |= CONC_SERCTL_ADCIE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+apci97_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ apci97_devc *devc = audio_engines[dev]->devc;
+ apci97_portc *portc = audio_engines[dev]->portc;
+ int tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (devc->revision >= 4)
+ {
+ /* set SPDIF to PCM mode */
+ OUTL (devc->osdev, INL (devc->osdev, devc->base + 0x1c) & ~0x2,
+ devc->base + 0x1c);
+ if (portc->bits & AFMT_AC3)
+ {
+ portc->channels = 2;
+ portc->bits = 16;
+ portc->speed = 48000;
+ /* set S/PDIF to AC3 Mode */
+ OUTL (devc->osdev, INL (devc->osdev, devc->base + 0x1c) | 0x2,
+ devc->base + 0x1c);
+ }
+ }
+
+ if (portc->atype)
+ {
+ /* Set physical address of the DMA buffer */
+ apci97_writemem (devc, CONC_SYNCTL_PAGE, CONC_dSYNPADDR_OFF,
+ dmap->dmabuf_phys);
+
+ /* Set DAC1 rate */
+ SRCSetRate (devc, SRC_SYNTH_BASE, portc->speed);
+
+ /* Set format */
+ tmp = INB (devc->osdev, devc->base + CONC_bSERFMT_OFF);
+ tmp &= ~((CONC_PCM_DAC_STEREO | CONC_PCM_DAC_16BIT) >> 2);
+ if (portc->channels == 2)
+ tmp |= (CONC_PCM_DAC_STEREO >> 2);
+ if (portc->bits == 16)
+ {
+ tmp |= (CONC_PCM_DAC_16BIT >> 2);
+ }
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERFMT_OFF);
+
+ /* Set the frame count */
+ apci97_writemem (devc, CONC_SYNCTL_PAGE, CONC_wSYNFC_OFF,
+ (dmap->bytes_in_use / 4) - 1);
+
+ /* Set # of samples between interrupts */
+ OUTW (devc->osdev,
+ (dmap->fragment_size / ((portc->channels * portc->bits) / 8)) - 1,
+ devc->base + CONC_wSYNIC_OFF);
+
+ /* Enable the wave interrupt */
+ tmp =
+ INB (devc->osdev,
+ devc->base + CONC_bSERCTL_OFF) & ~CONC_SERCTL_DAC1IE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ tmp |= CONC_SERCTL_DAC1IE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+
+ }
+ else
+ {
+ /* Set physical address of the DMA buffer */
+ apci97_writemem (devc, CONC_DACCTL_PAGE, CONC_dDACPADDR_OFF,
+ dmap->dmabuf_phys);
+
+ /* Set DAC rate */
+ SRCSetRate (devc, SRC_DAC_BASE, portc->speed);
+
+ /* Set format */
+ tmp = INB (devc->osdev, devc->base + CONC_bSERFMT_OFF);
+ tmp &= ~(CONC_PCM_DAC_STEREO | CONC_PCM_DAC_16BIT);
+ if (portc->channels == 2)
+ tmp |= CONC_PCM_DAC_STEREO;
+ if (portc->bits == 16)
+ {
+ tmp |= CONC_PCM_DAC_16BIT;
+ OUTB (devc->osdev, 0x10, devc->base + CONC_bSKIPC_OFF); /* Skip count register */
+ }
+ else
+ {
+ OUTB (devc->osdev, 0x08, devc->base + CONC_bSKIPC_OFF); /* Skip count register */
+ }
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERFMT_OFF);
+
+
+ /* Set the frame count */
+ apci97_writemem (devc, CONC_DACCTL_PAGE, CONC_wDACFC_OFF,
+ (dmap->bytes_in_use / 4) - 1);
+
+ /* Set # of samples between interrupts */
+ OUTW (devc->osdev,
+ (dmap->fragment_size / ((portc->channels * portc->bits) / 8)) - 1,
+ devc->base + CONC_wDACIC_OFF);
+
+ /* Enable the wave interrupt */
+ tmp =
+ INB (devc->osdev,
+ devc->base + CONC_bSERCTL_OFF) & ~CONC_SERCTL_DAC2IE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ tmp |= CONC_SERCTL_DAC2IE;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bSERCTL_OFF);
+ }
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+apci97_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ apci97_devc *devc = audio_engines[dev]->devc;
+ apci97_portc *portc = audio_engines[dev]->portc;
+ int ptr = 0, port = 0, page = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ if (portc->atype)
+ {
+ port = CONC_wSYNFC_OFF;
+ page = CONC_SYNCTL_PAGE;
+ }
+ else
+ {
+ port = CONC_wDACFC_OFF;
+ page = CONC_DACCTL_PAGE;
+ }
+ }
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ port = CONC_wADCFC_OFF;
+ page = CONC_ADCCTL_PAGE;
+ }
+
+ ptr = apci97_readmem (devc, page, port);
+ ptr >>= 16;
+ ptr <<= 2; /* count is in dwords */
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return ptr;
+}
+
+audiodrv_t apci97_audio_driver = {
+ apci97_audio_open,
+ apci97_audio_close,
+ apci97_audio_output_block,
+ apci97_audio_start_input,
+ apci97_audio_ioctl,
+ apci97_audio_prepare_for_input,
+ apci97_audio_prepare_for_output,
+ apci97_audio_reset,
+ NULL,
+ NULL,
+ apci97_audio_reset_input,
+ apci97_audio_reset_output,
+ apci97_audio_trigger,
+ apci97_audio_set_rate,
+ apci97_audio_set_format,
+ apci97_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* apci97_alloc_buffer */
+ NULL, /* apci97_free_buffer */
+ NULL,
+ NULL,
+ apci97_get_buffer_pointer
+};
+
+/*ARGSUSED*/
+static int
+apci97_midi_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ apci97_devc *devc = (apci97_devc *) midi_devs[dev]->devc;
+
+ if (devc->midi_opened)
+ {
+ return OSS_EBUSY;
+ }
+
+ devc->midi_input_intr = inputbyte;
+ devc->midi_opened = mode;
+
+ if (mode & OPEN_READ)
+ {
+ OUTB (devc->osdev, CONC_UART_RXINTEN, devc->base + CONC_bUARTCSTAT_OFF);
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+apci97_midi_close (int dev, int mode)
+{
+ apci97_devc *devc = (apci97_devc *) midi_devs[dev]->devc;
+
+ OUTB (devc->osdev, 0x00, devc->base + CONC_bUARTCSTAT_OFF);
+ devc->midi_opened = 0;
+}
+
+static int
+apci97_midi_out (int dev, unsigned char midi_byte)
+{
+ apci97_devc *devc = (apci97_devc *) midi_devs[dev]->devc;
+ int i;
+
+ unsigned char uart_stat =
+ INB (devc->osdev, devc->base + CONC_bUARTCSTAT_OFF);
+
+ i = 0;
+ while (i < 1000000 && !(uart_stat & CONC_UART_TXRDY))
+ {
+ uart_stat = INB (devc->osdev, devc->base + CONC_bUARTCSTAT_OFF);
+ i++;
+ }
+
+ if (!(uart_stat & CONC_UART_TXRDY))
+ return 0;
+
+
+ OUTB (devc->osdev, midi_byte, devc->base + CONC_bUARTDATA_OFF);
+
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+apci97_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t apci97_midi_driver = {
+ apci97_midi_open,
+ apci97_midi_close,
+ apci97_midi_ioctl,
+ apci97_midi_out
+};
+
+static int
+apci97_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ apci97_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case 1: /* Speaker Mode */
+ value = (INL (devc->osdev, devc->base + 4) & (1 << 26) ? 1 : 0);
+ break;
+
+ case 2: /* Dual Dac Mode */
+ value = INL (devc->osdev, devc->base + 4) & (1 << 27) ? 1 : 0;
+ break;
+ }
+ }
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case 1: /* Front/Rear Mirror */
+ if (value)
+ {
+ OUTL (devc->osdev,
+ INL (devc->osdev, devc->base + 4) | (1 << 26),
+ devc->base + 4);
+ }
+ else
+ {
+ OUTL (devc->osdev,
+ INL (devc->osdev, devc->base + 4) & ~(1 << 26),
+ devc->base + 4);
+ }
+ break;
+
+ case 2: /* DAC1->Front DAC2->REAR */
+ if (value)
+ {
+ /* disable front/rear mirroring */
+ OUTL (devc->osdev,
+ INL (devc->osdev, devc->base + 4) & ~(1 << 26),
+ devc->base + 4);
+ /* Enable Dual Dac mode */
+ OUTL (devc->osdev,
+ INL (devc->osdev, devc->base + 4) | (1 << 27) | (1 << 24),
+ devc->base + 4);
+ }
+ else
+ {
+ /* enable mirror */
+ OUTL (devc->osdev,
+ INL (devc->osdev, devc->base + 4) | (1 << 26),
+ devc->base + 4);
+ /* disable dual dac */
+ OUTL (devc->osdev,
+ INL (devc->osdev,
+ devc->base + 4) & ~((1 << 27) | (1 << 24)),
+ devc->base + 4);
+ }
+ break;
+ }
+ }
+ return value;
+}
+
+static int
+apci97_mix_init (int dev)
+{
+ int group, err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "MIXEXT")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group, 1, apci97_control,
+ MIXT_ENUM, "SPKMODE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 2, apci97_control,
+ MIXT_ONOFF, "DUALDAC", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ return 0;
+
+}
+
+static int
+init_apci97 (apci97_devc * devc, int device_id)
+{
+ int my_mixer;
+ int tmp, i;
+ int first_dev = 0;
+
+ if ((device_id == ENSONIQ_ES5880) || (device_id == ENSONIQ_ES5880A) ||
+ (device_id == ENSONIQ_ES5880B) ||
+ (device_id == 0x1371 && devc->revision == 7) ||
+ (device_id == 0x1371 && devc->revision >= 9))
+ {
+ int i;
+
+ /* Have a ES5880 so enable the codec manually */
+ tmp = INB (devc->osdev, devc->base + CONC_bINTSUMM_OFF) & 0xff;
+ tmp |= 0x20;
+ OUTB (devc->osdev, tmp, devc->base + CONC_bINTSUMM_OFF); /* OUTB? */
+ for (i = 0; i < 2000; i++)
+ oss_udelay (10);
+ }
+
+ SRCInit (devc);
+#if 0
+ OUTB (devc->osdev, 0x00, devc->base + CONC_bSERCTL_OFF);
+ OUTB (devc->osdev, 0x00, devc->base + CONC_bNMIENA_OFF); /* NMI off */
+ OUTB (devc->osdev, 0x00, devc->base + CONC_wNMISTAT_OFF); /* OUTB? */
+#endif
+/*
+ * Turn on UART and CODEC
+ */
+ tmp = INL (devc->osdev, devc->base + CONC_bDEVCTL_OFF) & 0xff;
+ tmp &= ~(CONC_DEVCTL_PCICLK_DS | CONC_DEVCTL_XTALCLK_DS);
+ OUTB (devc->osdev, tmp | CONC_DEVCTL_UART_EN | CONC_DEVCTL_JSTICK_EN,
+ devc->base + CONC_bDEVCTL_OFF);
+ OUTB (devc->osdev, 0x00, devc->base + CONC_bUARTCSTAT_OFF);
+
+ /* Perform AC97 codec warm reset */
+ tmp = INB (devc->osdev, devc->base + CONC_bMISCCTL_OFF) & 0xff;
+ OUTB (devc->osdev, tmp | CONC_MISCCTL_SYNC_RES,
+ devc->base + CONC_bMISCCTL_OFF);
+ oss_udelay (200);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bMISCCTL_OFF);
+ oss_udelay (200);
+
+/*
+ * Enable S/PDIF
+ */
+ if (devc->revision >= 4)
+ {
+ if (apci_spdif)
+ {
+ /* enable SPDIF */
+ OUTL (devc->osdev, INL (devc->osdev, devc->base + 0x04) | (1 << 18),
+ devc->base + 0x04);
+ /* SPDIF out = data from DAC */
+ OUTL (devc->osdev, INL (devc->osdev, devc->base + 0x00) | (1 << 26),
+ devc->base + 0x00);
+ }
+ else
+ {
+ /* disable spdif out */
+ OUTL (devc->osdev,
+ INL (devc->osdev, devc->base + 0x04) & ~(1 << 18),
+ devc->base + 0x04);
+ OUTL (devc->osdev,
+ INL (devc->osdev, devc->base + 0x00) & ~(1 << 26),
+ devc->base + 0x00);
+ }
+ }
+
+/*
+ * Init mixer
+ */
+ my_mixer =
+ ac97_install (&devc->ac97devc, "AC97 Mixer", ac97_read, ac97_write, devc,
+ devc->osdev);
+
+ if (my_mixer < 0)
+ return 0;
+
+ if (devc->revision >= 4)
+ {
+ /* enable 4 speaker mode */
+ OUTL (devc->osdev, INL (devc->osdev, devc->base + 4) | (1 << 26),
+ devc->base + 4);
+ mixer_ext_set_init_fn (my_mixer, apci97_mix_init, 5);
+ }
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+
+ int adev;
+ char tmp_name[100];
+ apci97_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE;
+ int fmts = AFMT_U8 | AFMT_S16_LE;
+
+ if (devc->revision >= 4)
+ fmts |= AFMT_AC3;
+
+ if (i == 0)
+ {
+ sprintf (tmp_name, "%s (rev %d)", devc->chip_name, devc->revision);
+ caps |= ADEV_DUPLEX;
+ }
+ else
+ {
+ sprintf (tmp_name, "%s (playback only)", devc->chip_name);
+ caps |= ADEV_NOINPUT;
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &apci97_audio_driver,
+ sizeof (audiodrv_t),
+ caps, fmts, devc, -1)) < 0)
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ portc->open_mode = 0;
+ portc->audiodev = adev;
+ portc->atype = i;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+
+ audio_engines[adev]->mixer_dev = my_mixer;
+ }
+
+ if ((devc->midi_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "APCI97", "APCI97 UART", &apci97_midi_driver, sizeof (midi_driver_t),
+ 0, devc, devc->osdev)) < 0)
+ {
+ cmn_err (CE_WARN, "Couldn't install MIDI device\n");
+ return 0;
+ }
+
+ devc->midi_opened = 0;
+ return 1;
+}
+
+int
+oss_sbpci_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ apci97_devc *devc;
+ int err;
+
+ DDB (cmn_err (CE_WARN, "Entered AudioPCI97 probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if ((vendor != ENSONIQ_VENDOR_ID && vendor != ECTIVA_VENDOR_ID) ||
+ (device != ENSONIQ_ES1371 && device != ENSONIQ_ES5880 &&
+ device != ENSONIQ_ES5880A && device != ECTIVA_ES1938 &&
+ device != ENSONIQ_ES5880B))
+
+ return 0;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d). Can't continue\n",
+ pci_irq_line);
+ return 0;
+ }
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ switch (device)
+ {
+ case ENSONIQ_ES1371:
+ devc->chip_name = "Creative AudioPCI97 (ES1371)";
+ break;
+ case ECTIVA_ES1938:
+ devc->chip_name = "Ectiva AudioPCI";
+ break;
+ case ENSONIQ_ES5880:
+ case ENSONIQ_ES5880A:
+ case ENSONIQ_ES5880B:
+ devc->chip_name = "Sound Blaster PCI128";
+ break;
+ default:
+ devc->chip_name = "AudioPCI97";
+ }
+
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+ /* Remove I/O space marker in bit 0. */
+ devc->base &= ~3;
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ /* set the PCI latency to 32 */
+ if ((apci_latency == 32) || (apci_latency == 64) || (apci_latency == 96) ||
+ (apci_latency == 128))
+ pci_write_config_byte (osdev, 0x0d, apci_latency);
+
+
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if ((err = oss_register_interrupts (osdev, 0, apci97intr, NULL)) < 0)
+ {
+ cmn_err (CE_WARN, "Can't allocate IRQ%d, err=%d\n", pci_irq_line, err);
+ return 0;
+ }
+
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+
+ devc->revision = pci_revision;
+ return init_apci97 (devc, device); /* Detected */
+}
+
+int
+oss_sbpci_detach (oss_device_t * osdev)
+{
+ apci97_devc *devc = (apci97_devc *) osdev->devc;
+ int tmp;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ tmp = INB (devc->osdev, devc->base + CONC_bDEVCTL_OFF) &
+ ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+ OUTB (devc->osdev, tmp, devc->base + CONC_bDEVCTL_OFF);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_sbpci/oss_sbpci.man b/kernel/drv/oss_sbpci/oss_sbpci.man
new file mode 100644
index 0000000..2e03556
--- /dev/null
+++ b/kernel/drv/oss_sbpci/oss_sbpci.man
@@ -0,0 +1,39 @@
+NAME
+oss_sbpci - Creative Labs ES1371 audio driver.
+
+DESCRIPTION
+Open Sound System driver for Creative Labs ES1371/ES1373/5880, Ectiva 1938
+audio controllers.
+
+APCI97 device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo playback/recording
+ o 8KHz to 48Khz sample rate
+
+ APCI97 MIXER EXTENSIONS
+
+Dual Dac mode: This feature turns the APCI97 into two output devices with
+the output going to front and rear speakers independantly (however volume
+control is global).
+
+Speaker Mode: This feature allows you to either have the audio coming out
+the front speakers or you can have audio duplicated on rear speakers. This
+mode is disabled when Dual Dac mode is enabled.
+
+SPDIF: This button enables or disables SPDIF output.
+
+OPTIONS
+o apci97_latency=<NNN>
+Certain models of the ES1371 sound devices will sound distorted playing stereo
+audio and setting the PCI latency fixes the problem
+
+o apci_spdif=0|1
+Certain models like the SB 4.1D/SB PCI128D have SPDIF output jacks and
+this setting enables the output device.
+
+FILES
+CONFIGFILEPATH/oss_sbpci.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_sbpci/sbpci.h b/kernel/drv/oss_sbpci/sbpci.h
new file mode 100644
index 0000000..4c2803a
--- /dev/null
+++ b/kernel/drv/oss_sbpci/sbpci.h
@@ -0,0 +1,181 @@
+/*
+ * Purpose: Definitions for the Creative/Ensoniq AudioPCI97 driver.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 ES1371_H
+#define ES1371_H
+
+/* CONCERT PCI-SIG defines */
+#define CONC_PCI_VENDID 0x1274U
+#define CONC_PCI_DEVID 0x1371U
+
+
+/* Concert97 direct register offset defines */
+#define CONC_bDEVCTL_OFF 0x00 /* Device control/enable */
+#define CONC_bMISCCTL_OFF 0x01 /* Miscellaneous control */
+#define CONC_bGPIO_OFF 0x02 /* General purpose I/O control */
+#define CONC_bJOYCTL_OFF 0x03 /* Joystick control (decode) */
+#define CONC_dSTATUS_OFF 0x04 /* long status register */
+#define CONC_bINTSTAT_OFF 0x04 /* Device interrupt status */
+#define CONC_bCODECSTAT_OFF 0x05 /* CODEC interface status */
+#define CONC_bINTSUMM_OFF 0x07 /* Interrupt summary status */
+#define CONC_bUARTDATA_OFF 0x08 /* UART data R/W - read clears RX int */
+#define CONC_bUARTCSTAT_OFF 0x09 /* UART control and status */
+#define CONC_bUARTTEST_OFF 0x0a /* UART test control reg */
+#define CONC_bMEMPAGE_OFF 0x0c /* Memory page select */
+#define CONC_dSRCIO_OFF 0x10 /* I/O ctl/stat/data for SRC RAM */
+#define CONC_dCODECCTL_OFF 0x14 /* CODEC control - dword read/write */
+#define CONC_wNMISTAT_OFF 0x18 /* Legacy NMI status */
+#define CONC_bNMIENA_OFF 0x1a /* Legacy NMI enable */
+#define CONC_bNMICTL_OFF 0x1b /* Legacy control */
+#define CONC_bSERFMT_OFF 0x20 /* Serial device control */
+#define CONC_bSERCTL_OFF 0x21 /* Serial device format */
+#define CONC_bSKIPC_OFF 0x22 /* DAC skip count reg */
+#define CONC_wSYNIC_OFF 0x24 /* Synth int count in sample frames */
+#define CONC_wSYNCIC_OFF 0x26 /* Synth current int count */
+#define CONC_wDACIC_OFF 0x28 /* DAC int count in sample frames */
+#define CONC_wDACCIC_OFF 0x2a /* DAC current int count */
+#define CONC_wADCIC_OFF 0x2c /* ADC int count in sample frames */
+#define CONC_wADCCIC_OFF 0x2e /* ADC current int count */
+#define CONC_MEMBASE_OFF 0x30 /* Memory window base - 16 byte window */
+
+/* Concert memory page-banked register offset defines */
+#define CONC_dSYNPADDR_OFF 0x30 /* Synth host frame PCI phys addr */
+#define CONC_wSYNFC_OFF 0x34 /* Synth host frame count in DWORDS */
+#define CONC_wSYNCFC_OFF 0x36 /* Synth host current frame count */
+#define CONC_dDACPADDR_OFF 0x38 /* DAC host frame PCI phys addr */
+#define CONC_wDACFC_OFF 0x3c /* DAC host frame count in DWORDS */
+#define CONC_wDACCFC_OFF 0x3e /* DAC host current frame count */
+#define CONC_dADCPADDR_OFF 0x30 /* ADC host frame PCI phys addr */
+#define CONC_wADCFC_OFF 0x34 /* ADC host frame count in DWORDS */
+#define CONC_wADCCFC_OFF 0x36 /* ADC host current frame count */
+
+/* Concert memory page number defines */
+#define CONC_SYNRAM_PAGE 0x00 /* Synth host/serial I/F RAM */
+#define CONC_DACRAM_PAGE 0x04 /* DAC host/serial I/F RAM */
+#define CONC_ADCRAM_PAGE 0x08 /* ADC host/serial I/F RAM */
+#define CONC_SYNCTL_PAGE 0x0c /* Page bank for synth host control */
+#define CONC_DACCTL_PAGE 0x0c /* Page bank for DAC host control */
+#define CONC_ADCCTL_PAGE 0x0d /* Page bank for ADC host control */
+#define CONC_FIFO0_PAGE 0x0e /* page 0 of UART "FIFO" (rx stash) */
+#define CONC_FIFO1_PAGE 0x0f /* page 1 of UART "FIFO" (rx stash) */
+
+/* PCM format defines */
+#define CONC_PCM_DAC_STEREO 0x04
+#define CONC_PCM_DAC_16BIT 0x08
+#define CONC_PCM_DAC_MASK 0xf3
+#define CONC_PCM_ADC_STEREO 0x10
+#define CONC_PCM_ADC_16BIT 0x20
+#define CONC_PCM_ADC_MASK 0xcf
+
+/* Device Control defines */
+#define CONC_DEVCTL_PCICLK_DS 0x01 /* PCI Clock Disable */
+#define CONC_DEVCTL_XTALCLK_DS 0x02 /* Crystal Clock Disable */
+#define CONC_DEVCTL_JSTICK_EN 0x04 /* Joystick Enable */
+#define CONC_DEVCTL_UART_EN 0x08 /* UART Enable */
+#define CONC_DEVCTL_ADC_EN 0x10 /* ADC Enable (record) */
+#define CONC_DEVCTL_DAC2_EN 0x20 /* DAC2 Enable (playback) */
+#define CONC_DEVCTL_DAC1_EN 0x40 /* DAC1 Enabale (synth) */
+
+/* Misc Control defines */
+#define CONC_MISCCTL_PDLEV_D0 0x00 /* These bits reflect the */
+#define CONC_MISCCTL_PDLEV_D1 0x01 /* power down state of */
+#define CONC_MISCCTL_PDLEV_D2 0x02 /* the part */
+#define CONC_MISCCTL_PDLEV_D3 0x03 /* */
+#define CONC_MISCCTL_CCBINTRM_EN 0x04 /* CCB module interrupt mask */
+
+#define CONC_MISCCTL_SYNC_RES 0x40 /* for AC97 warm reset */
+
+/* Serial Control defines */
+#define CONC_SERCTL_DAC1IE 0x01 /* playback interrupt enable P1_INT_EN */
+#define CONC_SERCTL_DAC2IE 0x02 /* playback interrupt enable P2_INT_EN */
+#define CONC_SERCTL_ADCIE 0x04 /* record interrupt enable R1_INT_EN */
+#define CONC_SERCTL_DACPAUSE 0x10 /* playback pause */
+#define CONC_SERCTL_R1LOOP 0x80
+#define CONC_SERCTL_P2LOOP 0x40
+#define CONC_SERCTL_P1LOOP 0x20
+
+/* Interrupt Status defines */
+#define CONC_INTSTAT_ADCINT 0x01 /* A/D interrupt pending bit */
+#define CONC_INTSTAT_DAC2INT 0x02 /* DAC2 interrupt pending bit */
+#define CONC_INTSTAT_DAC1INT 0x04 /* DAC1 interrupt pending bit */
+#define CONC_INTSTAT_UARTINT 0x08 /* UART interrupt pending bit */
+#define CONC_INTSTAT_PENDING 0x80000000 /* this bit set high while'st we have an interrupt */
+/* DEVCTL register masks */
+/*#define CONC_DEVCTL_D1EN 0x40 */
+/*#define CONC_DEVCTL_D2EN 0x20 */
+/*#define CONC_DEVCTL_ADEN 0x10 */
+
+/* SERCTL register masks */
+/*#define CONC_SERCTL_P1_INT_EN 0x01 */
+/*#define CONC_SERCTL_P2_INT_EN 0x02 */
+/*#define CONC_SERCTL_R1_INT_EN 0x04 */
+
+/* JOYCTL register defines */
+#define CONC_JOYCTL_200 0x00
+#define CONC_JOYCTL_208 0x01
+#define CONC_JOYCTL_210 0x02
+#define CONC_JOYCTL_218 0x03
+
+
+/* UARTCSTAT register masks */
+#define CONC_UART_RXRDY 0x01
+#define CONC_UART_TXRDY 0x02
+#define CONC_UART_TXINT 0x04
+#define CONC_UART_RXINT 0x80
+
+#define CONC_UART_CTL 0x03
+#define CONC_UART_TXINTEN 0x20
+#define CONC_UART_RXINTEN 0x80
+
+/* Logical index for each DMA controller on chip - used for */
+/* generic routines that access all DMA controllers */
+#define CONC_SYNTH_DAC 0
+#define CONC_WAVE_DAC 1
+#define CONC_WAVE_ADC 2
+
+/* defines for the CONCERT97 Sample Rate Converters */
+
+/* register/base equates for the SRC RAM */
+#define SRC_SYNTH_FIFO 0x00
+#define SRC_DAC_FIFO 0x20
+#define SRC_ADC_FIFO 0x40
+#define SRC_ADC_VOL_L 0x6c
+#define SRC_ADC_VOL_R 0x6d
+#define SRC_SYNTH_BASE 0x70
+#define SRC_DAC_BASE 0x74
+#define SRC_ADC_BASE 0x78
+#define SRC_SYNTH_VOL_L 0x7c
+#define SRC_SYNTH_VOL_R 0x7d
+#define SRC_DAC_VOL_L 0x7e
+#define SRC_DAC_VOL_R 0x7f
+
+#define SRC_TRUNC_N_OFF 0x00
+#define SRC_INT_REGS_OFF 0x01
+#define SRC_ACCUM_FRAC_OFF 0x02
+#define SRC_VFREQ_FRAC_OFF 0x03
+
+
+/* miscellaneous control defines */
+/*#define SRC_IOPOLL_COUNT 0x1000UL */
+#define SRC_IOPOLL_COUNT 0x20000UL
+#define SRC_WENABLE (1UL << 24)
+#define SRC_BUSY (1UL << 23)
+#define SRC_DISABLE (1UL << 22)
+#define SRC_SYNTHFREEZE (1UL << 21)
+#define SRC_DACFREEZE (1UL << 20)
+#define SRC_ADCFREEZE (1UL << 19)
+#define SRC_CTLMASK 0x00780000UL
+
+#endif /* ES1371_H */
diff --git a/kernel/drv/oss_sbxfi/.config b/kernel/drv/oss_sbxfi/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_sbxfi/.devices b/kernel/drv/oss_sbxfi/.devices
new file mode 100644
index 0000000..01f85a4
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/.devices
@@ -0,0 +1,3 @@
+oss_sbxfi pci1102,5 Creative SB X-Fi 20K1 *EARLY BETA*
+oss_sbxfi pci1102,b Creative SB X-Fi 20K2 *EARLY BETA*
+#oss_sbxfi pci1102,9 Creative SB X-Fi PCI-e *EARLY BETA*
diff --git a/kernel/drv/oss_sbxfi/.name b/kernel/drv/oss_sbxfi/.name
new file mode 100644
index 0000000..d63384d
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/.name
@@ -0,0 +1 @@
+Creative Sound Blaster X-Fi
diff --git a/kernel/drv/oss_sbxfi/.params b/kernel/drv/oss_sbxfi/.params
new file mode 100644
index 0000000..d9df108
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/.params
@@ -0,0 +1,15 @@
+int sbxfi_type=0;
+/*
+ * Override sbxfi autodetection.
+ * Values: 0-4. Default: 0
+ * 0 - Autodetect
+ * 1 - Sound Blaster X-Fi (SB046x/067x/076x)
+ * 2 - Sound Blaster X-Fi (SB073x)
+ * 3 - Sound Blaster X-Fi (SB055x)
+ * 4 - Sound Blaster X-Fi (UAA)
+ * 5 - Sound Blaster X-Fi (SB0760)
+ * 6 - Sound Blaster X-Fi (SB0880-1)
+ * 7 - Sound Blaster X-Fi (SB0880-2)
+ * 8 - Sound Blaster X-Fi (SB0880-3)
+ */
+
diff --git a/kernel/drv/oss_sbxfi/20k1reg.h b/kernel/drv/oss_sbxfi/20k1reg.h
new file mode 100644
index 0000000..051c5a0
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/20k1reg.h
@@ -0,0 +1,911 @@
+/**
+*******************************************************************************
+Confidential & Proprietary
+Private & Confidential
+Creative Confidential
+*******************************************************************************
+*/
+/**
+*******************************************************************************
+Copyright (C) Creative Technology, Ltd., 2007. All rights reserved.
+*******************************************************************************
+**/
+#ifndef _201kreg_H
+#define _20k1reg_H
+
+
+// PCI config registers
+#define PCI_CFGHDR_VENDORID 0x00
+#define PCI_CFGHDR_DEVICEID 0x02
+#define PCI_CFGHDR_CMDREG 0x04
+#define PCI_CFGHDR_STATUSREG 0x06
+#define PCI_CFGHDR_REVID 0x08
+#define PCI_CFGHDR_DEVCLASS 0x09
+#define PCI_CFGHDR_CACHESIZE 0x0C
+#define PCI_CFGHDR_LATENCY 0x0D
+#define PCI_CFGHDR_HEADERTYPE 0x0E
+#define PCI_CFGHDR_BIST 0x0F
+
+#define PCI_CFGHDR_BASEREG0 0x10
+#define PCI_CFGHDR_BASEREG1 0x14
+#define PCI_CFGHDR_BASEREG2 0x18
+#define PCI_CFGHDR_BASEREG3 0x1C
+#define PCI_CFGHDR_BASEREG4 0x20
+#define PCI_CFGHDR_BASEREG5 0x24
+
+#define PCI_CFGHDR_RESERVED1 0x28
+#define PCI_CFGHDR_SUBVENDORID 0x2C
+#define PCI_CFGHDR_SUBSYSTEMID 0x2E
+#define PCI_CFGHDR_EXPANDROM 0x30
+#define PCI_CFGHDR_RESERVED2 0x34
+#define PCI_CFGHDR_CAPS_PTR 0x34
+
+#define PCI_CFGHDR_IRQLINE 0x3C
+#define PCI_CFGHDR_IRQPIN 0x3D
+#define PCI_CFGHDR_MINGRANT 0x3E
+#define PCI_CFGHDR_MAXLATENCY 0x3F
+#define PCI_CFGHDR_LACR1 0x40
+#define PCI_CFGHDR_LACR2 0x41
+#define PCI_CFGHDR_LACR3 0x42
+#define PCI_CFGHDR_LACR4 0x43
+
+
+// 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 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(n) 0x140000+(8*(n))
+#define AMOP_END 0x147FFC
+#define PMOP_START 0x148000
+#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(n) 0x198000+(4*(n))
+#define PRING_LO_HI_END 0x19BFFC
+
+#define PINTFIFO 0x1A0000
+#define SRCCTL(n) 0x1B0000+((n)*0x100)
+# define SRCCTL_ILSZ (1<<16) // bits 16-19
+# define SRCCTL_IE (1<<15)
+#define SRCCCR(n) 0x1B0004+(0x100*(n))
+#define SRCIMAP(n) 0x1B0008+(0x100*(n))
+#define SRCODDC 0x1B000C
+#define SRCCA(n) 0x1B0010+((n)*0x100)
+#define SRCCF(n) 0x1B0014+((n)*0x100)
+#define SRCSA(n) 0x1B0018+((n)*0x100)
+#define SRCLA(n) 0x1B001C+((n)*0x100)
+#define SRCCTLSWR 0x1B0020
+
+///SRC HERE
+#define SRCALBA 0x1B002C
+#define SRCMCTL 0x1B012C
+#define SRCCERR 0x1B022C
+#define SRCITB 0x1B032C
+#define SRCIPM 0x1B082C
+#define SRCIP(n) 0x1B102C+((n)*0x100)
+#define SRCENBSTAT 0x1B202C
+#define SRCENBLO 0x1B212C
+#define SRCENBHI 0x1B222C
+#define SRCENBS 0x1B352C
+#define SRCENB07 0x1B282C
+#define SRCENBS07 0x1B302C
+
+#define SRCDN0Z0 0x1B0030
+#define SRCDN0Z1 0x1B0034
+#define SRCDN0Z2 0x1B0038
+#define SRCDN0Z3 0x1B003C
+#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 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(n) 0x1C5000+(4*(n))
+#define DAOIMAP_END 0x1C5124
+
+#define AC97D 0x1C5400
+#define AC97A 0x1C5404
+#define AC97CTL 0x1C5408
+#define I2SCTL 0x1C5420
+
+#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 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 PLL_INT (1<<10)
+# define FI_INT (1<<9)
+# define IT_INT (1<<8)
+# define PCI_INT (1<<7)
+# define URT_INT (1<<6)
+# define GPI_INT (1<<5)
+# define MIX_INT (1<<4)
+# define DAI_INT (1<<3)
+# define TP_INT (1<<2)
+# define DSP_INT (1<<1)
+# define SRC_INT (1<<0)
+#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 0x00700000L /* Midi Uart A DATa */
+//#define MUACMD 0x00710000L /* Midi Uart A CoMmanD */
+//#define MUASTAT 0x00710000L /* Midi Uart A STATus */
+//#define MUBDAT 0x00720000L /* Midi Uart B DATa */
+//#define MUBCMD 0x00730000L /* Midi Uart B CoMmanD */
+//#define MUBSTAT 0x00730000L /* Midi Uart B STATus */
+#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
+
+
+
+typedef enum
+{
+ //block 0
+ FIL_CH_0 = 0,
+ SRC_CH_0 = 0x1,
+ MIXER_SUM_CH_0 = 0xc,
+
+ //block 1
+ FIL_CH_1 = 0x10,
+ SRC_CH_1 = 0x11,
+ MIXER_SUM_CH_1 = 0x1c,
+
+
+ DAI_CH_AC97L = 0x5e5,
+ DAI_CH_AC97R = 0x7e5,
+ DAI_CH_AC97MIC = 0xde5,
+
+//daoi i2s out block
+ DAI_CH_I2SAL = 0x0,
+ DAI_CH_I2SAR = 0x1,
+ DAI_CH_I2SA1L = 0x2,
+ DAI_CH_I2SA1R = 0x3,
+ DAI_CH_I2SA2L = 0x4,
+ DAI_CH_I2SA2R = 0x5,
+ DAI_CH_I2SA3L = 0x6,
+ DAI_CH_I2SA3R = 0x7,
+
+ DAI_CH_I2SBL = 0x8,
+ DAI_CH_I2SBR = 0x9,
+ DAI_CH_I2SB1L = 0xa,
+ DAI_CH_I2SB1R = 0xb,
+ DAI_CH_I2SB2L = 0xc,
+ DAI_CH_I2SB2R = 0xd,
+ DAI_CH_I2SB3L = 0xe,
+ DAI_CH_I2SB3R = 0xf,
+
+ DAI_CH_I2SCL = 0x10,
+ DAI_CH_I2SCR = 0x11,
+ DAI_CH_I2SC1L = 0x12,
+ DAI_CH_I2SC1R = 0x13,
+ DAI_CH_I2SC2L = 0x14,
+ DAI_CH_I2SC2R = 0x15,
+ DAI_CH_I2SC3L = 0x16,
+ DAI_CH_I2SC3R = 0x17,
+
+ DAI_CH_I2SDL = 0x18,
+ DAI_CH_I2SDR = 0x19,
+ DAI_CH_I2SD1L = 0x1a,
+ DAI_CH_I2SD1R = 0x1b,
+ DAI_CH_I2SD2L = 0x1c,
+ DAI_CH_I2SD2R = 0x1d,
+ DAI_CH_I2SD3L = 0x1e,
+ DAI_CH_I2SD3R = 0x1f,
+
+//daoi spdif out
+ DAI_CH_SPDIFAL = 0x20,
+ DAI_CH_SPDIFAR = 0x21,
+ DAI_CH_SPDIFA1L = 0x22,
+ DAI_CH_SPDIFA1R = 0x23,
+ DAI_CH_SPDIFA2L = 0x24,
+ DAI_CH_SPDIFA2R = 0x25,
+ DAI_CH_SPDIFA3L = 0x26,
+ DAI_CH_SPDIFA3R = 0x27,
+
+ DAI_CH_SPDIFBL = 0x28,
+ DAI_CH_SPDIFBR = 0x29,
+ DAI_CH_SPDIFB1L = 0x2a,
+ DAI_CH_SPDIFB1R = 0x2b,
+ DAI_CH_SPDIFB2L = 0x2c,
+ DAI_CH_SPDIFB2R = 0x2d,
+ DAI_CH_SPDIFB3L = 0x2e,
+ DAI_CH_SPDIFB3R = 0x2f,
+
+ DAI_CH_SPDIFCL = 0x30,
+ DAI_CH_SPDIFCR = 0x31,
+ DAI_CH_SPDIFC1L = 0x32,
+ DAI_CH_SPDIFC1R = 0x33,
+ DAI_CH_SPDIFC2L = 0x34,
+ DAI_CH_SPDIFC2R = 0x35,
+ DAI_CH_SPDIFC3L = 0x36,
+ DAI_CH_SPDIFC3R = 0x37,
+
+ DAI_CH_SPDIFDL = 0x38,
+ DAI_CH_SPDIFDR = 0x39,
+ DAI_CH_SPDIFD1L = 0x3a,
+ DAI_CH_SPDIFD1R = 0x3b,
+ DAI_CH_SPDIFD2L = 0x3c,
+ DAI_CH_SPDIFD2R = 0x3d,
+ DAI_CH_SPDIFD3L = 0x3e,
+ DAI_CH_SPDIFD3R = 0x3f,
+
+//daio i2s block(in)
+ DAI_CH_I2SINA1L = 0x035,
+ DAI_CH_I2SINA1R = 0x03D,
+ DAI_CH_I2SINB1L = 0x0B5,
+ DAI_CH_I2SINB1R = 0x0BD,
+ DAI_CH_I2SINC1L = 0x135,
+ DAI_CH_I2SINC1R = 0x13D,
+ DAI_CH_I2SIND1L = 0x1B5,
+ DAI_CH_I2SIND1R = 0x1BD,
+ DAI_CH_I2SINA2L = 0x235,
+ DAI_CH_I2SINA2R = 0x23D,
+ DAI_CH_I2SINB2L = 0x2B5,
+ DAI_CH_I2SINB2R = 0x2BD,
+ DAI_CH_I2SINC2L = 0x335,
+ DAI_CH_I2SINC2R = 0x33D,
+ DAI_CH_I2SIND2L = 0x3B5,
+ DAI_CH_I2SIND2R = 0x3BD,
+ DAI_CH_I2SINA3L = 0x435,
+ DAI_CH_I2SINA3R = 0x43D,
+ DAI_CH_I2SINB3L = 0x4B5,
+ DAI_CH_I2SINB3R = 0x4BD,
+ DAI_CH_I2SINC3L = 0x535,
+ DAI_CH_I2SINC3R = 0x53D,
+ DAI_CH_I2SIND3L = 0x5B5,
+ DAI_CH_I2SIND3R = 0x5BD,
+ DAI_CH_I2SINA4L = 0x635,
+ DAI_CH_I2SINA4R = 0x63D,
+ DAI_CH_I2SINB4L = 0x6B5,
+ DAI_CH_I2SINB4R = 0x6BD,
+ DAI_CH_I2SINC4L = 0x735,
+ DAI_CH_I2SINC4R = 0x73D,
+ DAI_CH_I2SIND4L = 0x7B5,
+ DAI_CH_I2SIND4R = 0x7BD,
+ DAI_CH_I2SINA5L = 0x835,
+ DAI_CH_I2SINA5R = 0x83D,
+ DAI_CH_I2SINB5L = 0x8B5,
+ DAI_CH_I2SINB5R = 0x8BD,
+ DAI_CH_I2SINC5L = 0x935,
+ DAI_CH_I2SINC5R = 0x93D,
+ DAI_CH_I2SIND5L = 0x9B5,
+ DAI_CH_I2SIND5R = 0x9BD,
+ DAI_CH_I2SINA6L = 0xA35,
+ DAI_CH_I2SINA6R = 0xA3D,
+ DAI_CH_I2SINB6L = 0xAB5,
+ DAI_CH_I2SINB6R = 0xABD,
+ DAI_CH_I2SINC6L = 0xB35,
+ DAI_CH_I2SINC6R = 0xB3D,
+ DAI_CH_I2SIND6L = 0xBB5,
+ DAI_CH_I2SIND6R = 0xBBD,
+ DAI_CH_I2SINA7L = 0xC35,
+ DAI_CH_I2SINA7R = 0xC3D,
+ DAI_CH_I2SINB7L = 0xCB5,
+ DAI_CH_I2SINB7R = 0xCBD,
+ DAI_CH_I2SINC7L = 0xD35,
+ DAI_CH_I2SINC7R = 0xD3D,
+ DAI_CH_I2SIND7L = 0xDB5,
+ DAI_CH_I2SIND7R = 0xDBD,
+ DAI_CH_I2SINA8L = 0xE35,
+ DAI_CH_I2SINA8R = 0xE3D,
+ DAI_CH_I2SINB8L = 0xEB5,
+ DAI_CH_I2SINB8R = 0xEBD,
+ DAI_CH_I2SINC8L = 0xF35,
+ DAI_CH_I2SINC8R = 0xF3D,
+ DAI_CH_I2SIND8L = 0xFB5,
+ DAI_CH_I2SIND8R = 0xFBD,
+
+ //daio cd-spidf block
+ DAI_CH_CDSPDIFINA1L = 0x015,
+ DAI_CH_CDSPDIFINA1R = 0x01D,
+ DAI_CH_CDSPDIFINB1L = 0x095,
+ DAI_CH_CDSPDIFINB1R = 0x09D,
+ DAI_CH_CDSPDIFINC1L = 0x115,
+ DAI_CH_CDSPDIFINC1R = 0x11D,
+ DAI_CH_CDSPDIFIND1L = 0x195,
+ DAI_CH_CDSPDIFIND1R = 0x19D,
+ DAI_CH_CDSPDIFINA2L = 0x215,
+ DAI_CH_CDSPDIFINA2R = 0x21D,
+ DAI_CH_CDSPDIFINB2L = 0x295,
+ DAI_CH_CDSPDIFINB2R = 0x29D,
+ DAI_CH_CDSPDIFINC2L = 0x315,
+ DAI_CH_CDSPDIFINC2R = 0x31D,
+ DAI_CH_CDSPDIFIND2L = 0x395,
+ DAI_CH_CDSPDIFIND2R = 0x39D,
+ DAI_CH_CDSPDIFINA3L = 0x415,
+ DAI_CH_CDSPDIFINA3R = 0x41D,
+ DAI_CH_CDSPDIFINB3L = 0x495,
+ DAI_CH_CDSPDIFINB3R = 0x49D,
+ DAI_CH_CDSPDIFINC3L = 0x515,
+ DAI_CH_CDSPDIFINC3R = 0x51D,
+ DAI_CH_CDSPDIFIND3L = 0x595,
+ DAI_CH_CDSPDIFIND3R = 0x59D,
+ DAI_CH_CDSPDIFINA4L = 0x615,
+ DAI_CH_CDSPDIFINA4R = 0x61D,
+ DAI_CH_CDSPDIFINB4L = 0x695,
+ DAI_CH_CDSPDIFINB4R = 0x69D,
+ DAI_CH_CDSPDIFINC4L = 0x715,
+ DAI_CH_CDSPDIFINC4R = 0x71D,
+ DAI_CH_CDSPDIFIND4L = 0x795,
+ DAI_CH_CDSPDIFIND4R = 0x79D,
+ DAI_CH_CDSPDIFINA5L = 0x815,
+ DAI_CH_CDSPDIFINA5R = 0x81D,
+ DAI_CH_CDSPDIFINB5L = 0x895,
+ DAI_CH_CDSPDIFINB5R = 0x89D,
+ DAI_CH_CDSPDIFINC5L = 0x915,
+ DAI_CH_CDSPDIFINC5R = 0x91D,
+ DAI_CH_CDSPDIFIND5L = 0x995,
+ DAI_CH_CDSPDIFIND5R = 0x99D,
+ DAI_CH_CDSPDIFINA6L = 0xA15,
+ DAI_CH_CDSPDIFINA6R = 0xA1D,
+ DAI_CH_CDSPDIFINB6L = 0xA95,
+ DAI_CH_CDSPDIFINB6R = 0xA9D,
+ DAI_CH_CDSPDIFINC6L = 0xB15,
+ DAI_CH_CDSPDIFINC6R = 0xB1D,
+ DAI_CH_CDSPDIFIND6L = 0xB95,
+ DAI_CH_CDSPDIFIND6R = 0xB9D,
+ DAI_CH_CDSPDIFINA7L = 0xC15,
+ DAI_CH_CDSPDIFINA7R = 0xC1D,
+ DAI_CH_CDSPDIFINB7L = 0xC95,
+ DAI_CH_CDSPDIFINB7R = 0xC9D,
+ DAI_CH_CDSPDIFINC7L = 0xD15,
+ DAI_CH_CDSPDIFINC7R = 0xD1D,
+ DAI_CH_CDSPDIFIND7L = 0xD95,
+ DAI_CH_CDSPDIFIND7R = 0xD9D,
+ DAI_CH_CDSPDIFINA8L = 0xE15,
+ DAI_CH_CDSPDIFINA8R = 0xE1D,
+ DAI_CH_CDSPDIFINB8L = 0xE95,
+ DAI_CH_CDSPDIFINB8R = 0xE9D,
+ DAI_CH_CDSPDIFINC8L = 0xF15,
+ DAI_CH_CDSPDIFINC8R = 0xF1D,
+ DAI_CH_CDSPDIFIND8L = 0xF95,
+ DAI_CH_CDSPDIFIND8R = 0xF9D
+} ARCHANNEL;
+
+
+#endif
diff --git a/kernel/drv/oss_sbxfi/hwaccess.h b/kernel/drv/oss_sbxfi/hwaccess.h
new file mode 100644
index 0000000..872e2e2
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/hwaccess.h
@@ -0,0 +1,71 @@
+/**
+*******************************************************************************
+Confidential & Proprietary
+Private & Confidential
+Creative Confidential
+*******************************************************************************
+*/
+/**
+*******************************************************************************
+Copyright (C) Creative Technology, Ltd., 2007. All rights reserved.
+*******************************************************************************
+**/
+
+#ifndef _HWACCESS_H_
+#define _HWACCESS_H_
+
+unsigned int GetAudioSrcChan (unsigned int srcchn);
+unsigned int GetAudioSumChan (unsigned int chn);
+unsigned int GetParamPitchChan (unsigned int i);
+void WriteAMOP (sbxfi_devc_t * devc, unsigned int xdata, unsigned int ydata,
+ unsigned int chn, unsigned int hidata);
+void WriteSRC (sbxfi_devc_t * devc, unsigned int srcca, unsigned int srccf,
+ unsigned int srcsa, unsigned int srcla, unsigned int srcccr, unsigned int srcctl,
+ unsigned int chn);
+unsigned int HwRead20K1PCI (sbxfi_devc_t * devc, unsigned int dwReg);
+unsigned int HwRead20K1 (sbxfi_devc_t * devc, unsigned int dwReg);
+void HwWrite20K1 (sbxfi_devc_t * devc, unsigned int dwReg, unsigned int dwData);
+void HwWrite20K1PCI (sbxfi_devc_t * devc, unsigned int dwReg, unsigned int dwData);
+unsigned int ReadCfgDword (unsigned int dwBusNum, unsigned int dwDevNum, unsigned int dwFuncNum,
+ unsigned int dwReg);
+unsigned short ReadCfgWord (unsigned int dwBusNum, unsigned int dwDevNum, unsigned int dwFuncNum,
+ unsigned int dwReg);
+void WriteConfigDword (unsigned int dwBusNum, unsigned int dwDevNum, unsigned int dwFuncNum,
+ unsigned int dwReg, unsigned int dwData);
+
+unsigned char DetectAndConfigureHardware (sbxfi_devc_t * devc);
+unsigned char IsVistaCompatibleHardware (sbxfi_devc_t * devc);
+void SwitchToXFiCore (sbxfi_devc_t * devc);
+CTSTATUS InitHardware (sbxfi_devc_t * devc);
+CTSTATUS AllocateBuffers (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void FreeBuffers (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void SetupHardwarePageTable (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void InitADC (sbxfi_devc_t * devc, unsigned int src, unsigned char mic20db);
+void ResetDAC (sbxfi_devc_t * devc);
+void InitDAC (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+
+void SetupPlayMixer (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void UpdatePlayMixer (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void SetupPlayFormat (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void SetupAndStartPlaySRC (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void StopPlaySRC (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void SetupPlayInputMapper (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void StopPlay (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+
+void SetupRecordMixer (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void SetupRecordFormat (sbxfi_devc_t * devc);
+void SetupAndStartRecordSRC (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void StopRecordSRC (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void SetupRecordInputMapper (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void SetupInputToOutputMonitoring (sbxfi_devc_t * devc,
+ sbxfi_portc_t * portc);
+
+void _dumpRegisters (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void _dumpSRCs (sbxfi_devc_t * devc, sbxfi_portc_t * portc);
+void _dumpGlobal (sbxfi_devc_t * devc);
+
+#define osDelayms(usecs) oss_udelay(usecs)
+#define osInportd(devc, ioaddr) INL(devc->osdev, ioaddr)
+#define osOutportd(devc, ioaddr, data) OUTL(devc->osdev, data, ioaddr)
+
+#endif
diff --git a/kernel/drv/oss_sbxfi/oss_sbxfi.c b/kernel/drv/oss_sbxfi/oss_sbxfi.c
new file mode 100644
index 0000000..837ab33
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/oss_sbxfi.c
@@ -0,0 +1,1078 @@
+/*
+ * Purpose: Driver for Sound Blaster X-Fi (emu20k)
+ *
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_sbxfi_cfg.h"
+#include <oss_pci.h>
+#include "sbxfi.h"
+#include "20k1reg.h"
+#include "hwaccess.h"
+
+#define PCI_VENDOR_CREATIVE 0x1102
+#define CREATIVE_SBXFI_K1 0x0005
+#define CREATIVE_SBXFI_K2 0x000b
+#define CREATIVE_SBXFI_E 0x0009
+
+#define TIMER_INTERVAL 5 /* In milliseconds */
+
+#define DEFAULT_PLAY_RATE 96000 /* Default rate of play devices */
+#define DEFAULT_REC_RATE 96000 /* Default rate of rec devices */
+#define HARDWARE_RATE 96000 /* Internal rate used by the hardware */
+
+static void
+set_interval_timer(sbxfi_devc_t *devc, int msecs)
+{
+ int tic = (HARDWARE_RATE*msecs)/1000;
+
+ HwWrite20K1 (devc, TIMR, tic | TIMR_IE|TIMR_IP);
+}
+
+static int
+sbxfi_intr(oss_device_t *osdev)
+{
+ unsigned int status;
+ sbxfi_devc_t *devc = osdev->devc;
+
+ status = HwRead20K1 (devc, GIP);
+
+ if (status==0) /* Not for me */
+ return 0;
+
+ devc->interrupt_count++;
+
+#if 0
+ // Not using loop interrupts.
+ if (status & SRC_INT) /* SRC interrupt(s) pending */
+ {
+ unsigned int srcipm, srcip;
+ int i;
+
+ srcipm = HwRead20K1 (devc, SRCIPM); /* SRC interrupt pending map register */
+
+ for (i=0;i<7;i++)
+ if (srcipm & (1<<i))
+ {
+ int j;
+ srcip = HwRead20K1 (devc, SRCIP(i)); /* SRC interrupt pending register for block(i) */
+
+ for (j=0;j<32;j++)
+ if (srcip & (1<<j))
+ {
+ int chn=i*32+j;
+ sbxfi_portc_t *portc;
+
+ portc=devc->src_to_portc[chn];
+
+ if (portc==NULL)
+ {
+ cmn_err(CE_NOTE, "portc==NULL\n");
+ continue;
+ }
+
+ oss_audio_outputintr(portc->dev, 0);
+ }
+
+ HwWrite20K1 (devc, SRCIP(i), srcip); /* Acknowledge SRC interrupts for block(i) */
+ }
+ }
+#endif
+
+ if (status & IT_INT)
+ {
+ /*
+ * Interval timer interrupt
+ */
+ sbxfi_portc_t *portc;
+ int i;
+
+ for (i=0;i<devc->nr_outdevs;i++)
+ {
+ portc=&devc->play_portc[i];
+ if (portc->running)
+ oss_audio_outputintr(portc->dev, 0);
+ }
+
+ for (i=0;i<devc->nr_indevs;i++)
+ {
+ portc=&devc->rec_portc[i];
+ if (portc->running)
+ oss_audio_inputintr(portc->dev, 0);
+ }
+
+ set_interval_timer(devc, TIMER_INTERVAL); /* Rearm interval timer */
+ }
+
+ HwWrite20K1 (devc, GIP, status & FI_INT); /* Acknowledge interrupts */
+ return 1;
+}
+
+ /*ARGSUSED*/ static int
+sbxfi_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static mixer_driver_t sbxfi_mixer_driver = {
+ sbxfi_mixer_ioctl
+};
+
+static int
+sbxfi_set_rate (int dev, int arg)
+{
+ sbxfi_devc_t *devc = audio_engines[dev]->devc;
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+#if 0
+ // TODO: Implement support for other rates
+
+ if (arg == 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return portc->rate;
+ }
+
+#else
+ if (portc->direction == PCM_ENABLE_OUTPUT)
+ arg=DEFAULT_PLAY_RATE;
+ else
+ arg=DEFAULT_REC_RATE;
+#endif
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return portc->rate = arg;
+}
+
+static short
+sbxfi_set_channels (int dev, short arg)
+{
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->channels;
+
+ if (arg<2)
+ arg=2;
+ else
+ if (arg > MAX_PLAY_CHANNELS)
+ arg = MAX_PLAY_CHANNELS;
+ arg &= ~1; /* Even number of channels */
+
+ return portc->channels = arg;
+}
+
+static unsigned int
+sbxfi_set_format (int dev, unsigned int arg)
+{
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->fmt;
+
+ return portc->fmt = SUPPORTED_FORMAT;
+}
+
+static int
+sbxfi_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ //sbxfi_portc_t *portc = audio_engines[dev]->portc;
+ //sbxfi_devc_t *devc = audio_engines[dev]->devc;
+
+ return OSS_EINVAL;
+}
+
+static void sbxfi_trigger (int dev, int state);
+
+static void
+sbxfi_reset (int dev)
+{
+ sbxfi_trigger (dev, 0);
+}
+
+ /*ARGSUSED*/ static int
+sbxfi_open_input (int dev, int mode, int open_flags)
+{
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+ sbxfi_devc_t *devc = audio_engines[dev]->devc;
+ adev_p adev = audio_engines[dev];
+ oss_native_word flags;
+
+ if (mode & OPEN_WRITE)
+ {
+ cmn_err (CE_CONT, "Playback is not possible with %s\n", adev->devnode);
+ return OSS_ENOTSUP;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ portc->open_mode = mode;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+sbxfi_open_output (int dev, int mode, int open_flags)
+{
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+ sbxfi_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ adev_p adev = audio_engines[dev];
+
+ if (mode == OPEN_READ)
+ {
+ cmn_err (CE_CONT, "Recording is not possible with %s\n", adev->devnode);
+ return OSS_ENOTSUP;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+sbxfi_close (int dev, int mode)
+{
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+ sbxfi_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ portc->open_mode = 0;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+ /*ARGSUSED*/ static void
+sbxfi_output_block (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+ /*ARGSUSED*/ static void
+sbxfi_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+static void
+sbxfi_trigger (int dev, int state)
+{
+ sbxfi_devc_t *devc = audio_engines[dev]->devc;
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->state_bits == state) /* No change */
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return;
+ }
+ portc->state_bits = state;
+
+ if (portc->direction == PCM_ENABLE_OUTPUT)
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ SetupAndStartPlaySRC (devc, portc);
+ portc->running=1;
+ }
+ else
+ {
+ StopPlaySRC (devc, portc);
+ portc->running=0;
+ }
+ }
+
+ if (portc->direction == PCM_ENABLE_INPUT)
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ SetupAndStartRecordSRC (devc, portc);
+ portc->running=1;
+ }
+ else
+ {
+ StopRecordSRC (devc, portc);
+ portc->running=0;
+ }
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+ /*ARGSUSED*/ static int
+sbxfi_prepare_for_input (int dev, int bsize, int bcount)
+{
+ sbxfi_devc_t *devc = audio_engines[dev]->devc;
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_in;
+ oss_native_word flags;
+ int i;
+
+ if (audio_engines[dev]->flags & ADEV_NOINPUT)
+ return OSS_EACCES;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ // Fill record buffer to the page table entries.
+ // This need to sync up with setting SRCs start addx
+ for (i=0;i<(bsize*bcount)/4096;i++)
+ devc->pdwPageTable[portc->pgtable_index+i] = dmap->dmabuf_phys + (i*4096);
+
+ InitADC (devc, portc->dwDAChan[0], FALSE);
+
+ // Program input mapper
+ SetupRecordInputMapper (devc, portc);
+
+ // Program I2S
+ SetupRecordFormat (devc);
+ SetupRecordMixer (devc, portc);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+sbxfi_prepare_for_output (int dev, int bsize, int bcount)
+{
+ sbxfi_devc_t *devc = audio_engines[dev]->devc;
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_out;
+ oss_native_word flags;
+ int i;
+
+ if (audio_engines[dev]->flags & ADEV_NOOUTPUT)
+ return OSS_EACCES;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ // Fill play buffer to the page table entries.
+ // This need to sync up with setting SRCs start addx
+ for (i=0;i<(bsize*bcount)/4096;i++)
+ devc->pdwPageTable[portc->pgtable_index+i] = dmap->dmabuf_phys + (i*4096);
+
+ InitDAC (devc, portc);
+
+ // Program I2S
+ SetupPlayFormat (devc, portc);
+ SetupPlayMixer (devc, portc);
+
+ // Program input mapper
+ SetupPlayInputMapper (devc, portc);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+sbxfi_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ sbxfi_devc_t *devc = audio_engines[dev]->devc;
+ sbxfi_portc_t *portc = audio_engines[dev]->portc;
+ int pos;
+
+ pos = HwRead20K1 (devc, SRCCA(portc->SrcChan)) & 0x03ffffff;
+
+ if (pos>=128)
+ pos -= 128; /* The pointer is always 128 bytes ahead */
+
+ pos -= portc->pgtable_index*4096;
+
+ return pos;
+}
+
+static audiodrv_t sbxfi_output_driver = {
+ sbxfi_open_output,
+ sbxfi_close,
+ sbxfi_output_block,
+ sbxfi_start_input,
+ sbxfi_ioctl,
+ sbxfi_prepare_for_input,
+ sbxfi_prepare_for_output,
+ sbxfi_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ sbxfi_trigger,
+ sbxfi_set_rate,
+ sbxfi_set_format,
+ sbxfi_set_channels,
+ NULL,
+ NULL,
+ NULL, /* check input */
+ NULL, /* sbxfi_check_output */
+ NULL, /* sbxfi_alloc_buffer */
+ NULL, /* sbxfi_free_buffer */
+ NULL,
+ NULL,
+ sbxfi_get_buffer_pointer
+};
+
+static audiodrv_t sbxfi_input_driver = {
+ sbxfi_open_input,
+ sbxfi_close,
+ sbxfi_output_block,
+ sbxfi_start_input,
+ sbxfi_ioctl,
+ sbxfi_prepare_for_input,
+ sbxfi_prepare_for_output,
+ sbxfi_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ sbxfi_trigger,
+ sbxfi_set_rate,
+ sbxfi_set_format,
+ sbxfi_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* sbxfi_alloc_buffer */
+ NULL, /* sbxfi_free_buffer */
+ NULL,
+ NULL,
+ sbxfi_get_buffer_pointer
+};
+
+static int
+init_play_device (sbxfi_devc_t * devc,
+ char *name, int dev_flags)
+{
+ int opts, dev, formats;
+ char tmp[80];
+ sbxfi_portc_t *portc = NULL;
+ adev_p adev;
+
+ sprintf (tmp, "%s %s", devc->name, name);
+
+ if (devc->nr_outdevs > MAX_OUTPUTDEVS)
+ {
+ cmn_err (CE_CONT, "Too many audio devices\n");
+ return -1;
+ }
+
+ opts = ADEV_AUTOMODE | ADEV_NOINPUT;
+
+ formats = SUPPORTED_FORMAT;
+
+ if ((dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp,
+ &sbxfi_output_driver,
+ sizeof (audiodrv_t),
+ opts, formats, devc, -1)) < 0)
+ {
+ return -1;
+ }
+
+ if (devc->first_dev == -1)
+ {
+ devc->first_dev = dev;
+ }
+ adev = audio_engines[dev];
+
+ portc = &devc->play_portc[devc->nr_outdevs];
+
+ adev->portc = portc;
+ adev->devc = devc;
+ adev->mixer_dev = devc->mixer_dev;
+ adev->rate_source = devc->first_dev;
+ adev->min_rate = 48000;
+ adev->max_rate = 92600;
+ adev->min_block=4096;
+ adev->dmabuf_maxaddr = MEMLIMIT_ISA;
+
+ portc->dev = dev;
+ portc->open_mode = 0;
+ portc->fmt = SUPPORTED_FORMAT;
+ portc->dev_flags = dev_flags;
+ portc->state_bits = 0;
+ portc->direction = PCM_ENABLE_OUTPUT;
+
+ portc->rate = DEFAULT_PLAY_RATE;
+
+ // use the following SRC channels for Play
+ portc->SrcChan = devc->next_src;
+ devc->next_src += MAX_PLAY_CHANNELS;
+ devc->src_to_portc[portc->SrcChan]=portc;
+
+ portc->dwDAChan[0] = I2SA_L;
+ portc->dwDAChan[1] = I2SA_R;
+#if MAX_PLAY_CHANNELS>2
+ portc->dwDAChan[2] = I2SB_L;
+ portc->dwDAChan[3] = I2SB_R;
+ portc->dwDAChan[4] = I2SC_L;
+ portc->dwDAChan[5] = I2SC_R;
+#endif
+
+ portc->vol_left=portc->vol_right=MIXER_VOLSTEPS;
+
+ adev->min_channels = 2;
+ adev->max_channels = MAX_PLAY_CHANNELS;
+
+ portc->pgtable_index = devc->next_pg;
+ devc->next_pg += 128/4; // Up to 128k for buffer
+
+ devc->nr_outdevs++;
+
+ return dev;
+}
+
+static int
+init_rec_device (sbxfi_devc_t * devc,
+ char *name, int dev_flags)
+{
+ int opts, dev, formats;
+ char tmp[80];
+ sbxfi_portc_t *portc = NULL;
+ adev_p adev;
+
+ sprintf (tmp, "%s %s", devc->name, name);
+
+ if (devc->nr_indevs > MAX_INPUTDEVS)
+ {
+ cmn_err (CE_CONT, "Too many audio devices\n");
+ return -1;
+ }
+
+ opts = ADEV_AUTOMODE | ADEV_NOOUTPUT;
+
+ formats = SUPPORTED_FORMAT;
+
+ if ((dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp,
+ &sbxfi_input_driver,
+ sizeof (audiodrv_t),
+ opts, formats, devc, -1)) < 0)
+ {
+ return -1;
+ }
+
+ if (devc->first_dev == -1)
+ {
+ devc->first_dev = dev;
+ }
+ adev = audio_engines[dev];
+
+ portc = &devc->rec_portc[devc->nr_indevs];
+
+ adev->portc = portc;
+ adev->devc = devc;
+ adev->mixer_dev = devc->mixer_dev;
+ adev->rate_source = devc->first_dev;
+ adev->min_rate = 48000;
+ adev->max_rate = 96000;
+ adev->min_block=4096;
+ adev->dmabuf_maxaddr = MEMLIMIT_ISA;
+
+ portc->dev = dev;
+ portc->open_mode = 0;
+ portc->fmt = SUPPORTED_FORMAT;
+ portc->dev_flags = dev_flags;
+ portc->state_bits = 0;
+ portc->direction = PCM_ENABLE_INPUT;
+
+ portc->rate = DEFAULT_REC_RATE;
+
+ // use the following SRC channels for record
+ portc->SrcChan = devc->next_src;
+ devc->next_src += 2;
+ devc->src_to_portc[portc->SrcChan]=portc;
+
+ portc->dwDAChan[0] = ADC_SRC_LINEIN;
+
+ portc->vol_left=portc->vol_right=MIXER_VOLSTEPS;
+
+ adev->min_channels = 2;
+ adev->max_channels = 2;
+
+ portc->pgtable_index = devc->next_pg;
+ devc->next_pg += 128/4; // Up to 128k for buffer
+
+ devc->nr_indevs++;
+
+ return dev;
+}
+
+static int
+sbxfi_set_playvol (int dev, int ctrl, unsigned int cmd, int value)
+{
+ sbxfi_devc_t *devc = mixer_devs[dev]->devc;
+ sbxfi_portc_t *portc;
+ int left, right;
+
+ if (ctrl<0 || ctrl >= devc->nr_outdevs)
+ return OSS_ENXIO;
+ portc = &devc->play_portc[ctrl];
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return portc->vol_left | (portc->vol_right << 16);
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ left = value & 0xffff;
+ right = (value>>16) & 0xffff;
+
+ if (left > MIXER_VOLSTEPS)
+ left=MIXER_VOLSTEPS;
+ if (right > MIXER_VOLSTEPS)
+ right=MIXER_VOLSTEPS;
+
+ portc->vol_left=left;
+ portc->vol_right=right;
+ if (portc->running)
+ SetupPlayMixer(devc, portc);
+
+ return portc->vol_left | (portc->vol_right << 16);
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+sbxfi_set_recvol (int dev, int ctrl, unsigned int cmd, int value)
+{
+ sbxfi_devc_t *devc = mixer_devs[dev]->devc;
+ sbxfi_portc_t *portc;
+ int left, right;
+
+ if (ctrl<0 || ctrl >= devc->nr_indevs)
+ return OSS_ENXIO;
+ portc = &devc->rec_portc[ctrl];
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return portc->vol_left | (portc->vol_right << 16);
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ left = value & 0xffff;
+ right = (value>>16) & 0xffff;
+
+ if (left > MIXER_VOLSTEPS)
+ left=MIXER_VOLSTEPS;
+ if (right > MIXER_VOLSTEPS)
+ right=MIXER_VOLSTEPS;
+
+ portc->vol_left=left;
+ portc->vol_right=right;
+ if (portc->running)
+ SetupRecordMixer(devc, portc);
+
+ return portc->vol_left | (portc->vol_right << 16);
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+sbxfi_set_recsrc (int dev, int ctrl, unsigned int cmd, int value)
+{
+ sbxfi_devc_t *devc = mixer_devs[dev]->devc;
+ sbxfi_portc_t *portc;
+
+ if (ctrl<0 || ctrl >= devc->nr_indevs)
+ return OSS_ENXIO;
+ portc = &devc->rec_portc[ctrl];
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return portc->dwDAChan[0];
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ if (value<0 || value>ADC_SRC_NONE)
+ return portc->dwDAChan[0];
+
+ return portc->dwDAChan[0]=value;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+sbxfi_mix_init (int dev)
+{
+ int root=0, ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, root,
+ 0, sbxfi_set_playvol,
+ MIXT_STEREOSLIDER16,
+ "play", MIXER_VOLSTEPS,
+ MIXF_PCMVOL | MIXF_READABLE |
+ MIXF_WRITEABLE | MIXF_CENTIBEL)) <
+ 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, root,
+ 0, sbxfi_set_recvol,
+ MIXT_STEREOSLIDER16,
+ "rec", MIXER_VOLSTEPS,
+ MIXF_RECVOL | MIXF_READABLE |
+ MIXF_WRITEABLE | MIXF_CENTIBEL)) <
+ 0)
+ return ctl;
+
+ if ((ctl = mixer_ext_create_control (dev, root,
+ 0, sbxfi_set_recsrc,
+ MIXT_ENUM,
+ "recsrc", 5,
+ MIXF_READABLE |
+ MIXF_WRITEABLE | MIXF_CENTIBEL)) <
+ 0)
+ return ctl;
+
+ mixer_ext_set_strings (dev, ctl, "mic line video aux none", 0);
+
+ return 0;
+}
+
+int
+oss_sbxfi_attach (oss_device_t * osdev)
+{
+ unsigned short pci_command, vendor, device, revision;
+ unsigned short subvendor, subdevice;
+ int pdev, rdev;
+ extern int sbxfi_type;
+
+ sbxfi_devc_t *devc;
+ sbxfi_portc_t *portc;
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ memset (devc, 0, sizeof (*devc));
+
+ portc = &devc->play_portc[0];
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->name = "Sound Blaster X-Fi";
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ DDB (cmn_err
+ (CE_CONT, "oss_sbxfi_attach(Vendor %x, device %x)\n", vendor, device));
+
+ if (vendor != PCI_VENDOR_CREATIVE ||
+ (device != CREATIVE_SBXFI_K1 && device != CREATIVE_SBXFI_K2 &&
+ device != CREATIVE_SBXFI_E))
+ {
+ cmn_err (CE_WARN, "Hardware not recognized (vendor=%x, dev=%x)\n",
+ vendor, device);
+ return 0;
+ }
+ MUTEX_INIT (osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (osdev, devc->low_mutex, MH_DRV + 1);
+
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor);
+ pci_read_config_word (osdev, PCI_SUBSYSTEM_ID, &subdevice);
+ pci_read_config_word (osdev, PCI_REVISION_ID, &revision);
+
+ devc->wVendorID = vendor;
+ devc->wDeviceID = device;
+ devc->wSubsystemVendorID = subvendor;
+ devc->wSubsystemID = subdevice;
+ devc->wChipRevision = revision;
+
+ switch (sbxfi_type)
+ {
+ case 1:
+ devc->name = "Sound Blaster X-Fi (SB046x/067x/076x)";
+ devc->hw_family = HW_ORIG;
+ break;
+
+ case 2:
+ devc->name = "Sound Blaster X-Fi (SB073x)";
+ devc->hw_family = HW_073x;
+ break;
+
+ case 3:
+ devc->name = "Sound Blaster X-Fi (SB055x)";
+ devc->hw_family = HW_055x;
+ break;
+
+ case 4:
+ devc->name = "Sound Blaster X-Fi (UAA)";
+ devc->hw_family = HW_UAA;
+ break;
+
+ case 5:
+ devc->name = "Sound Blaster X-Fi (SB076x)";
+ devc->hw_family = HW_0760;
+ break;
+
+ case 6:
+ devc->name = "Sound Blaster X-Fi (SB0880-1)";
+ devc->hw_family = HW_08801;
+ break;
+
+ case 7:
+ devc->name = "Sound Blaster X-Fi (SB0880-2)";
+ devc->hw_family = HW_08802;
+ break;
+
+ case 8:
+ devc->name = "Sound Blaster X-Fi (SB0880-3)";
+ devc->hw_family = HW_08803;
+ break;
+
+ case 0:
+ default:
+ devc->hw_family = 0;
+ break;
+ }
+
+ if (!devc->hw_family && device == CREATIVE_SBXFI_K1) // EMU20K1 models
+ switch (subdevice)
+ {
+ case 0x0021: /* SB0460 */
+ case 0x0023:
+ case 0x0024:
+ case 0x0025:
+ case 0x0026:
+ case 0x0027:
+ case 0x0028:
+ case 0x002a:
+ case 0x002b:
+ case 0x002c:
+ case 0x002d:
+ case 0x002e:
+ case 0x0032:
+ case 0x0033:
+ case 0x0034: /* This is actually Auzentech Prelude (subvendor 415a) */
+ /*
+ * Original X-Fi hardware revision (SB046x/067x/076x)
+ */
+ devc->name = "Sound Blaster X-Fi (SB046x/067x/076x)";
+ devc->hw_family = HW_ORIG;
+ break;
+
+ case 0x0029:
+ case 0x0031:
+ devc->name = "Sound Blaster X-Fi (SB073x)";
+ devc->hw_family = HW_073x;
+ break;
+
+ case 0x0022:
+ case 0x002f:
+ devc->name = "Sound Blaster X-Fi (SB055x)";
+ devc->hw_family = HW_055x;
+ break;
+
+ default:
+ if (subdevice >= 0x6000 && subdevice <= 0x6fff) /* "Vista compatible" HW */
+ {
+ devc->name = "Sound Blaster X-Fi (UAA)";
+ devc->hw_family = HW_UAA;
+ }
+ }
+
+ if (!devc->hw_family && device == CREATIVE_SBXFI_K2) // EMU 20K2 models
+ switch (subdevice)
+ {
+ case PCI_SUBDEVICE_ID_CREATIVE_SB0760:
+ devc->name = "Sound Blaster X-Fi (SB076x)";
+ devc->hw_family = HW_0760;
+ break;
+
+ case PCI_SUBDEVICE_ID_CREATIVE_SB08801:
+ devc->name = "Sound Blaster X-Fi (SB0880-1)";
+ devc->hw_family = HW_08801;
+ break;
+
+ case PCI_SUBDEVICE_ID_CREATIVE_SB08802:
+ devc->name = "Sound Blaster X-Fi (SB0880-2)";
+ devc->hw_family = HW_08802;
+ break;
+
+ case PCI_SUBDEVICE_ID_CREATIVE_SB08803:
+ devc->name = "Sound Blaster X-Fi (SB0880-3)";
+ devc->hw_family = HW_08803;
+ break;
+
+ default:
+ devc->name = "Sound Blaster X-Fi (20K2)";
+ devc->hw_family = HW_UAA; // Just a wild guess
+ }
+
+ if (!devc->hw_family && device == CREATIVE_SBXFI_E) // PCI-e models
+ {
+ devc->name = "Sound Blaster X-Fi (PCI-e)";
+ devc->hw_family = HW_UAA; // Just a wild guess
+ }
+
+
+#if 1
+// Temporary hacking until proper 20K2 support is in place
+ if (devc->hw_family > HW_UAA) devc->hw_family = HW_UAA;
+#endif
+
+ oss_register_device (osdev, devc->name);
+
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ if ((osdev->hw_info = PMALLOC (osdev, 200)) != NULL)
+ {
+ sprintf (osdev->hw_info, "PCI device %04x:%04x, subdevice %04x:%04x\n",
+ vendor, device, subvendor, subdevice);
+ }
+
+ devc->interrupt_count=0;
+ if (oss_register_interrupts (devc->osdev, 0, sbxfi_intr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Unable to install interrupt handler\n");
+ return 0;
+ }
+
+ // Detect and Configure X-Fi PCI config space.
+ // Obtain the resource configuration from PCI config space.
+ if (!DetectAndConfigureHardware (devc))
+ {
+ cmn_err (CE_WARN, "Cannot configure X-Fi hardware...\n");
+ return 0;
+ }
+
+ if (IsVistaCompatibleHardware (devc))
+ {
+ // Switch to audio core to X-Fi core.
+ SwitchToXFiCore (devc);
+ }
+
+ // Initialize hardware. This include setup the PLL etc.
+ if (InitHardware (devc) != CTSTATUS_SUCCESS)
+ {
+ cmn_err (CE_WARN, "Init Hardware failed...\n");
+ return 0;
+ }
+
+ devc->dwPageTableSize = 1024; /* For up to 4M of memory */
+ devc->pdwPageTable = CONTIG_MALLOC (devc->osdev,
+ devc->dwPageTableSize,
+ MEMLIMIT_ISA, &devc->dwPTBPhysAddx, devc->pgtable_dma_handle);
+
+ HwWrite20K1 (devc, PTPALX, devc->dwPTBPhysAddx);
+ HwWrite20K1 (devc, PTPAHX, 0);
+
+ HwWrite20K1 (devc, TRNCTL, 0x13);
+ HwWrite20K1 (devc, TRNIS, 0x200c01);
+
+ HwWrite20K1 (devc, GIE, FI_INT); /* Enable "forced" interrupts */
+ HwWrite20K1 (devc, GIP, FI_INT); /* Trigger forced interrupt */
+
+ oss_udelay(1000);
+ if (devc->interrupt_count==0)
+ cmn_err(CE_WARN, "Interrupts don't seem to be working.\n");
+
+ set_interval_timer(devc, TIMER_INTERVAL);
+
+/*
+ * Disable FI and enable selected global interrupts
+ * (SRC, Interval Timer).
+ */
+ HwWrite20K1 (devc, GIE, SRC_INT | IT_INT);
+
+ if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ devc->name,
+ &sbxfi_mixer_driver,
+ sizeof (mixer_driver_t),
+ devc)) >= 0)
+ {
+ mixer_devs[devc->mixer_dev]->hw_devc = devc;
+ mixer_devs[devc->mixer_dev]->priority = 1; /* Possible default mixer candidate */
+ mixer_ext_set_init_fn (devc->mixer_dev, sbxfi_mix_init, 10);
+ }
+
+ devc->first_dev=-1; /* Not assigned */
+ pdev = init_play_device (devc, "output", 0);
+ rdev = init_rec_device (devc, "input", 0);
+#ifdef CONFIG_OSS_VMIX
+ if (pdev != -1)
+ {
+ vmix_attach_audiodev (devc->osdev, pdev, rdev, 0);
+ }
+#endif
+
+#if 0
+ // Initialize ADC
+ InitADC (devc, ADC_SRC_LINEIN, FALSE);
+#endif
+
+ return 1;
+}
+
+int
+oss_sbxfi_detach (oss_device_t * osdev)
+{
+ sbxfi_devc_t *devc = (sbxfi_devc_t *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ HwWrite20K1 (devc, GIE, 0); /* Disable global interrupts */
+ oss_unregister_interrupts (devc->osdev);
+
+ HwWrite20K1 (devc, PTPALX, 0);
+ if (devc->pdwPageTable != NULL)
+ {
+ CONTIG_FREE (devc->osdev, devc->pdwPageTable, devc->dwPageTableSize, devc->pgtable_dma_handle);
+ devc->pdwPageTable = NULL;
+ }
+ oss_unregister_device (osdev);
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ return 1;
+}
diff --git a/kernel/drv/oss_sbxfi/oss_sbxfi.man b/kernel/drv/oss_sbxfi/oss_sbxfi.man
new file mode 100644
index 0000000..a1f10bd
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/oss_sbxfi.man
@@ -0,0 +1,20 @@
+NAME
+oss_sbxfi - SoundBlaster X-Fi audio driver
+
+DESCRIPTION
+Open Sound System driver for the SoundBlaster X-Fi cards.
+
+OPTIONS
+o sbxfi_type Override X-Fi type autodetection. Values:
+ 0 - Autodetect type
+ 1 - Sound Blaster X-Fi (SB046x/067x/076x)
+ 2 - Sound Blaster X-Fi (SB073x)
+ 3 - Sound Blaster X-Fi (SB055x)
+ 4 - Sound Blaster X-Fi (UAA)
+ Default : 0.
+
+FILES
+CONFIGFILEPATH/oss_sbxfi.conf Device configuration file.
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_sbxfi/sbxfi.h b/kernel/drv/oss_sbxfi/sbxfi.h
new file mode 100644
index 0000000..dfb529f
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/sbxfi.h
@@ -0,0 +1,166 @@
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define PCI_SUBDEVICE_ID_CREATIVE_SB0760 0x0024
+#define PCI_SUBDEVICE_ID_CREATIVE_SB08801 0x0041
+#define PCI_SUBDEVICE_ID_CREATIVE_SB08802 0x0042
+#define PCI_SUBDEVICE_ID_CREATIVE_SB08803 0x0043
+
+#define MAX_OUTPUTDEVS 1
+#define MAX_INPUTDEVS 1
+#define SUPPORTED_FORMAT (AFMT_S16_LE)
+
+#define MIXER_VOLSTEPS 144 /* Centibel steps */
+
+//#define MAX_PLAY_CHANNELS 6 /* Does not work */
+#define MAX_PLAY_CHANNELS 2
+
+#if 0
+typedef unsigned char CTBYTE, *PCTBYTE;
+typedef unsigned short unsigned short, *Punsigned short;
+typedef signed short CTSHORT, *PCTSHORT;
+typedef unsigned int unsigned int, *unsigned int *;
+typedef signed long CTLONG, *PCTLONG;
+typedef void CTVOID, *PCTVOID;
+typedef unsigned int CTBOOL, *PCTBOOL;
+typedef unsigned int CTUINT, *PCTUINT;
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+typedef unsigned int CTSTATUS;
+typedef oss_native_word IOADDR;
+
+enum GlobalErrorCode
+{
+ CTSTATUS_SUCCESS = 0x0000,
+ CTSTATUS_ERROR,
+ CTSTATUS_INVALIDPARAM,
+ CTSTATUS_NOTSUPPORTED,
+ CTSTATUS_NOMEMORY,
+ CTSTATUS_INVALIDIO,
+ CTSTATUS_INVALIDIRQ,
+ CTSTATUS_INVALIDDMA,
+ CTSTATUS_INVALIDID,
+ CTSTATUS_INVALIDVALUE,
+ CTSTATUS_BADFORMAT_BITS,
+ CTSTATUS_BADFORMAT_RATE,
+ CTSTATUS_BADFORMAT_CHANNELS,
+ CTSTATUS_INUSE,
+ CTSTATUS_STILLPLAYING,
+ CTSTATUS_ALLOCATED,
+ CTSTATUS_INVALID_FORMAT,
+ CTSTATUS_OUT_OF_RESOURCE,
+ CTSTATUS_CHIP_INUSE,
+ CTSTATUS_NOCHIPRESOURCE,
+ CTSTATUS_PORTS_INUSE,
+ CTSTATUS_EXIT,
+ CTSTATUS_FAILURE
+};
+
+
+#define ADC_SRC_MICIN 0x0
+#define ADC_SRC_LINEIN 0x1
+#define ADC_SRC_VIDEO 0x2
+#define ADC_SRC_AUX 0x3
+#define ADC_SRC_NONE 0x4
+
+typedef struct
+{
+ char *name;
+ int dev;
+ int open_mode;
+ int fmt;
+ int dev_flags;
+ int direction;
+ int state_bits;
+ int pgtable_index; // Pointer to the first page table entry
+
+ int running;
+
+ int channels;
+
+ unsigned int rate;
+
+ // Audio Ring resources
+ unsigned int SrcChan;
+
+ unsigned int dwDAChan[MAX_PLAY_CHANNELS];
+
+ // Play volumes
+ int vol_left, vol_right;
+} sbxfi_portc_t;
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ char *name;
+ int hw_family;
+
+// 20K1 models
+#define HW_ORIG 0x0001
+#define HW_073x 0x0002
+#define HW_055x 0x0004
+#define HW_UAA 0x0008
+
+// 20K2 models
+#define HW_0760 0x0010
+#define HW_08801 0x0020
+#define HW_08802 0x0040
+#define HW_08803 0x0080
+
+
+ unsigned int interrupt_count;
+
+ // Hardware IDs
+ unsigned short wVendorID;
+ unsigned short wDeviceID;
+ unsigned short wSubsystemVendorID;
+ unsigned short wSubsystemID;
+ unsigned short wChipRevision;
+
+ // Hardware Resources
+ unsigned int dwMemBase;
+ unsigned short wIOPortBase;
+
+ // Buffers
+ oss_native_word dwPTBPhysAddx;
+ unsigned int *pdwPageTable;
+ unsigned int dwPageTableSize;
+ oss_dma_handle_t pgtable_dma_handle;
+ int next_pg; /* Next free index in the page table */
+
+ sbxfi_portc_t play_portc[MAX_OUTPUTDEVS];
+ int nr_outdevs;
+
+ sbxfi_portc_t rec_portc[MAX_INPUTDEVS];
+ int nr_indevs;
+
+ // Mixer
+ int mixer_dev;
+
+ // Audio
+ int first_dev;
+
+ int next_src; // Next free SRC channel
+
+ sbxfi_portc_t *src_to_portc[256];
+} sbxfi_devc_t;
diff --git a/kernel/drv/oss_sbxfi/sbxfi_hwaccess.c b/kernel/drv/oss_sbxfi/sbxfi_hwaccess.c
new file mode 100644
index 0000000..4d4dad9
--- /dev/null
+++ b/kernel/drv/oss_sbxfi/sbxfi_hwaccess.c
@@ -0,0 +1,1391 @@
+/**
+*******************************************************************************
+Confidential & Proprietary
+Private & Confidential
+Creative Confidential
+*******************************************************************************
+*/
+/**
+*******************************************************************************
+Copyright (C) Creative Technology, Ltd., 2007. All rights reserved.
+*******************************************************************************
+**/
+#include "oss_sbxfi_cfg.h"
+#include <oss_pci.h>
+#include "sbxfi.h"
+#include "20k1reg.h"
+#include "hwaccess.h"
+
+static const int
+volume_table[MIXER_VOLSTEPS+1] =
+{
+ 0x0000000, 0x000010a, 0x0000110, 0x0000116, 0x000011d,
+ 0x0000124, 0x000012a, 0x0000131, 0x0000138, 0x0000140,
+ 0x0000147, 0x000014f, 0x0000157, 0x000015f, 0x0000167,
+ 0x000016f, 0x0000178, 0x0000180, 0x0000189, 0x0000193,
+ 0x000019c, 0x00001a6, 0x00001af, 0x00001b9, 0x00001c4,
+ 0x00001ce, 0x00001d9, 0x00001e4, 0x00001ef, 0x00001fb,
+ 0x0000207, 0x0000213, 0x000021f, 0x000022c, 0x0000239,
+ 0x0000246, 0x0000254, 0x0000262, 0x0000270, 0x000027e,
+ 0x000028d, 0x000029c, 0x00002ac, 0x00002bc, 0x00002cc,
+ 0x00002dd, 0x00002ee, 0x0000300, 0x0000311, 0x0000324,
+ 0x0000336, 0x000034a, 0x000035d, 0x0000371, 0x0000386,
+ 0x000039b, 0x00003b0, 0x00003c6, 0x00003dd, 0x00003f4,
+ 0x000040c, 0x0000424, 0x000043c, 0x0000456, 0x0000470,
+ 0x000048a, 0x00004a5, 0x00004c1, 0x00004dd, 0x00004fa,
+ 0x0000518, 0x0000536, 0x0000555, 0x0000575, 0x0000596,
+ 0x00005b7, 0x00005d9, 0x00005fc, 0x0000620, 0x0000644,
+ 0x000066a, 0x0000690, 0x00006b7, 0x00006df, 0x0000708,
+ 0x0000732, 0x000075d, 0x0000789, 0x00007b6, 0x00007e4,
+ 0x0000813, 0x0000843, 0x0000874, 0x00008a7, 0x00008da,
+ 0x000090f, 0x0000945, 0x000097c, 0x00009b5, 0x00009ef,
+ 0x0000a2a, 0x0000a67, 0x0000aa5, 0x0000ae4, 0x0000b25,
+ 0x0000b68, 0x0000bac, 0x0000bf1, 0x0000c38, 0x0000c81,
+ 0x0000ccc, 0x0000d18, 0x0000d66, 0x0000db6, 0x0000e08,
+ 0x0000e5c, 0x0000eb1, 0x0000f09, 0x0000f63, 0x0000fbe,
+ 0x000101c, 0x000107c, 0x00010df, 0x0001143, 0x00011aa,
+ 0x0001214, 0x000127f, 0x00012ee, 0x000135f, 0x00013d2,
+ 0x0001448, 0x00014c1, 0x000153d, 0x00015bc, 0x000163d,
+ 0x00016c2, 0x000174a, 0x00017d4, 0x0001863, 0x00018f4,
+ 0x0001989, 0x0001a21, 0x0001abd, 0x0001b5c, 0x0001c00
+};
+
+unsigned char
+DetectAndConfigureHardware (sbxfi_devc_t * devc)
+{
+ unsigned short wData;
+
+ // Default setting for hendrix card is memory access, so must get IO access port from bar5.
+ // bar0 will be converted to IO access in SwitchToXFiCore()
+ if (devc->hw_family == HW_UAA)
+ {
+ // Base IO address is at register lcoation 0x24 (bar5)
+ pci_read_config_word (devc->osdev, PCI_BASE_ADDRESS_5, &wData);
+ devc->wIOPortBase = wData & 0xFFFC;
+ }
+ else
+ {
+ // Get the IO base address
+ pci_read_config_word (devc->osdev, PCI_BASE_ADDRESS_0, &wData);
+ devc->wIOPortBase = wData & 0xFFFC;
+ }
+
+ return TRUE;
+}
+
+unsigned char
+IsVistaCompatibleHardware (sbxfi_devc_t * devc)
+{
+ // Check the subsystem id
+ if (devc->hw_family == HW_UAA)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+SwitchToXFiCore (sbxfi_devc_t * devc)
+{
+ unsigned int bar0, bar1, bar2, bar3, bar4, bar5, irq, clSize, lTimer;
+
+ // program the hardware to X-Fi core.
+ // Check whether its hendrix card
+ // Save the previous memory/io address
+
+ pci_read_config_dword (devc->osdev, PCI_BASE_ADDRESS_0, &bar0);
+ pci_read_config_dword (devc->osdev, PCI_BASE_ADDRESS_1, &bar1);
+ pci_read_config_dword (devc->osdev, PCI_BASE_ADDRESS_2, &bar2);
+ pci_read_config_dword (devc->osdev, PCI_BASE_ADDRESS_3, &bar3);
+ pci_read_config_dword (devc->osdev, PCI_BASE_ADDRESS_4, &bar4);
+ pci_read_config_dword (devc->osdev, PCI_BASE_ADDRESS_5, &bar5);
+
+ pci_read_config_dword (devc->osdev, PCI_INTERRUPT_LINE, &irq);
+ pci_read_config_dword (devc->osdev, PCI_CFGHDR_CACHESIZE, &clSize);
+ pci_read_config_dword (devc->osdev, PCI_CFGHDR_LATENCY, &lTimer);
+
+ cmn_err (CE_CONT, "Switching to xfi core...\n");
+
+ // Switch to XFi core config space with BAR0
+ pci_write_config_dword (devc->osdev, 0xA0, 0x87654321);
+
+ // copy Base I/O address from UAA core to X-Fi core
+ pci_write_config_dword (devc->osdev, PCI_BASE_ADDRESS_5, bar5);
+
+ // Switch to XFi core config space without BAR0
+ pci_write_config_dword (devc->osdev, 0xA0, 0x12345678);
+
+ // copy all other setting from UAA config space to X-Fi config space
+ pci_write_config_dword (devc->osdev, PCI_BASE_ADDRESS_1, bar1);
+ pci_write_config_dword (devc->osdev, PCI_BASE_ADDRESS_2, bar2);
+ pci_write_config_dword (devc->osdev, PCI_BASE_ADDRESS_3, bar3);
+ pci_write_config_dword (devc->osdev, PCI_BASE_ADDRESS_4, bar4);
+
+ pci_write_config_dword (devc->osdev, PCI_INTERRUPT_LINE, irq);
+ pci_write_config_dword (devc->osdev, PCI_CFGHDR_CACHESIZE, clSize);
+ pci_write_config_dword (devc->osdev, PCI_CFGHDR_LATENCY, lTimer);
+
+ pci_write_config_dword (devc->osdev, PCI_CFGHDR_CMDREG, 0x07);
+
+ /*
+ NOTE:
+ The steps below is needed to switch the control signals to X-Fi core.
+
+ It needs to access the mode change register which reside in the UAA core BAR0 + 0x00003ffc.
+ Since this demo sample is a real-mode DOS program, it will need other services such as XMS to access
+ memory above 1MB.
+
+ Here is the pseudo code:
+
+ WriteMemory((bar0 + 0x00003ffc),0x43544c58); // CTLX
+ WriteMemory((bar0 + 0x00003ffc),0x43544c2d); // CTL-
+ WriteMemory((bar0 + 0x00003ffc),0x43544c46); // CTLF
+ WriteMemory((bar0 + 0x00003ffc),0x43544c69); // CTLi
+ */
+}
+
+
+CTSTATUS
+InitHardware (sbxfi_devc_t * devc)
+{
+ unsigned int gctlorg;
+ unsigned int dwIterCount, dwData;
+
+
+ // kick in auto-init
+ gctlorg = HwRead20K1 (devc, GCTL);
+ HwWrite20K1 (devc, GCTL, (~0x2 & gctlorg));
+ HwWrite20K1 (devc, GCTL, (0x2 | gctlorg));
+ osDelayms (1000);
+ // poll for AID in GCTL to be set
+ dwIterCount = 0x400000;
+ do
+ {
+ dwData = HwRead20K1 (devc, GCTL);
+ }
+ while (!(dwData & 0x00100000) && --dwIterCount);
+
+ // AID bit is not set when time out, return failure.
+ if (!(dwData & 0x00100000))
+ return CTSTATUS_ERROR;
+
+ gctlorg = HwRead20K1 (devc, GCTL);
+ HwWrite20K1 (devc, GCTL, (0x100aa3 | gctlorg));
+ osDelayms (10000);
+
+ HwWrite20K1 (devc, GIE, 0);
+ HwWrite20K1 (devc, SRCIP(0), 0);
+ osDelayms (30000);
+
+ if (((HwRead20K1 (devc, PLLCTL)) != 0x1480a001)
+ && ((HwRead20K1 (devc, PLLCTL)) != 0x1480a731))
+ {
+ HwWrite20K1 (devc, PLLCTL, 0x1480a001);
+ }
+ osDelayms (40000);
+ dwData = HwRead20K1 (devc, PLLCTL);
+
+ // configure GPIO per the card's family.
+ switch (devc->hw_family)
+ {
+ case HW_055x:
+ HwWrite20K1 (devc, GPIOCTL, 0x13fe);
+ break;
+ case HW_073x:
+ HwWrite20K1 (devc, GPIOCTL, 0x00e6);
+ break;
+ case HW_UAA:
+ HwWrite20K1 (devc, GPIOCTL, 0x00c2);
+ break;
+ case HW_ORIG:
+ default:
+ HwWrite20K1 (devc, GPIOCTL, 0x01e6);
+ break;
+ }
+
+ return CTSTATUS_SUCCESS;
+}
+
+CTSTATUS
+AllocateBuffers (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ int ctStatus = CTSTATUS_SUCCESS;
+
+#if 0
+ if (devc->pdwPageTable == NULL)
+ ctStatus = CTSTATUS_NOMEMORY;
+ else
+ {
+ // alloc playL buffer
+ portc->pdwPlayLBuffer = CONTIG_MALLOC (devc->osdev,
+ portc->dwPlayLBufferSize,
+ MEMLIMIT_32BITS,
+ &portc->dwPlayLPhysAddx, portc->playl_dma_handle);
+
+ if (portc->pdwPlayLBuffer == NULL)
+ ctStatus = CTSTATUS_NOMEMORY;
+ else
+ {
+ // alloc playR buffer
+ portc->pdwPlayRBuffer = CONTIG_MALLOC (devc->osdev,
+ portc->dwPlayRBufferSize,
+ MEMLIMIT_32BITS,
+ &portc->dwPlayLPhysAddx,portc->playr_dma_handle);
+
+ if (portc->pdwPlayRBuffer == NULL)
+ ctStatus = CTSTATUS_NOMEMORY;
+ else
+ {
+ // alloc recordL buffer
+ portc->pdwRecordLBuffer = CONTIG_MALLOC (devc->osdev,
+ portc->
+ dwRecordLBufferSize,
+ MEMLIMIT_32BITS,
+ &portc->
+ dwRecordLPhysAddx, portc->recl_dma_handle);
+
+ if (portc->pdwRecordLBuffer == NULL)
+ ctStatus = CTSTATUS_NOMEMORY;
+ else
+ {
+ // alloc recordR buffer
+ portc->pdwRecordRBuffer = CONTIG_MALLOC (devc->osdev,
+ portc->
+ dwRecordRBufferSize,
+ MEMLIMIT_32BITS,
+ &portc->
+ dwRecordRPhysAddx, portc->recr_dma_handle);
+ if (portc->pdwRecordRBuffer == NULL)
+ ctStatus = CTSTATUS_NOMEMORY;
+ }
+ }
+ }
+ }
+
+ if (ctStatus != CTSTATUS_SUCCESS)
+ FreeBuffers (devc, portc);
+#endif
+
+ return ctStatus;
+}
+
+void
+FreeBuffers (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+#if 0
+ if (portc->pdwRecordLBuffer != NULL)
+ {
+ CONTIG_FREE (devc->osdev, portc->pdwRecordLBuffer,
+ portc->dwRecordLBufferSize, portc->recl_dma_handle);
+ portc->pdwRecordLBuffer = NULL;
+ }
+
+ if (portc->pdwRecordRBuffer != NULL)
+ {
+ CONTIG_FREE (devc->osdev, portc->pdwRecordRBuffer,
+ portc->dwRecordRBufferSize, portc->recr_dma_handle);
+ portc->pdwRecordRBuffer = NULL;
+ }
+
+ if (portc->pdwPlayLBuffer != NULL)
+ {
+ CONTIG_FREE (devc->osdev, portc->pdwPlayLBuffer,
+ portc->dwPlayLBufferSize, portc->playl_dma_handle);
+ portc->pdwPlayLBuffer = NULL;
+ }
+
+ if (portc->pdwPlayRBuffer != NULL)
+ {
+ CONTIG_FREE (devc->osdev, portc->pdwPlayRBuffer,
+ portc->dwPlayRBufferSize, portc->playr_dma_handle);
+ portc->pdwPlayRBuffer = NULL;
+ }
+#endif
+}
+
+void
+_SetupSB055xADC (sbxfi_devc_t * devc, unsigned int src, unsigned char mic20db)
+{
+ unsigned short gpioorg;
+ unsigned short gpioval = 0x28;
+
+
+ // check and set the following GPIO bits accordingly
+ // ADC_Gain = GPIO2
+ // Mic_Pwr_on = GPIO7
+ // Digital_IO_Sel = GPIO8
+ // Mic_Sw = GPIO9
+ // Aux/MicLine_Sw = GPIO12
+ switch (src)
+ {
+ case ADC_SRC_MICIN:
+ gpioval = 0x28;
+ if (mic20db)
+ gpioval |= 4;
+ break;
+
+ case ADC_SRC_LINEIN:
+ gpioval = 0;
+ break;
+
+ case ADC_SRC_VIDEO:
+ gpioval = 0x100; // not supported, set to digital
+ break;
+
+ case ADC_SRC_AUX:
+ gpioval = 0x1000;
+ break;
+
+ case ADC_SRC_NONE:
+ gpioval = 0x100; // set to digital
+ break;
+
+ default:
+ break;
+ }
+
+ gpioorg = (unsigned short) HwRead20K1 (devc, GPIO);
+ gpioorg &= 0xec7b;
+ gpioorg |= gpioval;
+ HwWrite20K1 (devc, GPIO, gpioorg);
+
+ return;
+}
+
+void
+_SetupADC (sbxfi_devc_t * devc, unsigned int src, unsigned char mic20db)
+{
+ unsigned int i = 0;
+ unsigned short gpioorg;
+ unsigned short input_source;
+ unsigned int adcdata = 0;
+
+ input_source = 0x100; // default to analog
+ switch (src)
+ {
+ case ADC_SRC_MICIN:
+ adcdata = 0x1;
+ input_source = 0x180; // set GPIO7 to select Mic
+ break;
+
+ case ADC_SRC_LINEIN:
+ adcdata = 0x2;
+ break;
+
+ case ADC_SRC_VIDEO:
+ adcdata = 0x4;
+ break;
+
+ case ADC_SRC_AUX:
+ adcdata = 0x8;
+ break;
+
+ case ADC_SRC_NONE:
+ adcdata = 0x0;
+ input_source = 0x0; // set to Digital
+ break;
+
+ default:
+ break;
+ }
+
+
+ HwWrite20K1PCI (devc, 0xcc, 0x8c);
+ HwWrite20K1PCI (devc, 0xcc, 0x0e);
+ if (((HwRead20K1PCI (devc, 0xcc)) & 0xff) != 0xaa)
+ {
+ HwWrite20K1PCI (devc, 0xcc, 0xee);
+ HwWrite20K1PCI (devc, 0xcc, 0xaa);
+ }
+
+ if (((HwRead20K1PCI (devc, 0xcc)) & 0xff) != 0xaa)
+ return;
+
+ HwWrite20K1PCI (devc, 0xEC, 0x05); //write to i2c status control
+
+ HwWrite20K1PCI (devc, 0xE0, 0x001a0080);
+ HwWrite20K1PCI (devc, 0xE4, 0x080e);
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ HwWrite20K1PCI (devc, 0xE0, 0x001a0080);
+ HwWrite20K1PCI (devc, 0xE4, 0x0a18);
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ HwWrite20K1PCI (devc, 0xE0, 0x001a0080);
+
+ if (mic20db)
+ HwWrite20K1PCI (devc, 0xE4, 0xf71c);
+ else
+ HwWrite20K1PCI (devc, 0xE4, 0xcf1c);
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ HwWrite20K1PCI (devc, 0xE0, 0x001a0080);
+
+ if (mic20db)
+ HwWrite20K1PCI (devc, 0xE4, 0xf71e);
+ else
+ HwWrite20K1PCI (devc, 0xE4, 0xcf1e);
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ HwWrite20K1PCI (devc, 0xE0, 0x001a0080);
+ HwWrite20K1PCI (devc, 0xE4, 0x8628);
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ HwWrite20K1PCI (devc, 0xE0, 0x001a0080);
+ HwWrite20K1PCI (devc, 0xE4, 0x2a | (adcdata << 0x8));
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ } //i2c ready poll
+
+ gpioorg = (unsigned short) HwRead20K1 (devc, GPIO);
+ gpioorg &= 0xfe7f;
+ gpioorg |= input_source;
+ HwWrite20K1 (devc, GPIO, gpioorg);
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ if (!((HwRead20K1 (devc, ID0)) & 0x100))
+ {
+ HwWrite20K1PCI (devc, 0xE0, 0x001a0080);
+ HwWrite20K1PCI (devc, 0xE4, 0x2616);
+ }
+
+ return;
+}
+
+void
+InitADC (sbxfi_devc_t * devc, unsigned int src, unsigned char mic20db)
+{
+ unsigned short wSSID;
+
+ wSSID = devc->wSubsystemID;
+ if ((wSSID == 0x0022) || (wSSID == 0x002F))
+ {
+ // Sb055x card
+ _SetupSB055xADC (devc, src, mic20db);
+ }
+ else
+ {
+ _SetupADC (devc, src, mic20db);
+ }
+
+ return;
+}
+
+void
+ResetDAC (sbxfi_devc_t * devc)
+{
+ unsigned int i = 0;
+ unsigned short gpioorg;
+
+
+ HwWrite20K1PCI (devc, 0xcc, 0x8c);
+ HwWrite20K1PCI (devc, 0xcc, 0x0e);
+ if (((HwRead20K1PCI (devc, 0xcc)) & 0xff) != 0xaa)
+ {
+ HwWrite20K1PCI (devc, 0xcc, 0xee);
+ HwWrite20K1PCI (devc, 0xcc, 0xaa);
+ }
+ if (((HwRead20K1PCI (devc, 0xcc)) & 0xff) != 0xaa)
+ return;
+
+ HwWrite20K1PCI (devc, 0xEC, 0x05); //write to i2c status control
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ // To be effective, need to reset the DAC twice.
+ for (i = 0; i < 2; i++)
+ {
+ osDelayms (100000);
+ gpioorg = (unsigned short) HwRead20K1 (devc, GPIO);
+ gpioorg &= 0xfffd;
+ HwWrite20K1 (devc, GPIO, gpioorg);
+ osDelayms (1000);
+ HwWrite20K1 (devc, GPIO, gpioorg | 0x2);
+ } //set gpio
+
+ HwWrite20K1PCI (devc, 0xE0, 0x00180080);
+ HwWrite20K1PCI (devc, 0xE4, 0x8001);
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ HwWrite20K1PCI (devc, 0xE0, 0x00180080);
+ HwWrite20K1PCI (devc, 0xE4, 0x1002);
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+}
+
+void
+InitDAC (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int i = 0;
+ unsigned int wData;
+ unsigned short gpioorg;
+ unsigned int dwSamplingRate;
+ unsigned short wSSID;
+
+
+ wSSID = devc->wSubsystemID;
+ // if SB055x, unmute outputs
+ if ((wSSID == 0x0022) || (wSSID == 0x002F))
+ {
+ gpioorg = (unsigned short) HwRead20K1 (devc, GPIO);
+ gpioorg &= 0xffbf; // set GPIO6 to low
+ gpioorg |= 2; // set GPIO1 to high
+ HwWrite20K1 (devc, GPIO, gpioorg);
+
+ return;
+ }
+
+
+ dwSamplingRate = portc->rate;
+
+ // Mute outputs
+ gpioorg = (unsigned short) HwRead20K1 (devc, GPIO);
+ gpioorg &= 0xffbf;
+ HwWrite20K1 (devc, GPIO, gpioorg);
+
+ ResetDAC (devc);
+
+ HwWrite20K1PCI (devc, 0xcc, 0x8c);
+ HwWrite20K1PCI (devc, 0xcc, 0x0e);
+ if (((HwRead20K1PCI (devc, 0xcc)) & 0xff) != 0xaa)
+ {
+ HwWrite20K1PCI (devc, 0xcc, 0xee);
+ HwWrite20K1PCI (devc, 0xcc, 0xaa);
+ }
+ if (((HwRead20K1PCI (devc, 0xcc)) & 0xff) != 0xaa)
+ return;
+
+ HwWrite20K1PCI (devc, 0xEC, 0x05); //write to i2c status control
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ if (dwSamplingRate == 48000)
+ wData = 0x2400;
+ else if (dwSamplingRate == 96000)
+ wData = 0x2500;
+ else if (dwSamplingRate == 192000)
+ wData = 0x2600;
+ else
+ wData = 0x2400;
+
+ HwWrite20K1PCI (devc, 0xE0, 0x00180080);
+ HwWrite20K1PCI (devc, 0xE4, (wData | 0x6));
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ HwWrite20K1PCI (devc, 0xE0, 0x00180080);
+ HwWrite20K1PCI (devc, 0xE4, (wData | 0x9));
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ HwWrite20K1PCI (devc, 0xE0, 0x00180080);
+ HwWrite20K1PCI (devc, 0xE4, (wData | 0xc));
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ HwWrite20K1PCI (devc, 0xE0, 0x00180080);
+ HwWrite20K1PCI (devc, 0xE4, (wData | 0xf));
+
+ i = 0;
+ while (i != 0x800000)
+ {
+ i = ((HwRead20K1PCI (devc, 0xEC)) & 0x800000);
+ }
+
+ // unmute outputs
+ gpioorg = (unsigned short) HwRead20K1 (devc, GPIO);
+ gpioorg = gpioorg | 0x40;
+ HwWrite20K1 (devc, GPIO, gpioorg);
+}
+
+
+void
+SetupPlayInputMapper (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+/*
+ * TODO: This routine supports only stereo
+ */
+ unsigned int i;
+ unsigned int srcch;
+ unsigned int dio1, dio2;
+ unsigned int dwSamplingRate;
+
+
+ srcch = portc->SrcChan;
+ dio1 = portc->dwDAChan[0];
+ dio2 = portc->dwDAChan[1];
+ dwSamplingRate = portc->rate;
+
+ // initialize input mappers
+ for (i = 0; i < 0x50; i++)
+ HwWrite20K1 (devc, DAOIMAP_START(i), 0);
+
+ if (dwSamplingRate == 48000)
+ {
+ if (dio1 == 0)
+ {
+ HwWrite20K1 (devc, DAOIMAP_START(dio1), 0);
+ for (i=1;i<portc->channels;i++)
+ HwWrite20K1 (devc, DAOIMAP_START(dio2),
+ (dio1 << 16) | GetAudioSrcChan (srcch+i));
+ HwWrite20K1 (devc, DAOIMAP_START(dio1),
+ (dio2 << 16) | GetAudioSrcChan (srcch));
+ }
+ else
+ {
+ HwWrite20K1 (devc, DAOIMAP_START(0), 0);
+ HwWrite20K1 (devc, DAOIMAP_START(dio1),
+ (dio2 << 16) | GetAudioSrcChan (srcch));
+ for (i=1;i<portc->channels;i++)
+ HwWrite20K1 (devc, DAOIMAP_START(dio2),
+ (0 << 16) | GetAudioSrcChan (srcch+i));
+ HwWrite20K1 (devc, DAOIMAP_START(0), (dio1 << 16) | 0);
+ }
+ }
+ else if (dwSamplingRate == 96000)
+ {
+ // input mapper. Input mapper is a circular linked-list
+ if (dio1 == 0)
+ {
+ HwWrite20K1 (devc, DAOIMAP_START(dio1), 0);
+ for (i=1;i<portc->channels;i++)
+ HwWrite20K1 (devc, DAOIMAP_START(dio2),
+ ((dio1 + 2) << 16) | GetAudioSrcChan (srcch+i));
+ HwWrite20K1 (devc, DAOIMAP_START(dio1 + 2),
+ ((dio2 + 2) << 16) | GetAudioSrcChan (srcch + 0x80));
+ for (i=1;i<portc->channels;i++)
+ HwWrite20K1 (devc, DAOIMAP_START(dio2 + 2),
+ (dio1 << 16) | GetAudioSrcChan (srcch+i + 0x80));
+ HwWrite20K1 (devc, DAOIMAP_START(dio1),
+ (dio2 << 16) | GetAudioSrcChan (srcch));
+ }
+ else
+ {
+ HwWrite20K1 (devc, DAOIMAP_START(0), 0);
+ HwWrite20K1 (devc, DAOIMAP_START(dio1),
+ (dio2 << 16) | GetAudioSrcChan (srcch));
+ for (i=1;i<portc->channels;i++)
+ HwWrite20K1 (devc, DAOIMAP_START(dio2),
+ ((dio1 + 2) << 16) | GetAudioSrcChan (srcch+i));
+ HwWrite20K1 (devc, DAOIMAP_START(dio1 + 2),
+ ((dio2 + 2) << 16) | GetAudioSrcChan (srcch + 0x80));
+ for (i=1;i<portc->channels;i++)
+ HwWrite20K1 (devc, DAOIMAP_START(dio2 + 2),
+ (0 << 16) | GetAudioSrcChan (srcch+i + 0x80));
+ HwWrite20K1 (devc, DAOIMAP_START(0), (dio1 << 16) | 0);
+ }
+ }
+}
+
+void
+SetupPlayFormat (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int i2sorg;
+ unsigned int dio1;
+ unsigned int dwSamplingRate;
+
+
+ dio1 = portc->dwDAChan[0];
+ dwSamplingRate = portc->rate;
+
+ // Read I2S CTL. Keep original value.
+ i2sorg = HwRead20K1 (devc, I2SCTL);
+
+#if 1
+ i2sorg = i2sorg | 0x04040404; // All I2S outputs enabled
+#else
+ // setup I2S value to program
+ switch (dio1)
+ {
+ case I2SA_L:
+ i2sorg = i2sorg | 0x4;
+ break;
+ case I2SB_L:
+ i2sorg = i2sorg | 0x400;
+ break;
+ case I2SC_L:
+ i2sorg = i2sorg | 0x40000;
+ break;
+ case I2SD_L:
+ i2sorg = i2sorg | 0x4000000;
+ break;
+ default:
+ i2sorg = i2sorg | 0x4;
+ break;
+ }
+#endif
+
+ // Program I2S with proper sample rate and enable the correct I2S channel.
+ i2sorg &= 0xfffffffc;
+ if (dwSamplingRate == 96000)
+ {
+ i2sorg = i2sorg | 2;
+ HwWrite20K1 (devc, I2SCTL, i2sorg);
+ }
+ else
+ {
+ i2sorg = i2sorg | 1;
+ HwWrite20K1 (devc, I2SCTL, i2sorg);
+ }
+}
+
+void
+SetupPlayMixer (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ int i;
+ unsigned int fixed_pitch;
+ unsigned int srcArchn, srcArchnC;
+ unsigned int srcPrchn, srcPrchnC;
+ unsigned int srcArchn2, srcArchnC2;
+ unsigned int srcch;
+ unsigned int dwSamplingRate;
+ unsigned int dwYData;
+
+ srcch = portc->SrcChan;
+ dwSamplingRate = portc->rate;
+
+ // NOTE: Y-Data is a 14-bit immediate floating-point constant multiplier.
+ // Adjust the Y-Data to control the multiplier.
+ // This can be used to control the level of the signal.
+ // dwYData = 0x1c00; // Original level used by Creative's driver.
+ dwYData = volume_table[portc->vol_left];
+
+ srcArchn = GetAudioSrcChan (srcch);
+ srcArchnC = GetAudioSrcChan (srcch + 0x80); // conjugate channel for srcch
+ srcPrchn = GetParamPitchChan (srcch);
+ srcPrchnC = GetParamPitchChan (srcch + 0x80);
+
+ // since input is same as output, pitch is 1.0
+ // convert to fixed-point 8.24 format, shift left 24 bit.
+ fixed_pitch = 1;
+ fixed_pitch = fixed_pitch << 24;
+
+ // write the pitch to param ring of the corresponsing SRC pitch slot
+ HwWrite20K1 (devc, PRING_LO_HI_START(srcPrchn), fixed_pitch);
+ HwWrite20K1 (devc, PRING_LO_HI_START(srcPrchnC), fixed_pitch);
+
+ WriteAMOP (devc, srcArchn, dwYData, srcArchn, 0);
+ if (dwSamplingRate == 96000)
+ {
+ WriteAMOP (devc, srcArchnC, dwYData, srcArchnC, 0);
+ }
+
+ // Handle subsequent channels
+
+ for (i=1;i<portc->channels;i++)
+ {
+ dwYData = volume_table[(i&1) ? portc->vol_right : portc->vol_left];
+
+ // Since we will use 1st SRC ch as pitch master,
+ // we do not need to program the pitch for SRC ch2
+
+ srcArchn2 = GetAudioSrcChan (srcch+i);
+ srcArchnC2 = GetAudioSrcChan (srcch+i + 0x80); // conjugate channel for srcch+i
+
+ WriteAMOP (devc, srcArchn2, dwYData, srcArchn2, 0);
+ if (dwSamplingRate == 96000)
+ {
+ WriteAMOP (devc, srcArchnC2, dwYData, srcArchnC2, 0);
+ }
+ }
+}
+
+void
+SetupAndStartPlaySRC (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int Sa, Ladr, Ca, Ctl = 0x44c;
+ unsigned int srcch;
+ unsigned int dwSamplingRate;
+ int count;
+ int i;
+
+ srcch = portc->SrcChan;
+ dwSamplingRate = portc->rate;
+
+ count = audio_engines[portc->dev]->dmap_out->bytes_in_use;
+
+ // start addx: 1st entry in page table.
+ // Note: this must match with pagetable entry
+ Sa = portc->pgtable_index * 4096;
+ Ladr = Sa + count;
+ Ca = Sa + 0x100;
+ if (dwSamplingRate == 48000)
+ Ctl = 0x44c; // Set the Pitch Master for stereo.
+ else if ((dwSamplingRate == 96000))
+ Ctl = 0x45c; // Set the Pitch Master for stereo.
+
+ Ctl |= (portc->channels-1)*SRCCTL_ILSZ; /* Number of interleaved channels to follow */
+
+ // Program SRC for channel 1, enable interrupts and interleaved channels
+ WriteSRC (devc, Ca, 0, Sa, Ladr, 0x100, Ctl, srcch);
+
+ Ladr = Sa + count;
+ Ca = Sa + 0x100;
+
+ for (i=1;i<portc->channels;i++)
+ {
+ if (dwSamplingRate == 48000)
+ Ctl = 0x4c; // slave
+ else if ((dwSamplingRate == 96000))
+ Ctl = 0x5c; // slave
+ Ctl |= (portc->channels-i-1)*SRCCTL_ILSZ;
+
+ // Program SRC for channel 2
+ WriteSRC (devc, Ca, 0, Sa, Ladr, 0x100, Ctl, srcch+i);
+ }
+
+ //_dumpRegisters (devc, portc);
+}
+
+void
+StopPlay (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int srcch;
+ unsigned int dwData;
+ int i;
+
+ srcch = portc->SrcChan;
+
+ //WriteSRC(devc, 0, 0, 0, 0, 0, 0, srcch);
+ //WriteSRC(devc, 0, 0, 0, 0, 0, 0, srcch2);
+
+ dwData = HwRead20K1 (devc, SRCCTL(srcch));
+ dwData &= 0xfffffff0;
+ dwData |= 0;
+ dwData &= ~SRCCTL_IE; /* Interrupt disable */
+ HwWrite20K1 (devc, SRCCTL(srcch), dwData);
+
+ for (i=1;i<portc->channels;i++)
+ {
+ dwData = HwRead20K1 (devc, SRCCTL(srcch+i));
+ dwData &= 0xfffffff0;
+ dwData |= 0;
+ HwWrite20K1 (devc, SRCCTL(srcch+i), dwData);
+ }
+}
+
+
+void
+StopPlaySRC (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+#ifndef INTERNAL_LOOPBACK
+ StopPlay (devc, portc);
+#endif
+}
+
+
+//======================== RECORD ==========================
+
+
+
+void
+SetupRecordInputMapper (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int srcch, srcch2;
+
+
+ srcch = portc->SrcChan;
+ srcch2 = portc->SrcChan+1;
+
+ // Internal loopback means loop play channels to record
+#ifdef INTERNAL_LOOPBACK
+ {
+ unsigned int playch1, playch2;
+
+ playch1 = portc->dwPlayLSrcChan;
+ playch2 = portc->dwPlayRSrcChan;
+ if (srcch == 0)
+ {
+ HwWrite20K1 (devc, SRCIMAP(0), 0);
+ HwWrite20K1 (devc, SRCIMAP(srcch2),
+ srcch2 << 24 | (0x80 +
+ srcch) << 16 |
+ GetAudioSrcChan (playch2));
+ HwWrite20K1 (devc, SRCIMAP(0x80 + srcch),
+ (0x80 + srcch) << 24 | (srcch2 +
+ 0x80) << 16 |
+ GetAudioSrcChan (playch1 + 0x80));
+ HwWrite20K1 (devc, SRCIMAP(0x81 + srcch2),
+ (0x80 +
+ srcch2) << 24 | 0 << 16 | GetAudioSrcChan (playch2 +
+ 0x80));
+ HwWrite20K1 (devc, SRCIMAP(srcch),
+ srcch << 24 | srcch2 << 16 | GetAudioSrcChan (playch1));
+ }
+ else
+ {
+ HwWrite20K1 (devc, SRCIMAP(0), 0);
+ HwWrite20K1 (devc, SRCIMAP(srcch),
+ srcch << 24 | srcch2 << 16 | GetAudioSrcChan (playch1));
+ HwWrite20K1 (devc, SRCIMAP(srcch2),
+ srcch2 << 24 | (0x80 +
+ srcch) << 16 |
+ GetAudioSrcChan (playch2));
+ HwWrite20K1 (devc, SRCIMAP(0x80 + srcch),
+ (0x80 + srcch) << 24 | (srcch2 +
+ 0x80) << 16 |
+ GetAudioSrcChan (playch1 + 0x80));
+ HwWrite20K1 (devc, SRCIMAP(0x80 + srcch2),
+ (0x80 +
+ srcch2) << 24 | 0 << 16 | GetAudioSrcChan (playch2 +
+ 0x80));
+ HwWrite20K1 (devc, SRCIMAP(0),
+ (0 << 24) | (srcch << 16) | 0x0);
+ }
+ }
+#else
+ {
+ if (srcch == 0)
+ {
+ HwWrite20K1 (devc, SRCIMAP(0), 0);
+ HwWrite20K1 (devc, SRCIMAP(srcch2),
+ srcch2 << 24 | (0x80 +
+ srcch) << 16 |
+ GetAudioSumChan (srcch2));
+ HwWrite20K1 (devc, SRCIMAP(0x80 + srcch),
+ (0x80 + srcch) << 24 | (srcch2 +
+ 0x80) << 16 |
+ GetAudioSumChan (srcch + 0x80));
+ HwWrite20K1 (devc, SRCIMAP(0x81 + srcch2),
+ (0x80 +
+ srcch2) << 24 | 0 << 16 | GetAudioSumChan (srcch2 +
+ 0x80));
+ HwWrite20K1 (devc, SRCIMAP(srcch),
+ srcch << 24 | srcch2 << 16 | GetAudioSumChan (srcch));
+ }
+ else
+ {
+ HwWrite20K1 (devc, SRCIMAP(0), 0);
+ HwWrite20K1 (devc, SRCIMAP(srcch),
+ srcch << 24 | srcch2 << 16 | GetAudioSumChan (srcch));
+ HwWrite20K1 (devc, SRCIMAP(srcch2),
+ srcch2 << 24 | (0x80 +
+ srcch) << 16 |
+ GetAudioSumChan (srcch2));
+ HwWrite20K1 (devc, SRCIMAP(0x80 + srcch),
+ (0x80 + srcch) << 24 | (srcch2 +
+ 0x80) << 16 |
+ GetAudioSumChan (srcch + 0x80));
+ HwWrite20K1 (devc, SRCIMAP(0x80 + srcch2),
+ (0x80 +
+ srcch2) << 24 | 0 << 16 | GetAudioSumChan (srcch2 +
+ 0x80));
+ HwWrite20K1 (devc, SRCIMAP(0),
+ (0 << 24) | (srcch << 16) | 0x0);
+ }
+ }
+#endif
+}
+
+
+void
+_SetupInputToOutputMonitoring (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int i;
+ unsigned int dio1, dio2;
+ unsigned int srcch, srcch2;
+
+
+ srcch = portc->SrcChan;
+ srcch2 = portc->SrcChan+1;
+
+ dio1 = portc->dwDAChan[0];
+ dio2 = portc->dwDAChan[1];
+
+ // initialize input mappers
+ for (i = 0; i < 0x50; i++)
+ HwWrite20K1 (devc, DAOIMAP_START(i), 0);
+
+ HwWrite20K1 (devc, DAOIMAP_START(dio1), 0);
+ HwWrite20K1 (devc, DAOIMAP_START(dio2),
+ ((dio1 + 2) << 16) | GetAudioSumChan (srcch2));
+ HwWrite20K1 (devc, DAOIMAP_START(dio1 + 2),
+ ((dio2 + 2) << 16) | GetAudioSumChan (srcch + 0x80));
+ HwWrite20K1 (devc, DAOIMAP_START(dio2 + 2),
+ (dio1 << 16) | GetAudioSumChan (srcch2 + 0x80));
+ HwWrite20K1 (devc, DAOIMAP_START(dio1),
+ (dio2 << 16) | GetAudioSumChan (srcch));
+}
+
+void
+SetupRecordMixer (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int fixed_pitch;
+ unsigned int srcPrchn1, srcPrchnC1;
+ unsigned int srcch, srcch2, srcchnC1, srcchnC2;
+ unsigned int dwYData;
+ unsigned short i, inch1, inch2;
+
+
+ srcch = portc->SrcChan;
+ srcch2 = portc->SrcChan+1;
+
+ // NOTE: Y-Data is a 14-bit immediate floating-point constant multiplier.
+ // Adjust the Y-Data to control the multiplier.
+ // This can be used to control the level of the signal.
+ dwYData = 0x1c00;
+
+ srcchnC1 = srcch + 0x80;
+ srcchnC2 = srcch2 + 0x80;
+
+ srcPrchn1 = GetParamPitchChan (srcch);
+ srcPrchnC1 = GetParamPitchChan (srcch + 0x80);
+
+ // since input is 2x of output, pitch is 2.0
+ // convert to fixed-point 8.24 format, shift left 24 bit.
+ fixed_pitch = 2;
+ fixed_pitch = fixed_pitch << 24;
+
+ // write the pitch to param ring of the corresponsing SRC pitch slot
+ HwWrite20K1 (devc, PRING_LO_HI_START(srcPrchn1), fixed_pitch);
+ HwWrite20K1 (devc, PRING_LO_HI_START(srcPrchnC1), fixed_pitch);
+
+ inch1 = 0x1b5; // I2S-In3 L
+ inch2 = 0x1bd; // I2S-In3 R
+ // program all I2S-In3 slots
+ for (i = 0; i < 8; i++)
+ {
+ if (i <= 3)
+ {
+ WriteAMOP (devc, inch1 + (i * 0x200), dwYData, inch1 + (i * 0x200),
+ (0x80000000 + srcch));
+ WriteAMOP (devc, inch2 + (i * 0x200), dwYData, inch2 + (i * 0x200),
+ (0x80000000 + srcch2));
+ }
+ else
+ {
+ WriteAMOP (devc, inch1 + (i * 0x200), dwYData, inch1 + (i * 0x200),
+ (0x80000000 + srcchnC1));
+ WriteAMOP (devc, inch2 + (i * 0x200), dwYData, inch2 + (i * 0x200),
+ (0x80000000 + srcchnC2));
+ }
+ }
+
+ // enable physical input I2S_in3 to I2S-Out0 monitoring
+ _SetupInputToOutputMonitoring (devc, portc);
+}
+
+void
+SetupRecordFormat (sbxfi_devc_t * devc)
+{
+ unsigned int i2sorg;
+
+ i2sorg = HwRead20K1 (devc, I2SCTL);
+
+ // enable I2S-D input
+ i2sorg |= 0x90000000;
+ HwWrite20K1 (devc, I2SCTL, i2sorg);
+}
+
+void
+SetupAndStartRecordSRC (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int Sa, Ladr, Ca, Ctl = 0x64d;
+ int count;
+ unsigned int srcch, srcch2;
+ unsigned int dwSamplingRate;
+
+
+ srcch = portc->SrcChan;
+ srcch2 = portc->SrcChan+1;
+ dwSamplingRate = portc->rate;
+
+ count = audio_engines[portc->dev]->dmap_in->bytes_in_use;
+
+ // convert the num samples to bytes count
+
+ // hardcoded values:
+ // start addx: 4th entry in page table.
+ Sa = portc->pgtable_index * 4096;
+ Ladr = Sa + count;
+ Ca = Sa + 0x80;
+ if (dwSamplingRate == 48000)
+ Ctl = 0x64d; // record must start with RUN state!.
+ else if ((dwSamplingRate == 96000))
+ Ctl = 0x65d;
+
+ Ctl |= SRCCTL_ILSZ; // Interleaved stereo
+
+ WriteSRC (devc, Ca, 0, Sa, Ladr, 0x100, Ctl, srcch);
+
+ Ladr = Sa + count;
+ Ca = Sa + 0x80;
+ if (dwSamplingRate == 48000)
+ Ctl = 0x24d;
+ else if ((dwSamplingRate == 96000))
+ Ctl = 0x25d;
+
+ WriteSRC (devc, Ca, 0, Sa, Ladr, 0x80, Ctl, srcch2);
+
+ // Enable SRC input from Audio Ring
+ HwWrite20K1 (devc, SRCMCTL, 0x1);
+
+// _dumpRegisters(devc);
+}
+
+void
+StopRecordSRC (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int srcch, srcch2;
+ unsigned int dwData;
+ unsigned int i;
+
+ srcch = portc->SrcChan;
+ srcch2 = portc->SrcChan+1;
+
+ //WriteSRC(devc, 0, 0, 0, 0, 0, 0, srcch);
+ //WriteSRC(devc, 0, 0, 0, 0, 0, 0, srcch2);
+
+ dwData = HwRead20K1 (devc, SRCCTL(srcch));
+ dwData &= 0xfffffff0;
+ dwData |= 0;
+ HwWrite20K1 (devc, SRCCTL(srcch), dwData);
+
+ dwData = HwRead20K1 (devc, SRCCTL(srcch2));
+ dwData &= 0xfffffff0;
+ dwData |= 0;
+ HwWrite20K1 (devc, SRCCTL(srcch2), dwData);
+
+#ifdef INTERNAL_LOOPBACK
+ StopPlay (devc, portc);
+#endif
+
+ // Disable SRC inputs from Audio Ring
+ HwWrite20K1 (devc, SRCMCTL, 0x0);
+
+ for (i = 0; i < 0x50; i++)
+ HwWrite20K1 (devc, DAOIMAP_START(i), 0);
+}
+
+//========================
+
+unsigned int
+HwRead20K1PCI (sbxfi_devc_t * devc, unsigned int dwReg)
+{
+ unsigned int dwVal;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ osOutportd (devc, (IOADDR) devc->wIOPortBase + 0x10, dwReg);
+ dwVal = osInportd (devc, (IOADDR) (devc->wIOPortBase + 0x14));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return dwVal;
+}
+
+unsigned int
+HwRead20K1 (sbxfi_devc_t * devc, unsigned int dwReg)
+{
+ unsigned int dwVal;
+
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ osOutportd (devc, (IOADDR) devc->wIOPortBase + 0x0, dwReg);
+ dwVal = osInportd (devc, (IOADDR) (devc->wIOPortBase + 0x4));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+
+ return dwVal;
+}
+
+void
+HwWrite20K1PCI (sbxfi_devc_t * devc, unsigned int dwReg, unsigned int dwData)
+{
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ osOutportd (devc, (IOADDR) devc->wIOPortBase + 0x10, dwReg);
+ osOutportd (devc, (IOADDR) (devc->wIOPortBase + 0x14), dwData);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+
+void
+HwWrite20K1 (sbxfi_devc_t * devc, unsigned int dwReg, unsigned int dwData)
+{
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ osOutportd (devc, (IOADDR) devc->wIOPortBase + 0x0, dwReg);
+ osOutportd (devc, (IOADDR) (devc->wIOPortBase + 0x4), dwData);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+
+void
+WriteSRC
+ (sbxfi_devc_t * devc,
+ unsigned int srcca,
+ unsigned int srccf,
+ unsigned int srcsa, unsigned int srcla, unsigned int srcccr, unsigned int srcctl, unsigned int chn)
+{
+ HwWrite20K1 (devc, SRCCA(chn), srcca); // Current Address
+ HwWrite20K1 (devc, SRCCF(chn), srccf); // Current Fraction
+ HwWrite20K1 (devc, SRCSA(chn), srcsa); // START address
+ HwWrite20K1 (devc, SRCLA(chn), srcla); // LOOP address
+ HwWrite20K1 (devc, SRCCCR(chn), srcccr); // Cache control
+ HwWrite20K1 (devc, SRCCTL(chn), srcctl); // SRCCTL
+}
+
+#define CRM_TIMESLOT_ALLOC_BLOCK_SIZE 16
+#define CRM_PTS_PITCH 6
+#define CRM_PARAM_SRC_OFFSET 0x60
+
+unsigned int
+GetParamPitchChan (unsigned int i)
+{
+ int interpChanID =
+ (((int) i * CRM_TIMESLOT_ALLOC_BLOCK_SIZE) + CRM_PTS_PITCH) -
+ CRM_PARAM_SRC_OFFSET;
+ if (interpChanID < 0)
+ {
+ interpChanID += 4096;
+ }
+ return (unsigned int) interpChanID;
+}
+
+unsigned int
+GetAudioSrcChan (unsigned int srcchn)
+{
+ // SRC channel is in Audio Ring slot 1, after every 16 slot.
+ return (unsigned int) ((srcchn << 4) + 0x1);
+}
+
+unsigned int
+GetAudioSumChan (unsigned int chn)
+{
+ // SUM channel is in Audio Ring slot 0xc, after every 16 slot.
+ return (unsigned int) ((chn << 4) + 0xc);
+}
+
+void
+WriteAMOP
+ (sbxfi_devc_t * devc,
+ unsigned int xdata, unsigned int ydata, unsigned int chn, unsigned int hidata)
+{
+ HwWrite20K1 (devc, AMOP_START(chn), ((((unsigned int) ydata) << 18) | xdata << 4 | 1)); // Audio mixer, y-immediate
+ HwWrite20K1 (devc, AMOP_START(chn) + 4, hidata); // Audio mixer.
+}
+
+void
+_dumpRegisters (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ _dumpGlobal (devc);
+ _dumpSRCs (devc, portc);
+}
+
+void
+_dumpSRCs (sbxfi_devc_t * devc, sbxfi_portc_t * portc)
+{
+ unsigned int chn;
+
+ chn = portc->SrcChan;
+ cmn_err (CE_CONT,
+ "SRC chn=%lx, CA=%lx, CF=%lx, SA=%lx, LA=%lx, CCR=%lx, CTL=%lx\n",
+ chn, HwRead20K1 (devc, SRCCA(chn)),
+ HwRead20K1 (devc, SRCCF(chn)), HwRead20K1 (devc,
+ SRCSA(chn)),
+ HwRead20K1 (devc, SRCLA(chn)), HwRead20K1 (devc,
+ SRCCCR(chn)),
+ HwRead20K1 (devc, SRCCTL(chn)));
+
+ chn = portc->SrcChan+1;
+ cmn_err (CE_CONT,
+ "SRC chn=%lx, CA=%lx, CF=%lx, SA=%lx, LA=%lx, CCR=%lx, CTL=%lx\n",
+ chn, HwRead20K1 (devc, SRCCA(chn)),
+ HwRead20K1 (devc, SRCCF(chn)), HwRead20K1 (devc,
+ SRCSA(chn)),
+ HwRead20K1 (devc, SRCLA(chn)), HwRead20K1 (devc,
+ SRCCCR(chn)),
+ HwRead20K1 (devc, SRCCTL(chn)));
+}
+
+
+void
+_dumpGlobal (sbxfi_devc_t * devc)
+{
+ unsigned int i;
+
+ cmn_err (CE_CONT,
+ "GCTL=%lx, PLLCTL=%lx, GPIOCTL=%lx, GPIO=%lx, I2SCTL=%lx\n",
+ HwRead20K1 (devc, GCTL), HwRead20K1 (devc, PLLCTL),
+ HwRead20K1 (devc, GPIOCTL), HwRead20K1 (devc, GPIO),
+ HwRead20K1 (devc, I2SCTL));
+#if 1
+ cmn_err (CE_CONT, "DAOIMAP....\n");
+ for (i = 0; i < 0x50; i++)
+ {
+ cmn_err (CE_CONT, "%02lx: %lx ", i,
+ HwRead20K1 (devc, DAOIMAP_START(i)));
+ if (((i + 1) % 8) == 0)
+ cmn_err (CE_CONT, "\n");
+ }
+#endif
+#if 0
+ cmn_err (CE_CONT, "PageTable PhysAddx=%lx\n", HwRead20K1 (devc, PTPALX));
+ for (i = 0; i < 10; i++)
+ {
+ cmn_err (CE_CONT, "Entry[%lx]=%lx\n", i, devc->pdwPageTable[i]);
+ }
+#endif
+}
diff --git a/kernel/drv/oss_solo/.config b/kernel/drv/oss_solo/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_solo/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_solo/.devices b/kernel/drv/oss_solo/.devices
new file mode 100644
index 0000000..6003e9e
--- /dev/null
+++ b/kernel/drv/oss_solo/.devices
@@ -0,0 +1 @@
+oss_solo pci125d,1969 ESS Solo-1
diff --git a/kernel/drv/oss_solo/.name b/kernel/drv/oss_solo/.name
new file mode 100644
index 0000000..4711141
--- /dev/null
+++ b/kernel/drv/oss_solo/.name
@@ -0,0 +1 @@
+ESS Solo-1
diff --git a/kernel/drv/oss_solo/oss_solo.c b/kernel/drv/oss_solo/oss_solo.c
new file mode 100644
index 0000000..03605d9
--- /dev/null
+++ b/kernel/drv/oss_solo/oss_solo.c
@@ -0,0 +1,1230 @@
+/*
+ * Purpose: Driver for ESS Solo PCI audio controller.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_solo_cfg.h"
+#include "oss_pci.h"
+
+#define ESS_VENDOR_ID 0x125d
+#define ESS_SOLO1 0x1969
+
+#define DSP_RESET (devc->sb_base + 0x6)
+#define DSP_READ (devc->sb_base + 0xA)
+#define DSP_WRITE (devc->sb_base + 0xC)
+#define DSP_WRSTATUS (devc->sb_base + 0xC)
+#define DSP_STATUS (devc->sb_base + 0xE)
+#define DSP_STATUS16 (devc->sb_base + 0xF)
+#define MIXER_ADDR (devc->sb_base + 0x4)
+#define MIXER_DATA (devc->sb_base + 0x5)
+#define OPL3_LEFT (devc->sb_base + 0x0)
+#define OPL3_RIGHT (devc->sb_base + 0x2)
+#define OPL3_BOTH (devc->sb_base + 0x8)
+
+#define DSP_CMD_SPKON 0xD1
+#define DSP_CMD_SPKOFF 0xD3
+
+#define SBPRO_RECORDING_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD)
+#define SBPRO_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | \
+ SOUND_MASK_LINE | SOUND_MASK_MIC | \
+ SOUND_MASK_CD | SOUND_MASK_VOLUME)
+#define SOLO_RECORDING_DEVICES (SBPRO_RECORDING_DEVICES)
+#define SOLO_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_LINE2|SOUND_MASK_SPEAKER|SOUND_MASK_RECLEV|SOUND_MASK_LINE1)
+
+#define LEFT_CHN 0
+#define RIGHT_CHN 1
+
+#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
+
+static int default_levels[32] = {
+ 0x5a5a, /* Master Volume */
+ 0x4b4b, /* Bass */
+ 0x4b4b, /* Treble */
+ 0x4b4b, /* FM */
+ 0x4b4b, /* PCM */
+ 0x4b4b, /* PC Speaker */
+ 0x4b4b, /* Ext Line */
+ 0x2020, /* Mic */
+ 0x4b4b, /* CD */
+ 0x0000, /* Recording monitor */
+ 0x4b4b, /* SB PCM */
+ 0x4b4b, /* Recording level */
+ 0x4b4b, /* Input gain */
+ 0x4b4b, /* Output gain */
+ 0x4040, /* Line1 */
+ 0x4040, /* Line2 */
+ 0x1515 /* Line3 */
+};
+
+#define MAX_PORTC 2
+
+typedef struct solo_portc
+{
+ int speed, bits, channels;
+ int open_mode;
+ int audiodev;
+ int trigger_bits;
+ int audio_enabled;
+}
+solo_portc;
+
+typedef struct solo_devc
+{
+ oss_device_t *osdev;
+ oss_native_word base, ddma_base, sb_base, mpu_base;
+
+ int mpu_attached, fm_attached;
+ int irq;
+ char *chip_name;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+ oss_native_word last_capture_addr;
+ /* Audio parameters */
+ solo_portc portc[MAX_PORTC];
+
+ /* Mixer parameters */
+ int *levels;
+ int recmask;
+}
+solo_devc;
+
+
+static int
+solo_command (solo_devc * devc, unsigned char val)
+{
+ int i;
+
+ for (i = 0; i < 0x10000; i++)
+ {
+ if ((INB (devc->osdev, DSP_WRSTATUS) & 0x80) == 0)
+ {
+ OUTB (devc->osdev, val, DSP_WRITE);
+ return 1;
+ }
+ }
+
+ cmn_err (CE_WARN, "Command(%x) Timeout.\n", val);
+ return 0;
+}
+
+static int
+solo_get_byte (solo_devc * devc)
+{
+ int i;
+
+ for (i=0; i < 0x10000; i++)
+ if (INB (devc->osdev, DSP_STATUS) & 0x80)
+ {
+ return INB (devc->osdev, DSP_READ);
+ }
+
+ return 0xffff;
+}
+
+static int
+ext_read (solo_devc * devc, unsigned char reg)
+{
+
+ if (!solo_command (devc, 0xc0)) /* Read register command */
+ return OSS_EIO;
+
+ if (!solo_command (devc, reg))
+ return OSS_EIO;
+
+ return solo_get_byte (devc);
+}
+
+static int
+ext_write (solo_devc * devc, unsigned char reg, unsigned char data)
+{
+ if (!solo_command (devc, reg))
+ return 0;
+ return solo_command (devc, data);
+}
+
+static unsigned int
+solo_getmixer (solo_devc * devc, unsigned int port)
+{
+ unsigned int val;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, (unsigned char) (port & 0xff), MIXER_ADDR);
+ oss_udelay (50);
+ val = INB (devc->osdev, MIXER_DATA);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return val;
+}
+
+static void
+solo_setmixer (solo_devc * devc, unsigned int port, unsigned int value)
+{
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ OUTB (devc->osdev, (unsigned char) (port & 0xff), MIXER_ADDR);
+ oss_udelay (50);
+ OUTB (devc->osdev, (unsigned char) (value & 0xff), MIXER_DATA);
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+
+static int
+solo_reset (solo_devc * devc)
+{
+ int loopc;
+
+ DDB (cmn_err (CE_WARN, "Entered solo_reset()\n"));
+
+ OUTB (devc->osdev, 3, DSP_RESET); /* Reset FIFO too */
+ INB (devc->osdev, DSP_RESET); /* Reset FIFO too */
+ OUTB (devc->osdev, 0, DSP_RESET);
+ oss_udelay (10);
+
+ for (loopc = 0; loopc < 0x10000; loopc++)
+ if (INB (devc->osdev, DSP_STATUS) & 0x80)
+ if (INB (devc->osdev, DSP_READ) != 0xAA)
+ {
+ DDB (cmn_err (CE_WARN, "No response to RESET\n"));
+ return 0; /* Sorry */
+ }
+ solo_command (devc, 0xc6); /* Enable extended mode */
+
+ ext_write (devc, 0xb9, 3); /* Demand mode - set to reserve mode */
+ solo_setmixer (devc, 0x71, 0x32); /* 4x sampling + DAC2 asynch */
+
+ /* enable DMA/IRQ */
+ ext_write (devc, 0xb1, (ext_read (devc, 0xb1) & 0x0F) | 0x50);
+ ext_write (devc, 0xb2, (ext_read (devc, 0xb2) & 0x0F) | 0x50);
+
+ DDB (cmn_err (CE_WARN, "solo_reset() OK\n"));
+ return 1;
+}
+
+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;
+
+#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}}
+
+static mixer_tab solo_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, 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, 0x7c, 7, 4, 0x7c, 3, 4),
+ MIX_ENT (SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
+ MIX_ENT (SOUND_MIXER_IGAIN, 0x68, 7, 4, 0x68, 3, 4),
+ MIX_ENT (SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
+ MIX_ENT (SOUND_MIXER_LINE1, 0x6d, 7, 4, 0x6d, 3, 4),
+ MIX_ENT (SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
+ MIX_ENT (SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
+};
+
+/*ARGSUSED*/
+static void
+change_bits (solo_devc * devc, unsigned char *regval, int dev, int chn,
+ int newval)
+{
+ unsigned char mask;
+ int shift;
+
+ mask = (1 << solo_mix[dev][chn].nbits) - 1;
+ newval = (int) ((newval * mask) + 50) / 100; /* Scale */
+
+ shift = solo_mix[dev][chn].bitoffs - solo_mix[dev][LEFT_CHN].nbits + 1;
+
+ *regval &= ~(mask << shift); /* Mask out previous value */
+ *regval |= (newval & mask) << shift; /* Set the new value */
+}
+
+#if 0
+static int
+ess_set_reclev (solo_devc * devc, int dev, int left, int right)
+{
+ unsigned char b;
+
+ b = (((15 * right) / 100) << 4) | (((15 * left) / 100));
+
+ ext_write (devc, 0xb4, b); /* Change input volume control */
+ devc->levels[dev] = left | (right << 8);
+ return left | (right << 8);
+}
+
+static int
+ess_set_altpcm (solo_devc * devc, int dev, int left, int right)
+{
+ unsigned char b;
+
+ b = (((15 * right) / 100) << 4) | (((15 * left) / 100));
+ solo_setmixer (devc, 0x7C, b); /* Change dac2 volume control */
+ devc->levels[dev] = left | (right << 8);
+ return left | (right << 8);
+}
+#endif
+
+static int set_recmask (solo_devc * devc, int mask);
+
+static int
+solo_mixer_set (solo_devc * devc, int dev, int value)
+{
+ int left = value & 0x000000ff;
+ int right = (value & 0x0000ff00) >> 8;
+
+ int regoffs;
+ unsigned char val;
+
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+
+#if 0
+ if (dev == SOUND_MIXER_RECLEV)
+ return ess_set_reclev (devc, dev, left, right);
+ if (dev == SOUND_MIXER_ALTPCM)
+ return ess_set_altpcm (devc, dev, left, right);
+#endif
+
+ if (dev > 31)
+ return OSS_EINVAL;
+
+ if (!(SOLO_MIXER_DEVICES & (1 << dev))) /*
+ * Not supported
+ */
+ return OSS_EINVAL;
+
+ regoffs = solo_mix[dev][LEFT_CHN].regno;
+
+ if (regoffs == 0)
+ return OSS_EINVAL;
+
+ val = solo_getmixer (devc, regoffs);
+ change_bits (devc, &val, dev, LEFT_CHN, left);
+
+ devc->levels[dev] = left | (left << 8);
+
+ if (solo_mix[dev][RIGHT_CHN].regno != regoffs) /*
+ * Change register
+ */
+ {
+ solo_setmixer (devc, regoffs, val); /*
+ * Save the old one
+ */
+ regoffs = solo_mix[dev][RIGHT_CHN].regno;
+
+ if (regoffs == 0)
+ return left | (left << 8); /*
+ * Just left channel present
+ */
+
+ val = solo_getmixer (devc, regoffs); /*
+ * Read the new one
+ */
+ }
+
+ change_bits (devc, &val, dev, RIGHT_CHN, right);
+
+ solo_setmixer (devc, regoffs, val);
+
+ devc->levels[dev] = left | (right << 8);
+ return left | (right << 8);
+}
+
+/*ARGSUSED*/
+static int
+solo_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ solo_devc *devc = mixer_devs[dev]->devc;
+ int val;
+
+ if (cmd == SOUND_MIXER_PRIVATE1)
+ {
+ val = *arg;
+ if (val != 0 && val != 1)
+ return (OSS_EINVAL);
+
+ if (val)
+ {
+ cmn_err (CE_WARN, "turning on 26db mic boost\n");
+ ext_write (devc, 0xa9, ext_read (devc, 0xa9) | 0xC);
+ }
+ else
+ {
+ cmn_err (CE_WARN, "turning off 26db mic boost\n");
+ ext_write (devc, 0xa9, ext_read (devc, 0xa9) & ~0x4);
+ }
+ return *arg = val;
+ }
+
+
+ if (((cmd >> 8) & 0xff) == 'M')
+ {
+ if (IOC_IS_OUTPUT (cmd))
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ val = *arg;
+ return *arg = set_recmask (devc, val);
+ break;
+
+ default:
+
+ val = *arg;
+ return *arg = solo_mixer_set (devc, cmd & 0xff, val);
+ }
+ else
+ switch (cmd & 0xff)
+ {
+
+ case SOUND_MIXER_RECSRC:
+ return *arg = devc->recmask;
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ return *arg = SOLO_MIXER_DEVICES;
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ return *arg = SOLO_MIXER_DEVICES &
+ ~(SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_IMIX);
+ break;
+
+ case SOUND_MIXER_RECMASK:
+ return *arg = SOLO_RECORDING_DEVICES;
+ break;
+
+ case SOUND_MIXER_CAPS:
+ return *arg = SOUND_CAP_EXCL_INPUT;
+ break;
+
+ default:
+ return *arg = devc->levels[cmd & 0x1f];
+ }
+ }
+ else
+ return OSS_EINVAL;
+}
+
+static void
+set_recsrc (solo_devc * devc, int src)
+{
+ solo_setmixer (devc, RECORD_SRC,
+ (solo_getmixer (devc, RECORD_SRC) & ~7) | (src & 0x7));
+}
+
+static int
+set_recmask (solo_devc * devc, int mask)
+{
+ int devmask = mask & SOLO_RECORDING_DEVICES;
+
+ if (devmask != SOUND_MASK_MIC &&
+ devmask != SOUND_MASK_LINE && devmask != SOUND_MASK_CD)
+ { /*
+ * More than one devices selected.
+ * Drop the previous selection
+ */
+ devmask &= ~devc->recmask;
+ }
+
+ if (devmask != SOUND_MASK_MIC &&
+ devmask != SOUND_MASK_LINE && devmask != SOUND_MASK_CD)
+ { /*
+ * More than one devices selected.
+ * Default to mic
+ */
+ devmask = SOUND_MASK_MIC;
+ }
+
+
+ if (devmask ^ devc->recmask) /*
+ * Input source changed
+ */
+ {
+ switch (devmask)
+ {
+
+ case SOUND_MASK_MIC:
+ set_recsrc (devc, 0);
+ break;
+
+ case SOUND_MASK_LINE:
+ set_recsrc (devc, 6);
+ break;
+
+ case SOUND_MASK_CD:
+ set_recsrc (devc, 2);
+ break;
+
+ default:
+ set_recsrc (devc, 0);
+ }
+ }
+
+ devc->recmask = devmask;
+ return devc->recmask;
+}
+
+static void
+solo_mixer_reset (solo_devc * devc)
+{
+ char name[32];
+ int i;
+
+ sprintf (name, "SOLO");
+
+ devc->levels = load_mixer_volumes (name, default_levels, 1);
+ devc->recmask = 0;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ solo_mixer_set (devc, i, devc->levels[i]);
+
+ set_recmask (devc, SOUND_MASK_MIC);
+}
+
+static mixer_driver_t solo_mixer_driver = {
+ solo_mixer_ioctl
+};
+
+static int
+solointr (oss_device_t * osdev)
+{
+ solo_devc *devc = (solo_devc *) osdev->devc;
+ int status;
+ int serviced = 0;
+ int i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ status = INB (devc->osdev, devc->base + 7);
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ if (status & 0x10) /* ESS Native Mode */
+ {
+ int instat;
+ solo_portc *portc = &devc->portc[i];
+ serviced = 1;
+
+ instat = INB (devc->osdev, DSP_STATUS); /* Ack the interrupt */
+ if (portc->trigger_bits & PCM_ENABLE_INPUT)
+ oss_audio_inputintr (portc->audiodev, 1);
+ }
+
+ if (status & 0x20) /* ESS DAC2 Mode */
+ {
+ solo_portc *portc = &devc->portc[i];
+ serviced = 1;
+
+ if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ oss_audio_outputintr (portc->audiodev, 1);
+ solo_setmixer (devc, 0x7A, solo_getmixer (devc, 0x7A) & 0x47);
+ }
+ }
+
+ if (status & 0x80) /* MPU interrupt */
+ {
+ serviced = 1;
+ /* uart401intr (INT_HANDLER_CALL (devc->irq)); *//* UART401 interrupt */
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return serviced;
+}
+
+static int
+solo_audio_set_rate (int dev, int arg)
+{
+ solo_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 8000)
+ arg = 8000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+solo_audio_set_channels (int dev, short arg)
+{
+ solo_portc *portc = audio_engines[dev]->portc;
+
+ if ((arg != 1) && (arg != 2))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+solo_audio_set_format (int dev, unsigned int arg)
+{
+ solo_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+solo_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void solo_audio_trigger (int dev, int state);
+
+static void
+solo_audio_reset (int dev)
+{
+ solo_audio_trigger (dev, 0);
+}
+
+static void
+solo_audio_reset_input (int dev)
+{
+ solo_portc *portc = audio_engines[dev]->portc;
+ solo_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+solo_audio_reset_output (int dev)
+{
+ solo_portc *portc = audio_engines[dev]->portc;
+ solo_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+solo_audio_open (int dev, int mode, int open_flags)
+{
+ oss_native_word flags;
+ solo_portc *portc = audio_engines[dev]->portc;
+ solo_devc *devc = audio_engines[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ portc->open_mode = mode;
+ portc->audio_enabled = ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+solo_audio_close (int dev, int mode)
+{
+ solo_portc *portc = audio_engines[dev]->portc;
+
+ solo_audio_reset (dev);
+ portc->open_mode = 0;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+solo_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ solo_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+}
+
+/*ARGSUSED*/
+static void
+solo_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ solo_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+solo_audio_trigger (int dev, int state)
+{
+ oss_native_word flags;
+ solo_portc *portc = audio_engines[dev]->portc;
+ solo_devc *devc = audio_engines[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ solo_setmixer (devc, 0x78, 0x92); /* stablilze fifos */
+ oss_udelay(100);
+ solo_setmixer (devc, 0x78, 0x93); /* Go */
+ OUTB (devc->osdev, 0x0A, devc->base + 6); /*unmask dac2 intr */
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ solo_setmixer (devc, 0x78, 0); /* stop the audio dac2 dma */
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ ext_write (devc, 0xb8, 0x0f); /* Go */
+ OUTB (devc->osdev, 0x00, devc->ddma_base + 0x0f); /*start dma*/
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ ext_write (devc, 0xb8, 0x00); /* stop */
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+ext_speed (int dev, int direction)
+{
+ solo_devc *devc = audio_engines[dev]->devc;
+ solo_portc *portc = audio_engines[dev]->portc;
+ int divider, div, filter;
+ unsigned int rate;
+ int speed, s0, s1, use0;
+ int dif0, dif1;
+ unsigned char t0, t1;
+
+ /* rate = source / (256 - divisor) */
+ /* divisor = 256 - (source / rate) */
+ speed = portc->speed;
+
+ t0 = 128 - (793800 / speed);
+ s0 = 793800 / (128 - t0);
+
+ t1 = 128 - (768000 / speed);
+ s1 = 768000 / (128 - t1);
+ t1 |= 0x80;
+
+ dif0 = speed - s0;
+ if (dif0 < 0)
+ dif0 *= -1;
+ dif1 = speed - s1;
+ if (dif1 < 0)
+ dif1 *= -1;
+
+ use0 = (dif0 < dif1) ? 1 : 0;
+
+ if (use0)
+ {
+ rate = s0;
+ div = t0;
+ }
+ else
+ {
+ rate = s1;
+ div = t1;
+ }
+ portc->speed = rate;
+/*
+ * Set filter divider register
+ */
+ filter = (rate * 8 * 82) / 20; /* 80% of the rate */
+ divider = 256 - 7160000 / (filter);
+ if (direction)
+ {
+ ext_write (devc, 0xa1, div);
+ ext_write (devc, 0xa2, divider);
+ }
+ else
+ {
+ solo_setmixer (devc, 0x70, div);
+ solo_setmixer (devc, 0x72, divider);
+ }
+}
+
+/*ARGSUSED*/
+static int
+solo_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ solo_devc *devc = audio_engines[dev]->devc;
+ solo_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+ unsigned int left, right, reclev;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ int c;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ OUTB (devc->osdev, 2, DSP_RESET); /* Reset FIFO too */
+ INB (devc->osdev, DSP_RESET); /* Reset FIFO too */
+ OUTB (devc->osdev, 0, DSP_RESET);
+ oss_udelay (10);
+
+
+ ext_speed (dev, 1);
+
+ ext_write (devc, 0xa8, (ext_read (devc, 0xa8) & ~0x3) | (3 - portc->channels)); /* Mono/stereo */
+
+ solo_command (devc, DSP_CMD_SPKOFF);
+
+ if (portc->channels == 1)
+ {
+ if (portc->bits == AFMT_U8)
+ { /* 8 bit mono */
+ ext_write (devc, 0xb7, 0x51);
+ ext_write (devc, 0xb7, 0xd0);
+ }
+ else
+ { /* 16 bit mono */
+ ext_write (devc, 0xb7, 0x71);
+ ext_write (devc, 0xb7, 0xf4);
+ }
+ }
+ else
+ { /* Stereo */
+ if (portc->bits == AFMT_U8)
+ { /* 8 bit stereo */
+ ext_write (devc, 0xb7, 0x51);
+ ext_write (devc, 0xb7, 0x98);
+ }
+ else
+ { /* 16 bit stereo */
+ ext_write (devc, 0xb7, 0x71);
+ ext_write (devc, 0xb7, 0xbc);
+ }
+ }
+
+ /*
+ * reset the 0xb4 register to the stored value of RECLEV - for some
+ * reason it gets reset when you enter ESS Extension mode.
+ */
+ left = devc->levels[SOUND_MIXER_RECLEV] & 0xff;
+ right = (devc->levels[SOUND_MIXER_RECLEV] >> 8) & 0xff;
+ reclev = (((15 * right) / 100) << 4) | (((15 * left) / 100));
+ ext_write (devc, 0xb4, reclev);
+
+ OUTB (devc->osdev, 0xc4, devc->ddma_base + 0x08);
+ OUTB (devc->osdev, 0xff, devc->ddma_base + 0x0d); /* clear DMA */
+ OUTB (devc->osdev, 0x01, devc->ddma_base + 0x0f); /* stop DMA */
+ OUTB (devc->osdev, 0x14, devc->ddma_base + 0x0b); /*Demand/Single Mode */
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, devc->ddma_base + 0x00);
+ OUTW (devc->osdev, dmap->bytes_in_use, devc->ddma_base + 0x04);
+
+ c = -(dmap->fragment_size);
+ /* Reload DMA Count */
+ ext_write (devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
+ ext_write (devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
+
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+solo_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ solo_devc *devc = audio_engines[dev]->devc;
+ solo_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ int c;
+
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ OUTB (devc->osdev, 2, DSP_RESET); /* Reset FIFO too */
+ INB (devc->osdev, DSP_RESET);
+ OUTB (devc->osdev, 0, DSP_RESET);
+ ext_speed (dev, 0);
+ if (portc->channels == 1)
+ {
+ if (portc->bits == AFMT_U8)
+ solo_setmixer (devc, 0x7A, 0x40 | 0x00); /*8bit mono unsigned */
+ else
+ solo_setmixer (devc, 0x7A, 0x40 | 0x05); /*16bit mono signed */
+ }
+ else
+ {
+ if (portc->bits == AFMT_U8)
+ solo_setmixer (devc, 0x7A, 0x40 | 0x02); /*8bit stereo unsigned */
+ else
+ solo_setmixer (devc, 0x7A, 0x40 | 0x07); /*16bit stereo signed */
+ }
+
+ OUTL (devc->osdev, dmap->dmabuf_phys, devc->base + 0);
+ OUTW (devc->osdev, dmap->bytes_in_use, devc->base + 4);
+
+ OUTB (devc->osdev, 0x0, devc->base + 6); /* disable the DMA mask */
+
+ c = -(dmap->fragment_size>>1);
+ solo_setmixer (devc, 0x74, (unsigned char) ((unsigned short) c & 0xff));
+ solo_setmixer (devc, 0x76, (unsigned char) (((unsigned short) c >> 8) & 0xff));
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+solo_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ solo_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ oss_native_word ptr=0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ ptr = dmap->bytes_in_use - INW(devc->osdev, devc->base + 4);
+ }
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ int count;
+ unsigned int diff;
+
+ ptr = INL(devc->osdev, devc->ddma_base + 0x00);
+ count = INL(devc->osdev, devc->ddma_base + 0x04);
+
+ diff = dmap->dmabuf_phys + dmap->bytes_in_use - ptr - count;
+
+ if (ptr < dmap->dmabuf_phys ||
+ ptr >= dmap->dmabuf_phys + dmap->bytes_in_use)
+
+ ptr = devc->last_capture_addr; /* use prev value */
+ else
+ devc->last_capture_addr = ptr; /* save it */
+
+ ptr -= dmap->dmabuf_phys;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ptr;
+}
+
+
+static audiodrv_t solo_audio_driver = {
+ solo_audio_open,
+ solo_audio_close,
+ solo_audio_output_block,
+ solo_audio_start_input,
+ solo_audio_ioctl,
+ solo_audio_prepare_for_input,
+ solo_audio_prepare_for_output,
+ solo_audio_reset,
+ NULL,
+ NULL,
+ solo_audio_reset_input,
+ solo_audio_reset_output,
+ solo_audio_trigger,
+ solo_audio_set_rate,
+ solo_audio_set_format,
+ solo_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* solo_alloc_buffer, */
+ NULL, /* solo_free_buffer, */
+ NULL,
+ NULL,
+ solo_get_buffer_pointer
+};
+
+static int
+init_solo (solo_devc * devc)
+{
+ int my_mixer;
+ int i, adev;
+ int first_dev = 0;
+
+ devc->mpu_attached = devc->fm_attached = 0;
+
+/*
+ * Initialize and attach the legacy devices
+ */
+
+ if (!solo_reset (devc))
+ {
+ cmn_err (CE_WARN, "Reset command failed\n");
+ return 0;
+ }
+
+/* setup mixer regs */
+ solo_setmixer (devc, 0x7d, 0x0c);
+ OUTB (devc->osdev, 0xf0, devc->base + 7);
+ OUTB (devc->osdev, 0x00, devc->ddma_base + 0x0f);
+
+ if ((my_mixer = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "ESS Solo",
+ &solo_mixer_driver,
+ sizeof (mixer_driver_t), devc)) < 0)
+ {
+ return 0;
+ }
+ solo_mixer_reset (devc);
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ char tmp_name[100];
+ solo_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE;
+ strcpy (tmp_name, devc->chip_name);
+
+ if (i == 0)
+ {
+ strcpy (tmp_name, devc->chip_name);
+ caps |= ADEV_DUPLEX;
+ }
+ else
+ {
+ caps |= ADEV_DUPLEX | ADEV_SHADOW;
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &solo_audio_driver,
+ sizeof (audiodrv_t),
+ caps,
+ AFMT_U8 | AFMT_S16_LE, devc, -1)) < 0)
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->min_rate = 8000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->dmabuf_maxaddr = MEMLIMIT_ISA;
+ audio_engines[adev]->dmabuf_alloc_flags |= DMABUF_SIZE_16BITS;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ portc->open_mode = 0;
+ portc->audiodev = adev;
+ portc->audio_enabled = 0;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+ }
+ return 1;
+}
+
+int
+oss_solo_attach (oss_device_t * osdev)
+{
+
+ unsigned char pci_irq_line, pci_revision;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr0, pci_ioaddr1, pci_ioaddr2, pci_ioaddr3;
+ solo_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered ESS Solo probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != ESS_VENDOR_ID || device != ESS_SOLO1)
+ return 0;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr0);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_1, &pci_ioaddr1);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_2, &pci_ioaddr2);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_3, &pci_ioaddr3);
+
+ if (pci_ioaddr0 == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->irq = pci_irq_line;
+ devc->chip_name = "ESS Solo-1";
+
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr0);
+ /* Remove I/O space marker in bit 0. */
+ devc->base &= ~0x3;
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if (oss_register_interrupts (devc->osdev, 0, solointr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Can't allocate IRQ%d\n", pci_irq_line);
+ return 0;
+ }
+
+
+ /* Read the VCBase register */
+ if (pci_ioaddr2 == 0)
+ {
+ cmn_err (CE_WARN, "DMA I/O base not set\n");
+ /*return 0; */
+ }
+ /* Copy it's contents to the DDMA register */
+ pci_write_config_dword (osdev, 0x60, pci_ioaddr2 | 0x1); /* enabled DDMA */
+ devc->ddma_base = MAP_PCI_IOADDR (devc->osdev, 2, pci_ioaddr2);
+ devc->ddma_base &= ~0x3;
+
+ /* Init other SB base registers */
+ if (pci_ioaddr1 == 0)
+ {
+ cmn_err (CE_WARN, "SB I/O base not set\n");
+ return 0;
+ }
+ devc->sb_base = MAP_PCI_IOADDR (devc->osdev, 1, pci_ioaddr1);
+ devc->sb_base &= ~0x3;
+
+
+ /* Init MPU base register */
+ if (pci_ioaddr3 == 0)
+ {
+ cmn_err (CE_WARN, "MPU I/O base not set\n");
+ return 0;
+ }
+ devc->mpu_base = MAP_PCI_IOADDR (devc->osdev, 3, pci_ioaddr3);
+ devc->mpu_base &= ~0x3;
+
+ /* Setup Legacy audio register - disable legacy audio */
+ pci_write_config_word (osdev, 0x40, 0x805f);
+
+ /* Select DDMA and Disable IRQ emulation */
+ pci_write_config_dword (osdev, 0x50, 0);
+ pci_read_config_dword (osdev, 0x50, &pci_ioaddr0);
+ pci_ioaddr0 &= (~(0x0700 | 0x6000));
+ pci_write_config_dword (osdev, 0x50, pci_ioaddr0);
+
+ return init_solo (devc); /* Detected */
+}
+
+
+int
+oss_solo_detach (oss_device_t * osdev)
+{
+ solo_devc *devc = (solo_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ /* disable all interrupts */
+ /*OUTB (devc->osdev, 0, devc->base + 7); */
+
+#ifdef OBSOLETED_STUFF
+ if (devc->mpu_attached)
+ unload_mpu (devc);
+#endif
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+ UNMAP_PCI_IOADDR (devc->osdev, 1);
+ UNMAP_PCI_IOADDR (devc->osdev, 2);
+ UNMAP_PCI_IOADDR (devc->osdev, 3);
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_solo/oss_solo.man b/kernel/drv/oss_solo/oss_solo.man
new file mode 100644
index 0000000..a86e810
--- /dev/null
+++ b/kernel/drv/oss_solo/oss_solo.man
@@ -0,0 +1,19 @@
+NAME
+oss_solo - ESS Solo-1 audio driver
+
+DESCRIPTION
+Open Sound System driver for ESS Solo1/1938/1968 audio controllers.
+ESS Solo1 device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo playback/recording
+ o 8KHz to 48Khz sample rate.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_solo.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_trident/.devices b/kernel/drv/oss_trident/.devices
new file mode 100644
index 0000000..4d766ef
--- /dev/null
+++ b/kernel/drv/oss_trident/.devices
@@ -0,0 +1,5 @@
+oss_trident pci1023,2000 Trident 4DWave-DX
+oss_trident pci1023,2001 Trident 4DWave-NX
+oss_trident pci1023,2002 Trident 4DWave-CX
+oss_trident pci1039,7018 SiS 7018
+oss_trident pci10b9,5451 ALI M5451
diff --git a/kernel/drv/oss_trident/.name b/kernel/drv/oss_trident/.name
new file mode 100644
index 0000000..f3df66b
--- /dev/null
+++ b/kernel/drv/oss_trident/.name
@@ -0,0 +1 @@
+Trident 4DWave, SiS7018, ALI M5451
diff --git a/kernel/drv/oss_trident/.params b/kernel/drv/oss_trident/.params
new file mode 100644
index 0000000..70d8ef5
--- /dev/null
+++ b/kernel/drv/oss_trident/.params
@@ -0,0 +1,6 @@
+int trident_mpu_ioaddr=0;
+/*
+ * Trident MPU 401 I/O Address
+ * Values: 0x300, 0x330 Default: 0x330
+ */
+
diff --git a/kernel/drv/oss_trident/oss_trident.c b/kernel/drv/oss_trident/oss_trident.c
new file mode 100644
index 0000000..13d8872
--- /dev/null
+++ b/kernel/drv/oss_trident/oss_trident.c
@@ -0,0 +1,1580 @@
+/*
+ * Purpose: Driver for Trident 4DWAVE, ALI 5451 and SiS 7918 audio chips
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_trident_cfg.h"
+#include "oss_pci.h"
+#include "ac97.h"
+
+#if defined(sparc)
+#define MEM_MAPPED_REGISTERS
+#else
+#undef MEM_MAPPED_REGISTERS
+#endif
+
+#define TRIDENT_VENDOR_ID 0x1023
+#define TRIDENT_4DWAVEDX_ID 0x2000
+#define TRIDENT_4DWAVENX_ID 0x2001
+#define TRIDENT_4DWAVECX_ID 0x2002
+
+#define ALI_VENDOR_ID 0x10b9
+#define ALI_5451_ID 0x5451
+
+#define SIS_VENDOR_ID 0x1039
+#define SIS_7018_ID 0x7018
+
+/* DX/NX/CX IO Registers */
+#define SP_CSO 0x24
+#define SP_LBA 0x28
+#define SP_ESO 0x2C
+#define ACR0 0x40
+#define SP_STAT 0x64
+#define TLBC 0x6C
+#define START_A 0x80
+#define STOP_A 0x84
+#define INT_A 0x98
+#define INTEN_A 0xA4
+#define VOL 0xA8
+#define DELTA 0xAC
+#define MISCINT 0xB0
+#define START_B 0xB4
+#define STOP_B 0xB8
+#define INT_B 0xD8
+#define INTEN_B 0xDC
+#define CIR 0xA0
+#define CSO 0xE0
+#define LBA 0xE4
+#define ESO 0xE8
+#define FMC 0xEC
+#define TCTRL 0xF0
+#define EBUF1 0xF4
+#define EBUF2 0xF8
+
+#define DMAR0 0x00
+#define DMAR4 0x04
+#define DMAR6 0x06
+#define DMAR11 0x0b
+#define DMAR15 0x0f
+#define SBDELTA 0xac
+#define SBBL 0xc0
+#define SBCTL 0xc4
+
+/* SIS 7018 Define */
+#define SECONDARY_ID 0x00004000
+#define PCMOUT 0x00010000
+#define SURROUT 0x00020000
+#define CENTEROUT 0x00040000
+#define LFEOUT 0x00080000
+#define LINE1OUT 0x00100000
+#define LINE2OUT 0x00200000
+#define GPIOOUT 0x00400000
+#define CHANNEL_PB 0x0000
+#define CHANNEL_SPC_PB 0x4000
+#define CHANNEL_REC 0x8000
+#define CHANNEL_REC_PB 0xc000
+#define MODEM_LINE1 0x0000
+#define MODEM_LINE2 0x0400
+#define PCM_LR 0x0800
+#define HSET 0x0c00
+#define I2S_LR 0x1000
+#define CENTER_LFE 0x1400
+#define SURR_LR 0x1800
+#define SPDIF_LR 0x1c00
+#define MIC 0x1400
+#define MONO_LEFT 0x0000
+#define MONO_RIGHT 0x0100
+#define MONO_MIX 0x0200
+#define SRC_ENABLE 0x0080
+
+#define INTR(bank) ((bank==1)?INT_A:INT_B)
+#define INTEN(bank) ((bank==1)?INTEN_A:INTEN_B)
+#define STOP(bank) ((bank==1)?STOP_A:STOP_B)
+#define START(bank) ((bank==1)?START_A:START_B)
+
+/* ALI5451 definitions */
+#define ALI_5451_V02 0x2
+#define SIS_7018_V02 0x2
+
+
+extern int trident_mpu_ioaddr;
+
+#define MAX_PORTC 8
+
+typedef struct trident_portc
+{
+ int speed, bits, channels;
+ int open_mode;
+ int audio_enabled;
+ int trigger_bits;
+ int audiodev;
+ int port_type;
+#define DF_PCM 0
+#define DF_SPDIF 1
+ unsigned char play_chan, play_intr_chan;
+ unsigned char rec_chan, rec_intr_chan;
+ int pbank, rbank;
+#define BANK_A 1
+#define BANK_B 0
+} trident_portc;
+
+
+typedef struct trident_devc
+{
+ oss_device_t *osdev;
+ char *chip_name;
+ int chip_type;
+ int revision;
+ int irq;
+
+#ifdef MEM_MAPPED_REGISTERS
+ unsigned int bar1addr;
+ char *bar1virt;
+#else /* */
+ oss_native_word base;
+#endif /* */
+ volatile unsigned char intr_mask;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ /* Legacy */
+ int mpu_base, mpu_irq, mpu_attached;
+
+ /* Mixer parameters */
+ ac97_devc ac97devc;
+ int mixer_dev;
+
+ /* Audio parameters */
+ trident_portc portc[MAX_PORTC];
+ int audio_opened;
+ unsigned char sb_dma_flags;
+} trident_devc;
+
+#ifndef MEM_MAPPED_REGISTERS
+/* I/O mapped register access */
+#define READL(o,a) INL(o, devc->base+(a))
+#define READW(o,a) INW(o, devc->base+(a))
+#define READB(o,a) INB(o, devc->base+(a))
+#define WRITEL(o,d,a) OUTL(o, d, devc->base+(a))
+#define WRITEW(o,d,a) OUTW(o, d, devc->base+(a))
+#define WRITEB(o,d,a) OUTB(o, d, devc->base+(a))
+#else
+/* Mem mapped I/O registers */
+#define READL(o,a) *(volatile unsigned int*)(devc->bar1virt+(a))
+#define READW(o,a) *(volatile unsigned short*)(devc->bar1virt+(a))
+#define READB(o,a) *(volatile unsigned char*)(devc->bar1virt+(a))
+#define WRITEL(o,d,a) *(volatile unsigned int*)(devc->bar1virt+(a))=d
+#define WRITEW(o,d,a) *(volatile unsigned short*)(devc->bar1virt+(a))=d
+#define WRITEB(o,d,a) *(volatile unsigned char*)(devc->bar1virt+(a))=d
+#endif
+
+static int
+ac97_read (void *devc_, int addr)
+{
+ trident_devc *devc = devc_;
+ int t, ret;
+ oss_native_word data, reg = 0;
+ oss_native_word rmask = 0;
+ oss_native_word dmask = 0;
+ oss_native_word wport = 0;
+ oss_native_word rport = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ t = 20000;
+ switch (devc->chip_type)
+ {
+ case TRIDENT_4DWAVEDX_ID:
+ case SIS_7018_ID:
+ wport = 0x40;
+ rport = 0x44;
+ if (devc->revision == SIS_7018_V02)
+ {
+ rport = 0x40;
+ }
+ rmask = 0x00008000;
+ dmask = 0x00008000;
+ break;
+ case TRIDENT_4DWAVENX_ID:
+ wport = 0x44;
+ rport = 0x48;
+ rmask = 0x00000800;
+ dmask = 0x00000400;
+ break;
+ case ALI_5451_ID:
+ wport = 0x40;
+ rport = 0x44;
+ rmask = 0x00008000;
+ dmask = 0x00008000;
+ if (devc->revision == ALI_5451_V02)
+ {
+ rport = 0x40;
+ }
+ break;
+ default:
+ {
+ static int already_done = 0;
+ if (!already_done)
+ cmn_err (CE_WARN, "Unknown codec interface\n");
+ already_done = 1;
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+ }
+
+ /* Check to make sure No Writes are pending */
+ reg = READL (devc->osdev, wport);
+ while ((reg & dmask) && --t)
+ reg = READL (devc->osdev, wport); /* re-read status/data */
+
+ /* Check to make sure No reads are pending */
+ reg = READL (devc->osdev, rport);
+ while ((reg & dmask) && --t)
+ reg = READL (devc->osdev, rport); /* re-read status/data */
+ data = addr | rmask;
+ WRITEL (devc->osdev, data, rport); /* select register for reading */
+ reg = READL (devc->osdev, rport); /* read status/data */
+
+ t = 20000;
+
+ while ((reg & dmask) && --t)
+ { /* busy reading */
+ reg = READL (devc->osdev, rport); /* re-read status/data */
+ }
+ if (t)
+ ret = (reg >> 16);
+ else
+ {
+ DDB (cmn_err (CE_WARN, "AC97 mixer read timed out\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ret;
+}
+
+static int
+ac97_write (void *devc_, int addr, int data)
+{
+ trident_devc *devc = devc_;
+ int t;
+ oss_native_word wport = 0;
+ oss_native_word reg = 0;
+ unsigned int wmask = 0;
+ unsigned int dmask = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ t = 2000;
+
+ switch (devc->chip_type)
+ {
+ case TRIDENT_4DWAVEDX_ID:
+ case SIS_7018_ID:
+ wport = 0x40;
+ wmask = 0x00008000;
+ dmask = 0x00008000;
+ break;
+ case TRIDENT_4DWAVENX_ID:
+ wport = 0x44;
+ wmask = 0x00000800;
+ dmask = 0x00000800;
+ break;
+ case ALI_5451_ID:
+ wport = 0x40;
+ wmask = 0x00008000;
+ dmask = 0x00008000;
+ if (devc->revision == 2)
+ dmask = 0x100;
+ break;
+ default:
+ {
+ static int already_done = 0;
+ if (!already_done)
+ cmn_err (CE_WARN, "Unknown codec interface\n");
+ already_done = 1;
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+ }
+
+ /* Check to make sure No Writes are pending */
+ reg = READL (devc->osdev, wport);
+ while ((reg & wmask) && --t)
+ {
+ reg = READL (devc->osdev, wport); /* re-read status/data */
+ }
+ if (t)
+ {
+ reg = data << 16;
+ reg |= (addr & 0xff);
+ reg |= wmask | dmask;
+ WRITEL (devc->osdev, reg, wport);
+ }
+ else
+ DDB (cmn_err (CE_WARN, "AC97 mixer write timed out\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+static int
+tridentintr (oss_device_t * osdev)
+{
+ trident_devc *devc = (trident_devc *) osdev->devc;
+ int i;
+ oss_native_word status, intstat;
+ int serviced = 0;
+ dmap_t *dmapin;
+ oss_native_word flag;
+
+
+ /* check the interrupt status register MISCINT */
+ status = READL (devc->osdev, MISCINT);
+ serviced = 1;
+
+ /* If it is a not 4DWave Playback or MIDI interrupt then return */
+ if (!(status & (0x00000020 | 0x00000008 | 0x4)))
+ {
+ WRITEL (devc->osdev, status, MISCINT);
+ return 1;
+ }
+
+#ifdef OBSOLETED_STUFF
+/*
+ * This device has "ISA style" MIDI and FM subsystems. Such devices don't
+ * use PCI config space for the I/O ports and interrupts. Instead the driver
+ * needs to allocate proper resources itself. This functionality is no longer
+ * possible. For this reason the MIDI and FM parts are not accessible.
+ */
+ /* Check if this is a MIDI interrupt */
+ if (status & 0x00000008)
+ {
+ uart401intr (INT_HANDLER_CALL (devc->irq));
+ serviced = 1;
+ }
+#endif
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flag);
+
+ /* Check to see if this is our channel */
+ if (status & 0x20)
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ trident_portc *portc = &devc->portc[i];
+ serviced = 1;
+
+ /* Handle Playback Interrupts */
+ intstat = READL (devc->osdev, INTR (portc->pbank));
+
+ if (intstat & 1L << portc->play_intr_chan)
+ {
+ WRITEL (devc->osdev, READL (devc->osdev, INTR (portc->pbank))
+ | 1L << portc->play_intr_chan, INTR (portc->pbank));
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+
+ /* Handle Record Interrupts */
+ intstat = READL (devc->osdev, INTR (portc->rbank));
+
+ if (intstat & 1L << portc->rec_intr_chan)
+ {
+ WRITEL (devc->osdev, READL (devc->osdev, INTR (portc->rbank))
+ | 1L << portc->rec_intr_chan, INTR (portc->rbank));
+ if ((devc->chip_type == ALI_5451_ID)
+ || (devc->chip_type == SIS_7018_ID))
+ {
+ unsigned int ptr;
+ int i;
+ int chan;
+ dmapin = audio_engines[portc->audiodev]->dmap_in;
+
+ if (portc->rbank == BANK_A)
+ chan = portc->rec_chan;
+
+ else
+ chan = portc->rec_chan + 32;
+ WRITEL (devc->osdev,
+ (READL (devc->osdev, CIR) & ~0x3F) | chan, CIR);
+ ptr = READW (devc->osdev, CSO + 2);
+ ptr++;
+ ptr *= portc->channels * (portc->bits / 8);
+
+ if (dmapin->bytes_in_use == 0 || dmapin->fragment_size == 0)
+ {
+ cmn_err(CE_WARN, "bytes_in_use=%d, fragment_size=%d\n", dmapin->bytes_in_use, dmapin->fragment_size);
+ continue;
+ }
+ ptr %= dmapin->bytes_in_use;
+ ptr /= dmapin->fragment_size;
+ i = 0;
+ while (dmap_get_qtail (dmapin) != ptr && i++ < dmapin->nfrags)
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ else
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+
+ if (status & 0x4)
+ {
+ serviced = 1;
+ READB (devc->osdev, 0x1E); /*SB ESP ack */
+ READB (devc->osdev, 0x1F); /*SB IRQ ack */
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flag);
+ return serviced;
+}
+
+
+/***************************************************************************/
+static int
+trident_audio_set_rate (int dev, int arg)
+{
+ trident_portc *portc = audio_engines[dev]->portc;
+ if (arg == 0)
+ return portc->speed;
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+trident_audio_set_channels (int dev, short arg)
+{
+ trident_portc *portc = audio_engines[dev]->portc;
+ if ((arg != 1) && (arg != 2))
+ return portc->channels;
+ portc->channels = arg;
+ return portc->channels;
+}
+
+static unsigned int
+trident_audio_set_format (int dev, unsigned int arg)
+{
+ trident_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE | AFMT_AC3)))
+ return portc->bits;
+ portc->bits = arg;
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+trident_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void trident_audio_trigger (int dev, int state);
+
+static void
+trident_audio_reset (int dev)
+{
+ trident_audio_trigger (dev, 0);
+}
+
+static void
+trident_audio_reset_input (int dev)
+{
+ trident_portc *portc = audio_engines[dev]->portc;
+ trident_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+trident_audio_reset_output (int dev)
+{
+ trident_portc *portc = audio_engines[dev]->portc;
+ trident_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+trident_audio_open (int dev, int mode, int open_flags)
+{
+ trident_portc *portc = audio_engines[dev]->portc;
+ trident_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ portc->open_mode = mode;
+ portc->audio_enabled = ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+trident_audio_close (int dev, int mode)
+{
+ trident_portc *portc = audio_engines[dev]->portc;
+ trident_audio_reset (dev);
+ portc->open_mode = 0;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+trident_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ trident_portc *portc = audio_engines[dev]->portc;
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+trident_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ trident_portc *portc = audio_engines[dev]->portc;
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+trident_audio_trigger (int dev, int state)
+{
+ trident_devc *devc = audio_engines[dev]->devc;
+ trident_portc *portc = audio_engines[dev]->portc;
+ oss_native_word ainten = 0, playstop = 0, recstop = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT)
+ && !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+
+ /* Enable the channel interrupt */
+ WRITEL (devc->osdev, READL (devc->osdev, INTEN (portc->pbank))
+ | (1L << portc->play_intr_chan), INTEN (portc->pbank));
+
+ /* start playback and playback interrupt channels */
+ WRITEL (devc->osdev, READL (devc->osdev, START (portc->pbank))
+ | (1L << portc->play_chan)
+ | (1L << portc->play_intr_chan), START (portc->pbank));
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ /* disable playback interrupt channel */
+ ainten = READL (devc->osdev, INTEN (portc->pbank));
+ ainten = ainten & ~(1L << portc->play_intr_chan);
+ WRITEL (devc->osdev, ainten, INTEN (portc->pbank));
+
+ /* stop playback and playback interrupt channels */
+ playstop = ((1L << portc->play_chan) |
+ (1L << portc->play_intr_chan));
+ WRITEL (devc->osdev, playstop, STOP (portc->pbank));
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT)
+ && !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ /* Enable the channel interrupts */
+ WRITEL (devc->osdev, READL (devc->osdev, INTEN (portc->rbank))
+ | (1L << portc->rec_intr_chan), INTEN (portc->rbank));
+
+ if ((devc->chip_type != ALI_5451_ID)
+ && (devc->chip_type != SIS_7018_ID))
+ {
+ /* set recording flags */
+ WRITEB (devc->osdev, devc->sb_dma_flags, SBCTL);
+
+ /* start record interrupt channel */
+ WRITEL (devc->osdev, 1L << portc->rec_intr_chan,
+ START (portc->rbank));
+ }
+ else
+ {
+ WRITEL (devc->osdev,
+ READL (devc->osdev,
+ START (portc->rbank)) | (1L << portc->
+ rec_chan) | (1L <<
+ portc->
+ rec_intr_chan),
+ START (portc->rbank));
+ }
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ if ((devc->chip_type != ALI_5451_ID)
+ && (devc->chip_type != SIS_7018_ID))
+ {
+ /* disable the record interrrupt enable channel */
+ ainten = READL (devc->osdev, INTEN (portc->rbank));
+ ainten = ainten & ~(1L << portc->rec_intr_chan);
+ WRITEL (devc->osdev, ainten, INTEN (portc->rbank));
+
+ /* stop DMA controller */
+ WRITEB (devc->osdev, 0x00, SBCTL);
+
+ /* stop record interrupt channel */
+ recstop |= 1L << portc->rec_intr_chan;
+ WRITEL (devc->osdev, recstop, STOP (portc->rbank));
+ }
+ else
+ {
+ /* disable rec interrupt channel */
+ ainten = READL (devc->osdev, INTEN (portc->rbank));
+ ainten = ainten & ~(1L << portc->rec_intr_chan);
+ WRITEL (devc->osdev, ainten, INTEN (portc->rbank));
+
+ /* stop playback and playback interrupt channels */
+ recstop = ((1L << portc->rec_chan) |
+ (1L << portc->rec_intr_chan));
+ WRITEL (devc->osdev, recstop, STOP (portc->rbank));
+ }
+
+ /* ack any interrupts on INT_A */
+ recstop = READL (devc->osdev, INTR (portc->rbank));
+ recstop |= 1L << portc->rec_intr_chan;
+ WRITEL (devc->osdev, recstop, INTR (portc->rbank));
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+trident_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ trident_devc *devc = audio_engines[dev]->devc;
+ trident_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ oss_native_word bufsize, delta, eso;
+ oss_native_word temp;
+ unsigned int attribute = 0;
+ unsigned char bValue;
+ unsigned short wValue;
+ oss_native_word dwValue;
+ unsigned short wRecCodecSamples;
+ int chan;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ {
+ bValue = READB (devc->osdev, 0x48); /*enable AC97 ADC */
+ WRITEB (devc->osdev, bValue | 0x48, 0x48); /*disable rec intr */
+ }
+
+ if (devc->chip_type == TRIDENT_4DWAVENX_ID)
+ {
+ wValue = READW (devc->osdev, MISCINT);
+ WRITEW (devc->osdev, wValue | 0x1000, MISCINT);
+ }
+
+ if ((devc->chip_type != ALI_5451_ID) && (devc->chip_type != SIS_7018_ID))
+ {
+ /* Initialize legacy recording */
+ WRITEB (devc->osdev, 0, DMAR15);
+ bValue = READB (devc->osdev, DMAR11) & 0x03;
+ WRITEB (devc->osdev, bValue | 0x54, DMAR11);
+
+ /* Set base address in DMAR0-DMAR3 */
+ WRITEL (devc->osdev, dmap->dmabuf_phys, DMAR0);
+
+ /* Set count in DMAR4/DMAR5 */
+ eso = dmap->bytes_in_use;
+ WRITEW (devc->osdev, eso - 1, DMAR4);
+
+ /* Set speed in SBDelta */
+ dwValue = (48000 << 12) / portc->speed;
+ WRITEW (devc->osdev, (unsigned short) dwValue, SBDELTA);
+
+ /*Set channel interrupt blk length */
+ if ((portc->bits == 16) || (portc->channels == 2))
+ wRecCodecSamples = (unsigned short) ((eso >> 1) - 1);
+ else
+ wRecCodecSamples = (unsigned short) (eso - 1);
+
+ dwValue = wRecCodecSamples << 16;
+ dwValue |= wRecCodecSamples & 0x0000ffff;
+ WRITEL (devc->osdev, dwValue, SBBL);
+
+ /*set format */
+ devc->sb_dma_flags |= 0x19;
+ if (portc->bits == 16)
+ devc->sb_dma_flags |= 0xA0;
+ if (portc->channels == 2)
+ devc->sb_dma_flags |= 0x40;
+ }
+ else
+ {
+#if !defined(sparc)
+ if (devc->chip_type == ALI_5451_ID)
+ WRITEL (devc->osdev,
+ READL (devc->osdev, 0xd4) | ((unsigned int) 1 << 31), 0xd4);
+#endif
+
+ /* for SiS 7018: Rec with PCM_LR, MONO_MIX, SRC_EN */
+ if (devc->chip_type == SIS_7018_ID)
+ attribute = 0x8880; /* PCM->IN */
+
+ delta = (48000 << 12) / portc->speed;
+ bufsize = dmap->bytes_in_use;
+
+ if (portc->bits == 16)
+ bufsize /= 2;
+ if (portc->channels == 2)
+ bufsize /= 2;
+ bufsize--;
+
+ if (portc->rbank == BANK_A)
+ chan = portc->rec_chan;
+ else
+ chan = portc->rec_chan + 32;
+
+ WRITEL (devc->osdev, (READL (devc->osdev, CIR) & ~0x3F) | chan, CIR); /*select current chan */
+
+ /* Now set the buffer address pointer */
+ WRITEL (devc->osdev, dmap->dmabuf_phys, LBA);
+
+ /* Set the Size and Sampling Rate */
+ eso = (bufsize << 16) | (delta & 0x0000FFFF);
+ WRITEL (devc->osdev, eso, ESO);
+ temp = 0x80000000; /*enable gvsel */
+ if (portc->channels == 2)
+ temp |= 0x00004000; /*stereo/mono */
+ if (portc->bits == 16)
+ temp |= 0x0000A000; /*unsigned 8/signed 16bit */
+ temp |= 0x00001000; /*enable loop */
+ temp |= 0x003F0000; /*set pan to off */
+ temp |= 0x00000FFF; /*set vol to off */
+ WRITEL (devc->osdev, temp, TCTRL); /*set format */
+ WRITEL (devc->osdev, attribute << 16, FMC);
+ WRITEL (devc->osdev, 0, EBUF1);
+ WRITEL (devc->osdev, 0, EBUF2);
+ /* WRITEL (devc->osdev, 0xFFFF, VOL); *//*Music/WaveVol set to max */
+ WRITEL (devc->osdev, 0, CSO); /*set CSO and Alpha to 0 */
+ }
+
+/* Now prepare the Record Interrupt Channel */
+ delta = (48000 << 12) / portc->speed;
+ bufsize = dmap->fragment_size;
+ if (portc->bits == 16)
+ bufsize /= 2;
+ if (portc->channels == 2)
+ bufsize /= 2;
+ bufsize--;
+
+ if (portc->rbank == BANK_A)
+ chan = portc->rec_intr_chan;
+ else
+ chan = portc->rec_intr_chan + 32;
+
+ WRITEL (devc->osdev, (READL (devc->osdev, CIR) & ~0x3F) | chan, CIR);
+
+ /* Now set the buffer address pointer */
+ WRITEL (devc->osdev, dmap->dmabuf_phys, LBA);
+
+ /* Set the Size and Sampling Rate */
+ if ((devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ || (devc->chip_type == SIS_7018_ID) || (devc->chip_type == ALI_5451_ID))
+ {
+ eso = (bufsize << 16) | (delta & 0x0000FFFF);
+ WRITEL (devc->osdev, eso, ESO);
+ }
+ else
+ {
+ eso = ((delta << 16) & 0xff000000) | (bufsize & 0x00ffffff);
+ WRITEL (devc->osdev, eso, ESO);
+ }
+
+ temp = 0x80000000; /*enable gvsel */
+ if (portc->channels == 2)
+ temp |= 0x00004000; /*stereo/mono */
+ if (portc->bits == 16)
+ temp |= 0x0000A000; /*8 unsigned/16bit signed data */
+ temp |= 0x00001000; /*enable loop */
+ temp |= 0x003F0000; /*set pan to off */
+ temp |= 0x00000FFF; /*set vol to off */
+ WRITEL (devc->osdev, temp, TCTRL); /*set format */
+
+ /* for the record interrupt channel note that no attribute should be
+ * set for SIS7018
+ */
+ WRITEL (devc->osdev, 0, FMC);
+ WRITEL (devc->osdev, 0, EBUF1);
+ WRITEL (devc->osdev, 0, EBUF2);
+ /* WRITEL (devc->osdev, 0xFFFF, VOL); *//*Music/WaveVol set to min */
+ if ((devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ || (devc->chip_type == SIS_7018_ID) || (devc->chip_type == ALI_5451_ID))
+ {
+ WRITEL (devc->osdev, 0, CSO); /*set CSO and Alpha to 0 */
+ }
+ else
+ {
+ WRITEL (devc->osdev, (delta << 24) | (0 & 0x00ffffff), CSO);
+ }
+
+ /* Now set the mode on portc to record */
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+trident_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ trident_devc *devc = audio_engines[dev]->devc;
+ trident_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ oss_native_word bufsize, delta, eso;
+ oss_native_word temp;
+ int chan, spdif_rate, spdif_chan;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ /* prepare the main playback channel */
+ delta = (portc->speed * 4096) / 48000;
+ bufsize = dmap->bytes_in_use;
+
+ if (portc->bits == 16)
+ bufsize /= 2;
+ if (portc->channels == 2)
+ bufsize /= 2;
+ bufsize--;
+
+ if ((devc->chip_type == ALI_5451_ID) && (devc->revision == ALI_5451_V02)
+ && (portc->port_type == DF_SPDIF))
+
+ {
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_AUDIO, SNDCTL_MIX_WRITE,
+ 0);
+ portc->play_chan = 15;
+ portc->play_intr_chan = 14;
+
+ if (portc->bits == AFMT_AC3)
+
+ {
+ ac97_spdif_setup (devc->mixer_dev, portc->speed, portc->bits);
+ portc->bits = 16;
+ portc->channels = 2;
+ portc->speed = 48000;
+ /* set non-pcm (AC3) mode on SPDIF control */
+ WRITEW (devc->osdev, (READW (devc->osdev, 0x70) & ~0x2) | 0x2,
+ 0x70);
+ }
+ else
+ /* set pcm mode on SPDIF control */
+ WRITEW (devc->osdev, READW (devc->osdev, 0x70) & ~0x2, 0x70);
+
+ /*set up the sampling rate */
+ switch (portc->speed)
+ {
+ case 44100:
+ spdif_rate = 0;
+ break;
+ case 32000:
+ spdif_rate = 0x300;
+ break;
+ case 48000:
+ default:
+ spdif_rate = 0x200;
+ break;
+ }
+ spdif_chan = READB (devc->osdev, 0x74) & 0xbf; /*select spdif_out */
+ spdif_chan |= 0x80; /*select right */
+ WRITEB (devc->osdev, spdif_chan, 0x74);
+ WRITEB (devc->osdev, spdif_rate | 0x20, 0x72);
+ spdif_chan &= (~0x80); /*select left */
+ WRITEB (devc->osdev, spdif_chan, 0x74);
+ WRITEB (devc->osdev, spdif_rate | 0x10, 0x72);
+ }
+
+ if (portc->pbank == BANK_A)
+ chan = portc->play_chan;
+ else
+ chan = portc->play_chan + 32;
+
+ WRITEL (devc->osdev, (READL (devc->osdev, CIR) & ~0x3F) | chan, CIR); /*select current chan */
+
+ /* Now set the buffer address pointer */
+ WRITEL (devc->osdev, dmap->dmabuf_phys, LBA);
+
+ /* Set the Size and Sampling Rate */
+ if ((devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ || (devc->chip_type == SIS_7018_ID) || (devc->chip_type == ALI_5451_ID))
+ {
+ eso = (bufsize << 16) | (delta & 0x0000FFFF);
+ WRITEL (devc->osdev, eso, ESO);
+ }
+ else
+ {
+ eso = ((delta << 16) & 0xff000000) | (bufsize & 0x00ffffff);
+ WRITEL (devc->osdev, eso, ESO);
+ }
+ temp = 0x80000000; /*enable gvsel */
+ if (portc->channels == 2)
+ temp |= 0x00004000; /*stereo/mono */
+ if (portc->bits == 16)
+ temp |= 0x0000A000; /*8 unsigned/16bit signed data */
+ temp |= 0x00001000; /*enable loop */
+ WRITEL (devc->osdev, temp, TCTRL); /*set format */
+ WRITEL (devc->osdev, 0, FMC);
+ WRITEL (devc->osdev, 0, EBUF1);
+ WRITEL (devc->osdev, 0, EBUF2);
+ WRITEL (devc->osdev, 0, VOL); /*Music/WaveVol set to max */
+ if ((devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ || (devc->chip_type == SIS_7018_ID) || (devc->chip_type == ALI_5451_ID))
+ {
+ WRITEL (devc->osdev, 0, CSO); /*set CSO and Alpha to 0 */
+ }
+ else
+ {
+ WRITEL (devc->osdev, (delta << 24) | (0 & 0x00ffffff), CSO);
+ }
+
+ /* Now prepare the playback interrupt channel */
+ delta = (portc->speed * 4096) / 48000;
+ bufsize = dmap->fragment_size;
+ if (portc->bits == 16)
+ bufsize /= 2;
+ if (portc->channels == 2)
+ bufsize /= 2;
+ bufsize--;
+
+ if (portc->pbank == BANK_A)
+ chan = portc->play_intr_chan;
+ else
+ chan = portc->play_intr_chan + 32;
+
+ WRITEL (devc->osdev, (READL (devc->osdev, CIR) & ~0x3F) | chan, CIR); /*select current chan */
+
+ /* Now set the buffer address pointer */
+ WRITEL (devc->osdev, dmap->dmabuf_phys, LBA);
+
+ /* Set the Size and Sampling Rate */
+ if ((devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ || (devc->chip_type == SIS_7018_ID) || (devc->chip_type == ALI_5451_ID))
+ {
+ eso = (bufsize << 16) | (delta & 0x0000FFFF);
+ WRITEL (devc->osdev, eso, ESO);
+ }
+ else
+ {
+ eso = ((delta << 16) & 0xff000000) | (bufsize & 0x00ffffff);
+ WRITEL (devc->osdev, eso, ESO);
+ }
+
+ temp = 0x80000000; /*enable gvsel */
+ if (portc->channels == 2)
+ temp |= 0x00004000; /*stereo/mono */
+ if (portc->bits == 16)
+ temp |= 0x0000A000; /*8 unsigned/16bit signed data */
+ temp |= 0x00001000; /*enable loop */
+ temp |= 0xFFF; /* no vol */
+ temp |= 0x003F0000; /*set volume to off */
+ WRITEL (devc->osdev, temp, TCTRL); /*set format */
+ WRITEL (devc->osdev, 0, FMC);
+ WRITEL (devc->osdev, 0, EBUF1);
+ WRITEL (devc->osdev, 0, EBUF2);
+ WRITEL (devc->osdev, 0, VOL); /*Music/WaveVol set to max */
+ if ((devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ || (devc->chip_type == SIS_7018_ID) || (devc->chip_type == ALI_5451_ID))
+ {
+ WRITEL (devc->osdev, 0, CSO); /*set CSO and Alpha to 0 */
+ }
+ else
+ {
+ WRITEL (devc->osdev, (delta << 24) | (0 & 0x00ffffff), CSO);
+ }
+
+ /* Now set the mode on portc to playback */
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+#if 0
+static int
+trident_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ trident_devc *devc = audio_engines[dev]->devc;
+ trident_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+ int ptr = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ WRITEB (devc->osdev,
+ (READB (devc->osdev, CIR) & ~0x7F) | portc->rec_chan, CIR);
+ if ((devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ || (devc->chip_type == SIS_7018_ID)
+ || (devc->chip_type == ALI_5451_ID))
+ ptr = READW (devc->osdev, CSO + 2);
+ else /* ID_4DWAVE_NX */
+ {
+ ptr = READW (devc->osdev, SBBL) & 0xFFFF;
+ if (portc->channels > 1)
+ ptr >>= 1;
+ if (ptr > 0)
+ ptr = dmap->bytes_in_use - ptr;
+ }
+ }
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ WRITEB (devc->osdev,
+ (READB (devc->osdev, CIR) & ~0x7F) | portc->play_chan, CIR);
+ if ((devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ || (devc->chip_type == SIS_7018_ID)
+ || (devc->chip_type == ALI_5451_ID))
+ {
+ ptr = READW (devc->osdev, CSO + 2);
+ }
+ else
+ {
+ ptr = READL (devc->osdev, CSO) & 0x00ffffff;
+ }
+ if (ptr > dmap->bytes_in_use)
+ ptr = 0;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return ptr;
+}
+#endif
+
+#if !defined(sparc)
+static int
+trident_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ int err;
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+ if ((err = oss_alloc_dmabuf (dev, dmap, direction)) < 0)
+ {
+ cmn_err (CE_WARN, "Failed to allocate a DMA buffer.\n");
+ return err;
+ }
+ if (dmap->dmabuf_phys & 0x80000000)
+
+ {
+ cmn_err (CE_WARN, "Got DMA buffer address beyond 2G limit.\n");
+ oss_free_dmabuf (dev, dmap);
+ dmap->dmabuf = NULL;
+ return OSS_ENOSPC;
+ }
+ return 0;
+}
+#endif
+
+static audiodrv_t trident_audio_driver = {
+ trident_audio_open,
+ trident_audio_close,
+ trident_audio_output_block,
+ trident_audio_start_input,
+ trident_audio_ioctl,
+ trident_audio_prepare_for_input,
+ trident_audio_prepare_for_output,
+ trident_audio_reset,
+ NULL,
+ NULL,
+ trident_audio_reset_input,
+ trident_audio_reset_output,
+ trident_audio_trigger,
+ trident_audio_set_rate,
+ trident_audio_set_format,
+ trident_audio_set_channels,
+ NULL,
+ NULL,
+ NULL, /* trident_check_input, */
+ NULL, /* trident_check_output, */
+#if !defined(sparc)
+ trident_alloc_buffer,
+#else
+ NULL,
+#endif
+ NULL, /* trident_free_buffer, */
+ NULL,
+ NULL,
+ NULL /* trident_get_buffer_pointer */
+};
+
+
+#ifdef OBSOLETED_STUFF
+static void
+attach_mpu (trident_devc * devc)
+{
+ struct address_info hw_config;
+ hw_config.io_base = devc->mpu_base;
+ hw_config.irq = -devc->irq;
+ hw_config.dma = -1;
+ hw_config.dma2 = -1;
+ hw_config.always_detect = 0;
+ hw_config.name = devc->chip_name;
+ hw_config.driver_use_1 = 0;
+ hw_config.driver_use_2 = 0;
+ hw_config.osdev = devc->osdev;
+#ifdef CREATE_OSP
+ CREATE_OSP (hw_config.osdev);
+#endif
+ hw_config.card_subtype = 0;
+ if (!probe_uart401 (&hw_config))
+ {
+ cmn_err (CE_WARN, "MPU-401 was not detected\n");
+ return;
+ }
+ devc->mpu_attached = 1;
+ attach_uart401 (&hw_config);
+}
+
+static void
+unload_mpu (trident_devc * devc)
+{
+ struct address_info hw_config;
+ hw_config.io_base = devc->mpu_base;
+ hw_config.irq = devc->mpu_irq;
+ hw_config.dma = -1;
+ hw_config.dma2 = -1;
+ hw_config.always_detect = 0;
+ hw_config.name = devc->chip_name;
+ hw_config.driver_use_1 = 0;
+ hw_config.driver_use_2 = 0;
+ hw_config.osdev = devc->osdev;
+#ifdef CREATE_OSP
+ CREATE_OSP (hw_config.osdev);
+#endif /* */
+ hw_config.card_subtype = 0;
+ devc->mpu_attached = 0;
+ unload_uart401 (&hw_config);
+}
+#endif
+
+static int
+init_trident (trident_devc * devc)
+{
+ int my_mixer, i;
+ oss_device_t *osdev = devc->osdev;
+ unsigned char legacy;
+ oss_native_word global_control;
+ int adev;
+ unsigned int dwVal;
+ int first_dev = 0;
+
+/*
+ * Legacy I/O setup
+ */
+ devc->mpu_attached = 0;
+ legacy = 0xA0; /* Enable MPU, GP, FM */
+ switch (devc->mpu_base)
+ {
+ case 0x330:
+ legacy |= 0x00;
+ break;
+ case 0x300:
+ legacy |= 0x40;
+ break;
+ default:
+ devc->mpu_base = 0;
+ }
+ pci_write_config_byte (osdev, 0x44, legacy); /*setup legacy devs */
+
+ /* pci_write_config_byte (osdev, 0x45, 0x12); *//*setup DDMA */
+ /* pci_write_config_byte (osdev, 0x46, 0x02); *//*setup device r/w */
+
+ /* Now reset AC97 and unmute the codec channels */
+ if (devc->chip_type == TRIDENT_4DWAVEDX_ID)
+ {
+ WRITEB (devc->osdev, 0x09, 0x40); /*set ddma */
+ WRITEL (devc->osdev, 0x2, 0x48); /*enable the AC97 */
+ }
+
+ if (devc->chip_type == SIS_7018_ID)
+ {
+ WRITEL (devc->osdev, 0, 0x4c);
+ WRITEL (devc->osdev, 0xF0000, 0x48); /* enable ac97 link */
+ }
+
+ if (devc->chip_type == TRIDENT_4DWAVENX_ID)
+ {
+ WRITEL (devc->osdev, 0x2, 0x40);
+ /* Setup 48KHz S/PDIF output on 4DWave NX */
+ WRITEL (devc->osdev, INL (devc->osdev, SP_STAT) | 4, SP_STAT);
+ WRITEB (devc->osdev, 0x38, SP_CSO + 3);
+ }
+
+ if (devc->chip_type == ALI_5451_ID)
+ {
+#ifndef sparc
+ pci_read_config_dword (osdev, 0x7c, &dwVal);
+ pci_write_config_dword (osdev, 0x7c, dwVal | 0x08000000);
+ oss_udelay (5000);
+ pci_read_config_dword (osdev, 0x7c, &dwVal);
+ pci_write_config_dword (osdev, 0x7c, dwVal & 0xf7ffffff);
+ oss_udelay (5000);
+ pci_read_config_dword (osdev, 0x44, &dwVal);
+ pci_write_config_dword (osdev, 0x44, dwVal | 0x000c0000);
+ oss_udelay (500);
+ pci_read_config_dword (osdev, 0x44, &dwVal);
+ pci_write_config_dword (osdev, 0x44, dwVal & 0xfffbffff);
+#endif
+ /* enable full 32bit and disable DDMA */
+ pci_write_config_dword (osdev, 0x40, dwVal & 0x00000008);
+ oss_udelay (5000);
+ }
+
+ my_mixer = ac97_install (&devc->ac97devc, devc->chip_name, ac97_read,
+ ac97_write, devc, devc->osdev);
+ if (my_mixer >= 0)
+ {
+ devc->mixer_dev = my_mixer;
+ mixer_devs[my_mixer]->priority = 9;
+ }
+ else
+ return 0;
+
+#ifdef OBSOLETED_STUFF
+ if (devc->mpu_base > 0)
+ attach_mpu (devc);
+#endif
+
+ for (i = 0; i < 2; i++)
+ {
+ char tmp_name[1024];
+ trident_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE /* | ADEV_HWMIX */ ;
+ int porttype = DF_PCM;
+
+ sprintf (tmp_name, "%s (rev %d)", devc->chip_name, devc->revision);
+ if (i == 0)
+ {
+ caps |= ADEV_DUPLEX;
+ }
+ else
+ {
+ caps |= ADEV_NOINPUT;
+ if (i > 1)
+ caps |= ADEV_SHADOW;
+ }
+
+#if 0
+ /* This will not work any more */
+ if ((devc->chip_type == ALI_5451_ID)
+ && (devc->revision == ALI_5451_V02) && (i == 7))
+ {
+ /* need to set SPDIF output in PCI southbridge chip 0x1533 */
+ while ((osdev = (pci_find_class (0x601 << 8, osdev))))
+ {
+ unsigned short vendorid, deviceid;
+ unsigned char temp;
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendorid);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &deviceid);
+ if (vendorid != 0x10b9 || deviceid != 0x1533)
+ continue;
+ pci_read_config_byte (osdev, 0x61, &temp);
+ temp |= 0x40;
+ pci_write_config_byte (osdev, 0x61, temp);
+ pci_read_config_byte (osdev, 0x7d, &temp);
+ temp |= 0x01;
+ pci_write_config_byte (osdev, 0x7d, temp);
+ pci_read_config_byte (osdev, 0x7e, &temp);
+ temp &= (~0x20);
+ temp |= 0x10;
+ pci_write_config_byte (osdev, 0x7e, temp);
+
+ /* SPDIF Magic!!! */
+ pci_read_config_byte (osdev, 0x63, &temp);
+ temp |= 0x3; /* enable SPDIF OUT bit0=out bit1=in */
+ pci_write_config_byte (osdev, 0x63, temp);
+
+ /* SPDIF Output in SERIAL Config reg */
+ temp = READL (devc->osdev, 0x48);
+ WRITEB (devc->osdev, temp | 0x20, 0x48);
+ temp = READL (devc->osdev, 0x74);
+ WRITEB (devc->osdev, temp & 0xbf, 0x74);
+
+ /* Enable SPDIF on play_channel 15 and setup as SPDIFOUT */
+ WRITEW (devc->osdev, READW (devc->osdev, 0xd4) | 0x8000, 0xd4);
+ WRITEW (devc->osdev, READW (devc->osdev, 0xd4) & ~0x0400, 0xd4);
+
+ porttype = DF_SPDIF;
+ caps |= ADEV_SPECIAL | ADEV_FIXEDRATE;
+ sprintf (tmp_name, "%s (S/PDIF Output)", devc->chip_name);
+ }
+ }
+#endif
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &trident_audio_driver,
+ sizeof (audiodrv_t),
+ caps,
+ AFMT_U8 | AFMT_S16_LE | AFMT_AC3,
+ devc, -1)) < 0)
+
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->min_rate = 8000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+
+#if !defined(sparc)
+ /*
+ * Only 31 bit memory addresses are supported except under Sparc
+ * where the on-board audio chip supports the top half of 32 bit PCI
+ * address space.
+ */
+ audio_engines[adev]->dmabuf_maxaddr = MEMLIMIT_31BITS;
+#endif
+ portc->audiodev = adev;
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+
+ if (audio_engines[adev]->flags & ADEV_FIXEDRATE)
+ {
+ audio_engines[adev]->fixed_rate = 48000;
+ audio_engines[adev]->min_rate = 48000;
+ audio_engines[adev]->max_rate = 48000;
+ }
+
+ portc->port_type = porttype;
+ portc->play_chan = 3 + (2 * i);
+ portc->play_intr_chan = 2 + (2 * i);
+ portc->pbank = BANK_A;
+ portc->rec_chan = 1;
+ portc->rec_intr_chan = 0;
+ portc->rbank = BANK_A;
+
+ if (devc->chip_type == ALI_5451_ID)
+ {
+ portc->rec_chan = 31;
+ portc->rec_intr_chan = 30;
+ portc->rbank = BANK_A;
+ }
+ if (devc->chip_type == SIS_7018_ID)
+ {
+ portc->pbank = BANK_B;
+ portc->rec_chan = 1;
+ portc->rec_intr_chan = 0;
+ portc->rbank = BANK_B;
+ WRITEL (devc->osdev, READL (devc->osdev, CIR) | 0x10000, CIR);
+ }
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+
+ devc->audio_opened = 0;
+ /* set the global control and enable end interrupt condition */
+ global_control = READL (devc->osdev, CIR);
+ global_control |= (1 << 12); /* control end intr */
+ WRITEL (devc->osdev, global_control, CIR);
+ }
+ return 1;
+}
+
+int
+oss_trident_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision /*, pci_latency */ ;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ trident_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered Trident 4DWAVE probe routine\n"));
+
+ oss_pci_byteswap (osdev, 1);
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if ((vendor != TRIDENT_VENDOR_ID && vendor != ALI_VENDOR_ID
+ && vendor != SIS_VENDOR_ID) ||
+ (device != TRIDENT_4DWAVEDX_ID && device != TRIDENT_4DWAVENX_ID &&
+ device != TRIDENT_4DWAVECX_ID && device != ALI_5451_ID &&
+ device != SIS_7018_ID))
+
+ return 0;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->revision = pci_revision;
+ devc->irq = pci_irq_line;
+
+ switch (device)
+ {
+ case TRIDENT_4DWAVEDX_ID:
+ devc->chip_name = "Trident 4DWAVEDX";
+ devc->chip_type = TRIDENT_4DWAVEDX_ID;
+ break;
+ case TRIDENT_4DWAVENX_ID:
+ devc->chip_name = "Trident 4DWAVENX";
+ devc->chip_type = TRIDENT_4DWAVENX_ID;
+ break;
+ case TRIDENT_4DWAVECX_ID:
+ devc->chip_name = "Trident 4DWAVECX";
+ devc->chip_type = TRIDENT_4DWAVECX_ID;
+ break;
+ case ALI_5451_ID:
+ devc->chip_name = "ALI M5451";
+ devc->chip_type = ALI_5451_ID;
+ break;
+ case SIS_7018_ID:
+ devc->chip_name = "SiS 7018";
+ devc->chip_type = SIS_7018_ID;
+ break;
+ default:
+ devc->chip_name = "Trident 4DWAVE";
+ devc->chip_type = TRIDENT_4DWAVEDX_ID;
+ }
+
+#ifdef MEM_MAPPED_REGISTERS
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_1, &devc->bar1addr);
+ devc->bar1virt =
+ (char *) MAP_PCI_MEM (devc->osdev, 1, devc->bar1addr, 1024 * 1024);
+ pci_command |= PCI_COMMAND_MEMORY;
+#else
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+
+ /* Remove I/O space marker in bit 0. */
+ devc->base &= ~0x03;
+ pci_command |= PCI_COMMAND_IO;
+#endif
+ devc->mpu_base = trident_mpu_ioaddr;
+ devc->mpu_irq = devc->irq;
+
+ /* activate the device */
+ pci_command |= PCI_COMMAND_MASTER;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if (oss_register_interrupts (devc->osdev, 0, tridentintr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Can't allocate IRQ%d\n", pci_irq_line);
+ return 0;
+ }
+
+ return init_trident (devc); /*Detected */
+}
+
+
+
+int
+oss_trident_detach (oss_device_t * osdev)
+{
+ trident_devc *devc = (trident_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ WRITEL (devc->osdev, 0, CIR);
+ if (devc->chip_type == TRIDENT_4DWAVENX_ID)
+ WRITEL (devc->osdev, 0x0, SP_CSO); /*disable S/PDIF on NX */
+
+#ifdef OBSOLETED_STUFF
+ if (devc->mpu_attached)
+ {
+ unload_mpu (devc);
+ devc->mpu_attached = 0;
+ }
+#endif
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+
+#ifdef MEM_MAPPED_REGISTERS
+ UNMAP_PCI_MEM(osdev, 1, devc->bar1addr, devc->bar1virt, 1024x1024);
+#else
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+#endif
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_trident/oss_trident.man b/kernel/drv/oss_trident/oss_trident.man
new file mode 100644
index 0000000..d70929d
--- /dev/null
+++ b/kernel/drv/oss_trident/oss_trident.man
@@ -0,0 +1,27 @@
+NAME
+oss_trident - SiS7018, 4Dwave, ALIM5451 audio driver.
+
+DESCRIPTION
+Open Sound System driver for Trident 4DWave DX/NX, SiS7018 and ALI5451 audio
+controllers.
+
+Trident device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo playback/recording
+ o 8KHz to 48Khz sample rate.
+ o Upto 8 hardware channels to mixing audio streams
+
+OPTIONS
+trident_mpu_ioaddr=<xxx>
+Set the MPU I/O address. Refer to the driver.conf file for valid addresses.
+
+LIMITATIONS
+o Due to PCI addressing limitations any add-on cards based on these chips
+will not work under Sparc. The only exception is the ALI5451 chip that is
+used on the main boards on many Sparc based systems.
+
+FILES
+CONFIGFILEPATH/oss_trident.conf Device configuration file
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_usb/.config b/kernel/drv/oss_usb/.config
new file mode 100644
index 0000000..17d7733
--- /dev/null
+++ b/kernel/drv/oss_usb/.config
@@ -0,0 +1,3 @@
+bus=USB
+targetos=SunOS
+targetos=Linux
diff --git a/kernel/drv/oss_usb/.devices b/kernel/drv/oss_usb/.devices
new file mode 100644
index 0000000..456a797
--- /dev/null
+++ b/kernel/drv/oss_usb/.devices
@@ -0,0 +1,28 @@
+oss_usb usbif,class1 Generic USB audio/MIDI device (BETA)
+oss_usb usbif41e,3000 Creative Sound Blaster Extigy (BETA)
+oss_usb usbif41e,3010 Creative Sound Blaster MP3+ USB
+oss_usb usbif41e,3020 Creative Audigy2 NX USB (BETA)
+oss_usb usbif46d,8b2 Logitec Quickcam Pro 4000 (mic) (BETA)
+oss_usb usbif46d,a01 Logitec USB Headset
+oss_usb usbif471,311 Philips ToUcam Pro (mic) (BETA)
+oss_usb usbif672,1041 Labtec LCS1040 Speaker System (BETA)
+oss_usb usbifd8c,c C-Media USB audio adapter - model1
+oss_usb usbifd8c,103 C-Media USB audio adapter - model2
+oss_usb usbifd8c,102 C-Media USB 2/4/6/8ch audio adapter
+oss_usb usbif6f8,c000 Hercules Gamesurround MUSE Pocket (BETA)
+oss_usb usb763,1010 M Audio USB MIDISPORT 1x1 (BETA)
+oss_usb usb763,1011 M Audio USB MIDISPORT 1x1 (BETA)
+oss_usb usb763,1001 M Audio USB MIDISPORT 2x2 (BETA)
+oss_usb usb763,1002 M Audio USB MIDISPORT 2x2 (BETA)
+oss_usb usb763,1031 M Audio USB MIDISPORT 8x8 (BETA)
+oss_usb usbif763,2001 M Audio USB AudioSport Quatro (BETA)
+oss_usb usbif763,2002 M Audio USB AudioSport Duo (BETA)
+oss_usb usbif763,classff Generic M Audio USB MIDI interface (BETA)
+oss_usb usbif763,2007 M Audio Sonica Theater USB (BETA)
+oss_usb usbif763,200d M Audio OmniStudio USB (BETA)
+oss_usb usbif763,2805 M Audio Sonica USB (BETA)
+oss_usb usb763,1014 M Audio Oygen8 MIDI keyboard
+oss_usb usb763,1015 M Audio Oygen8 MIDI keyboard
+oss_usb usbifa92,1010 EGO SYStems RoMI/O USB MIDI interface (BETA)
+oss_usb usb499,1009 Yamaha UX16 USB MIDI interface (BETA)
+oss_usb usb499,101e Yamaha PSR-1K USB MIDI Keyboard (BETA)
diff --git a/kernel/drv/oss_usb/.name b/kernel/drv/oss_usb/.name
new file mode 100644
index 0000000..42bff9b
--- /dev/null
+++ b/kernel/drv/oss_usb/.name
@@ -0,0 +1 @@
+USB audio device support (BETA)
diff --git a/kernel/drv/oss_usb/.params b/kernel/drv/oss_usb/.params
new file mode 100644
index 0000000..01df07b
--- /dev/null
+++ b/kernel/drv/oss_usb/.params
@@ -0,0 +1,2 @@
+int usb_trace=0;
+int usb_mixerstyle=1;
diff --git a/kernel/drv/oss_usb/midisport1x1_fw.h b/kernel/drv/oss_usb/midisport1x1_fw.h
new file mode 100755
index 0000000..0a5eb07
--- /dev/null
+++ b/kernel/drv/oss_usb/midisport1x1_fw.h
@@ -0,0 +1,677 @@
+/*
+ * Purpose: Firmware download for Midiman MIDISport 1x1
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+const struct setup_request midisport1x1_setupRequest[] = {
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x146C, 0x0000, 0x0010, 0x0010,
+ "\xC2\x00\x90\x7F\xA5\xE0\x54\x18\xFF\x13\x13\x13\x54\x1F\x44\x50"},
+ {0x40, 0xA0, 0x147C, 0x0000, 0x0010, 0x0010,
+ "\xF5\x1C\x13\x92\x01\xD2\xE8\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9"},
+ {0x40, 0xA0, 0x148C, 0x0000, 0x0010, 0x0010,
+ "\xF0\x90\x7F\xAA\xF0\x53\x91\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90"},
+ {0x40, 0xA0, 0x149C, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAF\xE0\x44\x01\xF0\x90\x7F\xAE\xE0\x44\x05\xF0\xD2\xAF\x12"},
+ {0x40, 0xA0, 0x14AC, 0x0000, 0x000D, 0x000D,
+ "\x17\x5F\x30\x00\xFD\x12\x11\x00\xC2\x00\x80\xF6\x22"},
+ {0x40, 0xA0, 0x1100, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x24\x5D\x60\x0D\x14\x70\x03\x02\x12\x44\x24\x02"},
+ {0x40, 0xA0, 0x1110, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x12\x4A\x90\x7F\xEA\xE0\x75\x08\x00\xF5\x09\xA3\xE0"},
+ {0x40, 0xA0, 0x1120, 0x0000, 0x0010, 0x0010,
+ "\xFE\xE4\x25\x09\xF5\x09\xEE\x35\x08\xF5\x08\x90\x7F\xEE\xE0\x75"},
+ {0x40, 0xA0, 0x1130, 0x0000, 0x0010, 0x0010,
+ "\x0A\x00\xF5\x0B\xA3\xE0\xFE\xE4\x25\x0B\xF5\x0B\xEE\x35\x0A\xF5"},
+ {0x40, 0xA0, 0x1140, 0x0000, 0x0010, 0x0010,
+ "\x0A\x90\x7F\xE8\xE0\x64\xC0\x60\x03\x02\x11\xD4\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x1150, 0x0000, 0x0010, 0x0010,
+ "\x70\x03\x02\x12\x4A\xC3\xE5\x0B\x94\x40\xE5\x0A\x94\x00\x50\x08"},
+ {0x40, 0xA0, 0x1160, 0x0000, 0x0010, 0x0010,
+ "\x85\x0A\x0C\x85\x0B\x0D\x80\x06\x75\x0C\x00\x75\x0D\x40\x90\x7F"},
+ {0x40, 0xA0, 0x1170, 0x0000, 0x0010, 0x0010,
+ "\xE9\xE0\xB4\xA3\x25\xAE\x0C\xAF\x0D\xAA\x08\xA9\x09\x7B\x01\xC0"},
+ {0x40, 0xA0, 0x1180, 0x0000, 0x0010, 0x0010,
+ "\x03\xC0\x02\xC0\x01\x7A\x7F\x79\x00\x78\x00\x7C\x7F\xAD\x03\xD0"},
+ {0x40, 0xA0, 0x1190, 0x0000, 0x0010, 0x0010,
+ "\x01\xD0\x02\xD0\x03\x12\x13\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D"},
+ {0x40, 0xA0, 0x11A0, 0x0000, 0x0010, 0x0010,
+ "\x7A\x7F\x79\x00\x7B\x00\x12\x15\xA4\x90\x7F\xB5\xE5\x0D\xF0\xE5"},
+ {0x40, 0xA0, 0x11B0, 0x0000, 0x0010, 0x0010,
+ "\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5\x0B\x95\x0D"},
+ {0x40, 0xA0, 0x11C0, 0x0000, 0x0010, 0x0010,
+ "\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x20\xE2\x03\x02"},
+ {0x40, 0xA0, 0x11D0, 0x0000, 0x0010, 0x0010,
+ "\x11\x4C\x80\xF4\x90\x7F\xE8\xE0\x64\x40\x70\x6E\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x11E0, 0x0000, 0x0010, 0x0010,
+ "\x60\x68\xE4\x90\x7F\xC5\xF0\x90\x7F\xB4\xE0\x20\xE3\xF9\x90\x7F"},
+ {0x40, 0xA0, 0x11F0, 0x0000, 0x0010, 0x0010,
+ "\xC5\xE0\x75\x0C\x00\xF5\x0D\x90\x7F\xE9\xE0\xB4\xA3\x15\xAE\x0C"},
+ {0x40, 0xA0, 0x1200, 0x0000, 0x0010, 0x0010,
+ "\xAF\x0D\xA8\x09\xAC\x08\x7D\x01\x7B\x01\x7A\x7E\x79\xC0\x12\x13"},
+ {0x40, 0xA0, 0x1210, 0x0000, 0x0010, 0x0010,
+ "\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D\x7A\x7F\x79\x00\x7B\x00\x12"},
+ {0x40, 0xA0, 0x1220, 0x0000, 0x0010, 0x0010,
+ "\x14\xB9\xE5\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5"},
+ {0x40, 0xA0, 0x1230, 0x0000, 0x0010, 0x0010,
+ "\x0B\x95\x0D\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x44"},
+ {0x40, 0xA0, 0x1240, 0x0000, 0x000A, 0x000A,
+ "\x02\xF0\x80\x98\x90\x7F\xEA\xE0\xF5\x1C"},
+ {0x40, 0xA0, 0x124A, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x1558, 0x0000, 0x0006, 0x0006, "\xAB\x07\xAA\x06\xAC\x05"},
+ {0x40, 0xA0, 0x155E, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x11\xEA\xFF\xAE\x05\x0D\xEE\x24\x00\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x156E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEF\xF0\xEB\xAE\x05\x0D\x74\x00\x2E\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x157E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEB\xF0\xAF\x05\x0D\x74\x00\x2F\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x158E, 0x0000, 0x0010, 0x0010,
+ "\xE0\xF5\x83\xEC\xF0\xAF\x1C\x7A\xE0\x7B\x00\x12\x17\x20\x7F\x0A"},
+ {0x40, 0xA0, 0x159E, 0x0000, 0x0005, 0x0005, "\x7E\x00\x12\x17\x3C"},
+ {0x40, 0xA0, 0x15A3, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x14B9, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x14C3, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x13\xE5\x13\xC3\x95\x10\x50\x20\x05\x0F\xE5\x0F\xAE\x0E"},
+ {0x40, 0xA0, 0x14D3, 0x0000, 0x0010, 0x0010,
+ "\x70\x02\x05\x0E\x14\xFF\xE5\x12\x25\x13\xF5\x82\xE4\x35\x11\xF5"},
+ {0x40, 0xA0, 0x14E3, 0x0000, 0x000A, 0x000A,
+ "\x83\xE0\xFD\x12\x15\x58\x05\x13\x80\xD9"},
+ {0x40, 0xA0, 0x14ED, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x15A4, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x15AE, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x12\xE5\x0E\xFF\xAE\x05\x0D\xEE\x24\x03\xF5\x82"},
+ {0x40, 0xA0, 0x15BE, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\xE0\xF5\x83\xEF\xF0\xE5\x0F\xAE\x05\x0D\x74\x03\x2E\xF5"},
+ {0x40, 0xA0, 0x15CE, 0x0000, 0x0010, 0x0010,
+ "\x82\xE4\x34\xE0\xF5\x83\xE5\x0F\xF0\xAF\x1C\x7A\xE0\x7B\x03\x12"},
+ {0x40, 0xA0, 0x15DE, 0x0000, 0x000D, 0x000D,
+ "\x17\x20\xAF\x1C\xAD\x10\xAB\x12\xAA\x11\x12\x17\x04"},
+ {0x40, 0xA0, 0x15EB, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x166E, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x167E, 0x0000, 0x0010, 0x0010,
+ "\x00\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x168E, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1644, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x1654, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x1664, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1695, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16A5, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x02\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16B5, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x16BA, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16CA, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16DA, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x14FF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x16DF, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16EF, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16FF, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1767, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1768, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1769, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176A, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176B, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176C, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176D, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176E, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176F, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1770, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1771, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1772, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1773, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1774, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1775, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1776, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x15\x00"},
+ {0x40, 0xA0, 0x1500, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\x6E\x00\x02\x16\x95\x00\x02\x16\x44\x00\x02\x16\xDF\x00"},
+ {0x40, 0xA0, 0x1510, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\xBA\x00\x02\x14\xFF\x00\x02\x17\x67\x00\x02\x17\x68\x00"},
+ {0x40, 0xA0, 0x1520, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x69\x00\x02\x17\x6A\x00\x02\x17\x6B\x00\x02\x17\x6C\x00"},
+ {0x40, 0xA0, 0x1530, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x6D\x00\x02\x17\x6E\x00\x02\x17\x6F\x00\x02\x17\x70\x00"},
+ {0x40, 0xA0, 0x1540, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x71\x00\x02\x17\x72\x00\x02\x17\x73\x00\x02\x17\x74\x00"},
+ {0x40, 0xA0, 0x1550, 0x0000, 0x0008, 0x0008,
+ "\x02\x17\x75\x00\x02\x17\x76\x00"},
+ {0x40, 0xA0, 0x173C, 0x0000, 0x0010, 0x0010,
+ "\x8E\x14\x8F\x15\xE5\x15\x15\x15\xAE\x14\x70\x02\x15\x14\x4E\x60"},
+ {0x40, 0xA0, 0x174C, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x14\xEE\x80\xEE\x22"},
+ {0x40, 0xA0, 0x175F, 0x0000, 0x0008, 0x0008,
+ "\xE4\xF5\x1B\xD2\xE9\xD2\xAF\x22"},
+ {0x40, 0xA0, 0x1619, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x23\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x1629, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A\x18\x89"},
+ {0x40, 0xA0, 0x1639, 0x0000, 0x000B, 0x000B,
+ "\x19\xE4\xF5\x1A\x75\x1B\x01\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x15EC, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x25\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x15FC, 0x0000, 0x0010, 0x0010,
+ "\x44\x01\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A"},
+ {0x40, 0xA0, 0x160C, 0x0000, 0x000D, 0x000D,
+ "\x18\x89\x19\xE4\xF5\x1A\x75\x1B\x03\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x004B, 0x0000, 0x0003, 0x0003, "\x02\x13\x7F"},
+ {0x40, 0xA0, 0x137F, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x138F, 0x0000, 0x0010, 0x0010,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x01\xC0\x02\xC0\x03\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x139F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA5\xE0\x30\xE2\x06\x75\x1B\x06\x02\x14\x4E\x90\x7F\xA5"},
+ {0x40, 0xA0, 0x13AF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x20\xE1\x0C\xE5\x1B\x64\x02\x60\x06\x75\x1B\x07\x02\x14\x4E"},
+ {0x40, 0xA0, 0x13BF, 0x0000, 0x0010, 0x0010,
+ "\xAF\x1B\xEF\x24\xFE\x60\x48\x14\x60\x2C\x24\xFE\x60\x77\x24\x04"},
+ {0x40, 0xA0, 0x13CF, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x14\x4E\xAB\x17\xAA\x18\xA9\x19\xAF\x1A\x05\x1A\x8F"},
+ {0x40, 0xA0, 0x13DF, 0x0000, 0x0010, 0x0010,
+ "\x82\x75\x83\x00\x12\x12\x4B\x90\x7F\xA6\xF0\xE5\x1A\x65\x16\x70"},
+ {0x40, 0xA0, 0x13EF, 0x0000, 0x0010, 0x0010,
+ "\x5E\x75\x1B\x05\x80\x59\x90\x7F\xA6\xE0\xAB\x17\xAA\x18\xA9\x19"},
+ {0x40, 0xA0, 0x13FF, 0x0000, 0x0010, 0x0010,
+ "\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12\x78\x75\x1B\x02\x80\x40\xE5"},
+ {0x40, 0xA0, 0x140F, 0x0000, 0x0010, 0x0010,
+ "\x16\x24\xFE\xB5\x1A\x07\x90\x7F\xA5\xE0\x44\x20\xF0\xE5\x16\x14"},
+ {0x40, 0xA0, 0x141F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x1A\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x90\x7F\xA6"},
+ {0x40, 0xA0, 0x142F, 0x0000, 0x0010, 0x0010,
+ "\xE0\xAB\x17\xAA\x18\xA9\x19\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12"},
+ {0x40, 0xA0, 0x143F, 0x0000, 0x0010, 0x0010,
+ "\x78\x05\x1A\x80\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x53"},
+ {0x40, 0xA0, 0x144F, 0x0000, 0x0010, 0x0010,
+ "\x91\xDF\xD0\x07\xD0\x06\xD0\x03\xD0\x02\xD0\x01\xD0\x00\xD0\xD0"},
+ {0x40, 0xA0, 0x145F, 0x0000, 0x000D, 0x000D,
+ "\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1704, 0x0000, 0x0010, 0x0010,
+ "\x12\x15\xEC\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1714, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x1720, 0x0000, 0x0010, 0x0010,
+ "\x12\x16\x19\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1730, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x14EE, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x14FE, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x17\x53"},
+ {0x40, 0xA0, 0x1753, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x20\x02\x14\x6C"},
+ {0x40, 0xA0, 0x124B, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x125B, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x126B, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x1278, 0x0000, 0x0010, 0x0010,
+ "\xF8\xBB\x01\x0D\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE8\xF0"},
+ {0x40, 0xA0, 0x1288, 0x0000, 0x0010, 0x0010,
+ "\x22\x50\x06\xE9\x25\x82\xC8\xF6\x22\xBB\xFE\x05\xE9\x25\x82\xC8"},
+ {0x40, 0xA0, 0x1298, 0x0000, 0x0002, 0x0002, "\xF2\x22"},
+ {0x40, 0xA0, 0x129A, 0x0000, 0x0010, 0x0010,
+ "\xE7\x09\xF6\x08\xDF\xFA\x80\x46\xE7\x09\xF2\x08\xDF\xFA\x80\x3E"},
+ {0x40, 0xA0, 0x12AA, 0x0000, 0x0010, 0x0010,
+ "\x88\x82\x8C\x83\xE7\x09\xF0\xA3\xDF\xFA\x80\x32\xE3\x09\xF6\x08"},
+ {0x40, 0xA0, 0x12BA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x6E\xE3\x09\xF2\x08\xDF\xFA\x80\x66\x88\x82\x8C\x83"},
+ {0x40, 0xA0, 0x12CA, 0x0000, 0x0010, 0x0010,
+ "\xE3\x09\xF0\xA3\xDF\xFA\x80\x5A\x89\x82\x8A\x83\xE0\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x12DA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x4E\x89\x82\x8A\x83\xE0\xA3\xF2\x08\xDF\xFA\x80\x42"},
+ {0x40, 0xA0, 0x12EA, 0x0000, 0x0010, 0x0010,
+ "\x80\xD2\x80\xFA\x80\xC6\x80\xD4\x80\x55\x80\xF2\x80\x29\x80\x10"},
+ {0x40, 0xA0, 0x12FA, 0x0000, 0x0010, 0x0010,
+ "\x80\xA6\x80\xEA\x80\x9A\x80\xA8\x80\xDA\x80\xE2\x80\xCA\x80\x29"},
+ {0x40, 0xA0, 0x130A, 0x0000, 0x0010, 0x0010,
+ "\x88\x84\x8C\x85\x89\x82\x8A\x83\xE4\x93\xA3\x05\x86\xF0\xA3\x05"},
+ {0x40, 0xA0, 0x131A, 0x0000, 0x0010, 0x0010,
+ "\x86\xDF\xF5\xDE\xF3\x80\x0B\x89\x82\x8A\x83\xE4\x93\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x132A, 0x0000, 0x0010, 0x0010,
+ "\xDF\xF9\xEC\xFA\xA9\xF0\xED\xFB\x22\x88\x84\x8C\x85\x89\x82\x8A"},
+ {0x40, 0xA0, 0x133A, 0x0000, 0x0010, 0x0010,
+ "\x83\xE0\xA3\x05\x86\xF0\xA3\x05\x86\xDF\xF6\xDE\xF4\x80\xE3\x89"},
+ {0x40, 0xA0, 0x134A, 0x0000, 0x0010, 0x0010,
+ "\x82\x8A\x83\xE4\x93\xA3\xF2\x08\xDF\xF9\x80\xD6\x88\xF0\xED\x24"},
+ {0x40, 0xA0, 0x135A, 0x0000, 0x0010, 0x0010,
+ "\x02\xB4\x04\x00\x50\xCC\xF5\x82\xEB\x24\x02\xB4\x04\x00\x50\xC2"},
+ {0x40, 0xA0, 0x136A, 0x0000, 0x0010, 0x0010,
+ "\x23\x23\x45\x82\xF5\x82\xEF\x4E\x60\xB8\xEF\x60\x01\x0E\xE5\x82"},
+ {0x40, 0xA0, 0x137A, 0x0000, 0x0005, 0x0005, "\x23\x90\x12\xEA\x73"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x0100, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0110, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0120, 0x0000, 0x0010, 0x0010,
+ "\x4D\x69\x64\x69\x6D\x61\x6E\x20\x55\x53\x42\x20\x4D\x69\x64\x69"},
+ {0x40, 0xA0, 0x0130, 0x0000, 0x0010, 0x0010,
+ "\x53\x70\x6F\x72\x74\x20\x31\x78\x31\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0140, 0x0000, 0x0010, 0x0010,
+ "\x46\x69\x72\x6D\x77\x61\x72\x65\x20\x52\x65\x6C\x65\x61\x73\x65"},
+ {0x40, 0xA0, 0x0150, 0x0000, 0x0010, 0x0010,
+ "\x20\x31\x2E\x32\x31\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0160, 0x0000, 0x0010, 0x0010,
+ "\x28\x63\x29\x20\x32\x30\x30\x30\x2D\x32\x30\x30\x31\x2C\x20\x4D"},
+ {0x40, 0xA0, 0x0170, 0x0000, 0x0010, 0x0010,
+ "\x69\x64\x69\x6D\x61\x6E\x20\x49\x6E\x63\x2E\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0180, 0x0000, 0x0010, 0x0010,
+ "\x41\x6C\x6C\x20\x72\x69\x67\x68\x74\x73\x20\x72\x65\x73\x65\x72"},
+ {0x40, 0xA0, 0x0190, 0x0000, 0x0010, 0x0010,
+ "\x76\x65\x64\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01A0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01B0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x08B2, 0x0000, 0x0003, 0x0003, "\x01\x1C\x00"},
+ {0x40, 0xA0, 0x040D, 0x0000, 0x0010, 0x0010,
+ "\xC2\x01\xC2\x00\xC2\x04\xC2\x03\x12\x09\xE1\xD2\xE8\x43\xD8\x20"},
+ {0x40, 0xA0, 0x041D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9\xF0\x90\x7F\xAA\xF0\x53\x91"},
+ {0x40, 0xA0, 0x042D, 0x0000, 0x0010, 0x0010,
+ "\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90\x7F\xAF\xE0\x44\x01\xF0\x90"},
+ {0x40, 0xA0, 0x043D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAE\xE0\x44\x1D\xF0\x90\x7F\x92\xE0\x44\x02\xF0\x90\x7F\x95"},
+ {0x40, 0xA0, 0x044D, 0x0000, 0x0010, 0x0010,
+ "\xE0\x44\x01\xF0\x90\x7F\x9E\xE0\x54\xFE\xF0\x90\x7F\x95\xE0\x44"},
+ {0x40, 0xA0, 0x045D, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x90\x7F\x9E\xE0\x44\x02\xF0\x90\x7F\x95\xE0\x54\x83\xF0"},
+ {0x40, 0xA0, 0x046D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\x9E\xE0\x44\x7C\xF0\x90\x7F\x94\xE0\x54\xFE\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x047D, 0x0000, 0x0010, 0x0010,
+ "\x9D\xE0\x44\x01\xF0\x90\x7F\x9A\xE0\x44\x01\x90\x7F\x97\xF0\x43"},
+ {0x40, 0xA0, 0x048D, 0x0000, 0x0010, 0x0010,
+ "\x21\x20\x43\x21\x40\x43\x21\x10\x53\x89\xF0\xE4\xF5\x8C\xF5\x8A"},
+ {0x40, 0xA0, 0x049D, 0x0000, 0x0010, 0x0010,
+ "\xD2\x8C\xD2\xA9\x12\x0B\xAE\xD2\xAF\xE5\x89\x54\x0F\x24\x20\xF5"},
+ {0x40, 0xA0, 0x04AD, 0x0000, 0x0010, 0x0010,
+ "\x89\x75\x8D\xFE\x75\x8B\xFE\xD2\x8E\xC2\xAC\x75\x98\x50\xC2\x98"},
+ {0x40, 0xA0, 0x04BD, 0x0000, 0x0010, 0x0010,
+ "\xC2\x99\xD2\xAC\x53\x21\xDF\x53\x21\xBF\x53\x21\xEF\x90\x7F\x9A"},
+ {0x40, 0xA0, 0x04CD, 0x0000, 0x0010, 0x0010,
+ "\xE0\x54\xFE\x90\x7F\x97\xF0\x90\x7F\x98\xE5\x21\xF0\x75\x24\x3D"},
+ {0x40, 0xA0, 0x04DD, 0x0000, 0x0010, 0x0010,
+ "\xE5\x24\x70\xFC\x43\x21\x20\x43\x21\x40\x43\x21\x10\x90\x7F\x98"},
+ {0x40, 0xA0, 0x04ED, 0x0000, 0x0010, 0x0010,
+ "\xE5\x21\xF0\x20\x01\x3C\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9"},
+ {0x40, 0xA0, 0x04FD, 0x0000, 0x0010, 0x0010,
+ "\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9\x75\x24\xF4\xE5\x24\x60"},
+ {0x40, 0xA0, 0x050D, 0x0000, 0x0010, 0x0010,
+ "\x03\x30\x01\xF9\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9\x75\x24"},
+ {0x40, 0xA0, 0x051D, 0x0000, 0x0010, 0x0010,
+ "\xF4\xE5\x24\x60\x03\x30\x01\xF9\x20\x01\xC8\xD2\x06\x12\x0A\xE0"},
+ {0x40, 0xA0, 0x052D, 0x0000, 0x0010, 0x0010,
+ "\x80\xC1\x30\x01\x0C\x12\x01\xFF\xC2\x01\x90\x7F\xAE\xE0\x44\x02"},
+ {0x40, 0xA0, 0x053D, 0x0000, 0x0010, 0x0010,
+ "\xF0\x30\x04\x1A\x12\x0B\x91\x50\x13\x12\x0B\x05\x20\x03\x07\x90"},
+ {0x40, 0xA0, 0x054D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD6\xE0\x20\xE7\xF3\x12\x0B\x26\x12\x0B\xB2\xC2\x04\x05\x1C"},
+ {0x40, 0xA0, 0x055D, 0x0000, 0x0010, 0x0010,
+ "\xE5\x1C\xC3\x94\x06\x40\x03\xE4\xF5\x1C\xE5\x1C\x75\xF0\x03\xA4"},
+ {0x40, 0xA0, 0x056D, 0x0000, 0x000E, 0x000E,
+ "\x24\x0A\xF8\x08\xE6\xFA\x08\xE6\xF9\x12\x07\x11\x80\xB4"},
+ {0x40, 0xA0, 0x057B, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0033, 0x0000, 0x0003, 0x0003, "\x02\x0B\xAA"},
+ {0x40, 0xA0, 0x0BAA, 0x0000, 0x0004, 0x0004, "\x53\xD8\xEF\x32"},
+ {0x40, 0xA0, 0x0023, 0x0000, 0x0003, 0x0003, "\x02\x07\x17"},
+ {0x40, 0xA0, 0x0717, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x0727, 0x0000, 0x000C, 0x000C,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x05\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x0733, 0x0000, 0x0010, 0x0010,
+ "\x30\x99\x23\xC2\x99\xE5\x68\x60\x1B\xAF\x67\x05\x67\x74\x00\x2F"},
+ {0x40, 0xA0, 0x0743, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x0F\xF5\x83\xE0\xF5\x99\x15\x68\x53\x21\xBF\x75"},
+ {0x40, 0xA0, 0x0753, 0x0000, 0x0010, 0x0010,
+ "\x23\x0C\x80\x02\xD2\x02\x30\x98\x1E\xC2\x98\xAF\x99\xE5\x66\x04"},
+ {0x40, 0xA0, 0x0763, 0x0000, 0x0010, 0x0010,
+ "\x54\x3F\xFE\x65\x65\x60\x0A\xAD\x66\x74\x25\x2D\xF8\xA6\x07\x8E"},
+ {0x40, 0xA0, 0x0773, 0x0000, 0x0007, 0x0007,
+ "\x66\x53\x21\xDF\x75\x22\x0C"},
+ {0x40, 0xA0, 0x077A, 0x0000, 0x0010, 0x0010,
+ "\xD0\x07\xD0\x06\xD0\x05\xD0\x00\xD0\xD0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x078A, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0A17, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAC\x92\x06\xC2\xAC\x30\x02\x0C\xC2\x02\x8F\x99\x53\x21\xBF"},
+ {0x40, 0xA0, 0x0A27, 0x0000, 0x0010, 0x0010,
+ "\x75\x23\x0C\x80\x12\xAE\x69\x05\x69\x74\x00\x2E\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x0A37, 0x0000, 0x000B, 0x000B,
+ "\x0F\xF5\x83\xEF\xF0\x05\x68\xA2\x06\x92\xAC"},
+ {0x40, 0xA0, 0x0A42, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x01C0, 0x0000, 0x0010, 0x0010,
+ "\x12\x01\x00\x01\x00\x00\x00\x40\x63\x07\x11\x10\x21\x01\x00\x00"},
+ {0x40, 0xA0, 0x01D0, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x09\x02\x27\x00\x01\x01\x00\xA0\x00\x09\x04\x00\x00\x03"},
+ {0x40, 0xA0, 0x01E0, 0x0000, 0x0010, 0x0010,
+ "\xFF\x00\x00\x00\x07\x05\x81\x03\x20\x00\x01\x07\x05\x82\x02\x20"},
+ {0x40, 0xA0, 0x01F0, 0x0000, 0x000F, 0x000F,
+ "\x00\x00\x07\x05\x02\x02\x20\x00\x00\x04\x03\x09\x04\x00\x00"},
+ {0x40, 0xA0, 0x08B5, 0x0000, 0x0010, 0x0010,
+ "\x01\x24\x00\xC1\x01\x01\x22\x00\x01\x21\xFF\x01\x23\x00\xC1\x82"},
+ {0x40, 0xA0, 0x08C5, 0x0000, 0x000F, 0x000F,
+ "\x01\x65\x00\x01\x66\x00\x01\x67\x00\x01\x69\x00\x01\x68\x00"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x09\x00"},
+ {0x40, 0xA0, 0x0900, 0x0000, 0x0010, 0x0010,
+ "\x02\x0A\x6D\x00\x02\x08\x03\x00\x02\x0A\x43\x00\x02\x0A\x94\x00"},
+ {0x40, 0xA0, 0x0910, 0x0000, 0x0010, 0x0010,
+ "\x02\x0A\xBB\x00\x02\x0B\xBE\x00\x02\x0B\xBF\x00\x02\x0B\xC0\x00"},
+ {0x40, 0xA0, 0x0920, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC1\x00\x02\x0B\xC2\x00\x02\x0B\xC3\x00\x02\x0B\xC4\x00"},
+ {0x40, 0xA0, 0x0930, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC5\x00\x02\x0B\xC6\x00\x02\x0B\xC7\x00\x02\x0B\xC8\x00"},
+ {0x40, 0xA0, 0x0940, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC9\x00\x02\x0B\xCA\x00\x02\x0B\xCB\x00\x02\x0B\xCC\x00"},
+ {0x40, 0xA0, 0x0950, 0x0000, 0x0008, 0x0008,
+ "\x02\x0B\xCD\x00\x02\x0B\xCE\x00"},
+ {0x40, 0xA0, 0x08D4, 0x0000, 0x0010, 0x0010,
+ "\x12\x0A\xFF\x07\x91\xFF\x06\x08\xFF\x09\x58\xFF\x07\x91\xFF\x06"},
+ {0x40, 0xA0, 0x08E4, 0x0000, 0x000A, 0x000A,
+ "\x08\xFF\x0B\x57\x01\x08\xFF\x01\x09\x00"},
+ {0x40, 0xA0, 0x0791, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB6\xE0\x20\xE1\x6A\x7A\x7E\x79\x80\x7E\x7E\x7F\x80\x74"},
+ {0x40, 0xA0, 0x07A1, 0x0000, 0x0010, 0x0010,
+ "\x7E\x90\x7F\xE3\xF0\x74\x80\x90\x7F\xE4\xF0\xE4\xFF\xE5\x66\x65"},
+ {0x40, 0xA0, 0x07B1, 0x0000, 0x0010, 0x0010,
+ "\x65\x60\x43\xEF\xC3\x94\x08\x50\x3D\xE4\xFD\xE5\x66\x65\x65\x60"},
+ {0x40, 0xA0, 0x07C1, 0x0000, 0x0010, 0x0010,
+ "\x1B\xED\xC3\x94\x03\x50\x15\x74\x25\x25\x65\xF8\xE6\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x07D1, 0x0000, 0x0010, 0x0010,
+ "\xF0\x05\x65\xE5\x65\x54\x3F\xF5\x65\x0D\x80\xDF\xED\x60\xCE\xFE"},
+ {0x40, 0xA0, 0x07E1, 0x0000, 0x0010, 0x0010,
+ "\xEE\xC3\x94\x03\x50\x08\xE4\x90\x7F\xE5\xF0\x0E\x80\xF2\x90\x7F"},
+ {0x40, 0xA0, 0x07F1, 0x0000, 0x0010, 0x0010,
+ "\xE5\xED\xF0\x0F\x80\xB7\xEF\x60\x08\x25\xE0\x25\xE0\x90\x7F\xB7"},
+ {0x40, 0xA0, 0x0801, 0x0000, 0x0001, 0x0001, "\xF0"},
+ {0x40, 0xA0, 0x0802, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0958, 0x0000, 0x0010, 0x0010,
+ "\xE5\x08\x60\x16\x14\x60\x2A\x80\x00\x12\x08\xFD\xEF\x65\x09\x60"},
+ {0x40, 0xA0, 0x0968, 0x0000, 0x0010, 0x0010,
+ "\x36\x12\x08\xFD\x8F\x09\xE4\xF5\x08\x22\xE5\x22\x60\x10\xD5\x22"},
+ {0x40, 0xA0, 0x0978, 0x0000, 0x0010, 0x0010,
+ "\x0D\xA2\xAF\x92\x06\xC2\xAF\x43\x21\x20\xA2\x06\x92\xAF\x05\x08"},
+ {0x40, 0xA0, 0x0988, 0x0000, 0x0010, 0x0010,
+ "\x22\xE5\x23\x60\x10\xD5\x23\x0D\xA2\xAF\x92\x06\xC2\xAF\x43\x21"},
+ {0x40, 0xA0, 0x0998, 0x0000, 0x0007, 0x0007,
+ "\x40\xA2\x06\x92\xAF\x05\x08"},
+ {0x40, 0xA0, 0x099F, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B57, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAF\x92\x06\xC2\xAF\x90\x7F\x98\xE5\x21\xF0\xA2\x06\x92\xAF"},
+ {0x40, 0xA0, 0x0B67, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0608, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xC8\xE0\x30\xE1\x03\x02\x06\x92\x90\x7F\xC9\xE0\xF5\x6A"},
+ {0x40, 0xA0, 0x0618, 0x0000, 0x0010, 0x0010,
+ "\xC3\xE4\x95\x68\xFF\x74\x01\x94\x00\xFE\xC3\xE5\x6A\x9F\xE4\x9E"},
+ {0x40, 0xA0, 0x0628, 0x0000, 0x0010, 0x0010,
+ "\x50\x68\xE4\xF5\x6B\xE5\x6B\xC3\x95\x6A\x50\x59\x74\xC3\x25\x6B"},
+ {0x40, 0xA0, 0x0638, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x7D\xF5\x83\xE0\x54\x0F\xFD\x60\x48\x74\xC0\x25"},
+ {0x40, 0xA0, 0x0648, 0x0000, 0x0010, 0x0010,
+ "\x6B\xF5\x82\xE4\x34\x7D\x90\x7F\xE3\xF0\x74\xC0\x25\x6B\xF5\x82"},
+ {0x40, 0xA0, 0x0658, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\x7D\xE5\x82\x90\x7F\xE4\xF0\xAF\x05\xED\x14\x60\x16\x14"},
+ {0x40, 0xA0, 0x0668, 0x0000, 0x0010, 0x0010,
+ "\x60\x0B\x14\x70\x18\x90\x7F\xE5\xE0\xFF\x12\x0A\x17\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x0678, 0x0000, 0x0010, 0x0010,
+ "\xE0\xFF\x12\x0A\x17\x90\x7F\xE5\xE0\xFF\x12\x0A\x17\x74\x04\x25"},
+ {0x40, 0xA0, 0x0688, 0x0000, 0x000A, 0x000A,
+ "\x6B\xF5\x6B\x80\xA0\xE4\x90\x7F\xC9\xF0"},
+ {0x40, 0xA0, 0x0692, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x08EE, 0x0000, 0x0003, 0x0003, "\x01\x1D\x00"},
+ {0x40, 0xA0, 0x000B, 0x0000, 0x0003, 0x0003, "\x02\x0B\x84"},
+ {0x40, 0xA0, 0x0B84, 0x0000, 0x000D, 0x000D,
+ "\xC0\xE0\x05\x1D\xE5\x24\x60\x02\x15\x24\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x08FD, 0x0000, 0x0003, 0x0003, "\xAF\x1D\x22"},
+ {0x40, 0xA0, 0x0BAE, 0x0000, 0x0004, 0x0004, "\xE4\xF5\x1D\x22"},
+ {0x40, 0xA0, 0x08F1, 0x0000, 0x000B, 0x000B,
+ "\x01\x72\x01\x01\x73\x01\xC1\x85\x01\x74\x02"},
+ {0x40, 0xA0, 0x01FF, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x70\x03\x02\x02\xD4\x14\x70\x03\x02\x03\x4F\x24"},
+ {0x40, 0xA0, 0x020F, 0x0000, 0x0010, 0x0010,
+ "\xFE\x70\x03\x02\x03\xA8\x24\xFB\x70\x03\x02\x02\xCE\x14\x70\x03"},
+ {0x40, 0xA0, 0x021F, 0x0000, 0x0010, 0x0010,
+ "\x02\x02\xC8\x14\x70\x03\x02\x02\xBC\x14\x70\x03\x02\x02\xC2\x24"},
+ {0x40, 0xA0, 0x022F, 0x0000, 0x0010, 0x0010,
+ "\x05\x60\x03\x02\x03\xFA\x12\x0B\xB4\x40\x03\x02\x04\x05\x90\x7F"},
+ {0x40, 0xA0, 0x023F, 0x0000, 0x0010, 0x0010,
+ "\xEB\xE0\x24\xFE\x60\x16\x14\x60\x3F\x24\x02\x70\x67\x74\x01\x90"},
+ {0x40, 0xA0, 0x024F, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD4\xF0\x74\xC0\x90\x7F\xD5\xF0\x02\x04\x05\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x025F, 0x0000, 0x0010, 0x0010,
+ "\xFF\x12\x08\x63\x8B\x6A\x8A\x6B\x89\x6C\xEA\x49\x60\x11\xAE\x02"},
+ {0x40, 0xA0, 0x026F, 0x0000, 0x0010, 0x0010,
+ "\xEE\x90\x7F\xD4\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x05\x90"},
+ {0x40, 0xA0, 0x027F, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\x74\x01\xF0\x02\x04\x05\x90\x7F\xEA\xE0\xFF\x12\x09\xA0"},
+ {0x40, 0xA0, 0x028F, 0x0000, 0x0010, 0x0010,
+ "\x8B\x6A\x8A\x6B\x89\x6C\xEA\x49\x60\x11\xAE\x02\xEE\x90\x7F\xD4"},
+ {0x40, 0xA0, 0x029F, 0x0000, 0x0010, 0x0010,
+ "\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01"},
+ {0x40, 0xA0, 0x02AF, 0x0000, 0x0010, 0x0010,
+ "\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05\x12\x0B\x76"},
+ {0x40, 0xA0, 0x02BF, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x05\x12\x0B\xA2\x02\x04\x05\x12\x0B\x9A\x02\x04\x05\x12"},
+ {0x40, 0xA0, 0x02CF, 0x0000, 0x0010, 0x0010,
+ "\x0B\x68\x02\x04\x05\x12\x0B\xB6\x40\x03\x02\x04\x05\x90\x7F\xE8"},
+ {0x40, 0xA0, 0x02DF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x24\x7F\x60\x24\x14\x60\x31\x24\x02\x70\x5B\xA2\x03\xE4\x33"},
+ {0x40, 0xA0, 0x02EF, 0x0000, 0x0010, 0x0010,
+ "\xFF\x25\xE0\xFF\xA2\x00\xE4\x33\x4F\x90\x7F\x00\xF0\xE4\xA3\xF0"},
+ {0x40, 0xA0, 0x02FF, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x05\xE4\x90\x7F\x00\xF0\xA3\xF0"},
+ {0x40, 0xA0, 0x030F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x05\x90\x7F\xEC\xE0\xF4\x54\x80"},
+ {0x40, 0xA0, 0x031F, 0x0000, 0x0010, 0x0010,
+ "\xFF\xC4\x54\x0F\xFF\xE0\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x032F, 0x0000, 0x0010, 0x0010,
+ "\x34\x7F\xF5\x83\xE0\x54\xFD\x90\x7F\x00\xF0\xE4\xA3\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x033F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x74\x02\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05"},
+ {0x40, 0xA0, 0x034F, 0x0000, 0x0010, 0x0010,
+ "\x12\x0B\xB8\x40\x03\x02\x04\x05\x90\x7F\xE8\xE0\x24\xFE\x60\x1C"},
+ {0x40, 0xA0, 0x035F, 0x0000, 0x0010, 0x0010,
+ "\x24\x02\x60\x03\x02\x04\x05\x90\x7F\xEA\xE0\xB4\x01\x05\xC2\x03"},
+ {0x40, 0xA0, 0x036F, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x037F, 0x0000, 0x0010, 0x0010,
+ "\x70\x1F\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0\x54"},
+ {0x40, 0xA0, 0x038F, 0x0000, 0x0010, 0x0010,
+ "\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\xE4\xF0\x80"},
+ {0x40, 0xA0, 0x039F, 0x0000, 0x0010, 0x0010,
+ "\x65\x90\x7F\xC4\x74\x01\xF0\x80\x5D\x12\x0B\xBA\x50\x58\x90\x7F"},
+ {0x40, 0xA0, 0x03AF, 0x0000, 0x0010, 0x0010,
+ "\xE8\xE0\x24\xFE\x60\x17\x24\x02\x70\x4C\x90\x7F\xEA\xE0\xB4\x01"},
+ {0x40, 0xA0, 0x03BF, 0x0000, 0x0010, 0x0010,
+ "\x04\xD2\x03\x80\x41\x90\x7F\xC4\x74\x01\xF0\x80\x39\x90\x7F\xEA"},
+ {0x40, 0xA0, 0x03CF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x70\x20\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0"},
+ {0x40, 0xA0, 0x03DF, 0x0000, 0x0010, 0x0010,
+ "\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\x74\x01"},
+ {0x40, 0xA0, 0x03EF, 0x0000, 0x0010, 0x0010,
+ "\xF0\x80\x13\x90\x7F\xC4\x74\x01\xF0\x80\x0B\x12\x0B\xBC\x50\x06"},
+ {0x40, 0xA0, 0x03FF, 0x0000, 0x000D, 0x000D,
+ "\x90\x7F\xC4\x74\x01\xF0\x90\x7F\xB4\xE0\x44\x02\xF0"},
+ {0x40, 0xA0, 0x040C, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x09E1, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xDE\x74\x06\xF0\x90\x7F\xDF\x74\x04\xF0\x90\x7F\xDD\x74"},
+ {0x40, 0xA0, 0x09F1, 0x0000, 0x0010, 0x0010,
+ "\x18\xF0\x90\x7F\xB6\x74\x02\xF0\x90\x7F\xB8\xF0\x90\x7F\xBA\xF0"},
+ {0x40, 0xA0, 0x0A01, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xBC\xF0\x90\x7F\xBE\xF0\x90\x7F\xC0\xF0\x90\x7F\xC2\xF0"},
+ {0x40, 0xA0, 0x0A11, 0x0000, 0x0006, 0x0006, "\xE4\x90\x7F\xC9\xF0\x22"},
+ {0x40, 0xA0, 0x0B91, 0x0000, 0x0009, 0x0009,
+ "\x90\x7F\xAF\xE0\x44\x08\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BB2, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BB4, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0B9A, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x76\xD3\x22"},
+ {0x40, 0xA0, 0x0B68, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x76\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BA2, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x75\xD3\x22"},
+ {0x40, 0xA0, 0x0B76, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x75\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BB6, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BB8, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BBA, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BBC, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0A6D, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0A7D, 0x0000, 0x0010, 0x0010,
+ "\x01\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0A8D, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0A43, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x0A53, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x0A63, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0803, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x0813, 0x0000, 0x0001, 0x0001, "\xD0"},
+ {0x40, 0xA0, 0x0814, 0x0000, 0x0010, 0x0010,
+ "\x53\x91\xEF\x90\x7F\xAB\x74\x02\xF0\x30\x05\x14\x15\x72\xE5\x72"},
+ {0x40, 0xA0, 0x0824, 0x0000, 0x0010, 0x0010,
+ "\x70\x2E\x43\x21\x10\xC2\x05\xC3\x74\x1E\x95\x74\xF5\x72\x80\x20"},
+ {0x40, 0xA0, 0x0834, 0x0000, 0x0010, 0x0010,
+ "\xD5\x72\x1D\x53\x21\xEF\xD2\x05\xE5\x73\x25\x74\xF5\x74\x64\x02"},
+ {0x40, 0xA0, 0x0844, 0x0000, 0x0010, 0x0010,
+ "\x60\x05\xE5\x74\xB4\x1C\x06\xE5\x73\xF4\x04\xF5\x73\x85\x74\x72"},
+ {0x40, 0xA0, 0x0854, 0x0000, 0x000F, 0x000F,
+ "\xD0\xD0\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0ABB, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x0ACB, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x0ADB, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BBE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0A94, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0AA4, 0x0000, 0x0010, 0x0010,
+ "\x04\x53\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0AB4, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BBF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC0, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC1, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC2, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC3, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC4, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC5, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC6, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC7, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC8, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC9, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCA, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCB, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCC, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCD, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0B26, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x30\xE7\x12\xE0\x44\x01\xF0\x7F\x14\x7E\x00\x12"},
+ {0x40, 0xA0, 0x0B36, 0x0000, 0x000A, 0x000A,
+ "\x0B\x40\x90\x7F\xD6\xE0\x54\xFE\xF0\x22"},
+ {0x40, 0xA0, 0x0B05, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x44\x80\xF0\x43\x87\x01\x00\x00\x00\x00\x00\x22"},
+ {0x40, 0xA0, 0x0AE0, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x54\xFB\xF0\xE0\x44\x08\xF0\x30\x06\x04\xE0\x44"},
+ {0x40, 0xA0, 0x0AF0, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x7F\xF4\x7E\x01\x12\x0B\x40\x90\x7F\xD6\xE0\x54\xF7\xF0"},
+ {0x40, 0xA0, 0x0B00, 0x0000, 0x0005, 0x0005, "\xE0\x44\x04\xF0\x22"},
+ {0x40, 0xA0, 0x09A0, 0x0000, 0x0002, 0x0002, "\x8F\x6D"},
+ {0x40, 0xA0, 0x09A2, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x6E\x75\x6F\xFF\x75\x70\x01\x75\x71\xF9\xAB\x6F\xAA\x70"},
+ {0x40, 0xA0, 0x09B2, 0x0000, 0x0010, 0x0010,
+ "\xA9\x71\x90\x00\x01\x12\x06\xAC\xB4\x03\x1D\xAF\x6E\x05\x6E\xEF"},
+ {0x40, 0xA0, 0x09C2, 0x0000, 0x0010, 0x0010,
+ "\xB5\x6D\x01\x22\x12\x06\x93\x7E\x00\x29\xFF\xEE\x3A\xA9\x07\x75"},
+ {0x40, 0xA0, 0x09D2, 0x0000, 0x000E, 0x000E,
+ "\x6F\xFF\xF5\x70\x89\x71\x80\xD4\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x09E0, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0863, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFE\x75\x6F\xFF\x75\x70\x01\x75\x71\xD2\xAB\x6F\xAA\x70\xA9"},
+ {0x40, 0xA0, 0x0873, 0x0000, 0x0010, 0x0010,
+ "\x71\x90\x00\x01\x12\x06\xAC\x64\x02\x70\x2D\xAD\x06\x0E\xED\xB5"},
+ {0x40, 0xA0, 0x0883, 0x0000, 0x0010, 0x0010,
+ "\x07\x01\x22\x90\x00\x02\x12\x06\xD9\x85\xF0\x6D\xF5\x6E\x62\x6D"},
+ {0x40, 0xA0, 0x0893, 0x0000, 0x0010, 0x0010,
+ "\xE5\x6D\x62\x6E\xE5\x6E\x62\x6D\x29\xFD\xE5\x6D\x3A\xA9\x05\x75"},
+ {0x40, 0xA0, 0x08A3, 0x0000, 0x000E, 0x000E,
+ "\x6F\xFF\xF5\x70\x89\x71\x80\xC3\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x08B1, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B40, 0x0000, 0x0010, 0x0010,
+ "\x8E\x6A\x8F\x6B\xE5\x6B\x15\x6B\xAE\x6A\x70\x02\x15\x6A\x4E\x60"},
+ {0x40, 0xA0, 0x0B50, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x0B\x15\x80\xEE\x22"},
+ {0x40, 0xA0, 0x0B15, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x0B25, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x05\x7C"},
+ {0x40, 0xA0, 0x057C, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x76\x02\x05\xC3"},
+ {0x40, 0xA0, 0x0693, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x06\x89\x82\x8A\x83\xE0\x22\x50\x02\xE7\x22\xBB\xFE\x02"},
+ {0x40, 0xA0, 0x06A3, 0x0000, 0x0009, 0x0009,
+ "\xE3\x22\x89\x82\x8A\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x06AC, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x06BC, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x06CC, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x06D9, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x10\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\xF5\xF0"},
+ {0x40, 0xA0, 0x06E9, 0x0000, 0x0010, 0x0010,
+ "\xA3\xE0\x22\x50\x09\xE9\x25\x82\xF8\x86\xF0\x08\xE6\x22\xBB\xFE"},
+ {0x40, 0xA0, 0x06F9, 0x0000, 0x0010, 0x0010,
+ "\x0A\xE9\x25\x82\xF8\xE2\xF5\xF0\x08\xE2\x22\xE5\x83\x2A\xF5\x83"},
+ {0x40, 0xA0, 0x0709, 0x0000, 0x0008, 0x0008,
+ "\xE9\x93\xF5\xF0\xA3\xE9\x93\x22"},
+ {0x40, 0xA0, 0x0711, 0x0000, 0x0006, 0x0006, "\x8A\x83\x89\x82\xE4\x73"},
+ {0x40, 0xA0, 0x0588, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x0D\xE4\x93\xA3\xF8\xE4\x93\xA3\x40\x03\xF6\x80\x01\xF2"},
+ {0x40, 0xA0, 0x0598, 0x0000, 0x0010, 0x0010,
+ "\x08\xDF\xF4\x80\x29\xE4\x93\xA3\xF8\x54\x07\x24\x0C\xC8\xC3\x33"},
+ {0x40, 0xA0, 0x05A8, 0x0000, 0x0010, 0x0010,
+ "\xC4\x54\x0F\x44\x20\xC8\x83\x40\x04\xF4\x56\x80\x01\x46\xF6\xDF"},
+ {0x40, 0xA0, 0x05B8, 0x0000, 0x0010, 0x0010,
+ "\xE4\x80\x0B\x01\x02\x04\x08\x10\x20\x40\x80\x90\x08\xB2\xE4\x7E"},
+ {0x40, 0xA0, 0x05C8, 0x0000, 0x0010, 0x0010,
+ "\x01\x93\x60\xBC\xA3\xFF\x54\x3F\x30\xE5\x09\x54\x1F\xFE\xE4\x93"},
+ {0x40, 0xA0, 0x05D8, 0x0000, 0x0010, 0x0010,
+ "\xA3\x60\x01\x0E\xCF\x54\xC0\x25\xE0\x60\xA8\x40\xB8\xE4\x93\xA3"},
+ {0x40, 0xA0, 0x05E8, 0x0000, 0x0010, 0x0010,
+ "\xFA\xE4\x93\xA3\xF8\xE4\x93\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA"},
+ {0x40, 0xA0, 0x05F8, 0x0000, 0x0010, 0x0010,
+ "\xF0\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA\xDF\xE9\xDE\xE7\x80\xBE"},
+ {0x40, 0xA0, 0x08FC, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x09, 0x0001, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x0000, NULL}
+};
diff --git a/kernel/drv/oss_usb/midisport2x2_fw.h b/kernel/drv/oss_usb/midisport2x2_fw.h
new file mode 100755
index 0000000..8bfb036
--- /dev/null
+++ b/kernel/drv/oss_usb/midisport2x2_fw.h
@@ -0,0 +1,756 @@
+/*
+ * Purpose: Firmware download for Midiman MIDISport 2x2
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+struct setup_request
+{
+ unsigned char bmRequestType;
+ unsigned char bRequest;
+ unsigned short wValue;
+ unsigned short wIndex;
+ unsigned short wLength;
+ unsigned short cbData;
+ const /*unsigned */ char *pData;
+};
+
+const struct setup_request midisport2x2_setupRequest[] = {
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x146C, 0x0000, 0x0010, 0x0010,
+ "\xC2\x00\x90\x7F\xA5\xE0\x54\x18\xFF\x13\x13\x13\x54\x1F\x44\x50"},
+ {0x40, 0xA0, 0x147C, 0x0000, 0x0010, 0x0010,
+ "\xF5\x1C\x13\x92\x01\xD2\xE8\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9"},
+ {0x40, 0xA0, 0x148C, 0x0000, 0x0010, 0x0010,
+ "\xF0\x90\x7F\xAA\xF0\x53\x91\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90"},
+ {0x40, 0xA0, 0x149C, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAF\xE0\x44\x01\xF0\x90\x7F\xAE\xE0\x44\x05\xF0\xD2\xAF\x12"},
+ {0x40, 0xA0, 0x14AC, 0x0000, 0x000D, 0x000D,
+ "\x17\x5F\x30\x00\xFD\x12\x11\x00\xC2\x00\x80\xF6\x22"},
+ {0x40, 0xA0, 0x1100, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x24\x5D\x60\x0D\x14\x70\x03\x02\x12\x44\x24\x02"},
+ {0x40, 0xA0, 0x1110, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x12\x4A\x90\x7F\xEA\xE0\x75\x08\x00\xF5\x09\xA3\xE0"},
+ {0x40, 0xA0, 0x1120, 0x0000, 0x0010, 0x0010,
+ "\xFE\xE4\x25\x09\xF5\x09\xEE\x35\x08\xF5\x08\x90\x7F\xEE\xE0\x75"},
+ {0x40, 0xA0, 0x1130, 0x0000, 0x0010, 0x0010,
+ "\x0A\x00\xF5\x0B\xA3\xE0\xFE\xE4\x25\x0B\xF5\x0B\xEE\x35\x0A\xF5"},
+ {0x40, 0xA0, 0x1140, 0x0000, 0x0010, 0x0010,
+ "\x0A\x90\x7F\xE8\xE0\x64\xC0\x60\x03\x02\x11\xD4\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x1150, 0x0000, 0x0010, 0x0010,
+ "\x70\x03\x02\x12\x4A\xC3\xE5\x0B\x94\x40\xE5\x0A\x94\x00\x50\x08"},
+ {0x40, 0xA0, 0x1160, 0x0000, 0x0010, 0x0010,
+ "\x85\x0A\x0C\x85\x0B\x0D\x80\x06\x75\x0C\x00\x75\x0D\x40\x90\x7F"},
+ {0x40, 0xA0, 0x1170, 0x0000, 0x0010, 0x0010,
+ "\xE9\xE0\xB4\xA3\x25\xAE\x0C\xAF\x0D\xAA\x08\xA9\x09\x7B\x01\xC0"},
+ {0x40, 0xA0, 0x1180, 0x0000, 0x0010, 0x0010,
+ "\x03\xC0\x02\xC0\x01\x7A\x7F\x79\x00\x78\x00\x7C\x7F\xAD\x03\xD0"},
+ {0x40, 0xA0, 0x1190, 0x0000, 0x0010, 0x0010,
+ "\x01\xD0\x02\xD0\x03\x12\x13\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D"},
+ {0x40, 0xA0, 0x11A0, 0x0000, 0x0010, 0x0010,
+ "\x7A\x7F\x79\x00\x7B\x00\x12\x15\xA4\x90\x7F\xB5\xE5\x0D\xF0\xE5"},
+ {0x40, 0xA0, 0x11B0, 0x0000, 0x0010, 0x0010,
+ "\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5\x0B\x95\x0D"},
+ {0x40, 0xA0, 0x11C0, 0x0000, 0x0010, 0x0010,
+ "\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x20\xE2\x03\x02"},
+ {0x40, 0xA0, 0x11D0, 0x0000, 0x0010, 0x0010,
+ "\x11\x4C\x80\xF4\x90\x7F\xE8\xE0\x64\x40\x70\x6E\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x11E0, 0x0000, 0x0010, 0x0010,
+ "\x60\x68\xE4\x90\x7F\xC5\xF0\x90\x7F\xB4\xE0\x20\xE3\xF9\x90\x7F"},
+ {0x40, 0xA0, 0x11F0, 0x0000, 0x0010, 0x0010,
+ "\xC5\xE0\x75\x0C\x00\xF5\x0D\x90\x7F\xE9\xE0\xB4\xA3\x15\xAE\x0C"},
+ {0x40, 0xA0, 0x1200, 0x0000, 0x0010, 0x0010,
+ "\xAF\x0D\xA8\x09\xAC\x08\x7D\x01\x7B\x01\x7A\x7E\x79\xC0\x12\x13"},
+ {0x40, 0xA0, 0x1210, 0x0000, 0x0010, 0x0010,
+ "\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D\x7A\x7F\x79\x00\x7B\x00\x12"},
+ {0x40, 0xA0, 0x1220, 0x0000, 0x0010, 0x0010,
+ "\x14\xB9\xE5\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5"},
+ {0x40, 0xA0, 0x1230, 0x0000, 0x0010, 0x0010,
+ "\x0B\x95\x0D\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x44"},
+ {0x40, 0xA0, 0x1240, 0x0000, 0x000A, 0x000A,
+ "\x02\xF0\x80\x98\x90\x7F\xEA\xE0\xF5\x1C"},
+ {0x40, 0xA0, 0x124A, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x1558, 0x0000, 0x0006, 0x0006, "\xAB\x07\xAA\x06\xAC\x05"},
+ {0x40, 0xA0, 0x155E, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x11\xEA\xFF\xAE\x05\x0D\xEE\x24\x00\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x156E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEF\xF0\xEB\xAE\x05\x0D\x74\x00\x2E\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x157E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEB\xF0\xAF\x05\x0D\x74\x00\x2F\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x158E, 0x0000, 0x0010, 0x0010,
+ "\xE0\xF5\x83\xEC\xF0\xAF\x1C\x7A\xE0\x7B\x00\x12\x17\x20\x7F\x0A"},
+ {0x40, 0xA0, 0x159E, 0x0000, 0x0005, 0x0005, "\x7E\x00\x12\x17\x3C"},
+ {0x40, 0xA0, 0x15A3, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x14B9, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x14C3, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x13\xE5\x13\xC3\x95\x10\x50\x20\x05\x0F\xE5\x0F\xAE\x0E"},
+ {0x40, 0xA0, 0x14D3, 0x0000, 0x0010, 0x0010,
+ "\x70\x02\x05\x0E\x14\xFF\xE5\x12\x25\x13\xF5\x82\xE4\x35\x11\xF5"},
+ {0x40, 0xA0, 0x14E3, 0x0000, 0x000A, 0x000A,
+ "\x83\xE0\xFD\x12\x15\x58\x05\x13\x80\xD9"},
+ {0x40, 0xA0, 0x14ED, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x15A4, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x15AE, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x12\xE5\x0E\xFF\xAE\x05\x0D\xEE\x24\x03\xF5\x82"},
+ {0x40, 0xA0, 0x15BE, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\xE0\xF5\x83\xEF\xF0\xE5\x0F\xAE\x05\x0D\x74\x03\x2E\xF5"},
+ {0x40, 0xA0, 0x15CE, 0x0000, 0x0010, 0x0010,
+ "\x82\xE4\x34\xE0\xF5\x83\xE5\x0F\xF0\xAF\x1C\x7A\xE0\x7B\x03\x12"},
+ {0x40, 0xA0, 0x15DE, 0x0000, 0x000D, 0x000D,
+ "\x17\x20\xAF\x1C\xAD\x10\xAB\x12\xAA\x11\x12\x17\x04"},
+ {0x40, 0xA0, 0x15EB, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x166E, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x167E, 0x0000, 0x0010, 0x0010,
+ "\x00\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x168E, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1644, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x1654, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x1664, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1695, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16A5, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x02\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16B5, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x16BA, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16CA, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16DA, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x14FF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x16DF, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16EF, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16FF, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1767, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1768, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1769, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176A, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176B, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176C, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176D, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176E, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176F, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1770, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1771, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1772, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1773, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1774, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1775, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1776, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x15\x00"},
+ {0x40, 0xA0, 0x1500, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\x6E\x00\x02\x16\x95\x00\x02\x16\x44\x00\x02\x16\xDF\x00"},
+ {0x40, 0xA0, 0x1510, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\xBA\x00\x02\x14\xFF\x00\x02\x17\x67\x00\x02\x17\x68\x00"},
+ {0x40, 0xA0, 0x1520, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x69\x00\x02\x17\x6A\x00\x02\x17\x6B\x00\x02\x17\x6C\x00"},
+ {0x40, 0xA0, 0x1530, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x6D\x00\x02\x17\x6E\x00\x02\x17\x6F\x00\x02\x17\x70\x00"},
+ {0x40, 0xA0, 0x1540, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x71\x00\x02\x17\x72\x00\x02\x17\x73\x00\x02\x17\x74\x00"},
+ {0x40, 0xA0, 0x1550, 0x0000, 0x0008, 0x0008,
+ "\x02\x17\x75\x00\x02\x17\x76\x00"},
+ {0x40, 0xA0, 0x173C, 0x0000, 0x0010, 0x0010,
+ "\x8E\x14\x8F\x15\xE5\x15\x15\x15\xAE\x14\x70\x02\x15\x14\x4E\x60"},
+ {0x40, 0xA0, 0x174C, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x14\xEE\x80\xEE\x22"},
+ {0x40, 0xA0, 0x175F, 0x0000, 0x0008, 0x0008,
+ "\xE4\xF5\x1B\xD2\xE9\xD2\xAF\x22"},
+ {0x40, 0xA0, 0x1619, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x23\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x1629, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A\x18\x89"},
+ {0x40, 0xA0, 0x1639, 0x0000, 0x000B, 0x000B,
+ "\x19\xE4\xF5\x1A\x75\x1B\x01\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x15EC, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x25\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x15FC, 0x0000, 0x0010, 0x0010,
+ "\x44\x01\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A"},
+ {0x40, 0xA0, 0x160C, 0x0000, 0x000D, 0x000D,
+ "\x18\x89\x19\xE4\xF5\x1A\x75\x1B\x03\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x004B, 0x0000, 0x0003, 0x0003, "\x02\x13\x7F"},
+ {0x40, 0xA0, 0x137F, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x138F, 0x0000, 0x0010, 0x0010,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x01\xC0\x02\xC0\x03\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x139F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA5\xE0\x30\xE2\x06\x75\x1B\x06\x02\x14\x4E\x90\x7F\xA5"},
+ {0x40, 0xA0, 0x13AF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x20\xE1\x0C\xE5\x1B\x64\x02\x60\x06\x75\x1B\x07\x02\x14\x4E"},
+ {0x40, 0xA0, 0x13BF, 0x0000, 0x0010, 0x0010,
+ "\xAF\x1B\xEF\x24\xFE\x60\x48\x14\x60\x2C\x24\xFE\x60\x77\x24\x04"},
+ {0x40, 0xA0, 0x13CF, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x14\x4E\xAB\x17\xAA\x18\xA9\x19\xAF\x1A\x05\x1A\x8F"},
+ {0x40, 0xA0, 0x13DF, 0x0000, 0x0010, 0x0010,
+ "\x82\x75\x83\x00\x12\x12\x4B\x90\x7F\xA6\xF0\xE5\x1A\x65\x16\x70"},
+ {0x40, 0xA0, 0x13EF, 0x0000, 0x0010, 0x0010,
+ "\x5E\x75\x1B\x05\x80\x59\x90\x7F\xA6\xE0\xAB\x17\xAA\x18\xA9\x19"},
+ {0x40, 0xA0, 0x13FF, 0x0000, 0x0010, 0x0010,
+ "\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12\x78\x75\x1B\x02\x80\x40\xE5"},
+ {0x40, 0xA0, 0x140F, 0x0000, 0x0010, 0x0010,
+ "\x16\x24\xFE\xB5\x1A\x07\x90\x7F\xA5\xE0\x44\x20\xF0\xE5\x16\x14"},
+ {0x40, 0xA0, 0x141F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x1A\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x90\x7F\xA6"},
+ {0x40, 0xA0, 0x142F, 0x0000, 0x0010, 0x0010,
+ "\xE0\xAB\x17\xAA\x18\xA9\x19\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12"},
+ {0x40, 0xA0, 0x143F, 0x0000, 0x0010, 0x0010,
+ "\x78\x05\x1A\x80\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x53"},
+ {0x40, 0xA0, 0x144F, 0x0000, 0x0010, 0x0010,
+ "\x91\xDF\xD0\x07\xD0\x06\xD0\x03\xD0\x02\xD0\x01\xD0\x00\xD0\xD0"},
+ {0x40, 0xA0, 0x145F, 0x0000, 0x000D, 0x000D,
+ "\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1704, 0x0000, 0x0010, 0x0010,
+ "\x12\x15\xEC\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1714, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x1720, 0x0000, 0x0010, 0x0010,
+ "\x12\x16\x19\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1730, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x14EE, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x14FE, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x17\x53"},
+ {0x40, 0xA0, 0x1753, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x20\x02\x14\x6C"},
+ {0x40, 0xA0, 0x124B, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x125B, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x126B, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x1278, 0x0000, 0x0010, 0x0010,
+ "\xF8\xBB\x01\x0D\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE8\xF0"},
+ {0x40, 0xA0, 0x1288, 0x0000, 0x0010, 0x0010,
+ "\x22\x50\x06\xE9\x25\x82\xC8\xF6\x22\xBB\xFE\x05\xE9\x25\x82\xC8"},
+ {0x40, 0xA0, 0x1298, 0x0000, 0x0002, 0x0002, "\xF2\x22"},
+ {0x40, 0xA0, 0x129A, 0x0000, 0x0010, 0x0010,
+ "\xE7\x09\xF6\x08\xDF\xFA\x80\x46\xE7\x09\xF2\x08\xDF\xFA\x80\x3E"},
+ {0x40, 0xA0, 0x12AA, 0x0000, 0x0010, 0x0010,
+ "\x88\x82\x8C\x83\xE7\x09\xF0\xA3\xDF\xFA\x80\x32\xE3\x09\xF6\x08"},
+ {0x40, 0xA0, 0x12BA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x6E\xE3\x09\xF2\x08\xDF\xFA\x80\x66\x88\x82\x8C\x83"},
+ {0x40, 0xA0, 0x12CA, 0x0000, 0x0010, 0x0010,
+ "\xE3\x09\xF0\xA3\xDF\xFA\x80\x5A\x89\x82\x8A\x83\xE0\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x12DA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x4E\x89\x82\x8A\x83\xE0\xA3\xF2\x08\xDF\xFA\x80\x42"},
+ {0x40, 0xA0, 0x12EA, 0x0000, 0x0010, 0x0010,
+ "\x80\xD2\x80\xFA\x80\xC6\x80\xD4\x80\x55\x80\xF2\x80\x29\x80\x10"},
+ {0x40, 0xA0, 0x12FA, 0x0000, 0x0010, 0x0010,
+ "\x80\xA6\x80\xEA\x80\x9A\x80\xA8\x80\xDA\x80\xE2\x80\xCA\x80\x29"},
+ {0x40, 0xA0, 0x130A, 0x0000, 0x0010, 0x0010,
+ "\x88\x84\x8C\x85\x89\x82\x8A\x83\xE4\x93\xA3\x05\x86\xF0\xA3\x05"},
+ {0x40, 0xA0, 0x131A, 0x0000, 0x0010, 0x0010,
+ "\x86\xDF\xF5\xDE\xF3\x80\x0B\x89\x82\x8A\x83\xE4\x93\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x132A, 0x0000, 0x0010, 0x0010,
+ "\xDF\xF9\xEC\xFA\xA9\xF0\xED\xFB\x22\x88\x84\x8C\x85\x89\x82\x8A"},
+ {0x40, 0xA0, 0x133A, 0x0000, 0x0010, 0x0010,
+ "\x83\xE0\xA3\x05\x86\xF0\xA3\x05\x86\xDF\xF6\xDE\xF4\x80\xE3\x89"},
+ {0x40, 0xA0, 0x134A, 0x0000, 0x0010, 0x0010,
+ "\x82\x8A\x83\xE4\x93\xA3\xF2\x08\xDF\xF9\x80\xD6\x88\xF0\xED\x24"},
+ {0x40, 0xA0, 0x135A, 0x0000, 0x0010, 0x0010,
+ "\x02\xB4\x04\x00\x50\xCC\xF5\x82\xEB\x24\x02\xB4\x04\x00\x50\xC2"},
+ {0x40, 0xA0, 0x136A, 0x0000, 0x0010, 0x0010,
+ "\x23\x23\x45\x82\xF5\x82\xEF\x4E\x60\xB8\xEF\x60\x01\x0E\xE5\x82"},
+ {0x40, 0xA0, 0x137A, 0x0000, 0x0005, 0x0005, "\x23\x90\x12\xEA\x73"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x0100, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0110, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0120, 0x0000, 0x0010, 0x0010,
+ "\x4D\x69\x64\x69\x6D\x61\x6E\x20\x55\x53\x42\x20\x4D\x69\x64\x69"},
+ {0x40, 0xA0, 0x0130, 0x0000, 0x0010, 0x0010,
+ "\x53\x70\x6F\x72\x74\x20\x32\x78\x32\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0140, 0x0000, 0x0010, 0x0010,
+ "\x46\x69\x72\x6D\x77\x61\x72\x65\x20\x52\x65\x6C\x65\x61\x73\x65"},
+ {0x40, 0xA0, 0x0150, 0x0000, 0x0010, 0x0010,
+ "\x20\x31\x2E\x32\x31\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0160, 0x0000, 0x0010, 0x0010,
+ "\x28\x63\x29\x20\x31\x39\x39\x39\x2D\x32\x30\x30\x31\x2C\x20\x4D"},
+ {0x40, 0xA0, 0x0170, 0x0000, 0x0010, 0x0010,
+ "\x69\x64\x69\x6D\x61\x6E\x20\x49\x6E\x63\x2E\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0180, 0x0000, 0x0010, 0x0010,
+ "\x41\x6C\x6C\x20\x72\x69\x67\x68\x74\x73\x20\x72\x65\x73\x65\x72"},
+ {0x40, 0xA0, 0x0190, 0x0000, 0x0010, 0x0010,
+ "\x76\x65\x64\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01A0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01B0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0962, 0x0000, 0x0003, 0x0003, "\x01\x40\x00"},
+ {0x40, 0xA0, 0x041B, 0x0000, 0x0010, 0x0010,
+ "\xC2\x01\xC2\x00\xC2\x05\xC2\x04\x12\x0A\xBA\xD2\xE8\x43\xD8\x20"},
+ {0x40, 0xA0, 0x042B, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9\xF0\x90\x7F\xAA\xF0\x53\x91"},
+ {0x40, 0xA0, 0x043B, 0x0000, 0x0010, 0x0010,
+ "\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90\x7F\xAF\xE0\x44\x01\xF0\x90"},
+ {0x40, 0xA0, 0x044B, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAE\xE0\x44\x1D\xF0\x90\x7F\x92\xE0\x44\x02\xF0\x90\x7F\x94"},
+ {0x40, 0xA0, 0x045B, 0x0000, 0x0010, 0x0010,
+ "\xE0\x44\x04\xF0\x90\x7F\x9D\xE0\x54\xFB\xF0\x90\x7F\x95\xE0\x44"},
+ {0x40, 0xA0, 0x046B, 0x0000, 0x0010, 0x0010,
+ "\x01\xF0\x90\x7F\x9E\xE0\x54\xFE\xF0\x90\x7F\x94\xE0\x44\x08\xF0"},
+ {0x40, 0xA0, 0x047B, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\x9D\xE0\x44\x08\xF0\x90\x7F\x95\xE0\x44\x02\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x048B, 0x0000, 0x0010, 0x0010,
+ "\x9E\xE0\x44\x02\xF0\x90\x7F\x95\xE0\x54\x83\xF0\x90\x7F\x9E\xE0"},
+ {0x40, 0xA0, 0x049B, 0x0000, 0x0010, 0x0010,
+ "\x44\x7C\xF0\x90\x7F\x94\xE0\x54\xFE\xF0\x90\x7F\x9D\xE0\x44\x01"},
+ {0x40, 0xA0, 0x04AB, 0x0000, 0x0010, 0x0010,
+ "\xF0\x90\x7F\x9A\xE0\x44\x01\x90\x7F\x97\xF0\x43\x08\x20\x43\x08"},
+ {0x40, 0xA0, 0x04BB, 0x0000, 0x0010, 0x0010,
+ "\x08\x43\x08\x10\x43\x08\x04\x43\x08\x40\x53\x89\xF0\xE4\xF5\x8C"},
+ {0x40, 0xA0, 0x04CB, 0x0000, 0x0010, 0x0010,
+ "\xF5\x8A\xD2\x8C\xD2\xA9\x12\x00\x36\xD2\xAF\xE5\x89\x54\x0F\x24"},
+ {0x40, 0xA0, 0x04DB, 0x0000, 0x0010, 0x0010,
+ "\x20\xF5\x89\x75\x8D\xFE\x75\x8B\xFE\xD2\x8E\xC2\xAC\x75\x98\x50"},
+ {0x40, 0xA0, 0x04EB, 0x0000, 0x0010, 0x0010,
+ "\xC2\x98\xC2\x99\xD2\xAC\xC2\xAE\x75\xC0\x50\xC2\xC0\xC2\xC1\xD2"},
+ {0x40, 0xA0, 0x04FB, 0x0000, 0x0010, 0x0010,
+ "\xAE\x53\x08\xDF\x53\x08\xEF\x53\x08\xF7\x53\x08\xFB\x53\x08\xBF"},
+ {0x40, 0xA0, 0x050B, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\x9A\xE0\x54\xFE\x90\x7F\x97\xF0\x90\x7F\x98\xE5\x08\xF0"},
+ {0x40, 0xA0, 0x051B, 0x0000, 0x0010, 0x0010,
+ "\x75\x0D\x3D\xE5\x0D\x70\xFC\x43\x08\x20\x43\x08\x10\x43\x08\x08"},
+ {0x40, 0xA0, 0x052B, 0x0000, 0x0010, 0x0010,
+ "\x43\x08\x04\x43\x08\x40\x90\x7F\x98\xE5\x08\xF0\x20\x01\x11\x75"},
+ {0x40, 0xA0, 0x053B, 0x0000, 0x0010, 0x0010,
+ "\x0D\xF4\xE5\x0D\x70\xFC\x20\x01\xF3\xD2\x07\x12\x0C\x21\x80\xEC"},
+ {0x40, 0xA0, 0x054B, 0x0000, 0x0010, 0x0010,
+ "\x30\x01\x0C\x12\x02\x0D\xC2\x01\x90\x7F\xAE\xE0\x44\x02\xF0\x30"},
+ {0x40, 0xA0, 0x055B, 0x0000, 0x0010, 0x0010,
+ "\x05\x1A\x12\x0A\xF4\x50\x13\x12\x0C\x46\x20\x04\x07\x90\x7F\xD6"},
+ {0x40, 0xA0, 0x056B, 0x0000, 0x0010, 0x0010,
+ "\xE0\x20\xE7\xF3\x12\x0C\x67\x12\x00\x41\xC2\x05\x05\x40\xE5\x40"},
+ {0x40, 0xA0, 0x057B, 0x0000, 0x0010, 0x0010,
+ "\xC3\x94\x08\x40\x03\xE4\xF5\x40\xE5\x40\x75\xF0\x03\xA4\x24\x23"},
+ {0x40, 0xA0, 0x058B, 0x0000, 0x000C, 0x000C,
+ "\xF8\x08\xE6\xFA\x08\xE6\xF9\x12\x07\xEC\x80\xB4"},
+ {0x40, 0xA0, 0x0597, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0033, 0x0000, 0x0003, 0x0003, "\x02\x00\x1F"},
+ {0x40, 0xA0, 0x001F, 0x0000, 0x0004, 0x0004, "\x53\xD8\xEF\x32"},
+ {0x40, 0xA0, 0x0023, 0x0000, 0x0003, 0x0003, "\x02\x08\x6E"},
+ {0x40, 0xA0, 0x086E, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x087E, 0x0000, 0x000C, 0x000C,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x05\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x088A, 0x0000, 0x0010, 0x0010,
+ "\x30\x99\x23\xC2\x99\xE5\x14\x60\x1B\xAF\x11\x05\x11\x74\x00\x2F"},
+ {0x40, 0xA0, 0x089A, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x0E\xF5\x83\xE0\xF5\x99\x15\x14\x53\x08\xEF\x75"},
+ {0x40, 0xA0, 0x08AA, 0x0000, 0x0010, 0x0010,
+ "\x0B\x0C\x80\x02\xD2\x02\x30\x98\x1E\xC2\x98\xAF\x99\xE5\x10\x04"},
+ {0x40, 0xA0, 0x08BA, 0x0000, 0x0010, 0x0010,
+ "\x54\x3F\xFE\x65\x0E\x60\x0A\xAD\x10\x74\x42\x2D\xF8\xA6\x07\x8E"},
+ {0x40, 0xA0, 0x08CA, 0x0000, 0x0007, 0x0007,
+ "\x10\x53\x08\xDF\x75\x09\x0C"},
+ {0x40, 0xA0, 0x08D1, 0x0000, 0x0010, 0x0010,
+ "\xD0\x07\xD0\x06\xD0\x05\xD0\x00\xD0\xD0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x08E1, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x003B, 0x0000, 0x0003, 0x0003, "\x02\x08\xE8"},
+ {0x40, 0xA0, 0x08E8, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x08F8, 0x0000, 0x000C, 0x000C,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x05\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x0904, 0x0000, 0x0010, 0x0010,
+ "\x30\xC1\x23\xC2\xC1\xE5\x15\x60\x1B\xAF\x13\x05\x13\x74\x00\x2F"},
+ {0x40, 0xA0, 0x0914, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x0F\xF5\x83\xE0\xF5\xC1\x15\x15\x53\x08\xFB\x75"},
+ {0x40, 0xA0, 0x0924, 0x0000, 0x0010, 0x0010,
+ "\x0C\x0C\x80\x02\xD2\x03\x30\xC0\x1E\xC2\xC0\xAF\xC1\xE5\x12\x04"},
+ {0x40, 0xA0, 0x0934, 0x0000, 0x0010, 0x0010,
+ "\x54\x3F\xFE\x65\x0F\x60\x0A\xAD\x12\x74\x82\x2D\xF8\xA6\x07\x8E"},
+ {0x40, 0xA0, 0x0944, 0x0000, 0x0007, 0x0007,
+ "\x12\x53\x08\xF7\x75\x0A\x0C"},
+ {0x40, 0xA0, 0x094B, 0x0000, 0x0010, 0x0010,
+ "\xD0\x07\xD0\x06\xD0\x05\xD0\x00\xD0\xD0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x095B, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x00D2, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAC\x92\x07\xC2\xAC\x30\x02\x0C\xC2\x02\x8F\x99\x53\x08\xEF"},
+ {0x40, 0xA0, 0x00E2, 0x0000, 0x0010, 0x0010,
+ "\x75\x0B\x0C\x80\x12\xAE\x16\x05\x16\x74\x00\x2E\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x00F2, 0x0000, 0x000B, 0x000B,
+ "\x0E\xF5\x83\xEF\xF0\x05\x14\xA2\x07\x92\xAC"},
+ {0x40, 0xA0, 0x00FD, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B58, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAE\x92\x07\xC2\xAE\x30\x03\x0C\xC2\x03\x8F\xC1\x53\x08\xFB"},
+ {0x40, 0xA0, 0x0B68, 0x0000, 0x0010, 0x0010,
+ "\x75\x0C\x0C\x80\x12\xAE\x17\x05\x17\x74\x00\x2E\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x0B78, 0x0000, 0x000B, 0x000B,
+ "\x0F\xF5\x83\xEF\xF0\x05\x15\xA2\x07\x92\xAE"},
+ {0x40, 0xA0, 0x0B83, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x01C0, 0x0000, 0x0010, 0x0010,
+ "\x12\x01\x00\x01\x00\x00\x00\x40\x63\x07\x02\x10\x21\x01\x00\x00"},
+ {0x40, 0xA0, 0x01D0, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x09\x02\x35\x00\x01\x01\x00\xA0\x00\x09\x04\x00\x00\x05"},
+ {0x40, 0xA0, 0x01E0, 0x0000, 0x0010, 0x0010,
+ "\xFF\x00\x00\x00\x07\x05\x81\x03\x20\x00\x01\x07\x05\x82\x02\x20"},
+ {0x40, 0xA0, 0x01F0, 0x0000, 0x0010, 0x0010,
+ "\x00\x00\x07\x05\x02\x02\x20\x00\x00\x07\x05\x84\x02\x20\x00\x00"},
+ {0x40, 0xA0, 0x0200, 0x0000, 0x000D, 0x000D,
+ "\x07\x05\x04\x02\x20\x00\x00\x04\x03\x09\x04\x00\x00"},
+ {0x40, 0xA0, 0x0965, 0x0000, 0x0010, 0x0010,
+ "\x01\x0D\x00\xC1\x01\x01\x09\x00\x01\x0A\x00\x01\x08\xFF\x01\x0B"},
+ {0x40, 0xA0, 0x0975, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x0C\x00\xC1\x82\xC1\x83\x01\x0E\x00\x01\x10\x00\x01\x0F"},
+ {0x40, 0xA0, 0x0985, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x12\x00\x01\x11\x00\x01\x16\x00\x01\x14\x00\x01\x13\x00"},
+ {0x40, 0xA0, 0x0995, 0x0000, 0x0006, 0x0006, "\x01\x17\x00\x01\x15\x00"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x0B\x00"},
+ {0x40, 0xA0, 0x0B00, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xAE\x00\x02\x09\xCA\x00\x02\x0B\x84\x00\x02\x0B\xD5\x00"},
+ {0x40, 0xA0, 0x0B10, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xFC\x00\x02\x00\x3A\x00\x02\x0A\xFF\x00\x02\x0C\xC2\x00"},
+ {0x40, 0xA0, 0x0B20, 0x0000, 0x0010, 0x0010,
+ "\x02\x0C\xC3\x00\x02\x0C\xC4\x00\x02\x0C\xC5\x00\x02\x0C\xC6\x00"},
+ {0x40, 0xA0, 0x0B30, 0x0000, 0x0010, 0x0010,
+ "\x02\x0C\xC7\x00\x02\x0C\xC8\x00\x02\x0C\xC9\x00\x02\x0C\xCA\x00"},
+ {0x40, 0xA0, 0x0B40, 0x0000, 0x0010, 0x0010,
+ "\x02\x0C\xCB\x00\x02\x0C\xCC\x00\x02\x0C\xCD\x00\x02\x0C\xCE\x00"},
+ {0x40, 0xA0, 0x0B50, 0x0000, 0x0008, 0x0008,
+ "\x02\x0C\xCF\x00\x02\x0C\xD0\x00"},
+ {0x40, 0xA0, 0x099B, 0x0000, 0x0010, 0x0010,
+ "\x18\x23\xFF\x05\x98\xFF\x06\x58\xFF\x06\xE3\xFF\x07\xF2\xFF\x05"},
+ {0x40, 0xA0, 0x09AB, 0x0000, 0x0010, 0x0010,
+ "\x98\xFF\x06\x58\xFF\x06\xE3\xFF\x00\x0E\x01\x21\xFF\x01\x22\x00"},
+ {0x40, 0xA0, 0x0598, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB6\xE0\x30\xE1\x03\x02\x06\x57\x7A\x7E\x79\x80\x7E\x7E"},
+ {0x40, 0xA0, 0x05A8, 0x0000, 0x0010, 0x0010,
+ "\x7F\x80\x74\x7E\x90\x7F\xE3\xF0\x74\x80\x90\x7F\xE4\xF0\xE4\xFF"},
+ {0x40, 0xA0, 0x05B8, 0x0000, 0x0010, 0x0010,
+ "\xE5\x10\x65\x0E\x60\x43\xEF\xC3\x94\x04\x50\x3D\xE4\xFD\xE5\x10"},
+ {0x40, 0xA0, 0x05C8, 0x0000, 0x0010, 0x0010,
+ "\x65\x0E\x60\x1B\xED\xC3\x94\x03\x50\x15\x74\x42\x25\x0E\xF8\xE6"},
+ {0x40, 0xA0, 0x05D8, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE5\xF0\x05\x0E\xE5\x0E\x54\x3F\xF5\x0E\x0D\x80\xDF\xED"},
+ {0x40, 0xA0, 0x05E8, 0x0000, 0x0010, 0x0010,
+ "\x60\xCE\xFC\xEC\xC3\x94\x03\x50\x08\xE4\x90\x7F\xE5\xF0\x0C\x80"},
+ {0x40, 0xA0, 0x05F8, 0x0000, 0x0010, 0x0010,
+ "\xF2\x90\x7F\xE5\xED\xF0\x0F\x80\xB7\xE5\x12\x65\x0F\x60\x45\xEF"},
+ {0x40, 0xA0, 0x0608, 0x0000, 0x0010, 0x0010,
+ "\xC3\x94\x08\x50\x3F\xE4\xFD\xE5\x12\x65\x0F\x60\x1B\xED\xC3\x94"},
+ {0x40, 0xA0, 0x0618, 0x0000, 0x0010, 0x0010,
+ "\x03\x50\x15\x74\x82\x25\x0F\xF8\xE6\x90\x7F\xE5\xF0\x05\x0F\xE5"},
+ {0x40, 0xA0, 0x0628, 0x0000, 0x0010, 0x0010,
+ "\x0F\x54\x3F\xF5\x0F\x0D\x80\xDF\xED\x60\xCE\xFC\xEC\xC3\x94\x03"},
+ {0x40, 0xA0, 0x0638, 0x0000, 0x0010, 0x0010,
+ "\x50\x08\xE4\x90\x7F\xE5\xF0\x0C\x80\xF2\xED\x24\x10\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x0648, 0x0000, 0x000F, 0x000F,
+ "\xF0\x0F\x80\xB5\xEF\x60\x08\x25\xE0\x25\xE0\x90\x7F\xB7\xF0"},
+ {0x40, 0xA0, 0x0657, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x07F2, 0x0000, 0x0010, 0x0010,
+ "\xE5\x21\x60\x1C\x14\x60\x30\x14\x60\x44\x14\x60\x58\x80\x00\x12"},
+ {0x40, 0xA0, 0x0802, 0x0000, 0x0010, 0x0010,
+ "\x00\x3E\xEF\x65\x22\x60\x64\x12\x00\x3E\x8F\x22\xE4\xF5\x21\x22"},
+ {0x40, 0xA0, 0x0812, 0x0000, 0x0010, 0x0010,
+ "\xE5\x09\x60\x10\xD5\x09\x0D\xA2\xAF\x92\x07\xC2\xAF\x43\x08\x20"},
+ {0x40, 0xA0, 0x0822, 0x0000, 0x0010, 0x0010,
+ "\xA2\x07\x92\xAF\x05\x21\x22\xE5\x0A\x60\x10\xD5\x0A\x0D\xA2\xAF"},
+ {0x40, 0xA0, 0x0832, 0x0000, 0x0010, 0x0010,
+ "\x92\x07\xC2\xAF\x43\x08\x08\xA2\x07\x92\xAF\x05\x21\x22\xE5\x0B"},
+ {0x40, 0xA0, 0x0842, 0x0000, 0x0010, 0x0010,
+ "\x60\x10\xD5\x0B\x0D\xA2\xAF\x92\x07\xC2\xAF\x43\x08\x10\xA2\x07"},
+ {0x40, 0xA0, 0x0852, 0x0000, 0x0010, 0x0010,
+ "\x92\xAF\x05\x21\x22\xE5\x0C\x60\x10\xD5\x0C\x0D\xA2\xAF\x92\x07"},
+ {0x40, 0xA0, 0x0862, 0x0000, 0x000B, 0x000B,
+ "\xC2\xAF\x43\x08\x04\xA2\x07\x92\xAF\x05\x21"},
+ {0x40, 0xA0, 0x086D, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x000E, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAF\x92\x07\xC2\xAF\x90\x7F\x98\xE5\x08\xF0\xA2\x07\x92\xAF"},
+ {0x40, 0xA0, 0x001E, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0658, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xC8\xE0\x30\xE1\x03\x02\x06\xE2\x90\x7F\xC9\xE0\xF5\x18"},
+ {0x40, 0xA0, 0x0668, 0x0000, 0x0010, 0x0010,
+ "\xC3\xE4\x95\x14\xFF\x74\x01\x94\x00\xFE\xC3\xE5\x18\x9F\xE4\x9E"},
+ {0x40, 0xA0, 0x0678, 0x0000, 0x0010, 0x0010,
+ "\x50\x68\xE4\xF5\x19\xE5\x19\xC3\x95\x18\x50\x59\x74\xC3\x25\x19"},
+ {0x40, 0xA0, 0x0688, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x7D\xF5\x83\xE0\x54\x0F\xFD\x60\x48\x74\xC0\x25"},
+ {0x40, 0xA0, 0x0698, 0x0000, 0x0010, 0x0010,
+ "\x19\xF5\x82\xE4\x34\x7D\x90\x7F\xE3\xF0\x74\xC0\x25\x19\xF5\x82"},
+ {0x40, 0xA0, 0x06A8, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\x7D\xE5\x82\x90\x7F\xE4\xF0\xAF\x05\xED\x14\x60\x16\x14"},
+ {0x40, 0xA0, 0x06B8, 0x0000, 0x0010, 0x0010,
+ "\x60\x0B\x14\x70\x18\x90\x7F\xE5\xE0\xFF\x12\x00\xD2\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x06C8, 0x0000, 0x0010, 0x0010,
+ "\xE0\xFF\x12\x00\xD2\x90\x7F\xE5\xE0\xFF\x12\x00\xD2\x74\x04\x25"},
+ {0x40, 0xA0, 0x06D8, 0x0000, 0x000A, 0x000A,
+ "\x19\xF5\x19\x80\xA0\xE4\x90\x7F\xC9\xF0"},
+ {0x40, 0xA0, 0x06E2, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x06E3, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xCC\xE0\x30\xE1\x03\x02\x07\x6D\x90\x7F\xCD\xE0\xF5\x18"},
+ {0x40, 0xA0, 0x06F3, 0x0000, 0x0010, 0x0010,
+ "\xC3\xE4\x95\x15\xFF\x74\x01\x94\x00\xFE\xC3\xE5\x18\x9F\xE4\x9E"},
+ {0x40, 0xA0, 0x0703, 0x0000, 0x0010, 0x0010,
+ "\x50\x68\xE4\xF5\x19\xE5\x19\xC3\x95\x18\x50\x59\x74\xC3\x25\x19"},
+ {0x40, 0xA0, 0x0713, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x7C\xF5\x83\xE0\x54\x0F\xFD\x60\x48\x74\xC0\x25"},
+ {0x40, 0xA0, 0x0723, 0x0000, 0x0010, 0x0010,
+ "\x19\xF5\x82\xE4\x34\x7C\x90\x7F\xE3\xF0\x74\xC0\x25\x19\xF5\x82"},
+ {0x40, 0xA0, 0x0733, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\x7C\xE5\x82\x90\x7F\xE4\xF0\xAF\x05\xED\x14\x60\x16\x14"},
+ {0x40, 0xA0, 0x0743, 0x0000, 0x0010, 0x0010,
+ "\x60\x0B\x14\x70\x18\x90\x7F\xE5\xE0\xFF\x12\x0B\x58\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x0753, 0x0000, 0x0010, 0x0010,
+ "\xE0\xFF\x12\x0B\x58\x90\x7F\xE5\xE0\xFF\x12\x0B\x58\x74\x04\x25"},
+ {0x40, 0xA0, 0x0763, 0x0000, 0x000A, 0x000A,
+ "\x19\xF5\x19\x80\xA0\xE4\x90\x7F\xCD\xF0"},
+ {0x40, 0xA0, 0x076D, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x09BB, 0x0000, 0x0003, 0x0003, "\x01\x41\x00"},
+ {0x40, 0xA0, 0x000B, 0x0000, 0x0003, 0x0003, "\x02\x00\x26"},
+ {0x40, 0xA0, 0x0026, 0x0000, 0x000D, 0x000D,
+ "\xC0\xE0\x05\x41\xE5\x0D\x60\x02\x15\x0D\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x003E, 0x0000, 0x0003, 0x0003, "\xAF\x41\x22"},
+ {0x40, 0xA0, 0x0036, 0x0000, 0x0004, 0x0004, "\xE4\xF5\x41\x22"},
+ {0x40, 0xA0, 0x09BE, 0x0000, 0x000B, 0x000B,
+ "\x01\x3B\x01\x01\x3C\x01\xC1\x86\x01\x3D\x03"},
+ {0x40, 0xA0, 0x020D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x70\x03\x02\x02\xE2\x14\x70\x03\x02\x03\x5D\x24"},
+ {0x40, 0xA0, 0x021D, 0x0000, 0x0010, 0x0010,
+ "\xFE\x70\x03\x02\x03\xB6\x24\xFB\x70\x03\x02\x02\xDC\x14\x70\x03"},
+ {0x40, 0xA0, 0x022D, 0x0000, 0x0010, 0x0010,
+ "\x02\x02\xD6\x14\x70\x03\x02\x02\xCA\x14\x70\x03\x02\x02\xD0\x24"},
+ {0x40, 0xA0, 0x023D, 0x0000, 0x0010, 0x0010,
+ "\x05\x60\x03\x02\x04\x08\x12\x00\xFE\x40\x03\x02\x04\x13\x90\x7F"},
+ {0x40, 0xA0, 0x024D, 0x0000, 0x0010, 0x0010,
+ "\xEB\xE0\x24\xFE\x60\x16\x14\x60\x3F\x24\x02\x70\x67\x74\x01\x90"},
+ {0x40, 0xA0, 0x025D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD4\xF0\x74\xC0\x90\x7F\xD5\xF0\x02\x04\x13\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x026D, 0x0000, 0x0010, 0x0010,
+ "\xFF\x12\x0A\x2A\x8B\x18\x8A\x19\x89\x1A\xEA\x49\x60\x11\xAE\x02"},
+ {0x40, 0xA0, 0x027D, 0x0000, 0x0010, 0x0010,
+ "\xEE\x90\x7F\xD4\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x13\x90"},
+ {0x40, 0xA0, 0x028D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\x74\x01\xF0\x02\x04\x13\x90\x7F\xEA\xE0\xFF\x12\x0A\x79"},
+ {0x40, 0xA0, 0x029D, 0x0000, 0x0010, 0x0010,
+ "\x8B\x18\x8A\x19\x89\x1A\xEA\x49\x60\x11\xAE\x02\xEE\x90\x7F\xD4"},
+ {0x40, 0xA0, 0x02AD, 0x0000, 0x0010, 0x0010,
+ "\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x13\x90\x7F\xC4\x74\x01"},
+ {0x40, 0xA0, 0x02BD, 0x0000, 0x0010, 0x0010,
+ "\xF0\x02\x04\x13\x90\x7F\xC4\x74\x01\xF0\x02\x04\x13\x12\x0C\xA6"},
+ {0x40, 0xA0, 0x02CD, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x13\x12\x0C\xB4\x02\x04\x13\x12\x00\x03\x02\x04\x13\x12"},
+ {0x40, 0xA0, 0x02DD, 0x0000, 0x0010, 0x0010,
+ "\x0C\x98\x02\x04\x13\x12\x0A\xFD\x40\x03\x02\x04\x13\x90\x7F\xE8"},
+ {0x40, 0xA0, 0x02ED, 0x0000, 0x0010, 0x0010,
+ "\xE0\x24\x7F\x60\x24\x14\x60\x31\x24\x02\x70\x5B\xA2\x04\xE4\x33"},
+ {0x40, 0xA0, 0x02FD, 0x0000, 0x0010, 0x0010,
+ "\xFF\x25\xE0\xFF\xA2\x00\xE4\x33\x4F\x90\x7F\x00\xF0\xE4\xA3\xF0"},
+ {0x40, 0xA0, 0x030D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x13\xE4\x90\x7F\x00\xF0\xA3\xF0"},
+ {0x40, 0xA0, 0x031D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x13\x90\x7F\xEC\xE0\xF4\x54\x80"},
+ {0x40, 0xA0, 0x032D, 0x0000, 0x0010, 0x0010,
+ "\xFF\xC4\x54\x0F\xFF\xE0\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x033D, 0x0000, 0x0010, 0x0010,
+ "\x34\x7F\xF5\x83\xE0\x54\xFD\x90\x7F\x00\xF0\xE4\xA3\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x034D, 0x0000, 0x0010, 0x0010,
+ "\xB5\x74\x02\xF0\x02\x04\x13\x90\x7F\xC4\x74\x01\xF0\x02\x04\x13"},
+ {0x40, 0xA0, 0x035D, 0x0000, 0x0010, 0x0010,
+ "\x12\x0C\xBC\x40\x03\x02\x04\x13\x90\x7F\xE8\xE0\x24\xFE\x60\x1C"},
+ {0x40, 0xA0, 0x036D, 0x0000, 0x0010, 0x0010,
+ "\x24\x02\x60\x03\x02\x04\x13\x90\x7F\xEA\xE0\xB4\x01\x05\xC2\x04"},
+ {0x40, 0xA0, 0x037D, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x13\x90\x7F\xC4\x74\x01\xF0\x02\x04\x13\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x038D, 0x0000, 0x0010, 0x0010,
+ "\x70\x1F\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0\x54"},
+ {0x40, 0xA0, 0x039D, 0x0000, 0x0010, 0x0010,
+ "\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\xE4\xF0\x80"},
+ {0x40, 0xA0, 0x03AD, 0x0000, 0x0010, 0x0010,
+ "\x65\x90\x7F\xC4\x74\x01\xF0\x80\x5D\x12\x0C\xBE\x50\x58\x90\x7F"},
+ {0x40, 0xA0, 0x03BD, 0x0000, 0x0010, 0x0010,
+ "\xE8\xE0\x24\xFE\x60\x17\x24\x02\x70\x4C\x90\x7F\xEA\xE0\xB4\x01"},
+ {0x40, 0xA0, 0x03CD, 0x0000, 0x0010, 0x0010,
+ "\x04\xD2\x04\x80\x41\x90\x7F\xC4\x74\x01\xF0\x80\x39\x90\x7F\xEA"},
+ {0x40, 0xA0, 0x03DD, 0x0000, 0x0010, 0x0010,
+ "\xE0\x70\x20\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0"},
+ {0x40, 0xA0, 0x03ED, 0x0000, 0x0010, 0x0010,
+ "\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\x74\x01"},
+ {0x40, 0xA0, 0x03FD, 0x0000, 0x0010, 0x0010,
+ "\xF0\x80\x13\x90\x7F\xC4\x74\x01\xF0\x80\x0B\x12\x0C\xC0\x50\x06"},
+ {0x40, 0xA0, 0x040D, 0x0000, 0x000D, 0x000D,
+ "\x90\x7F\xC4\x74\x01\xF0\x90\x7F\xB4\xE0\x44\x02\xF0"},
+ {0x40, 0xA0, 0x041A, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0ABA, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xDE\x74\x16\xF0\x90\x7F\xDF\x74\x14\xF0\x90\x7F\xDD\x74"},
+ {0x40, 0xA0, 0x0ACA, 0x0000, 0x0010, 0x0010,
+ "\x18\xF0\x90\x7F\xB6\x74\x02\xF0\x90\x7F\xB8\xF0\x90\x7F\xBA\xF0"},
+ {0x40, 0xA0, 0x0ADA, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xBC\xF0\x90\x7F\xBE\xF0\x90\x7F\xC0\xF0\x90\x7F\xC2\xF0"},
+ {0x40, 0xA0, 0x0AEA, 0x0000, 0x000A, 0x000A,
+ "\xE4\x90\x7F\xC9\xF0\x90\x7F\xCD\xF0\x22"},
+ {0x40, 0xA0, 0x0AF4, 0x0000, 0x0009, 0x0009,
+ "\x90\x7F\xAF\xE0\x44\x08\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0041, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x00FE, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0003, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x3F\xD3\x22"},
+ {0x40, 0xA0, 0x0C98, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x3F\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0CB4, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x3E\xD3\x22"},
+ {0x40, 0xA0, 0x0CA6, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x3E\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0AFD, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0CBC, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0CBE, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0CC0, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BAE, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0BBE, 0x0000, 0x0010, 0x0010,
+ "\x01\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0BCE, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0B84, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x0B94, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x0BA4, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x09CA, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x09DA, 0x0000, 0x0001, 0x0001, "\xD0"},
+ {0x40, 0xA0, 0x09DB, 0x0000, 0x0010, 0x0010,
+ "\x53\x91\xEF\x90\x7F\xAB\x74\x02\xF0\x30\x06\x14\x15\x3B\xE5\x3B"},
+ {0x40, 0xA0, 0x09EB, 0x0000, 0x0010, 0x0010,
+ "\x70\x2E\x43\x08\x40\xC2\x06\xC3\x74\x1E\x95\x3D\xF5\x3B\x80\x20"},
+ {0x40, 0xA0, 0x09FB, 0x0000, 0x0010, 0x0010,
+ "\xD5\x3B\x1D\x53\x08\xBF\xD2\x06\xE5\x3C\x25\x3D\xF5\x3D\x64\x03"},
+ {0x40, 0xA0, 0x0A0B, 0x0000, 0x0010, 0x0010,
+ "\x60\x05\xE5\x3D\xB4\x1C\x06\xE5\x3C\xF4\x04\xF5\x3C\x85\x3D\x3B"},
+ {0x40, 0xA0, 0x0A1B, 0x0000, 0x000F, 0x000F,
+ "\xD0\xD0\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BFC, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x0C0C, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x0C1C, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x003A, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BD5, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0BE5, 0x0000, 0x0010, 0x0010,
+ "\x05\x53\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0BF5, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0AFF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC2, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC3, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC4, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC5, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC6, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC7, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC8, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CC9, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCA, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCB, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCC, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCD, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CCF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0CD0, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0C67, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x30\xE7\x12\xE0\x44\x01\xF0\x7F\x14\x7E\x00\x12"},
+ {0x40, 0xA0, 0x0C77, 0x0000, 0x000A, 0x000A,
+ "\x0C\x81\x90\x7F\xD6\xE0\x54\xFE\xF0\x22"},
+ {0x40, 0xA0, 0x0C46, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x44\x80\xF0\x43\x87\x01\x00\x00\x00\x00\x00\x22"},
+ {0x40, 0xA0, 0x0C21, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x54\xFB\xF0\xE0\x44\x08\xF0\x30\x07\x04\xE0\x44"},
+ {0x40, 0xA0, 0x0C31, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x7F\xF4\x7E\x01\x12\x0C\x81\x90\x7F\xD6\xE0\x54\xF7\xF0"},
+ {0x40, 0xA0, 0x0C41, 0x0000, 0x0005, 0x0005, "\xE0\x44\x04\xF0\x22"},
+ {0x40, 0xA0, 0x0A79, 0x0000, 0x0002, 0x0002, "\x8F\x1B"},
+ {0x40, 0xA0, 0x0A7B, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x1C\x75\x1D\xFF\x75\x1E\x02\x75\x1F\x07\xAB\x1D\xAA\x1E"},
+ {0x40, 0xA0, 0x0A8B, 0x0000, 0x0010, 0x0010,
+ "\xA9\x1F\x90\x00\x01\x12\x07\x87\xB4\x03\x1D\xAF\x1C\x05\x1C\xEF"},
+ {0x40, 0xA0, 0x0A9B, 0x0000, 0x0010, 0x0010,
+ "\xB5\x1B\x01\x22\x12\x07\x6E\x7E\x00\x29\xFF\xEE\x3A\xA9\x07\x75"},
+ {0x40, 0xA0, 0x0AAB, 0x0000, 0x000E, 0x000E,
+ "\x1D\xFF\xF5\x1E\x89\x1F\x80\xD4\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x0AB9, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0A2A, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFE\x75\x1D\xFF\x75\x1E\x01\x75\x1F\xD2\xAB\x1D\xAA\x1E\xA9"},
+ {0x40, 0xA0, 0x0A3A, 0x0000, 0x0010, 0x0010,
+ "\x1F\x90\x00\x01\x12\x07\x87\x64\x02\x70\x2D\xAD\x06\x0E\xED\xB5"},
+ {0x40, 0xA0, 0x0A4A, 0x0000, 0x0010, 0x0010,
+ "\x07\x01\x22\x90\x00\x02\x12\x07\xB4\x85\xF0\x1B\xF5\x1C\x62\x1B"},
+ {0x40, 0xA0, 0x0A5A, 0x0000, 0x0010, 0x0010,
+ "\xE5\x1B\x62\x1C\xE5\x1C\x62\x1B\x29\xFD\xE5\x1B\x3A\xA9\x05\x75"},
+ {0x40, 0xA0, 0x0A6A, 0x0000, 0x000E, 0x000E,
+ "\x1D\xFF\xF5\x1E\x89\x1F\x80\xC3\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x0A78, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0C81, 0x0000, 0x0010, 0x0010,
+ "\x8E\x18\x8F\x19\xE5\x19\x15\x19\xAE\x18\x70\x02\x15\x18\x4E\x60"},
+ {0x40, 0xA0, 0x0C91, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x0C\x56\x80\xEE\x22"},
+ {0x40, 0xA0, 0x0C56, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x0C66, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x00\x46"},
+ {0x40, 0xA0, 0x0046, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\xC1\x02\x00\x8D"},
+ {0x40, 0xA0, 0x076E, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x06\x89\x82\x8A\x83\xE0\x22\x50\x02\xE7\x22\xBB\xFE\x02"},
+ {0x40, 0xA0, 0x077E, 0x0000, 0x0009, 0x0009,
+ "\xE3\x22\x89\x82\x8A\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x0787, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x0797, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x07A7, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x07B4, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x10\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\xF5\xF0"},
+ {0x40, 0xA0, 0x07C4, 0x0000, 0x0010, 0x0010,
+ "\xA3\xE0\x22\x50\x09\xE9\x25\x82\xF8\x86\xF0\x08\xE6\x22\xBB\xFE"},
+ {0x40, 0xA0, 0x07D4, 0x0000, 0x0010, 0x0010,
+ "\x0A\xE9\x25\x82\xF8\xE2\xF5\xF0\x08\xE2\x22\xE5\x83\x2A\xF5\x83"},
+ {0x40, 0xA0, 0x07E4, 0x0000, 0x0008, 0x0008,
+ "\xE9\x93\xF5\xF0\xA3\xE9\x93\x22"},
+ {0x40, 0xA0, 0x07EC, 0x0000, 0x0006, 0x0006, "\x8A\x83\x89\x82\xE4\x73"},
+ {0x40, 0xA0, 0x0052, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x1B\xE4\x93\xA3\xF8\xE4\x93\xA3\x40\x03\xF6\x80\x01\xF2"},
+ {0x40, 0xA0, 0x0062, 0x0000, 0x0010, 0x0010,
+ "\x08\xDF\xF4\x80\x29\xE4\x93\xA3\xF8\x54\x07\x24\x0C\xC8\xC3\x33"},
+ {0x40, 0xA0, 0x0072, 0x0000, 0x0010, 0x0010,
+ "\xC4\x54\x0F\x44\x20\xC8\x83\x40\x04\xF4\x56\x80\x01\x46\xF6\xDF"},
+ {0x40, 0xA0, 0x0082, 0x0000, 0x0010, 0x0010,
+ "\xE4\x80\x0B\x01\x02\x04\x08\x10\x20\x40\x80\x90\x09\x62\xE4\x7E"},
+ {0x40, 0xA0, 0x0092, 0x0000, 0x0010, 0x0010,
+ "\x01\x93\x60\xBC\xA3\xFF\x54\x3F\x30\xE5\x09\x54\x1F\xFE\xE4\x93"},
+ {0x40, 0xA0, 0x00A2, 0x0000, 0x0010, 0x0010,
+ "\xA3\x60\x01\x0E\xCF\x54\xC0\x25\xE0\x60\xA8\x40\xB8\xE4\x93\xA3"},
+ {0x40, 0xA0, 0x00B2, 0x0000, 0x0010, 0x0010,
+ "\xFA\xE4\x93\xA3\xF8\xE4\x93\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA"},
+ {0x40, 0xA0, 0x00C2, 0x0000, 0x0010, 0x0010,
+ "\xF0\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA\xDF\xE9\xDE\xE7\x80\xBE"},
+ {0x40, 0xA0, 0x09C9, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x09, 0x0001, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x0000, NULL}
+};
diff --git a/kernel/drv/oss_usb/oss_usb.c b/kernel/drv/oss_usb/oss_usb.c
new file mode 100644
index 0000000..2b5f119
--- /dev/null
+++ b/kernel/drv/oss_usb/oss_usb.c
@@ -0,0 +1,2505 @@
+/*
+ * Purpose: Top level USB audio class initialization and mixer functions
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define KBUILD_MODNAME oss_usb
+#include "oss_config.h"
+#include "ossusb.h"
+
+
+static const udi_usb_devinfo known_devices[] = {
+ {0x763, 0x2002, "M Audio USB AudioSport Duo",
+ {
+ {"OFF 24bit_hispeed 16bit_hispeed 24bit_lowspeed 16bit_lowspeed", 2,
+ 0x0014},
+ {"OFF 24bit_hispeed 16bit_hispeed 24bit_lowspeed 16bit_lowspeed", 2,
+ 0x0014}
+ }
+ },
+ {0x763, 0x2001, "M Audio USB AudioSport Quatro"},
+ {0x763, 0x2805, "M Audio Sonica"},
+ {0x763, 0x2007, "M Audio Sonica Theatre",
+ {
+ {"OFF 24bit_hispeed 16bit_hispeed 16bit_hispeed 24bit_lowspeed 24bit24bit 16bit 16bit OFF OFF", 3},
+ {"OFF 24bit_hispeed 16bit_hispeed 24bit 16bit_lowspeed", 2}
+ }
+ },
+ {0x763, 0x200d, "M Audio OmniStudio USB"},
+ {0x41e, 0x3000, "Creative Sound Blaster Extigy"},
+ {0x41e, 0x3010, "Creative Sound Blaster MP3+"},
+ {0x41e, 0x3020, "Creative Audigy2 NX USB",
+ {
+ {"OFF 16bit22kHz 16bit44kHz " /* 0-2 */
+ "24bit44kHz 16bit48kHz 24bit48kHz " /* 3-5 */
+ "16bit96kHz 24bit96kHz 16bit22kHz " /* 6-8 */
+ "16bit48kHz 24bit48kHz 16bit5.1ch22kHz " /* 9-11 */
+ "16bit5.1ch48kHz 24bit5.1ch48kHz 16bit7.1ch22kHz " /* 12-14 */
+ "16bit7.1ch48kHz" /* 15 */ , 4},
+
+ {"OFF 16bit32kHz 24bit32kHz " /* 0-2 */
+ "16bit44kHz 24bit44kHz 16bit48kHz " /* 3-5 */
+ "24bit48kHzin 24bit96kHz 24bit96kHz ", /* 6-8 */
+ 5}
+ }
+ },
+ {0x46d, 0x8b2, "Logitec Quickcam Pro 4000 (mic)"},
+ {0x46d, 0xa01, "Logitec USB Headset"},
+ {0x0471, 0x0311, "Philips ToUcam Pro (mic)"},
+ {0x672, 0x1041, "Labtec LCS1040 Speaker System"},
+ {0x6f8, 0xc000, "Hercules Gamesurround MUSE Pocket"},
+ {0x0d8c, 0x000c, "C-Media USB audio"},
+ {0x0d8c, 0x0102, "C-Media 2/4/6/8ch USB audio",
+ {
+ {"OFF 7.1 2.0 3.1 5.1 digital", 2},
+ {"OFF stereo"}
+ }
+ },
+ {0x0d8c, 0x0103, "C-Media USB audio"},
+ {-1, -1, "USB sound device"}
+};
+
+typedef struct
+{
+ unsigned int devid;
+ special_driver_t driver;
+}
+special_table_t;
+
+extern int usb_mixerstyle;
+
+#define MAX_DEVC 10
+static ossusb_devc *devc_list[MAX_DEVC];
+static int ndevs = 0;
+int usb_quiet = 0;
+
+
+void
+ossusb_dump_desc (unsigned char *desc, int cfg_len)
+{
+ int i;
+
+ for (i = 0; i < cfg_len; i++)
+ {
+ if (!(i % 16))
+ cmn_err (CE_CONT, "\n%04x: ", i);
+ cmn_err (CE_CONT, "%02x ", desc[i]);
+ }
+ cmn_err (CE_CONT, "\n");
+}
+
+unsigned int
+ossusb_get_int (unsigned char *p, int nbytes)
+{
+ unsigned int v = 0;
+ int i;
+
+ for (i = 0; i < nbytes; i++)
+ {
+ v |= (*p++) << (i * 8);
+ }
+
+ return v;
+}
+
+/*
+ * Mixer stuff
+ */
+
+static int
+decode_vol (usb_control_t * c, unsigned char *buf, int l)
+{
+ int value, range;
+
+ if (l == 1)
+ value = (signed char) buf[0];
+ else
+ value = (signed short) (buf[0] | (buf[1] << 8));
+
+ range = c->max - c->min;
+
+ value -= c->min;
+ value = (value * c->scale + range / 2) / range;
+
+ if (value < 0)
+ value = 0;
+ if (value > 255)
+ value = 255;
+ return value;
+}
+
+static void
+encode_vol (usb_control_t * c, unsigned char *buf, int l, int value)
+{
+ int range;
+
+ range = c->max - c->min;
+
+ value = (value * range + c->scale / 2) / c->scale;
+
+ value += c->min;
+
+ if (l == 1)
+ buf[0] = value;
+ else
+ {
+ buf[0] = value & 0xff;
+ buf[1] = (value >> 8) & 0xff;
+ }
+
+}
+
+static int
+read_feature_value (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
+{
+ int len, value = 0, l;
+ int nch, ch;
+ unsigned char buf[2];
+
+/*
+ * Volume controls use two message bytes while the others use just one.
+ */
+ l = (c->index == 1) ? 2 : 1;
+
+ ch = c->min_ch + 1;
+ if (c->global)
+ ch = 0;
+
+ if (rq != GET_CUR)
+ {
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | (ch), // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ return 0;
+
+ value =
+ (len ==
+ 1) ? (signed char) buf[0] : (signed short) (buf[0] | (buf[1] << 8));
+ *v = value;
+ return 1;
+ }
+
+ nch = c->max_ch - c->min_ch + 1;
+
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | (ch), // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ {
+ // cmn_err(CE_CONT, "feature (%s/%d) read error %d\n", c->unit->name, c->index, len);
+ *v = 0;
+ return 0;
+ }
+
+ value = decode_vol (c, buf, len);
+
+ if (!c->global)
+ if (nch == 2) /* Read the right channel */
+ {
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | (ch + 1), // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ value |= (value & 0xff) << 8;
+ else
+ value |= (decode_vol (c, buf, len)) << 8;
+ }
+
+ *v = value;
+ return 1;
+}
+
+static int
+write_feature_value (ossusb_devc * devc, usb_control_t * c, int value)
+{
+ int len, l;
+ int left, right;
+ int ch, nch;
+ unsigned char buf[2];
+
+ ch = c->min_ch + 1;
+ if (c->global)
+ ch = 0;
+
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+
+ if (left > (c->max - c->min))
+ left = c->max - c->min;
+ if (right > (c->max - c->min))
+ right = c->max - c->min;
+
+ l = (c->index == 1) ? 2 : 1;
+
+ nch = c->max_ch - c->min_ch + 1;
+ buf[0] = buf[1] = 0;
+ encode_vol (c, buf, l, left);
+
+ len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | ch, // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ {
+ cmn_err (CE_CONT, "feature write error %d\n", len);
+ return len;
+ }
+
+ if (nch == 2) /* Write the right channel */
+ {
+ buf[0] = buf[1] = 0;
+ encode_vol (c, buf, l, right);
+
+ len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((c->index + 1) << 8) | (ch + 1), // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ * 2);
+ }
+ else
+ right = left;
+
+ value = left | (right << 8);
+ return value;
+}
+
+static int
+read_mixer_value (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
+{
+ int len, value = 0;
+ unsigned char buf[2];
+
+ if (rq != GET_CUR)
+ {
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ (c->index << 8) | c->min_ch, // value
+ (c->unit->num << 8) | 1, // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ return 0;
+
+ *v = (signed char) buf[1];
+ return 1;
+ }
+
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ (c->index << 8) | c->min_ch, // value
+ (c->unit->num << 8) | 1, // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ {
+ cmn_err (CE_CONT, "mixer read error %d\n", len);
+ return 0;
+ }
+
+ value = buf[1] - c->min;
+
+ *v = value;
+ return 1;
+}
+
+static int
+write_mixer_value (ossusb_devc * devc, usb_control_t * c, int value)
+{
+ int len;
+ unsigned char buf[2];
+
+ value &= 0xff;
+
+ buf[0] = 0;
+ buf[1] = value + c->min;
+ len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ (c->index << 8) | c->min_ch, // value
+ (c->unit->num << 8) | 1, // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+ if (len < 0)
+ {
+ cmn_err (CE_CONT, "mixer write error %d\n", len);
+ return 0;
+ }
+
+ return value;
+}
+
+static int
+read_unit (ossusb_devc * devc, usb_control_t * c, int rq, int *v)
+{
+ int err, value;
+ unsigned char buf[2];
+
+ *v = value = 0;
+
+ switch (c->unit->typ)
+ {
+ case TY_FEAT:
+ return read_feature_value (devc, c, rq, v);
+ break;
+
+ case TY_MIXER:
+ return read_mixer_value (devc, c, rq, v);
+ break;
+
+ case TY_SELECT:
+ err = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ rq, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ 0, // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ 1, // buflen
+ OSS_HZ * 2);
+ if (err < 0)
+ {
+ cmn_err (CE_CONT, "USB mixer unit read error %d\n", err);
+ return 0;
+ }
+ value = buf[0] - 1;
+ break;
+
+ } /* switch */
+
+ *v = value;
+ return 1;
+}
+
+static int
+read_current_value (ossusb_devc * devc, usb_control_t * c)
+{
+ int v;
+
+ if (!read_unit (devc, c, GET_CUR, &v))
+ return 0;
+
+ c->value = v;
+
+ return 1;
+}
+
+static int
+write_current_value (ossusb_devc * devc, usb_control_t * c, int value)
+{
+ unsigned char buf[2];
+ int err;
+
+ switch (c->unit->typ)
+ {
+ case TY_SELECT:
+ if (value > c->max)
+ value = c->max;
+ buf[0] = value + 1;
+ err = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ 0, // value
+ (c->unit->num << 8), // index
+ buf, // buffer
+ 1, // buflen
+ OSS_HZ * 2);
+ if (err < 0)
+ {
+ cmn_err (CE_CONT, "Selector write error %d\n", err);
+ return 0;
+ }
+ break;
+
+ case TY_FEAT:
+ value = write_feature_value (devc, c, value);
+ break;
+
+ case TY_MIXER:
+ value = write_mixer_value (devc, c, value);
+ break;
+
+ default:
+ return OSS_EIO;
+ }
+
+ return value;
+}
+
+static int
+new_ctl (ossusb_devc * devc, usb_audio_unit_t * un, int index, int exttype,
+ int chmask)
+{
+ int n, min, max;
+ usb_control_t *c;
+ int i, min_ch = 0, max_ch = 0;
+
+ if (devc->ncontrols >= MAX_CONTROLS)
+ {
+ cmn_err (CE_CONT, "Too many mixer features.\n");
+ return OSS_EIO;
+ }
+
+ n = devc->ncontrols++;
+
+ c = &devc->controls[n];
+
+ if (chmask)
+ {
+ min_ch = -1;
+
+ for (i = 0; i < 32; i++)
+ if (chmask & (1 << i))
+ {
+ if (min_ch == -1)
+ min_ch = i;
+ max_ch = i;
+ }
+ }
+
+ c->unit = un;
+ c->index = index;
+ c->exttype = exttype;
+ c->min_ch = min_ch;
+ c->global = (chmask == 0) ? 1 : 0;
+ c->max_ch = max_ch;
+ c->min = 0;
+ c->max = 255;
+ c->chmask = chmask;
+ c->value = 0;
+
+ if (index != 1) /* Not volume control */
+ {
+ c->max = 1;
+ }
+ else
+ {
+ if (read_unit (devc, c, GET_MAX, &max))
+ {
+ c->max = max;
+ if (read_unit (devc, c, GET_MIN, &min))
+ {
+ c->min = min;
+ }
+ }
+ }
+
+ if (c->max <= c->min)
+ {
+/*
+ * The device reported bad limits. Try to fix the situation.
+ */
+ if (c->min < 0)
+ c->max = 0;
+ else
+ c->min = 0;
+ if (c->max <= c->min)
+ {
+ c->min = 0;
+ c->max = 255;
+ }
+ }
+
+ c->scale = 255;
+ if (c->max - c->min < 255)
+ c->scale = c->max - c->min;
+
+
+ read_current_value (devc, c);
+
+ if (usb_trace)
+ {
+ cmn_err (CE_CONT, "Ctl %2d: %d/%s %d ", n, c->unit->num, c->unit->name,
+ c->index);
+ cmn_err (CE_CONT, "Min %d, max %d, scale %d\n", c->min, c->max,
+ c->scale);
+ cmn_err (CE_CONT, "ch=%x ", c->chmask);
+ cmn_err (CE_CONT, "Value %04x, (%d - %d, %d)\n", c->value, c->min,
+ c->max, c->scale);
+ }
+
+ return n;
+}
+
+static int
+mixer_func (int dev, int ctrl, unsigned int cmd, int value)
+{
+ ossusb_devc *devc = mixer_devs[dev]->devc;
+ usb_control_t *c;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ if (ctrl < 0 || ctrl >= devc->ncontrols)
+ return OSS_EIO;
+
+ c = &devc->controls[ctrl];
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return c->value;
+ }
+
+ if (cmd != SNDCTL_MIX_WRITE)
+ return OSS_EINVAL;
+
+ value = c->value = write_current_value (devc, c, value);
+
+ return value;
+}
+
+static char *
+get_feature_name (int n)
+{
+ switch (n)
+ {
+ case 0:
+ return "mute";
+ case 1:
+ return "vol";
+ case 2:
+ return "bass";
+ case 3:
+ return "mid";
+ case 4:
+ return "treble";
+ case 5:
+ return "eq";
+ case 6:
+ return "agc";
+ case 7:
+ return "delay";
+ case 8:
+ return "boost";
+ case 9:
+ return "loud";
+ case 10:
+ return "igain";
+ case 11:
+ return "igainpad";
+ case 12:
+ return "phaseinv";
+ case 13:
+ return "underflow";
+ case 14:
+ return "overflow";
+ default:
+ return "misc";
+ }
+}
+
+static int
+get_feature_type (int n)
+{
+ switch (n)
+ {
+ case 0:
+ return MIXT_ONOFF;
+ case 1:
+ return MIXT_SLIDER;
+ case 2:
+ return MIXT_SLIDER;
+ case 3:
+ return MIXT_SLIDER;
+ case 4:
+ return MIXT_SLIDER;
+ case 5:
+ return MIXT_SLIDER;
+ case 6:
+ return MIXT_ONOFF;
+ case 7:
+ return MIXT_SLIDER;
+ case 8:
+ return MIXT_ONOFF;
+ case 9:
+ return MIXT_ONOFF;
+ default:
+ return MIXT_ONOFF;
+ }
+}
+
+struct chmasks
+{
+ unsigned int mask;
+ char *name;
+ char type;
+ char channels;
+};
+
+static const struct chmasks chmasks[] = {
+ {0x00000003, "front", MIXT_STEREOSLIDER, 2},
+ {0x00000001, "L", MIXT_MONOSLIDER, 1},
+ {0x00000002, "R", MIXT_MONOSLIDER, 1},
+ {0x00000030, "surr", MIXT_STEREOSLIDER, 2},
+ {0x00000010, "LS", MIXT_MONOSLIDER, 1},
+ {0x00000020, "RS", MIXT_MONOSLIDER, 1},
+ {0x0000000c, "C/L", MIXT_STEREOSLIDER, 2},
+ {0x00000004, "C", MIXT_MONOSLIDER, 1},
+ {0x00000008, "LFE", MIXT_MONOSLIDER, 1},
+ {0x000000c0, "center", MIXT_STEREOSLIDER, 2},
+ {0x00000040, "LC", MIXT_MONOSLIDER, 1},
+ {0x00000080, "RC", MIXT_MONOSLIDER, 1},
+ {0x00000100, "surr", MIXT_STEREOSLIDER, 2},
+ {0x00000600, "side", MIXT_STEREOSLIDER, 2},
+ {0x00000200, "SL", MIXT_MONOSLIDER, 1},
+ {0x00000400, "SR", MIXT_MONOSLIDER, 1},
+ {0x00000800, "TC", MIXT_MONOSLIDER, 1},
+ {0x00001000, "TFL", MIXT_MONOSLIDER, 1},
+ {0x00002000, "TFC", MIXT_MONOSLIDER, 1},
+ {0x00004000, "TFR", MIXT_MONOSLIDER, 1},
+ {0x00008000, "TBL", MIXT_MONOSLIDER, 1},
+ {0x00010000, "TBC", MIXT_MONOSLIDER, 1},
+ {0x00020000, "TBR", MIXT_MONOSLIDER, 1},
+ {0x00040000, "TFLC", MIXT_MONOSLIDER, 1},
+ {0x00080000, "TFRC", MIXT_MONOSLIDER, 1},
+ {0x00100000, "LLFE", MIXT_MONOSLIDER, 1},
+ {0x00200000, "RLFE", MIXT_MONOSLIDER, 1},
+ {0x00400000, "TSL", MIXT_MONOSLIDER, 1},
+ {0x00800000, "TSR", MIXT_MONOSLIDER, 1},
+ {0x01000000, "BC", MIXT_MONOSLIDER, 1},
+ {0x02000000, "BLC", MIXT_MONOSLIDER, 1},
+ {0x04000000, "BRC", MIXT_MONOSLIDER, 1},
+ {0x80000000, "RD", MIXT_MONOSLIDER, 1},
+ {0, NULL}
+};
+
+static int
+count_source_controls (ossusb_devc * devc, int unit)
+{
+ int n = 0, nn, i;
+ usb_audio_unit_t *un;
+ unsigned char *d;
+
+ if (unit <= 0 || unit >= devc->nunits)
+ return 0;
+
+ un = &devc->units[unit];
+ d = un->desc;
+
+ if (un == NULL)
+ return 0;
+
+ switch (un->typ)
+ {
+ case TY_MIXER:
+ case TY_SELECT:
+ nn = d[4];
+ d += 5;
+ for (i = 0; i < nn; i++)
+ {
+ n += count_source_controls (devc, *d);
+ d++;
+ }
+ break;
+
+ case TY_PROC:
+ case TY_EXT:
+ nn = d[6];
+ d += 7;
+ for (i = 0; i < nn; i++)
+ {
+ n += count_source_controls (devc, *d);
+ d++;
+ }
+ break;
+
+ default:
+ if (un->source <= 0 && un->source < devc->nunits)
+ {
+ n = count_source_controls (devc, un->source);
+ }
+ }
+
+ if (!un->ctl_avail)
+ return n;
+
+ return n + un->control_count;
+}
+
+static int
+count_target_controls (ossusb_devc * devc, int unit)
+{
+ int n = 0;
+ usb_audio_unit_t *un;
+
+ if (unit <= 0 || unit >= devc->nunits)
+ return 0;
+
+ un = &devc->units[unit];
+
+ if (un == NULL)
+ return 0;
+
+ if (un->typ == TY_SELECT || un->typ == TY_MIXER)
+ {
+ n = 0;
+ }
+ else if (un->target <= 0 && un->target < devc->nunits)
+ {
+ n = count_target_controls (devc, un->target);
+ }
+
+ if (!un->ctl_avail)
+ return n;
+
+ return n + un->control_count;
+}
+
+static int
+follow_source_links (ossusb_devc * devc, usb_audio_unit_t * un)
+{
+ while (un->source > 0 && un->source < devc->nunits)
+ un = &devc->units[un->source];
+
+ return un->num;
+}
+
+static int
+follow_target_links (ossusb_devc * devc, usb_audio_unit_t * un)
+{
+ while (un->target > 0 && un->target < devc->nunits)
+ un = &devc->units[un->target];
+
+ return un->num;
+}
+
+static void
+add_controls_for_mixer (ossusb_devc * devc, usb_audio_unit_t * un, int group)
+{
+ int i, n;
+ unsigned char *d = un->desc;
+
+ if (!un->ctl_avail)
+ return;
+
+ n = d[4];
+ d += 5;
+
+ for (i = 0; i < n; i++)
+ if (*d > 0 && *d < devc->nunits)
+ {
+ int ref = follow_source_links (devc, &devc->units[*d]);
+
+ {
+
+ int ctl = new_ctl (devc, un, i, MIXT_MONOSLIDER, un->chmask);
+ UDB (cmn_err
+ (CE_CONT, "Add mixer control %d/%s\n", un->num,
+ devc->units[ref].name));
+ if (mixer_ext_create_control (devc->mixer_dev, group, ctl,
+ mixer_func, MIXT_MONOSLIDER,
+ devc->units[ref].name, 255,
+ MIXF_READABLE | MIXF_WRITEABLE) < 0)
+ return;
+ }
+ d++;
+ }
+
+ un->ctl_avail = 0;
+}
+
+/*ARGSUSED*/
+static void
+add_controls_for_proc (ossusb_devc * devc, usb_audio_unit_t * un, int group)
+{
+ int i, n;
+ unsigned char *d = un->desc;
+
+ if (!un->ctl_avail)
+ return;
+
+ n = d[6];
+ d += 7;
+
+ for (i = 0; i < n; i++)
+ if (*d > 0 && *d < devc->nunits)
+ {
+ d++;
+ }
+
+ un->ctl_avail = 0;
+}
+
+static void
+add_controls_for_selector (ossusb_devc * devc, usb_audio_unit_t * un,
+ int group)
+{
+ static oss_mixer_enuminfo ent;
+ char *s;
+ int i, n, err;
+ unsigned char *d = un->desc;
+ int ctl = new_ctl (devc, un, 0, MIXT_ENUM, 0);
+
+ if (!un->ctl_avail)
+ return;
+
+ n = d[4];
+ d += 5;
+ UDB (cmn_err (CE_CONT, "Add selector control %d/%s\n", un->num, un->name));
+ if ((err = mixer_ext_create_control (devc->mixer_dev, group,
+ ctl, mixer_func,
+ MIXT_ENUM,
+ un->name, n,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return;
+
+ memset (&ent, 0, sizeof (ent));
+
+ s = ent.strings;
+
+ for (i = 0; i < n; i++)
+ if (*d > 0 && *d < devc->nunits)
+ {
+ int ref = follow_source_links (devc, &devc->units[*d]);
+ d++;
+
+ if (s > ent.strings)
+ *s++ = '|';
+ strcpy (s, devc->units[ref].name);
+ s += strlen (s);
+ }
+
+ s = ent.strings;
+ for (i = 0; i < strlen (s); i++)
+ {
+ if (s[i] == ' ')
+ s[i] = '_';
+ if (s[i] == '|')
+ s[i] = ' ';
+ }
+
+ ent.dev = devc->mixer_dev;
+ ent.ctrl = err;
+ ent.nvalues = 0;
+
+ mixer_ext_set_enum (&ent);
+
+ un->ctl_avail = 0;
+}
+
+/*ARGSUSED*/
+static void
+add_multich_volumes (ossusb_devc * devc, usb_audio_unit_t * un, int group,
+ int fea, int mask, unsigned int *feature_mask)
+{
+ int i;
+
+ for (i = 0; mask != 0 && chmasks[i].mask != 0; i++)
+ {
+ int m = chmasks[i].mask;
+ int ctl;
+ usb_control_t *c;
+
+ if (!(mask & m))
+ continue;
+
+ ctl = new_ctl (devc, un, fea, chmasks[i].type, chmasks[i].mask);
+ c = &devc->controls[ctl];
+
+ UDB (cmn_err
+ (CE_CONT, "Add multich feature control %d/%s\n", un->num,
+ chmasks[i].name));
+ if (mixer_ext_create_control (devc->mixer_dev, group, ctl, mixer_func,
+ chmasks[i].type, chmasks[i].name,
+ c->scale,
+ MIXF_READABLE | MIXF_WRITEABLE) < 0)
+ return;
+
+ mask &= ~m;
+ }
+
+ if (mask)
+ cmn_err (CE_CONT, "Warning! Unsupported channels (%02x)\n", mask);
+}
+
+static void
+translate_feature_mask_usb2 (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
+{
+ int i, n, c;
+ unsigned char *d = un->desc;
+
+ n = 4;
+ d = d + 5 + n; // Skip the global mask
+
+/*
+ * USB 2.0 uses 2 bits for each control
+ * 01b means that the control is read only and 11b means it's RW
+ */
+ for (c = 0; c < un->channels; c++)
+ {
+ unsigned int mask;
+ unsigned char *p = d + c * n;
+
+ mask = p[3] |
+ (p[2] << 8) |
+ (p[1] << 16) |
+ (p[0] << 24);
+
+ for (i = 0; i < n * 4; i++)
+ if ((mask & (3 << 2*i)) && (un->ctl_avail & (1 << i)))
+ {
+ feature_mask[i] |= 1 << c;
+ }
+ }
+}
+
+static void
+translate_feature_mask (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
+{
+ int i, n, c;
+ unsigned char *d = un->desc;
+
+ if (devc->usb_version > 1)
+ {
+ translate_feature_mask_usb2(devc, un, feature_mask);
+ return;
+ }
+
+ n = d[5];
+ if (n < 1 || n > 2)
+ {
+ cmn_err (CE_CONT, "Bad feature mask size %d\n", n);
+ return;
+ }
+
+ d = d + 6 + n; // Skip the global mask
+
+ for (c = 0; c < un->channels; c++)
+ {
+ int mask = d[c * n];
+ if (n > 1)
+ mask |= d[c * n + 1];
+
+ for (i = 0; i < n * 8; i++)
+ if ((mask & (1 << i)) && (un->ctl_avail & (1 << i)))
+ {
+ feature_mask[i] |= 1 << c;
+ }
+ }
+}
+
+static void
+add_controls_for_feature (ossusb_devc * devc, usb_audio_unit_t * un,
+ int group)
+{
+ int i;
+ unsigned int feature_mask[16], global_mask;
+
+ if (!un->ctl_avail)
+ return;
+
+// Handle the global controls first
+
+ global_mask = un->desc[6];
+ if (un->desc[5] > 0)
+ global_mask |= un->desc[7] << 8;
+
+ for (i = 0; i < 11; i++)
+ if (un->ctl_avail & (1 << i) && (global_mask & (1 << i)))
+ {
+ char *name = get_feature_name (i);
+ int type = get_feature_type (i);
+ int max;
+ char tmp[16];
+ int ctl;
+
+ ctl = new_ctl (devc, un, i, type, 0);
+ strcpy (tmp, name);
+ if (type == MIXT_SLIDER)
+ max = devc->controls[ctl].max - devc->controls[ctl].min;
+ else
+ max = 1;
+
+ if (max > 255)
+ max = 255;
+
+ UDB (cmn_err
+ (CE_CONT, "Add (global) feature control %d:%s, max=%d\n",
+ un->num, name, max));
+ if (mixer_ext_create_control (devc->mixer_dev, group, ctl,
+ mixer_func, type, tmp, max,
+ MIXF_READABLE | MIXF_WRITEABLE) < 0)
+ return;
+ //un->ctl_avail &= ~(1 << i);
+ }
+
+// Handle the channelized controls
+
+ if (un->ctl_avail == 0) /* Nothing left */
+ return;
+
+ // Translate the channel/feature availability matrix
+
+ memset (feature_mask, 0, sizeof (feature_mask));
+ translate_feature_mask (devc, un, feature_mask);
+
+ for (i = 0; i < 16; i++)
+ if (feature_mask[i])
+ {
+ char *name = get_feature_name (i);
+ int type = get_feature_type (i);
+ int max, instances = 0;
+
+ int nc = 0, j;
+
+ for (j = 0; j < 16; j++)
+ if (feature_mask[i] & (1 << j))
+ nc = j + 1;
+
+ if (type == MIXT_SLIDER)
+ {
+ if (nc == 1)
+ {
+ type = MIXT_MONOSLIDER;
+ instances = 1;
+ }
+ else if (nc == 2)
+ {
+ type = MIXT_STEREOSLIDER;
+ instances = 1;
+ }
+ else
+ {
+ type = MIXT_MONOSLIDER;
+ if (i == 1) /* "volume" */
+ instances = nc;
+ else
+ {
+ instances = 0;
+ type = MIXT_MONOSLIDER;
+ }
+ }
+ max = 255;
+ }
+ else
+ max = 2;
+
+ if (instances && (instances > 1 || feature_mask[i] > 0x0003))
+ {
+ int g;
+ char tmp[16];
+ strcpy (tmp, name);
+ UDB (cmn_err (CE_CONT, "Add feature group %s\n", tmp));
+ if ((g =
+ mixer_ext_create_group (devc->mixer_dev, group, tmp)) < 0)
+ return;
+
+ add_multich_volumes (devc, un, g, i, feature_mask[i],
+ feature_mask);
+ }
+ else
+ {
+ char tmp[16];
+ int ctl = new_ctl (devc, un, i, type, un->chmask);
+ strcpy (tmp, name);
+ max = devc->controls[ctl].max - devc->controls[ctl].min;
+ if (max > 255)
+ max = 255;
+
+ UDB (cmn_err
+ (CE_CONT, "Add feature control %d:%s\n", un->num, name));
+ if (mixer_ext_create_control (devc->mixer_dev, group, ctl,
+ mixer_func, type, tmp, max,
+ MIXF_READABLE | MIXF_WRITEABLE) < 0)
+ return;
+ }
+ }
+
+ un->ctl_avail = 0; // All done (hope so)
+}
+
+static void
+traverse_source_controls (ossusb_devc * devc, usb_audio_unit_t * un,
+ int group)
+{
+ unsigned char *d;
+
+ d = un->desc;
+
+ if (un->typ == TY_MIXER)
+ {
+ add_controls_for_mixer (devc, un, group);
+ return;
+ }
+
+ if (un->typ == TY_PROC)
+ {
+ add_controls_for_proc (devc, un, group);
+
+ if (d[6] > 1) /* More than 1 sources */
+ return;
+ }
+
+ if (un->typ == TY_SELECT)
+ {
+ add_controls_for_selector (devc, un, group);
+ return;
+ }
+
+ if (un->source > 0 && un->source < devc->nunits)
+ {
+ traverse_source_controls (devc, &devc->units[un->source], group);
+ }
+
+ if (un->typ == TY_FEAT)
+ {
+ add_controls_for_feature (devc, un, group);
+ }
+}
+
+static void
+traverse_target_controls (ossusb_devc * devc, usb_audio_unit_t * un,
+ int group)
+{
+ unsigned char *d;
+
+
+ d = un->desc;
+
+ if (un->typ == TY_SELECT)
+ {
+ add_controls_for_selector (devc, un, group);
+ }
+
+ if (un->typ == TY_PROC || un->typ == TY_EXT)
+ if (d[6] > 1) // More than 1 input pins
+ return;
+
+ if (un->typ == TY_MIXER)
+ {
+#if 1
+ add_controls_for_mixer (devc, un, group);
+#endif
+ }
+
+ if (un->target > 0 && un->target < devc->nunits)
+ traverse_target_controls (devc, &devc->units[un->target], group);
+
+ if (un->typ == TY_FEAT)
+ {
+ add_controls_for_feature (devc, un, group);
+ }
+}
+
+void
+ossusb_create_altset_control (int dev, int portc_num, int nalt, char *name)
+{
+ int ctl;
+ ossusb_devc *devc = mixer_devs[dev]->devc;
+ char *as = NULL;
+ int default_altsetting;
+ unsigned int altsetting_mask;
+
+ if (nalt < 3) /* Only one alternative setting (plus "OFF") available */
+ return;
+ if ((as =
+ udi_usbdev_get_altsetting_labels (devc->mixer_usbdev, portc_num,
+ &default_altsetting,
+ &altsetting_mask)) != NULL)
+ {
+ if (altsetting_mask != 0)
+ {
+ /*
+ * Check if more than one of them are enabled.
+ */
+
+ int i, n = 0;
+
+ for (i = 1; i < nalt; i++)
+ if (altsetting_mask & (1 << i))
+ n++;
+
+ if (n < 2) /* No */
+ return;
+ }
+ }
+
+ if ((ctl = mixer_ext_create_control (dev, 0,
+ portc_num, ossusb_change_altsetting,
+ MIXT_ENUM,
+ name, nalt,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return;
+
+ if (as != NULL) /* Use custom labels */
+ {
+ mixer_ext_set_strings (dev, ctl, as, 0);
+ if (altsetting_mask != 0)
+ {
+ oss_mixext *ext;
+ int i;
+
+ ext = mixer_find_ext (dev, ctl);
+
+ memset (ext->enum_present, 0, sizeof (ext->enum_present));
+ for (i = 0; i < nalt; i++)
+ if (altsetting_mask & (1 << i))
+ ext->enum_present[i / 8] |= (1 << (i % 8));
+ }
+
+ if (default_altsetting > 0)
+ ossusb_change_altsetting (dev, portc_num, SNDCTL_MIX_WRITE,
+ default_altsetting);
+ }
+ else
+ mixer_ext_set_strings (dev, ctl,
+ "OFF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19",
+ 0);
+
+}
+
+static int
+usb_mix_init (int dev)
+{
+ ossusb_devc *devc;
+ int i, group;
+
+ devc = mixer_devs[dev]->devc;
+
+ for (i = 0; i < devc->nunits; i++)
+ {
+ usb_audio_unit_t *un = &devc->units[i];
+
+ if (un->typ == TY_OUTPUT)
+ {
+ if (count_source_controls (devc, un->source) == 0)
+ {
+ continue;
+ }
+
+ if ((group = mixer_ext_create_group (dev, 0, un->name)) < 0)
+ return group;
+
+ traverse_source_controls (devc, un, group);
+ continue;
+ }
+ }
+
+ for (i = 0; i < devc->nunits; i++)
+ {
+ usb_audio_unit_t *un = &devc->units[i];
+
+ if (un->typ == TY_INPUT)
+ {
+ if (count_target_controls (devc, un->target) == 0)
+ {
+ continue;
+ }
+
+ if ((group = mixer_ext_create_group (dev, 0, un->name)) < 0)
+ return group;
+
+ traverse_target_controls (devc, un, group);
+ un->ctl_avail = 0;
+ continue;
+ }
+ }
+
+ return 0;
+}
+
+static char *
+check_feature (usb_audio_unit_t * un, unsigned char *mask, int n)
+{
+ if (mask[n / 8] & (1 << (n % 8)))
+ {
+ un->control_count++;
+
+ return get_feature_name (n);
+ }
+
+ return NULL;
+}
+
+/*ARGSUSED*/
+static int
+usb_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ ossusb_devc *devc = mixer_devs[dev]->hw_devc;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ switch (cmd)
+ {
+ case SOUND_MIXER_READ_DEVMASK:
+ return *arg = devc->devmask | devc->recmask;
+ case SOUND_MIXER_READ_RECMASK:
+ return *arg = devc->recmask;
+ case SOUND_MIXER_READ_RECSRC:
+ return *arg = devc->recsrc;
+ case SOUND_MIXER_READ_STEREODEVS:
+ return *arg = devc->stereodevs;
+ }
+
+ return *arg = 0;
+}
+
+static mixer_driver_t usb_mixer_driver = {
+ usb_mixer_ioctl
+};
+
+static int
+init_mixer (ossusb_devc * devc)
+{
+ if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ devc->dev_name,
+ &usb_mixer_driver,
+ sizeof (mixer_driver_t),
+ devc)) >= 0)
+ {
+ char mxname[20];
+
+ sprintf (mxname, "USB_%d", ndevs);
+
+ devc->levels = load_mixer_volumes (mxname, NULL, 1);
+ mixer_devs[devc->mixer_dev]->hw_devc = devc;
+ mixer_ext_set_init_fn (devc->mixer_dev, usb_mix_init, MAX_CONTROLS);
+ }
+
+ return 1;
+}
+
+static usb_audio_unit_t *
+setup_unit (ossusb_devc * devc, int unit, char *name, unsigned char *desc,
+ int desclen, int typ)
+{
+ usb_audio_unit_t *un;
+
+ if (unit < 0 || unit >= MAX_UNIT)
+ {
+ cmn_err (CE_WARN, "Bad unit number %d\n", unit);
+ return NULL;
+ }
+
+ if (typ >= sizeof (devc->unit_counters))
+ {
+ cmn_err (CE_WARN, "Bad unit type %d\n", typ);
+ return NULL;
+ }
+
+ devc->unit_counters[typ]++;
+
+ if (unit >= devc->nunits)
+ devc->nunits = unit + 1;
+
+ un = &devc->units[unit];
+
+ un->num = unit;
+ un->typ = typ;
+ un->desc = desc;
+ un->desclen = desclen;
+ un->mixnum = -1;
+ un->channels = 2;
+ un->chmask = 0x03;
+ strcpy (un->name, name);
+
+ return un;
+}
+
+static char *
+get_terminal_id (int type, char *def, int typ, int *mn)
+{
+ int dummy, *mixnum;
+
+ if (mn != NULL)
+ mixnum = mn;
+ else
+ mixnum = &dummy;
+ switch (type)
+ {
+ case 0x0101:
+ if (typ == TY_INPUT)
+ {
+ *mixnum = SOUND_MIXER_PCM;
+ return "play";
+ }
+ if (typ == TY_OUTPUT)
+ {
+ *mixnum = SOUND_MIXER_RECLEV;
+ return "rec";
+ }
+ break;
+ case 0x0301:
+ *mixnum = SOUND_MIXER_VOLUME;
+ return "output";
+ case 0x0302:
+ *mixnum = SOUND_MIXER_VOLUME;
+ return "headph";
+ case 0x0307:
+ return "LFE";
+
+ case 0x0401:
+ return "handset";
+ case 0x0402:
+ return "headset";
+
+ case 0x0403:
+ case 0x0404:
+ case 0x0405:
+ case 0x0500:
+ case 0x0501:
+ case 0x0502:
+ case 0x0504:
+ return "phone";
+ break;
+
+ case 0x0600:
+ *mixnum = SOUND_MIXER_LINE1;
+ return "aux";
+ case 0x0601:
+ *mixnum = SOUND_MIXER_LINE2;
+ return "aux";
+ case 0x0602:
+ return "digital";
+ case 0x0603:
+ *mixnum = SOUND_MIXER_LINE;
+ return "line";
+ case 0x0604:
+ *mixnum = SOUND_MIXER_SPEAKER;
+ return "pc_in";
+ case 0x0605:
+ *mixnum = SOUND_MIXER_DIGITAL1;
+ if (typ == TY_INPUT)
+ return "spdin";
+ else
+ return "spdout";
+ case 0x0606:
+ return "da_stream";
+ case 0x0607:
+ return "DV_audio";
+
+ case 0x0701:
+ return "noise";
+ case 0x0702:
+ return "eq_noise";
+ case 0x0703:
+ *mixnum = SOUND_MIXER_CD;
+ return "cd";
+ case 0x0704:
+ return "dat";
+ case 0x0706:
+ return "md";
+ case 0x0707:
+ return "tape";
+ case 0x0708:
+ return "phono";
+ case 0x0709:
+ *mixnum = SOUND_MIXER_VIDEO;
+ return "vcr";
+ case 0x070b:
+ return "dvd";
+ case 0x070c:
+ return "tv";
+ case 0x070d:
+ return "sat";
+ case 0x070e:
+ return "cable";
+ case 0x0710:
+ *mixnum = SOUND_MIXER_RADIO;
+ return "radio";
+ case 0x0711:
+ *mixnum = SOUND_MIXER_RADIO;
+ return "xmitter";
+ case 0x0712:
+ return "mtrack";
+ case 0x0713:
+ *mixnum = SOUND_MIXER_SYNTH;
+ return "synth";
+ }
+
+ if (type < 0x201) // Unknown type
+ return def;
+
+ if (type < 0x300)
+ {
+ *mixnum = SOUND_MIXER_MIC;
+ return "mic";
+ }
+
+ return def;
+}
+
+static void
+setup_legacy_mixer (ossusb_devc * devc)
+{
+ int x;
+
+// Set up the recording selector
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int i, n;
+ unsigned char *d = un->desc;
+
+ if (un->typ != TY_SELECT || strcmp (un->name, "rec.src") != 0)
+ continue;
+
+ if (!un->ctl_avail)
+ continue;
+
+ devc->rec_unit = x;
+ un->ctl_avail = 0;
+
+ devc->num_recdevs = n = d[4];
+ d += 5;
+ for (i = 0; i < n; i++)
+ {
+ int ref = follow_source_links (devc, &devc->units[*d]);
+ int mask;
+
+ d++;
+
+ if (ref < 1 || ref >= devc->nunits || devc->units[ref].mixnum == -1)
+ continue;
+
+ mask = (1 << devc->units[ref].mixnum);
+ if (devc->recmask & mask) // Duplicate
+ continue;
+ UDB (cmn_err
+ (CE_CONT, "Recsrc %d, num=%d, mask %x\n", i, ref, mask));
+
+ devc->recdevs[i] = mask;
+
+ devc->recmask |= mask;
+ if (devc->recsrc == 0)
+ devc->recsrc = mask;
+ }
+
+ break;
+ }
+
+// Set up the legacy mixer controls
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int mixnum;
+ unsigned char *d = un->desc;
+
+ if (!(un->ctl_avail & 0x02))
+ continue;
+
+ if (un->typ == TY_FEAT && d[6] & 0x02) // Volume control
+ {
+ int t;
+ mixnum = un->mixnum;
+
+ if (mixnum == -1)
+ {
+ t = follow_target_links (devc, un);
+ if (t && devc->units[t].mixnum != -1)
+ mixnum = devc->units[t].mixnum;
+ else
+ {
+ t = follow_source_links (devc, un);
+ if (t && devc->units[t].mixnum != -1)
+ mixnum = devc->units[t].mixnum;
+ }
+ }
+
+ if (mixnum == -1 || un->channels > 2)
+ continue;
+ UDB (cmn_err (CE_CONT, "Unit %d is volume %d\n", x, mixnum));
+ un->ctl_avail &= ~0x02; // Reserve the volume slider
+
+ devc->devmask |= (1 << mixnum);
+ if (un->channels == 2)
+ devc->stereodevs |= (1 << mixnum);
+
+ continue;
+ }
+ }
+
+}
+
+static char *
+get_processor_type (int t)
+{
+ switch (t)
+ {
+ case 0x01:
+ return "upmix";
+ case 0x02:
+ return "prologic";
+ case 0x03:
+ return "3D";
+ case 0x04:
+ return "reverb";
+ case 0x05:
+ return "chorus";
+ case 0x06:
+ return "compress";
+ default:
+ return "proc";
+ }
+}
+
+static void
+parse_processing_unit (ossusb_devc * devc, unsigned char *d, int l)
+{
+ usb_audio_unit_t *un;
+ char *name;
+
+ name = get_processor_type (d[4]);
+
+ if ((un = setup_unit (devc, d[3], name, d, l, TY_PROC)) == NULL)
+ return;
+ un->subtyp = d[4];
+ un->ctl_avail = 1;
+
+ if (un->subtyp == 1) // Upmix/downmix unit
+ {
+ un->channels = d[8];
+ un->chmask = ossusb_get_int (&d[9], 2);
+ }
+}
+
+static int
+get_feature_mask (unsigned char *d, int channels)
+{
+ int i, n, mask = 0, v;
+ n = d[5];
+
+ for (i = 0; i <= channels; i++)
+ {
+ v = d[6 + i * n];
+ if (n > 1)
+ v |= d[6 + i * n + 1] << 8;
+
+ mask |= v;
+ }
+
+ return mask;
+}
+
+#if 1
+static void
+mixer_dump (ossusb_devc * devc)
+{
+ int i, j, c;
+ usb_audio_unit_t *un;
+
+ for (i = 1; i < devc->nunits; i++)
+ {
+ un = &devc->units[i];
+
+ if (un->typ == TY_FEAT)
+ {
+ cmn_err (CE_CONT, "Unit %d\n", un->num);
+
+ for (j = 0; j < 8; j++)
+ {
+ for (c = 0; c < 7; c++)
+ {
+ unsigned char buf[2];
+ int len;
+
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((j) << 8) | (c), // value
+ (un->num << 8), // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+
+ if (len < 0)
+ continue;
+ cmn_err (CE_CONT, " Feature %d/%d, ch %d: ", un->num, j,
+ c);
+ cmn_err (CE_CONT, "%02x%02x ", buf[0], buf[1]);
+
+ if (len == 1)
+ cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
+ else
+ cmn_err (CE_CONT, "(%d) ",
+ (signed short) (buf[0] | (buf[1] << 8)));
+
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((j) << 8) | (c), // value
+ (un->num << 8), // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+
+ if (len >= 0)
+ cmn_err (CE_CONT, "Min=%02x%02x ", buf[0], buf[1]);
+ if (len == 1)
+ cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
+ else if (len == 2)
+ cmn_err (CE_CONT, "(%d) ",
+ (signed short) (buf[0] | (buf[1] << 8)));
+
+ buf[0] = buf[1] = 0;
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS, // rqtype
+ ((j) << 8) | (c), // value
+ (un->num << 8), // index
+ buf, // buffer
+ 2, // buflen
+ OSS_HZ * 2);
+
+ if (len >= 0)
+ cmn_err (CE_CONT, "max=%02x%02x ", buf[0], buf[1]);
+ if (len == 1)
+ cmn_err (CE_CONT, "(%d) ", (signed char) buf[0]);
+ else if (len == 2)
+ cmn_err (CE_CONT, "(%d) ",
+ (signed short) (buf[0] | (buf[1] << 8)));
+
+ cmn_err (CE_CONT, "\n");
+ }
+ }
+ }
+ }
+}
+#endif
+
+/*ARGSUSED*/
+static ossusb_devc *
+ossusb_init_audioctl (ossusb_devc * devc, udi_usb_devc * usbdev, int inum,
+ int reinit)
+{
+ int desc_len;
+ unsigned char *desc, *d;
+ int i, l, n = 0, p, x, mixnum = -1;
+ char *name;
+ usb_audio_unit_t *un;
+
+ /* nsettings = udi_usbdev_get_num_altsettings (usbdev); */
+ devc->mixer_usbdev = usbdev;
+
+ if (!init_mixer (devc))
+ return NULL;
+
+ desc = udi_usbdev_get_altsetting (usbdev, 0, &desc_len);
+
+ if (desc == NULL)
+ {
+ cmn_err (CE_CONT, "Can't read interface descriptors\n");
+ return NULL;
+ }
+
+ p = 0;
+ while (p < desc_len)
+ {
+ d = desc + p;
+
+ l = *d;
+ if (usb_trace > 1)
+ {
+ char str[256], *s = str;
+ sprintf (s, "Control desc(%d): ", p);
+ s += strlen (s);
+ for (i = 0; i < l; i++)
+ {
+ sprintf (s, "%02x ", d[i]);
+ s += strlen (s);
+ }
+ cmn_err (CE_CONT, "%s\n", str);
+ }
+
+#define CASE(x) case x:cmn_err(CE_CONT, #x "\n"); break;
+
+ if (d[1] == CS_INTERFACE)
+ switch (d[2])
+ {
+ case AC_HEADER:
+ if (usb_trace)
+ {
+ cmn_err (CE_CONT, " Audio control interface header\n");
+ n = d[7];
+ cmn_err (CE_CONT, " %d related streaming interfaces: ",
+ n);
+ for (i = 0; i < n; i++)
+ {
+ cmn_err (CE_CONT, "%d ", d[8 + i]);
+ }
+ cmn_err (CE_CONT, "\n");
+ }
+ break;
+
+ case AC_INPUT_TERMINAL:
+ name =
+ get_terminal_id (ossusb_get_int (&d[4], 2), "in", TY_INPUT,
+ &mixnum);
+ if ((un = setup_unit (devc, d[3], name, d, l, TY_INPUT)) == NULL)
+ return NULL;
+ un->mixnum = mixnum;
+ un->channels = d[7];
+ un->chmask = ossusb_get_int (&d[8], 2);
+ break;
+
+ case AC_OUTPUT_TERMINAL:
+ name =
+ get_terminal_id (ossusb_get_int (&d[4], 2), "out", TY_OUTPUT,
+ &mixnum);
+ if ((un = setup_unit (devc, d[3], name, d, l, TY_OUTPUT)) == NULL)
+ return NULL;
+ un->mixnum = mixnum;
+ break;
+
+ case AC_MIXER_UNIT:
+ if ((un = setup_unit (devc, d[3], "mix", d, l, TY_MIXER)) == NULL)
+ return NULL;
+ {
+ // Check if there are any visible controls
+
+ int mask = 0, nn;
+
+ n = d[4]; // # of input pins
+ d += 5 + n;
+ nn = *d; // # of channels
+ d += 4; // Seek to bmControls
+
+ n = (n * nn + 7) / 8;
+
+ for (i = 0; i < n; i++)
+ mask |= d[i];
+
+ un->ctl_avail = mask;
+ }
+ break;
+
+ case AC_SELECTOR_UNIT:
+ if ((un =
+ setup_unit (devc, d[3], "src", d, l, TY_SELECT)) == NULL)
+ return NULL;
+ un->ctl_avail = 1;
+ break;
+
+ case AC_FEATURE_UNIT:
+ if ((un = setup_unit (devc, d[3], "fea", d, l, TY_FEAT)) == NULL)
+ return NULL;
+ un->ctl_avail = get_feature_mask (d, 2); /* For now */
+ break;
+
+ case AC_PROCESSING_UNIT:
+ parse_processing_unit (devc, d, l);
+ break;
+
+ case AC_EXTENSION_UNIT:
+ if ((un = setup_unit (devc, d[3], "ext", d, l, TY_EXT)) == NULL)
+ return NULL;
+ un->ctl_avail = 1;
+
+ break;
+
+ }
+
+ p += l;
+ }
+
+// Make sure the unit names are unique */
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int n = 0;
+
+ if (un->typ != TY_SELECT)
+ for (i = x + 1; i < devc->nunits; i++)
+ if (strcmp (devc->units[i].name, un->name) == 0)
+ n++;
+
+ if (n > 0)
+ {
+ char tmpname[16];
+ strcpy (tmpname, un->name);
+ n = 1;
+
+ for (i = x; i < devc->nunits; i++)
+ if (strcmp (devc->units[i].name, tmpname) == 0)
+ {
+ if (n > 1)
+ sprintf (devc->units[i].name, "%s%d", tmpname, n);
+ n++;
+ }
+ }
+
+// Make sure the mixer control numbers are unique too
+
+ n = 0;
+ if (un->mixnum != -1)
+ for (i = x + 1; i < devc->nunits; i++)
+ if (devc->units[i].mixnum == un->mixnum)
+ n++;
+
+ if (n > 0)
+ for (i = x + 1; i < devc->nunits; i++)
+ if (devc->units[i].mixnum == un->mixnum)
+ {
+ usb_audio_unit_t *uu = &devc->units[i];
+
+ switch (uu->mixnum)
+ {
+ case SOUND_MIXER_PCM:
+ uu->mixnum = SOUND_MIXER_ALTPCM;
+ break;
+ case SOUND_MIXER_LINE:
+ uu->mixnum = SOUND_MIXER_LINE1;
+ break;
+ case SOUND_MIXER_LINE1:
+ uu->mixnum = SOUND_MIXER_LINE2;
+ break;
+ case SOUND_MIXER_LINE2:
+ uu->mixnum = SOUND_MIXER_LINE3;
+ break;
+ case SOUND_MIXER_DIGITAL1:
+ uu->mixnum = SOUND_MIXER_DIGITAL2;
+ break;
+ case SOUND_MIXER_DIGITAL2:
+ uu->mixnum = SOUND_MIXER_DIGITAL3;
+ break;
+ default:
+ uu->mixnum = -1;
+ }
+ }
+
+ }
+
+// Handle output selector names
+
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int n;
+
+ if (un->typ != TY_OUTPUT)
+ continue;
+
+ n = un->desc[7]; // Source ID
+ if (n < 0 || n >= devc->nunits)
+ continue;
+
+ if (devc->units[n].target == 0)
+ devc->units[n].target = x;
+
+ if (devc->units[n].typ == TY_SELECT && usb_mixerstyle == 0)
+ sprintf (devc->units[n].name, "%s.src", un->name);
+ }
+
+// Find out the sources
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+
+ d = un->desc;
+ l = un->desclen;
+
+ switch (un->typ)
+ {
+ case TY_INPUT:
+ break;
+
+ case TY_OUTPUT:
+ un->source = d[7];
+ break;
+
+ case TY_SELECT:
+ un->source = d[5];
+ n = d[4];
+ for (i = 0; i < n; i++)
+ if (d[i + 5] > 0 && d[i + 5] <= devc->nunits)
+ if (devc->units[d[i + 5]].target == 0)
+ devc->units[d[i + 5]].target = x;
+ break;
+
+ case TY_MIXER:
+ n = d[4];
+ un->control_count = n;
+ un->source = d[5];
+ for (i = 0; i < n; i++)
+ if (d[i + 5] > 0 && d[i + 5] <= devc->nunits)
+ if (devc->units[d[i + 5]].target == 0)
+ devc->units[d[i + 5]].target = x;
+
+ d += n + 5;
+ un->channels = *d++;
+ un->chmask = ossusb_get_int (d, 2);
+ break;
+
+ case TY_FEAT:
+ un->source = d[4];
+ if (d[4] > 0 && d[4] <= devc->nunits)
+ if (devc->units[d[4]].target == 0)
+ devc->units[d[4]].target = x;
+ break;
+
+ //case TY_EXT:
+ case TY_PROC:
+ n = d[6];
+ un->source = d[7];
+ for (i = 0; i < n; i++)
+ if (d[i + 7] > 0 && d[i + 7] <= devc->nunits)
+ if (devc->units[d[i + 7]].target == 0)
+ devc->units[d[i + 7]].target = x;
+ break;
+ }
+ }
+
+// Trace the channel config
+
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x], *uu;
+ int ref;
+
+ if (un->typ == TY_INPUT || un->typ == TY_MIXER)
+ continue;
+
+ if (un->typ == TY_PROC && un->subtyp == 1) // Upmix/downmix unit
+ continue;
+
+ ref = follow_source_links (devc, un);
+ uu = &devc->units[ref];
+
+ un->channels = uu->channels;
+ un->chmask = uu->chmask;
+ }
+
+// Handle feature channels
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+
+ if (un->num == 0 || un->typ != TY_FEAT)
+ continue;
+
+ d = un->desc;
+ l = un->desclen;
+
+ un->ctl_avail = get_feature_mask (d, un->channels);
+ }
+
+// Final checks
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int j;
+
+ if (un->num == 0)
+ {
+ //cmn_err(CE_CONT, "Skipped undefined control %d\n", x);
+ continue;
+ }
+ d = un->desc;
+ l = un->desclen;
+
+ switch (un->typ)
+ {
+ case TY_SELECT:
+ n = d[4];
+ un->control_count = n;
+ d += 5;
+ break;
+
+ case TY_MIXER:
+ n = d[4];
+ un->control_count = n;
+ d += 5;
+ break;
+
+ case TY_FEAT:
+ n = d[5];
+ d += 6;
+ for (i = 0; i < n * 8; i++)
+ name = check_feature (un, d, i);
+ for (j = 1; j <= un->channels; j++)
+ {
+ for (i = 0; i < n * 8; i++)
+ name = check_feature (un, d + j * n, i);
+ }
+ break;
+
+ }
+ }
+
+#if 0
+// Debugging
+ if (usb_trace)
+ for (x = 1; x < devc->nunits; x++)
+ {
+ usb_audio_unit_t *un = &devc->units[x];
+ int j;
+ int ref = 0;
+
+ if (un->num == 0)
+ {
+ //cmn_err(CE_CONT, "Skipped undefined control %d\n", x);
+ continue;
+ }
+ d = un->desc;
+ l = un->desclen;
+ // ossusb_dump_desc (d, l);
+ cmn_err (CE_CONT, "%2d: %s ", un->num, un->name);
+ if (un->mixnum != -1)
+ cmn_err (CE_CONT, "mix=%d ", un->mixnum);
+ if (un->source)
+ cmn_err (CE_CONT, "source=%d ", un->source);
+ if (un->target)
+ cmn_err (CE_CONT, "target=%d ", un->target);
+ cmn_err (CE_CONT, "ch=%d/%x ", un->channels, un->chmask);
+
+ switch (un->typ)
+ {
+ case TY_INPUT:
+ cmn_err (CE_CONT, "Input terminal type: %04x ",
+ ossusb_get_int (&d[4], 2));
+ cmn_err (CE_CONT, "Associated output 0x%02x ", d[6]);
+ cmn_err (CE_CONT, "#chn %d ", d[7]);
+ cmn_err (CE_CONT, "chconf %04x ", ossusb_get_int (&d[8], 2));
+ if (d[10])
+ cmn_err (CE_CONT, "chname# %d ", d[10]);
+ if (d[11])
+ cmn_err (CE_CONT, "terminalname# %d (%s) ", d[11],
+ udi_usbdev_get_string (usbdev, d[11]));
+ break;
+
+ case TY_OUTPUT:
+ cmn_err (CE_CONT, "Output terminal type: %04x ",
+ ossusb_get_int (&d[4], 2));
+ cmn_err (CE_CONT, "Associated input 0x%02x ", d[6]);
+ cmn_err (CE_CONT, "sourceid %d ", d[7]);
+ if (d[8])
+ cmn_err (CE_CONT, "terminalname# %d ", d[8]);
+ break;
+
+ case TY_SELECT:
+ n = d[4];
+ d += 5;
+ cmn_err (CE_CONT, "%d input pins (", n);
+ for (i = 0; i < n; i++)
+ {
+ ref = follow_source_links (devc, &devc->units[*d]);
+ cmn_err (CE_CONT, "%d/%s ", *d, devc->units[ref].name);
+ d++;
+ }
+ cmn_err (CE_CONT, ") ");
+ break;
+
+ case TY_MIXER:
+ n = d[4];
+ d += 5;
+ cmn_err (CE_CONT, "%d inputs (", n);
+ for (i = 0; i < n; i++)
+ {
+ ref = follow_source_links (devc, &devc->units[*d]);
+ cmn_err (CE_CONT, "%d/%s ", *d, devc->units[ref].name);
+ d++;
+ }
+ cmn_err (CE_CONT, ") ");
+ break;
+
+ case TY_FEAT:
+ //ossusb_dump_desc(d, l);
+ cmn_err (CE_CONT, "Source %d:%s ", d[4], devc->units[d[4]].name);
+ n = d[5];
+ d += 6;
+ cmn_err (CE_CONT, "main (", n);
+ for (i = 0; i < n * 8; i++)
+ if ((name = check_feature (un, d, i)) != NULL)
+ cmn_err (CE_CONT, "%s ", name);
+ cmn_err (CE_CONT, ") ");
+ for (j = 1; j <= un->channels; j++)
+ {
+ cmn_err (CE_CONT, "ch %d (", j);
+ for (i = 0; i < n * 8; i++)
+ if ((name = check_feature (un, d + j * n, i)) != NULL)
+ cmn_err (CE_CONT, "%s ", name);
+ cmn_err (CE_CONT, ") ");
+ }
+ break;
+
+ case TY_PROC:
+ cmn_err (CE_CONT, "subtype %x Sources/%d) (", un->subtyp, n);
+ n = d[6];
+ d += 7;
+ cmn_err (CE_CONT, "%d ", *d);
+ d++;
+ cmn_err (CE_CONT, ") ");
+ break;
+
+ case TY_EXT:
+ cmn_err (CE_CONT, "Extension unit %02x%02x ", d[5], d[4]);
+ break;
+
+ }
+
+ cmn_err (CE_CONT, "\n");
+ }
+#endif
+
+ if (usb_mixerstyle == 0)
+ setup_legacy_mixer (devc);
+ touch_mixer (devc->mixer_dev);
+
+ if (usb_trace)
+ mixer_dump (devc);
+
+ return devc;
+}
+
+static ossusb_devc *
+find_devc (char *devpath, int vendor, int product)
+{
+ int i;
+
+ for (i = 0; i < ndevs; i++)
+ {
+ if (devc_list[i]->vendor == vendor && devc_list[i]->product == product)
+ if (strcmp (devc_list[i]->devpath, devpath) == 0)
+ {
+ UDB (cmn_err (CE_CONT, "Another instance of '%s'\n", devpath));
+ return devc_list[i];
+ }
+ }
+
+ return NULL;
+}
+
+static void
+ossusb_device_disconnect (void *d)
+{
+ ossusb_devc *devc = d;
+ int i;
+
+ if (devc == NULL)
+ {
+ cmn_err (CE_WARN, "oss_usb_device_disconnect: devc==NULL\n");
+ return;
+ }
+
+ if (devc->unload_func)
+ {
+ devc->unload_func (devc);
+ return;
+ }
+
+ devc->disabled = 1;
+
+ for (i = 0; i < devc->num_audio_engines; i++)
+ {
+ int dev;
+
+ dev = devc->portc[i].audio_dev;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ continue;
+
+ audio_engines[dev]->enabled = 0;
+
+ if (devc->mixer_dev >= 0)
+ mixer_devs[devc->mixer_dev]->enabled = 0;
+ }
+
+}
+
+static void *
+ossusb_device_attach (udi_usb_devc * usbdev, oss_device_t * osdev)
+{
+ ossusb_devc *devc;
+ char *devpath;
+ int inum;
+ int old = 1;
+ int i;
+ int class, subclass;
+ int vendor, product, version;
+
+ devpath = udi_usbdev_get_devpath (usbdev);
+ inum = udi_usbdev_get_inum (usbdev);
+ class = udi_usbdev_get_class (usbdev);
+ subclass = udi_usbdev_get_subclass (usbdev);
+ vendor = udi_usbdev_get_vendor (usbdev);
+ product = udi_usbdev_get_product (usbdev);
+ version = udi_usbdev_get_usb_version (usbdev);
+
+ if ((devc = find_devc (devpath, vendor, product)) == NULL)
+ {
+ old = 0;
+
+ if (ndevs >= MAX_DEVC)
+ {
+ cmn_err (CE_CONT, "Too many USB audio devices\n");
+ return NULL;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_CONT, "Out of memory\n");
+ return NULL;
+ }
+ memset (devc, 0, sizeof (*devc));
+ devc->mixer_dev = -1;
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+
+ devc->vendor = vendor;
+ devc->product = product;
+ devc->usb_version = version;
+ devc->dev_name = udi_usbdev_get_name (usbdev);
+
+ strcpy (devc->devpath, udi_usbdev_get_devpath (usbdev));
+
+ devc_list[ndevs++] = devc;
+ }
+ else
+ {
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ }
+
+ if (devc->dev_name == NULL)
+ devc->dev_name = "Generic USB device";
+ oss_register_device (osdev, devc->dev_name);
+
+ devc->disabled = 0;
+
+ if (old)
+ {
+ /* Check if this interface number is already seen */
+ old = 0;
+ for (i = 0; !old && i < devc->num_interfaces; i++)
+ if (devc->inum[i] == inum)
+ old = 1;
+ }
+
+ if (!old)
+ {
+ if (devc->num_interfaces >= MAX_IFACE)
+ {
+ cmn_err (CE_CONT, "The device has too many interfaces\n");
+ return NULL;
+ }
+
+ devc->usbdev[devc->num_interfaces] = usbdev;
+ devc->last_usbdev = usbdev;
+ devc->inum[devc->num_interfaces] = inum;
+ devc->num_interfaces++;
+ }
+ else
+ {
+ devc->last_usbdev = usbdev;
+ }
+
+ switch (class)
+ {
+ case USBCLASS_AUDIO:
+ switch (subclass)
+ {
+ case 1: /* Audiocontrol subclass */
+ devc->main_osdev = osdev;
+ if (!usb_quiet)
+ cmn_err (CE_CONT, "%s audioctl device %s/%d - %s\n",
+ old ? "Reinsert of an" : "New",
+ devc->devpath, inum, devc->dev_name);
+ return ossusb_init_audioctl (devc, usbdev, inum, old);
+ break;
+
+ case 2: /* Audio streaming subclass */
+ if (!usb_quiet)
+ cmn_err (CE_CONT, "%s audio streaming device %s/%d - %s\n",
+ old ? "Reinsert of an" : "New",
+ devc->devpath, inum, devc->dev_name);
+ devc->osdev->first_mixer = devc->main_osdev->first_mixer;
+ return ossusb_init_audiostream (devc, usbdev, inum, old);
+ break;
+
+ case 3: /* MIDI streaming subclass */
+ return NULL;
+ break;
+
+ default:
+ cmn_err (CE_CONT,
+ "Unknown USB audio device subclass %x:%d, device=%s\n",
+ class, subclass, devc->dev_name);
+ return NULL;
+ }
+ break;
+
+#if 0
+ case USBCLASS_HID:
+ cmn_err (CE_CONT, "HID interface class %x:%d, device=%s\n",
+ class, subclass, devc->dev_name);
+ return NULL;
+ break;
+#endif
+
+ default:
+ cmn_err (CE_CONT, "Unknown USB device class %x:%d, device=%s\n",
+ class, subclass, devc->dev_name);
+ }
+
+ return devc;
+}
+
+static udi_usb_driver ossusb_driver = {
+ ossusb_device_attach,
+ ossusb_device_disconnect
+};
+
+int
+oss_usb_attach (oss_device_t * osdev)
+{
+ if (usb_trace < 0)
+ {
+ udi_usb_trace = 0;
+ usb_trace = 0;
+ usb_quiet = 1;
+ }
+ else if (usb_trace > 0)
+ udi_usb_trace = usb_trace;
+
+ return udi_attach_usbdriver (osdev, known_devices, &ossusb_driver);
+}
+
+int
+oss_usb_detach (oss_device_t * osdev)
+{
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ udi_unload_usbdriver (osdev);
+ oss_unregister_device (osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_usb/oss_usb.man b/kernel/drv/oss_usb/oss_usb.man
new file mode 100644
index 0000000..556e4de
--- /dev/null
+++ b/kernel/drv/oss_usb/oss_usb.man
@@ -0,0 +1,56 @@
+NAME
+ oss_usb - USB Audio/MIDI/Mixer driver
+
+DESCRIPTION
+ The Open Sound System driver for USB Audio and MIDI devices.
+
+ AUDIO
+ The Audio driver supports:
+
+ o 8-96Khz Playback/Recording
+ o 8 or 16 or 32 bits
+ o 2, 4, 6 or 8 channel audio.
+ o SPDIF digital output and Input
+ o AC3 passthrough
+ o Volume control and device input mixer
+
+ MIDI
+The oss_usb driver supports all MIDI devices that are compatible with the
+official USB MIDI specification. In addition the driver supports few devices
+that use their own private protocol (including some Yamaha and Midiman models).
+
+ USB MIXER
+ The USB Audio mixer is a new type of mixer that doesn't have
+ the normal volume controls found on AC97 or Legacy SB devices.
+ The USB audio mixer provides control for selecting the Alternate
+ device setting - this usually allows the device to be switched
+ into a Professional audio mode (eg 24bit or 96Khz mode)
+
+ ALTERNATIVE SETTINGS
+ Some USB audio devices use a feature called as alternative settings for
+ bandwidth management. Typically such devices have multiple high speed
+ inputs and outputs that may require more bandwidth than provided by the USB
+ bus. The alternative settings feature is used to select between multiple
+ low speed devices or just few high speed devices.
+
+ When the device has multiple alternative settings an "altsetting" selector
+ will be visible in the control panel for the device (use ossmix(1) or
+ ossxmix(1) to change it). Alternative setting OFF means that all
+ audio devices are disabled. The other settings provide different combinations
+ of high/medium speed devices. You can use the ossinfo(1) command
+ (ossinfo -a -v3) to find out the devices supported by the currently selected
+ alternative settings and the capabilities of them.
+
+KNOWN BUGS
+ Under Linux it is necessary to run the ossdetect -d and ossdevlinks commands
+ after an USB device has been hot-plugged. Alternatively you can execute
+ soundoff and soundon to reload OSS.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_usb.conf Device configuration file
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_usb/ossusb.h b/kernel/drv/oss_usb/ossusb.h
new file mode 100644
index 0000000..df28418
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb.h
@@ -0,0 +1,246 @@
+/*
+ * Purpose: Definitions for the USB audio driver files
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 __OSUSB_H_
+#define __OSUSB_H_
+
+#include "udi.h"
+#include "midi_core.h"
+
+#define CS_DEVICE 0x21
+#define CS_CONFIG 0x22
+#define CS_STRING 0x23
+#define CS_INTERFACE 0x24
+#define CS_ENDPOINT 0x25
+
+#define AC_HEADER 0x01
+#define AC_INPUT_TERMINAL 0x02
+#define AC_OUTPUT_TERMINAL 0x03
+#define AC_MIXER_UNIT 0x04
+#define AC_SELECTOR_UNIT 0x05
+#define AC_FEATURE_UNIT 0x06
+#define AC_PROCESSING_UNIT 0x07
+#define AC_EXTENSION_UNIT 0x08
+
+#define AS_GENERAL 0x01
+#define AS_FORMAT_TYPE 0x02
+#define AS_FORMAT_SPECIFIC 0x03
+
+#define SET_CUR 0x01
+#define SET_MEM 0x05
+#define GET_CUR 0x81
+#define GET_MIN 0x82
+#define GET_MAX 0x83
+#define GET_RES 0x84
+#define GET_MEM 0x85
+#define GET_STAT 0xff
+
+#define USB_RECIP_MASK 0x1f
+#define USB_RECIP_DEVICE 0x00
+#define USB_RECIP_INTERFACE 0x01
+#define USB_RECIP_ENDPOINT 0x02
+#define USB_RECIP_OTHER 0x03
+#define USB_VENDOR_REQUEST 0x40
+
+#define USB_TYPE_CLASS 0x20
+
+/*
+ * Unit types
+ *
+ * Note that TY_OUTPUT is actually PCM input and TY_INPUT is actually
+ * PCM output. Unit types are defined as seen as the USB control interface.
+ * Input terminals listen to the output streaming interfases and output
+ * terminals feed the input streaming interfaces. Confusing it is.
+ */
+#define TY_INPUT 0
+#define TY_OUTPUT 1
+#define TY_MIXER 2
+#define TY_SELECT 3
+#define TY_FEAT 4
+#define TY_PROC 5
+#define TY_EXT 6
+// Remember to inclease size of devc->unit_counters[] if adding more unit types
+
+#define USBCLASS_AUDIO 1
+#define USBCLASS_HID 3
+
+#define MAX_IFACE 10
+
+typedef struct
+{
+ int num;
+ int typ; // TY_*
+ int subtyp;
+ char name[16];
+ unsigned char *desc;
+ int desclen;
+ int mixnum;
+ int target;
+ int source;
+ int ctl_avail;
+ int control_count;
+ int channels;
+ int chmask;
+} usb_audio_unit_t;
+
+#define MAX_UNIT 40
+#define MAX_CONTROLS 100
+#define MAX_PORTC 8 /* Max audio streaming interfaces per device */
+#define MAX_MIDIC 16 /* Max MIDI streaming interfaces per device */
+
+typedef struct
+{
+ usb_audio_unit_t *unit;
+ int index;
+ int flags;
+ int min_ch, max_ch;
+ int global;
+ int chmask;
+ int value;
+ int min, max, scale;
+ int exttype;
+} usb_control_t;
+
+typedef struct ossusb_devc ossusb_devc;
+
+typedef struct
+{
+ ossusb_devc *devc;
+ int disabled;
+ int if_number;
+ void *endpoint_desc, *orig_endpoint_desc;
+ udi_endpoint_handle_t *endpoint_handle;
+ int audio_dev;
+ int open_mode;
+ int permitted_modes;
+ int prepared_modes;
+ int stopping;
+
+ int speed;
+ int bytes_per_sample;
+ int terminal_link;
+ udi_usb_devc *usbdev;
+ int num_settings;
+ int act_setting;
+
+#define NR_DATAPIPES 2
+ udi_usb_request_t *datapipe[NR_DATAPIPES];
+ int curr_datapipe;
+ int fragment_size; /* Bytes per (1ms) USB tick */
+ int overflow_samples, overflow_size;
+ int convert_3byte;
+ int pipeline_delay;
+ unsigned char *tmp_buf[2];
+ int use_tmpbuf;
+ oss_dma_handle_t tmpbuf_dma_handle[2];
+} ossusb_portc;
+
+typedef struct
+{
+ struct ossusb_devc *devc;
+ oss_device_t *osdev;
+ udi_usb_devc *usbdev;
+
+ void *in_endpoint_desc, *out_endpoint_desc;
+ udi_endpoint_handle_t *in_endpoint_handle, *out_endpoint_handle;
+ int portnum;
+ int midi_dev;
+ int open_mode;
+ // int output_endpoint;
+ oss_midi_inputbyte_t midi_input_intr;
+ oss_midi_outputintr_t midi_output_intr;
+} ossusb_midic;
+
+typedef void *(*special_driver_t) (ossusb_devc * devc);
+typedef void (*special_unload_t) (void *devc);
+
+struct ossusb_devc
+{
+ special_unload_t unload_func;
+ oss_device_t *osdev;
+ oss_device_t *main_osdev;
+ oss_mutex_t mutex;
+ int num_interfaces;
+ udi_usb_devc *usbdev[MAX_IFACE], *last_usbdev;
+ int inum[MAX_IFACE];
+ int vendor, product;
+ char *dev_name, devpath[32];
+ int nports;
+ int disabled;
+ int usb_version; // 1 or 2
+
+ /*
+ * Units
+ */
+
+ usb_audio_unit_t units[MAX_UNIT];
+ int nunits;
+ char unit_counters[7]; // For TY_* identifiers
+
+ /*
+ * Mixer stuff
+ */
+ int mixer_dev;
+ void *mixer_usbdev;
+ int devmask, recmask, stereodevs, recsrc;
+
+ int rec_unit;
+ int num_recdevs;
+ int recdevs[32];
+
+ int *levels;
+
+ usb_control_t controls[MAX_CONTROLS];
+ int ncontrols;
+
+/* Audio stuff */
+ int num_audio_engines, num_inputs, num_outputs;
+ ossusb_portc portc[MAX_PORTC];
+
+/* MIDI stuff */
+ int num_mididevs;
+ ossusb_midic midic[MAX_MIDIC];
+
+ unsigned char *playbuf;
+ oss_dma_handle_t playbuf_dma_handle;
+ udi_usb_request_t *output_pipe;
+ int output_busy;
+#define Q_MAX 4096
+ unsigned char queue[Q_MAX];
+ int q_nbytes;
+
+ unsigned char *recbuf;
+ oss_dma_handle_t recbuf_dma_handle;
+ udi_usb_request_t *input_pipe;
+ udi_endpoint_handle_t *input_endpoint_handle;
+};
+
+extern int usb_trace, usb_quiet;
+
+#define UDB(x) {if (usb_trace) x;}
+
+extern ossusb_devc *ossusb_init_audiostream (ossusb_devc * devc,
+ udi_usb_devc * usbdev, int inum,
+ int reinit);
+extern ossusb_devc *ossusb_init_midistream (ossusb_devc * devc,
+ udi_usb_devc * usbdev, int inum,
+ int reinit);
+extern void ossusb_disconnect_midistream (ossusb_devc * devc);
+extern void ossusb_dump_desc (unsigned char *desc, int cfg_len);
+extern unsigned int ossusb_get_int (unsigned char *p, int nbytes);
+extern int ossusb_change_altsetting (int dev, int ctrl, unsigned int cmd,
+ int value);
+extern void ossusb_create_altset_control(int dev, int portc_num, int nalt, char *name);
+#endif
diff --git a/kernel/drv/oss_usb/ossusb_audio.c b/kernel/drv/oss_usb/ossusb_audio.c
new file mode 100644
index 0000000..8135d62
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb_audio.c
@@ -0,0 +1,1425 @@
+/*
+ * Purpose: USB audio streaming interface support
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "ossusb.h"
+
+#define SAMPLING_FREQ_CONTROL 0x01
+#define PITCH_CONTROL 0x02
+
+#define FORMAT_II_UNDEFINED 0x1000
+#define FORMAT_II_MPEG 0x1001
+#define FORMAT_II_AC3 0x1002
+
+#define TMPBUF_SIZE 4096
+
+#if 0
+static int
+read_control_value (ossusb_devc * devc, int endpoint, int ctl, int l)
+{
+ unsigned char buf[4];
+ int len, i, v;
+
+ memset (buf, 0, sizeof (buf));
+
+ len = udi_usb_rcv_control_msg (devc->mixer_usbdev, 0, // endpoint
+ GET_CUR, USB_RECIP_ENDPOINT | USB_TYPE_CLASS, // rqtype
+ ctl << 8, // value
+ endpoint, // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ);
+ if (len < 0)
+ {
+ cmn_err (CE_WARN, "Endpoint read error %d\n", len);
+ return 0;
+ }
+
+ cmn_err (CE_CONT, "Read len %d (%d): ", len, l);
+ for (i = 0; i < len; i++)
+ cmn_err (CE_CONT, "%02x ", buf[i]);
+
+ switch (len)
+ {
+ case 3:
+ v = buf[0] | (buf[1] << 8) | (buf[2] << 16);
+ break;
+
+ default:
+ cmn_err (CE_CONT, "oss usbaudio: Bad control read (%d)\n", l);
+ }
+
+ cmn_err (CE_CONT, "= %d\n", v);
+
+ return v;
+}
+#endif
+
+static int
+write_control_value (ossusb_devc * devc, udi_endpoint_handle_t * endpoint,
+ int ctl, int l, unsigned int v)
+{
+ unsigned char buf[4];
+ int len;
+
+ memset (buf, 0, sizeof (buf));
+
+ switch (l)
+ {
+ case 3:
+ buf[0] = (v) & 0xff;
+ buf[1] = (v >> 8) & 0xff;
+ buf[2] = (v >> 16) & 0xff;
+ break;
+
+ default:
+ cmn_err (CE_CONT, "oss usbaudio: Bad control size %d\n", l);
+ return OSS_EIO;
+ }
+
+ len = udi_usb_snd_control_msg (devc->mixer_usbdev, 0, // endpoint
+ SET_CUR, USB_RECIP_ENDPOINT | USB_TYPE_CLASS, // rqtype
+ ctl << 8, // value
+ udi_endpoint_get_num (endpoint), // index
+ buf, // buffer
+ l, // buflen
+ OSS_HZ);
+ if (len < 0)
+ {
+ cmn_err (CE_WARN, "Endpoint control write error %d\n", len);
+ return OSS_EIO;
+ }
+
+ return len;
+}
+
+static void
+set_fraglimits (adev_t * adev, ossusb_portc * portc)
+{
+ int l, m;
+
+ if (portc->bytes_per_sample < 1)
+ portc->bytes_per_sample = 1;
+
+ l = portc->bytes_per_sample * adev->min_channels * portc->speed / 1000;
+ l = (l / portc->bytes_per_sample) * portc->bytes_per_sample;
+
+ m = 2;
+
+ while (m < l)
+ m *= 2;
+
+ adev->min_block = m;
+ adev->max_block = TMPBUF_SIZE / 2;
+ portc->fragment_size = l;
+}
+
+static int
+usbaudio_set_rate (int dev, int arg)
+{
+ adev_p adev = audio_engines[dev];
+ ossusb_portc *portc = adev->portc;
+ ossusb_devc *devc = adev->devc;
+
+ int i, x, diff, bestdiff;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (arg < adev->min_rate)
+ arg = adev->min_rate;
+ if (arg > adev->max_rate)
+ arg = adev->max_rate;
+
+ if (!(adev->caps & PCM_CAP_FREERATE))
+ {
+ /* Search for the nearest supported rate */
+ bestdiff = 0x7fffffff;
+ x = -1;
+
+ for (i = 0; i < adev->nrates; i++)
+ {
+ diff = arg - adev->rates[i];
+
+ if (diff < 0)
+ diff = -diff; /* ABS */
+ if (diff < bestdiff)
+ {
+ x = i;
+ bestdiff = diff;
+ }
+ }
+
+ if (x > -1)
+ arg = adev->rates[x];
+ }
+
+ portc->speed = arg;
+ set_fraglimits (adev, portc);
+
+ return portc->speed;
+}
+
+/*ARGSUSED*/
+static short
+usbaudio_set_channels (int dev, short arg)
+{
+ adev_p adev = audio_engines[dev];
+ ossusb_devc *devc = adev->devc;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ return adev->min_channels; /* max_channels should be the same too */
+}
+
+/*ARGSUSED*/
+static unsigned int
+usbaudio_set_format (int dev, unsigned int arg)
+{
+ adev_p adev = audio_engines[dev];
+ ossusb_devc *devc = adev->devc;
+
+ if (devc->disabled)
+ return adev->oformat_mask;
+
+ return adev->oformat_mask; /* iformat_mask should be the same too */
+}
+
+/*ARGSUSED*/
+static int
+usbaudio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static int
+setup_format_I (ossusb_devc * devc, ossusb_portc * portc, adev_p adev,
+ unsigned char *d, int l)
+{
+ int min_rate = 0, max_rate = 0;
+ int i, n;
+ int frame_size, bits, channels;
+ unsigned int fmt = 0;
+
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT,
+ "AS_FORMAT_TYPE: FORMAT_TYPE_I, #ch %d, framesize %d, bits %d, freq_type %02x, freq=",
+ d[4], d[5], d[6], d[7]);
+ if (d[7] == 0)
+ cmn_err (CE_CONT, "%d-%d ", ossusb_get_int (&d[8], 3),
+ ossusb_get_int (&d[11], 3));
+ {
+ for (i = 0; i < d[7]; i++)
+ cmn_err (CE_CONT, "%d ", ossusb_get_int (&d[8 + i * 3], 3));
+ cmn_err (CE_CONT, " ");
+ }
+
+ switch (d[3])
+ {
+ case 0x00:
+ cmn_err (CE_CONT, "Undefined ");
+ break;
+ case 0x01:
+ cmn_err (CE_CONT, "PCM ");
+ break;
+ case 0x02:
+ cmn_err (CE_CONT, "PCM8 ");
+ break;
+ case 0x03:
+ cmn_err (CE_CONT, "float ");
+ break;
+ case 0x04:
+ cmn_err (CE_CONT, "A-Law ");
+ break;
+ case 0x05:
+ cmn_err (CE_CONT, "u-Law ");
+ break;
+ }
+ cmn_err (CE_CONT, "\n");
+ }
+
+ channels = d[4];
+ frame_size = d[5];
+ bits = d[6];
+ UDB (cmn_err (CE_CONT, "Channels %d, bits %d (%d bytes)\n", channels, bits,
+ frame_size));
+
+ adev->min_channels = adev->max_channels = channels;
+ portc->convert_3byte = 0;
+
+ switch (d[3])
+ {
+ case 0x01:
+ fmt = AFMT_S16_LE;
+ break;
+ case 0x02:
+ fmt = AFMT_U8;
+ break;
+ case 0x03:
+ fmt = AFMT_FLOAT;
+ break;
+ case 0x04:
+ fmt = AFMT_A_LAW;
+ break;
+ case 0x05:
+ fmt = AFMT_MU_LAW;
+ break;
+ }
+
+ if (fmt == AFMT_S16_LE) /* Have to check the frame size too */
+ {
+ switch (frame_size)
+ {
+ case 1:
+ fmt = AFMT_S8;
+ break;
+ case 2:
+ fmt = AFMT_S16_LE;
+ break;
+ case 3:
+ fmt = AFMT_S32_LE;
+ frame_size = 4;
+ portc->convert_3byte = 1;
+ break;
+ case 4:
+ fmt = AFMT_S32_LE;
+ break;
+ }
+ }
+
+ portc->bytes_per_sample = frame_size;
+ adev->oformat_mask = adev->iformat_mask = fmt;
+ UDB (cmn_err (CE_CONT, "Format mask %08x\n", fmt));
+
+ adev->caps &= ~PCM_CAP_FREERATE;
+ n = d[7];
+ if (n < 1) /* Free rate selection between min (0) and max (1) */
+ {
+ n = 2;
+ adev->caps |= PCM_CAP_FREERATE;
+ }
+
+ min_rate = 0x7fffffff;
+ max_rate = 0;
+
+ if (n > 20)
+ {
+ cmn_err (CE_WARN, "The device supports too many sample rates\n");
+ n = 20;
+ }
+
+ adev->nrates = 0;
+
+ for (i = 0; i < n; i++)
+ {
+ int rate = ossusb_get_int (&d[8 + i * 3], 3);
+
+#if 0
+ /* Skip rates that are not multiples of 1000 Hz */
+ if (rate % 1000)
+ continue;
+#endif
+
+ if (rate < min_rate)
+ min_rate = rate;
+ if (rate > max_rate)
+ max_rate = rate;
+ adev->rates[adev->nrates++] = rate;
+ }
+
+ adev->min_rate = min_rate;
+ adev->max_rate = max_rate;
+ UDB (cmn_err (CE_CONT, "Min rate %d, max rate %d\n", min_rate, max_rate));
+
+ adev->caps &= ~DSP_CH_MASK;
+
+ switch (channels)
+ {
+ case 1:
+ adev->caps |= DSP_CH_MONO;
+ break;
+ case 2:
+ adev->caps |= DSP_CH_STEREO;
+ break;
+ default:
+ adev->caps |= DSP_CH_MULTI;
+ break;
+ }
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+setup_format_II (ossusb_devc * devc, ossusb_portc * portc, adev_p adev,
+ unsigned char *d, int l)
+{
+ int min_rate = 0, max_rate = 0;
+ int i;
+
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "MaxBitRate %d ", d[4]);
+ cmn_err (CE_CONT, "SamplesPerFrame %d ", d[5]);
+
+ if (d[8] == 0)
+ cmn_err (CE_CONT, "Sample Rates %d-%d ", ossusb_get_int (&d[9], 3),
+ ossusb_get_int (&d[12], 3));
+ else
+ {
+ int n;
+ int min_rate = 0x7fffffff;
+ int max_rate = 0;
+
+ n = d[8];
+
+ if (n > 20)
+ {
+ cmn_err (CE_CONT, "oss usbaudio: Too many sample rates (%d)\n",
+ n);
+ n = 20;
+ }
+
+ adev->nrates = 0;
+ cmn_err (CE_CONT, "Possible sample rates: ");
+ for (i = 0; i < d[8]; i++)
+ {
+ int rate = ossusb_get_int (&d[9 + i * 3], 3);
+
+#if 0
+ /* Skip rates that are not multiples of 1000 Hz */
+ if (rate % 1000)
+ continue;
+#endif
+
+ if (rate < min_rate)
+ min_rate = rate;
+ if (rate > max_rate)
+ max_rate = rate;
+ cmn_err (CE_CONT, "%d ", rate);
+ adev->rates[adev->nrates++] = rate;
+ }
+ adev->min_rate = min_rate;
+ adev->max_rate = max_rate;
+ }
+
+ cmn_err (CE_CONT, "\n");
+ }
+
+ adev->caps &= ~PCM_CAP_FREERATE;
+ if (d[8] == 0)
+ {
+ min_rate = ossusb_get_int (&d[9], 3);
+ max_rate = ossusb_get_int (&d[12], 3);
+ adev->caps |= PCM_CAP_FREERATE;
+ }
+ else
+ {
+ min_rate = 1 << 30;
+ max_rate = 0;
+
+ for (i = 0; i < d[8]; i++)
+ {
+ int r = ossusb_get_int (&d[9 + i * 3], 3);
+
+ if (r < min_rate)
+ min_rate = r;
+ if (r > max_rate)
+ max_rate = r;
+ }
+ }
+
+ adev->min_channels = adev->max_channels = 2;
+ adev->oformat_mask = adev->iformat_mask = AFMT_AC3;
+ adev->min_rate = min_rate;
+ adev->max_rate = max_rate;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+setup_format_specific (ossusb_devc * devc, ossusb_portc * portc, adev_p adev,
+ unsigned char *d, int l)
+{
+ int fmt;
+
+ fmt = ossusb_get_int (&d[3], 2);
+
+ if (usb_trace > 1)
+ cmn_err (CE_CONT, "Format specific: fmt=%04x\n", fmt);
+
+ switch (fmt)
+ {
+ case FORMAT_II_MPEG:
+ if (usb_trace > 1)
+ cmn_err (CE_CONT, "MPEG format\n");
+ adev->oformat_mask = adev->iformat_mask = AFMT_MPEG;
+ break;
+
+ case FORMAT_II_AC3:
+ if (usb_trace > 1)
+ cmn_err (CE_CONT, "AC3 format\n");
+ adev->oformat_mask = adev->iformat_mask = AFMT_AC3;
+#if 0
+ cmn_err (CE_CONT, "BSID=%08x\n", ossusb_get_int (&d[5], 4));
+ cmn_err (CE_CONT, "AC3Features %02x\n", d[9]);
+#endif
+ break;
+
+ default:
+ cmn_err (CE_CONT, "oss usbaudio: Unsupported FORMAT II tag %04x\n",
+ fmt);
+ adev->enabled = 0;
+ return OSS_ENXIO;
+ }
+ return 0;
+}
+
+static int
+prepare_altsetting (ossusb_devc * devc, ossusb_portc * portc, int new_setting)
+{
+ int desc_len;
+ unsigned char *desc, *d;
+ int l, p;
+ int err;
+ adev_p adev;
+
+ adev = audio_engines[portc->audio_dev];
+ adev->enabled = 1;
+ portc->disabled = 0;
+
+ if (portc->act_setting == new_setting) /* No need to change */
+ return 0;
+
+ if (new_setting < portc->num_settings)
+ desc = udi_usbdev_get_altsetting (portc->usbdev, new_setting, &desc_len);
+ else
+ desc = NULL;
+
+ if (desc == NULL || desc_len < 3)
+ {
+ cmn_err (CE_CONT,
+ "Audio device %d not available when altsetting=%d\n",
+ audio_engines[portc->audio_dev]->real_dev, new_setting);
+ portc->disabled = 1;
+ adev->enabled = 0;
+ portc->act_setting = new_setting;
+ return OSS_ENXIO;
+ }
+
+ UDB (cmn_err
+ (CE_CONT, "Select active setting %d on interface %d (dsp%d)\n",
+ new_setting, portc->if_number, adev->engine_num));
+ portc->act_setting = new_setting;
+
+ p = 0;
+ while (p < desc_len)
+ {
+ int i;
+
+ d = desc + p;
+ l = *d;
+
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "Streaming desc: ");
+ for (i = 0; i < l; i++)
+ cmn_err (CE_CONT, "%02x ", d[i]);
+ cmn_err (CE_CONT, "\n");
+
+ }
+
+ if (d[1] != CS_INTERFACE)
+ {
+ UDB (cmn_err (CE_CONT, "Unknown descriptor type %02x\n", d[1]))}
+ else
+ switch (d[2])
+ {
+ case AS_GENERAL:
+ portc->terminal_link = d[3];
+ portc->pipeline_delay = d[4];
+
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "AS_GENERAL ");
+ cmn_err (CE_CONT, "Terminal link %d/%s ", d[3],
+ devc->units[d[3]].name);
+ cmn_err (CE_CONT, "Delay %d ", d[4]);
+ cmn_err (CE_CONT, "Format tag %02x%02x ", d[5], d[6]);
+ cmn_err (CE_CONT, "\n");
+ }
+ break;
+
+ case AS_FORMAT_TYPE:
+ if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "AS_FORMAT_TYPE: FORMAT_TYPE_%d: ", d[3]);
+ }
+
+ switch (d[3])
+ {
+ case 1: /* FORMAT_TYPE_I */
+ if ((err = setup_format_I (devc, portc, adev, d, l)) < 0)
+ return err;
+ break;
+
+ case 2: /* FORMAT_TYPE_II */
+ if ((err = setup_format_II (devc, portc, adev, d, l)) < 0)
+ return err;
+ break;
+
+ default:
+ cmn_err (CE_CONT,
+ "\noss usbaudio: Unsupported format type %d\n",
+ d[3]);
+ adev->enabled = 0;
+ return OSS_ENXIO;
+ }
+ break;
+
+ case AS_FORMAT_SPECIFIC:
+ if ((err = setup_format_specific (devc, portc, adev, d, l)) < 0)
+ return err;
+ break;
+
+ default:
+ UDB (cmn_err
+ (CE_CONT, "Unknown descriptor subtype %02x\n", d[2]));
+ }
+
+ p += l;
+ }
+
+ desc = udi_usbdev_get_endpoint (portc->usbdev, portc->act_setting, 0, &l);
+ if (desc == NULL)
+ {
+ cmn_err (CE_CONT, "oss usbaudio: Bad endpoint\n");
+ return OSS_EIO;
+ }
+
+ portc->endpoint_desc = desc;
+
+ desc = udi_usbdev_get_endpoint (portc->usbdev, portc->act_setting, 1, &l);
+#if 0
+ if (desc != NULL)
+ {
+ /* TODO: Handle sync endpoints */
+ cmn_err (CE_CONT, "Sync Endpoint: ");
+ ossusb_dump_desc (desc, l);
+ }
+#endif
+
+ return 0;
+}
+
+static void usbaudio_close (int dev, int mode);
+
+/*ARGSUSED*/
+static int
+usbaudio_open (int dev, int mode, int open_flags)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags, phaddr;
+ int err;
+ int i;
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode != 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+ portc->open_mode = mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if ((err = prepare_altsetting (devc, portc, portc->act_setting)) < 0)
+ {
+ portc->open_mode = 0;
+ return err;
+ }
+
+ {
+ int i;
+
+ for (i = 0; i < 2; i++)
+ portc->tmp_buf[i] =
+ CONTIG_MALLOC (devc->osdev, TMPBUF_SIZE, MEMLIMIT_32BITS, &phaddr, portc->tmpbuf_dma_handle[i]);
+ }
+
+ if ((err =
+ udi_usbdev_set_interface (portc->usbdev, portc->if_number,
+ portc->act_setting)) < 0)
+ {
+ cmn_err (CE_NOTE,
+ "oss usbaudio: Failed to set interface mode, error %d - ignored\n",
+ err);
+ // portc->open_mode = 0;
+ //return err;
+ }
+
+ portc->curr_datapipe = 0;
+
+ if ((portc->endpoint_handle =
+ udi_open_endpoint (portc->usbdev, portc->endpoint_desc)) == NULL)
+ {
+ usbaudio_close (dev, mode);
+ cmn_err (CE_WARN, "Cannot open audio pipe\n");
+ return OSS_ENOMEM;
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ if ((portc->datapipe[i] =
+ udi_usb_alloc_request (portc->usbdev, portc->endpoint_handle, 1,
+ UDI_USBXFER_ISO_WRITE)) == NULL)
+ {
+ usbaudio_close (dev, mode);
+ cmn_err (CE_WARN, "Cannot alloc isoc request\n");
+ return OSS_ENOMEM;
+ }
+ }
+
+ set_fraglimits (audio_engines[dev], portc);
+ return 0;
+}
+
+static void usbaudio_reset (int dev);
+
+/*ARGSUSED*/
+static void
+usbaudio_close (int dev, int mode)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ int i;
+
+ usbaudio_reset (dev);
+
+ for (i = 0; i < 2; i++)
+ {
+ if (portc->datapipe[i] != NULL)
+ {
+ udi_usb_free_request (portc->datapipe[i]);
+ portc->datapipe[i] = NULL;
+ }
+
+ if (portc->tmp_buf[i] != NULL)
+ {
+ CONTIG_FREE (devc->osdev, portc->tmp_buf[i], TMPBUF_SIZE, portc->tmpbuf_dma_handle[i]);
+ portc->tmp_buf[i] = NULL;
+ }
+ }
+
+ if (portc->endpoint_handle != NULL)
+ udi_close_endpoint (portc->endpoint_handle);
+
+ udi_usbdev_set_interface (portc->usbdev, portc->if_number, 0);
+ portc->open_mode = 0;
+}
+
+/*ARGSUSED*/
+static void
+usbaudio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ return;
+}
+
+/*ARGSUSED*/
+static void
+usbaudio_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ return;
+}
+
+static int feed_output (int dev, ossusb_devc * devc, ossusb_portc * portc);
+static void start_input (int dev, ossusb_devc * devc, ossusb_portc * portc);
+
+static int
+copy_input (ossusb_portc * portc, dmap_t * dmap, unsigned char *buf, int len)
+{
+ int outlen = 0;
+ int offs;
+
+ offs = (int) (dmap->byte_counter % dmap->bytes_in_use);
+
+ while (len > 0)
+ {
+ int l;
+ l = len;
+
+ if (portc->convert_3byte)
+ {
+ int i, n;
+ int *dmabuf;
+
+ l = (l * 4) / 3;
+ /* Check for buffer wraparound */
+ if (offs + l > dmap->bytes_in_use)
+ l = dmap->bytes_in_use - offs;
+
+ n = (l / 4);
+
+ if (dmap == NULL || dmap->dmabuf == NULL)
+ return outlen;
+
+ dmabuf = (int *) (dmap->dmabuf + offs);
+
+ for (i = 0; i < n; i++)
+ {
+ int v;
+
+ v = buf[2] | (buf[1] << 8) | (buf[0] << 16);
+ *dmabuf++ = v;
+ buf += 3;
+ }
+
+ outlen += l;
+ }
+ else
+ {
+ unsigned char *dmabuf;
+ dmabuf = dmap->dmabuf;
+
+ if (dmap == NULL || dmap->dmabuf == NULL)
+ return outlen;
+
+ /* Check for buffer wraparound */
+ if (offs + l > dmap->bytes_in_use)
+ l = dmap->bytes_in_use - offs;
+
+ memcpy (dmabuf + offs, buf, l);
+ outlen += l;
+ buf += l;
+ }
+
+ len -= l;
+ offs = 0;
+ }
+
+ return outlen;
+}
+
+/*ARGSUSED*/
+static void
+play_callback (udi_usb_request_t * request, void *arg)
+{
+ ossusb_portc *portc = arg;
+
+ feed_output (portc->audio_dev, portc->devc, portc);
+ oss_audio_outputintr (portc->audio_dev,
+ AINTR_NO_POINTER_UPDATES | AINTR_LOCALQUEUE);
+}
+
+static void
+rec_callback (udi_usb_request_t * request, void *arg)
+{
+ ossusb_portc *portc = arg;
+ dmap_t *dmap;
+ int len;
+
+ if (portc == NULL || (unsigned long) arg < 4096)
+ {
+ cmn_err (CE_WARN, "Bad portc\n");
+ return;
+ }
+
+ dmap = audio_engines[portc->audio_dev]->dmap_in;
+ len = udi_usb_request_actlen (request);
+
+ if (len == 0)
+ return; /* No data so it looks like we are closing down */
+
+ if ((len =
+ copy_input (portc, dmap, udi_usb_request_actdata (request), len)) < 1)
+ {
+ cmn_err (CE_WARN, "Saving recorded data failed (%d)\n", len);
+ return;
+ }
+
+ oss_audio_inc_byte_counter (dmap, len);
+ oss_audio_inputintr (portc->audio_dev, AINTR_NO_POINTER_UPDATES);
+#ifdef linux
+ start_input (portc->audio_dev, portc->devc, portc);
+#endif
+}
+
+#if 0
+/*
+ * Testing stuff only
+ */
+static int
+sin_gen (void)
+{
+
+ static int phase = 0, v;
+
+ static short sinebuf[48] = {
+ 0, 4276, 8480, 12539, 16383, 19947, 23169, 25995,
+ 28377, 30272, 31650, 32486, 32767, 32486, 31650, 30272,
+ 28377, 25995, 23169, 19947, 16383, 12539, 8480, 4276,
+ 0, -4276, -8480, -12539, -16383, -19947, -23169, -25995,
+ -28377, -30272, -31650, -32486, -32767, -32486, -31650, -30272,
+ -28377, -25995, -23169, -19947, -16383, -12539, -8480, -4276
+ };
+ v = sinebuf[phase] * 256;
+ phase = (phase + 1) % 48;
+
+ return v;
+}
+#endif
+
+/*ARGSUSED*/
+static int
+output_convert (ossusb_devc * devc, ossusb_portc * portc, dmap_p dmap,
+ unsigned char *dmabuf, int pos, int pn, int total_len)
+{
+ unsigned char *tmpbuf = portc->tmp_buf[pn], *b;
+ int i, n, len, out_size = 0;
+ int err;
+
+ while (total_len > 0)
+ {
+ int l = total_len;
+
+ /* Check for buffer wraparound */
+ if (pos + l > dmap->bytes_in_use)
+ l = dmap->bytes_in_use - pos;
+
+ total_len -= l;
+
+ b = dmabuf + pos;
+
+ if (portc->convert_3byte)
+ {
+ int *buf;
+
+ n = l / sizeof (*buf);
+ buf = (int *) b;
+
+ len = n * 3;
+
+ for (i = 0; i < n; i++)
+ {
+ int val = (*buf++);
+
+ val /= 256;
+ // val=sin_gen();
+ *tmpbuf++ = (val) & 0xff;
+ *tmpbuf++ = (val >> 8) & 0xff;
+ *tmpbuf++ = (val >> 16) & 0xff;
+ }
+ }
+ else
+ {
+ len = l;
+ memcpy (tmpbuf, b, l);
+ tmpbuf += l;
+ }
+
+ pos = 0;
+ out_size += len;
+ }
+
+ if ((err =
+ udi_usb_submit_request (portc->datapipe[pn], play_callback, portc,
+ portc->endpoint_handle, UDI_USBXFER_ISO_WRITE,
+ portc->tmp_buf[pn], out_size)) < 0)
+ {
+ //cmn_err(CE_CONT, "oss usbaudio: Write transfer eror %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+feed_output (int dev, ossusb_devc * devc, ossusb_portc * portc)
+{
+ int pn, pos, len;
+ oss_native_word flags;
+ adev_p adev = audio_engines[dev];
+ dmap_p dmap = adev->dmap_out;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->stopping)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+
+ pn = portc->curr_datapipe;
+ portc->curr_datapipe = (portc->curr_datapipe + 1) % NR_DATAPIPES;
+
+ pos = (int) (dmap->byte_counter % dmap->bytes_in_use);
+ len = portc->fragment_size;
+
+ portc->overflow_samples += portc->overflow_size;
+ if (portc->overflow_samples > 1000)
+ {
+ len += dmap->frame_size * (portc->overflow_samples / 1000);
+ portc->overflow_samples = portc->overflow_samples % 1000;
+ }
+
+ output_convert (devc, portc, dmap, dmap->dmabuf, pos, pn, len);
+ oss_audio_inc_byte_counter (dmap, len);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+start_input (int dev, ossusb_devc * devc, ossusb_portc * portc)
+{
+ int frag, err;
+ oss_native_word flags;
+ adev_p adev = audio_engines[dev];
+ dmap_p dmap = adev->dmap_in;
+
+ if (portc->stopping)
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ frag = 0;
+
+ if ((err =
+ udi_usb_submit_request (portc->datapipe[0], rec_callback, portc,
+ portc->endpoint_handle, UDI_USBXFER_ISO_READ,
+ dmap->dmabuf + frag * portc->fragment_size,
+ portc->fragment_size)) < 0)
+ {
+ cmn_err (CE_WARN, "oss usbaudio: Read transfer error %d\n", err);
+ cmn_err (CE_CONT, "Endpoint %02x\n",
+ udi_endpoint_get_num (portc->endpoint_handle));
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+usbaudio_trigger (int dev, int state)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+
+ if (devc->disabled)
+ return;
+
+ if (portc->open_mode & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->prepared_modes & PCM_ENABLE_OUTPUT)
+ && (state & PCM_ENABLE_OUTPUT))
+ {
+ portc->prepared_modes &= ~PCM_ENABLE_OUTPUT;
+ portc->curr_datapipe = 0;
+ portc->stopping = 0;
+
+ feed_output (dev, devc, portc);
+ feed_output (dev, devc, portc);
+ }
+ else if (!(state & PCM_ENABLE_OUTPUT))
+ {
+ portc->stopping = 1;
+#if 1
+ udi_usb_cancel_request (portc->datapipe[0]);
+ udi_usb_cancel_request (portc->datapipe[1]);
+#endif
+ portc->curr_datapipe = 0;
+ }
+ }
+
+ if (portc->open_mode & PCM_ENABLE_INPUT)
+ {
+ if ((portc->prepared_modes & PCM_ENABLE_INPUT)
+ && (state & PCM_ENABLE_INPUT))
+ {
+ portc->prepared_modes &= ~PCM_ENABLE_INPUT;
+ portc->stopping = 0;
+ start_input (dev, devc, portc);
+ }
+ else if (!(state & PCM_ENABLE_INPUT))
+ {
+ portc->stopping = 1;
+#if 0
+ udi_usb_cancel_request (portc->datapipe[0]);
+ udi_usb_cancel_request (portc->datapipe[1]);
+#endif
+ portc->curr_datapipe = 0;
+ }
+ }
+}
+
+static void
+usbaudio_reset (int dev)
+{
+ usbaudio_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static int
+usbaudio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ adev_p adev = audio_engines[dev];
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+
+ if (adev->flags & ADEV_NOINPUT)
+ return OSS_ENOTSUP;
+
+ portc->stopping = 0;
+
+ if (write_control_value
+ (devc, portc->endpoint_handle, SAMPLING_FREQ_CONTROL, 3,
+ portc->speed) < 0)
+ {
+ cmn_err (CE_CONT, "Failed to set %d Hz sampling rate\n", portc->speed);
+ return OSS_EIO;
+ }
+
+ /*
+ * Handle fractional samples that don't fit in the 1ms period.
+ */
+ portc->overflow_size = portc->speed % 1000;
+ portc->overflow_samples = 0;
+
+ portc->prepared_modes |= PCM_ENABLE_INPUT;
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+usbaudio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ adev_p adev = audio_engines[dev];
+
+ if (devc->disabled)
+ return OSS_EPIPE;
+
+ if (adev->flags & ADEV_NOOUTPUT)
+ return OSS_ENOTSUP;
+
+ portc->stopping = 0;
+
+ if (write_control_value
+ (devc, portc->endpoint_handle, SAMPLING_FREQ_CONTROL, 3,
+ portc->speed) < 0)
+ {
+ cmn_err (CE_CONT, "Failed to set %d Hz sampling rate\n", portc->speed);
+ return OSS_EIO;
+ }
+
+ /*
+ * Handle fractional samples that don't fit in the 1ms period.
+ */
+ portc->overflow_size = portc->speed % 1000;
+ portc->overflow_samples = 0;
+
+ portc->prepared_modes |= PCM_ENABLE_OUTPUT;
+ return 0;
+}
+
+static int
+usbaudio_check_input (int dev)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ {
+ cmn_err (CE_CONT,
+ "oss usbaudio: Audio device %d removed from the system.\n",
+ dev);
+ return OSS_EPIPE;
+ }
+
+ cmn_err (CE_CONT, "oss usbaudio: Audio input timed out on device %d.\n",
+ dev);
+ return OSS_EIO;
+}
+
+static int
+usbaudio_check_output (int dev)
+{
+ ossusb_devc *devc = audio_engines[dev]->devc;
+ if (devc->disabled)
+ {
+ cmn_err (CE_CONT,
+ "oss usbaudio: Audio device %d removed from the system.\n",
+ dev);
+ return OSS_EPIPE;
+ }
+
+ cmn_err (CE_CONT, "oss usbaudio: Audio output timed out on device %d.\n",
+ dev);
+ return OSS_EIO;
+}
+
+static int
+usbaudio_local_qlen (int dev)
+{
+ ossusb_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_out;
+ int delay = portc->pipeline_delay + 1; /* Pipeline delay in 1 msec ticks */
+
+ delay = delay * dmap->data_rate / 1000; /* Bytes/msec */
+
+ return delay;
+}
+
+static audiodrv_t usbaudio_driver = {
+ usbaudio_open,
+ usbaudio_close,
+ usbaudio_output_block,
+ usbaudio_start_input,
+ usbaudio_ioctl,
+ usbaudio_prepare_for_input,
+ usbaudio_prepare_for_output,
+ usbaudio_reset,
+ usbaudio_local_qlen,
+ NULL,
+ NULL,
+ NULL,
+ usbaudio_trigger,
+ usbaudio_set_rate,
+ usbaudio_set_format,
+ usbaudio_set_channels,
+ NULL,
+ NULL,
+ usbaudio_check_input,
+ usbaudio_check_output,
+ NULL, /* usbaudio_alloc_buffer */
+ NULL, /* usbaudio_free_buffer */
+ NULL,
+ NULL,
+ NULL /* usbaudio_get_buffer_pointer */
+};
+
+ossusb_devc *
+ossusb_init_audiostream (ossusb_devc * devc, udi_usb_devc * usbdev, int inum,
+ int reinit)
+{
+ int nsettings, actsetting = 0, desc_len;
+ unsigned char *desc, *d;
+ adev_p adev;
+ int i, p, l;
+ int portc_num;
+ void *endpoint_desc;
+
+ char dev_name[128];
+
+ int opts = ADEV_AUTOMODE;
+
+ ossusb_portc *portc;
+
+ if (devc->num_audio_engines >= MAX_PORTC)
+ {
+ cmn_err (CE_CONT, "usbaudio: Too many audio streaming interfaces\n");
+ return devc;
+ }
+
+ if (usbdev == NULL)
+ {
+ cmn_err (CE_CONT, "usbaudio: usbdev==NULL\n");
+ return devc;
+ }
+
+ nsettings = udi_usbdev_get_num_altsettings (usbdev);
+ desc = udi_usbdev_get_endpoint (usbdev, 1, 0, &l);
+ if (desc != NULL)
+ {
+ /* cmn_err(CE_CONT, "Endpoint: ");ossusb_dump_desc(desc, l); */
+ endpoint_desc = desc;
+ }
+ else
+ endpoint_desc = NULL;
+
+ if (reinit)
+ for (i = 0; i < devc->num_audio_engines; i++)
+ if (devc->portc[i].orig_endpoint_desc == endpoint_desc) /* Already registered this */
+ {
+ prepare_altsetting (devc, &devc->portc[i],
+ devc->portc[i].act_setting);
+ return devc;
+ }
+
+ portc = &devc->portc[devc->num_audio_engines];
+ portc_num = devc->num_audio_engines;
+ portc->if_number = inum;
+ portc->endpoint_desc = portc->orig_endpoint_desc = endpoint_desc;
+ portc->usbdev = usbdev;
+ portc->act_setting = -1; /* Set to an impossible value */
+ devc->num_audio_engines++;
+
+ memset (dev_name, 0, sizeof (dev_name));
+ strncpy (dev_name, devc->dev_name, sizeof (dev_name) - 1);
+ portc->num_settings = nsettings;
+
+#if 1
+ if (usb_trace > 2)
+ for (i = 0; i < nsettings; i++)
+ {
+ desc = udi_usbdev_get_altsetting (usbdev, i, &desc_len);
+ cmn_err (CE_CONT, "\nDumping altsetting %d (l=%d)\n", i, desc_len);
+ if (usb_trace)
+ ossusb_dump_desc (desc, desc_len);
+ }
+#endif
+
+ desc = udi_usbdev_get_altsetting (usbdev, actsetting, &desc_len);
+
+ if (desc == NULL || desc_len < 1)
+ for (i = 0; i < nsettings && (desc == NULL || desc_len < 1); i++)
+ {
+ UDB (cmn_err (CE_CONT, "Trying to read altsetting %d\n", i));
+ desc = udi_usbdev_get_altsetting (usbdev, i, &desc_len);
+ if (desc != NULL)
+ actsetting = i;
+ }
+
+ UDB (cmn_err (CE_CONT, "Altsetting %d, len %d\n", actsetting, desc_len));
+
+ if (desc == NULL)
+ {
+ cmn_err (CE_WARN, "Can't read interface descriptors\n");
+ return NULL;
+ }
+
+ if (usb_trace > 2)
+ ossusb_dump_desc (desc, desc_len);
+
+ p = 0;
+ while (p < desc_len)
+ {
+ d = desc + p;
+ l = *d;
+
+ if (d[1] != CS_INTERFACE)
+ {
+ UDB (cmn_err (CE_CONT, "Unknown descriptor type %02x\n", d[1]))}
+ else
+ switch (d[2])
+ {
+ case AS_GENERAL:
+ portc->terminal_link = d[3];
+ break;
+ }
+
+ p += l;
+ }
+
+ if (portc->terminal_link > 0 && portc->terminal_link <= devc->nunits)
+ {
+ char *s = dev_name + strlen (dev_name);
+
+ sprintf (s, " %s", devc->units[portc->terminal_link].name);
+ s += strlen (s);
+
+ if (devc->units[portc->terminal_link].typ == TY_OUTPUT) /* USB terminal type */
+ {
+ opts |= ADEV_NOOUTPUT;
+ }
+ else
+ {
+ opts |= ADEV_NOINPUT;
+ }
+ }
+
+ if ((portc->audio_dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ dev_name,
+ &usbaudio_driver,
+ sizeof (audiodrv_t),
+ opts,
+ AFMT_S16_NE, devc, -1)) < 0)
+ {
+ return devc;
+ }
+
+ portc->devc = devc;
+ adev = audio_engines[portc->audio_dev];
+ adev->portc = portc;
+ adev->mixer_dev = devc->mixer_dev;
+ adev->rate_source = devc->portc[0].audio_dev;
+ adev->max_block = 256;
+ adev->min_fragments = 4; /* vmix needs this */
+
+ prepare_altsetting (devc, portc, 1);
+
+ if (portc->num_settings > 2)
+ {
+ char name[128];
+
+ sprintf (name, "%s-altset", devc->units[portc->terminal_link].name);
+ ossusb_create_altset_control (devc->mixer_dev, portc_num,
+ portc->num_settings, name);
+ }
+
+#if 0
+ // TODO: This needs to be checked before vmix is enabled
+#ifdef CONFIG_OSS_VMIX
+ if (devc->units[portc->terminal_link].typ != TY_OUTPUT)
+ vmix_attach_audiodev(devc->osdev, portc->audio_dev, -1, 0);
+#endif
+#endif
+ return devc;
+}
+
+/*ARGSUSED*/
+int
+ossusb_change_altsetting (int dev, int ctrl, unsigned int cmd, int value)
+{
+ ossusb_devc *devc = mixer_devs[dev]->devc;
+ ossusb_portc *portc;
+
+ if (ctrl < 0 || ctrl >= devc->num_audio_engines)
+ return OSS_ENXIO;
+
+ portc = &devc->portc[ctrl];
+
+ if (cmd == SNDCTL_MIX_READ)
+ return portc->act_setting;
+
+ if (value >= portc->num_settings)
+ value = portc->num_settings - 1;
+
+ if (portc->act_setting != value)
+ {
+ prepare_altsetting (devc, portc, value);
+ }
+ return value;
+}
diff --git a/kernel/drv/oss_usb/ossusb_midi.c b/kernel/drv/oss_usb/ossusb_midi.c
new file mode 100644
index 0000000..f843594
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb_midi.c
@@ -0,0 +1,442 @@
+/*
+ * Purpose: USB MIDI streaming interface support
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "ossusb.h"
+
+#define RECBUF_SIZE 32
+#define PLAYBUF_SIZE 32
+
+/*
+ * MS Class-Specific Interface Descriptor Subtypes
+ */
+#define MS_HEADER 0x01
+#define MIDI_IN_JACK 0x02
+#define MIDI_OUT_JACK 0x03
+#define ELEMENT 0x04
+
+/* Jack types */
+#define JT_EMBEDDED 0x01
+#define JT_EXTERNAL 0x02
+
+static int usb_midi_start_input (ossusb_devc * devc, ossusb_midic * midic);
+
+static void
+record_callback (udi_usb_request_t * request, void *arg)
+{
+ ossusb_midic *midic = arg;
+ ossusb_devc *devc = midic->devc;
+ int i, l;
+
+ l = udi_usb_request_actlen (request);
+ if (l == 0)
+ goto restart;
+
+ for (i = 0; i < l; i++)
+ cmn_err (CE_CONT, "%02x ", devc->recbuf[i]);
+ cmn_err (CE_CONT, "\n");
+
+restart:
+ usb_midi_start_input (devc, midic);
+}
+
+static int
+usb_midi_start_input (ossusb_devc * devc, ossusb_midic * midic)
+{
+ oss_native_word flags;
+ int err = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if ((err =
+ udi_usb_submit_request (devc->input_pipe, record_callback, midic,
+ midic->in_endpoint_handle,
+ UDI_USBXFER_BULK_READ, devc->recbuf,
+ RECBUF_SIZE)) < 0)
+ {
+ cmn_err (CE_WARN, "usbmidi: udi_usb_submit_request failed, err=%d\n",
+ err);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return err;
+}
+
+static int usb_midi_start_output (ossusb_devc * devc, ossusb_midic * midic);
+
+ /*ARGSUSED*/ static void
+play_callback (udi_usb_request_t * request, void *arg)
+{
+ ossusb_midic *midic = arg;
+ ossusb_devc *devc = midic->devc;
+
+ devc->output_busy = 0;
+ usb_midi_start_output (devc, midic);
+}
+
+static int
+usb_midi_start_output (ossusb_devc * devc, ossusb_midic * midic)
+{
+ oss_native_word flags;
+ int err = 0, l = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ l = devc->q_nbytes;
+ if (l > PLAYBUF_SIZE)
+ l = PLAYBUF_SIZE;
+
+ if (l == 0 || devc->output_busy)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+
+ memcpy (devc->playbuf, devc->queue, l);
+
+ if ((err =
+ udi_usb_submit_request (devc->output_pipe, play_callback, midic,
+ midic->out_endpoint_handle,
+ UDI_USBXFER_BULK_WRITE, devc->playbuf, l)) < 0)
+ {
+ cmn_err (CE_WARN, "usbmidi: udi_usb_submit_request() failed, err=%d\n",
+ err);
+ }
+ else
+ devc->output_busy = 1;
+
+ /* Remove the vbytes from the queue */
+ if (l >= devc->q_nbytes)
+ devc->q_nbytes = 0;
+ else
+ {
+ int n = devc->q_nbytes - l;
+ memcpy (devc->queue, devc->queue + l, n);
+ devc->q_nbytes -= l;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return err;
+}
+
+static void
+usb_midi_close (int dev, int mode)
+{
+ oss_native_word flags;
+ ossusb_midic *midic;
+ ossusb_devc *devc;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ midic->midi_output_intr = NULL;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (mode & OPEN_READ)
+ {
+ if (devc->input_pipe != NULL)
+ udi_usb_cancel_request (devc->input_pipe);
+ devc->input_pipe = NULL;
+
+ if (devc->recbuf != NULL)
+ CONTIG_FREE (devc->osdev, devc->recbuf, RECBUF_SIZE, devc->recbuf_dma_handle);
+ devc->recbuf = NULL;
+ if (devc->playbuf != NULL)
+ CONTIG_FREE (devc->osdev, devc->playbuf, PLAYBUF_SIZE, devc->playbuf_dma_handle);
+ devc->playbuf = NULL;
+ udi_close_endpoint (midic->in_endpoint_handle);
+ }
+
+ if (mode & OPEN_WRITE)
+ {
+ udi_usb_cancel_request (devc->output_pipe);
+ udi_close_endpoint (midic->out_endpoint_handle);
+ }
+}
+
+ /*ARGSUSED*/ static int
+usb_midi_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf, oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags, phaddr;
+ ossusb_midic *midic;
+ ossusb_devc *devc;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->midi_input_intr = inputbyte;
+ midic->midi_output_intr = outputintr;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (mode & OPEN_WRITE)
+ {
+ if ((midic->out_endpoint_handle =
+ udi_open_endpoint (midic->usbdev,
+ midic->out_endpoint_desc)) == NULL)
+ {
+ usb_midi_close (dev, mode);
+ cmn_err (CE_WARN, "Cannot open midi output pipe\n");
+ return OSS_ENOMEM;
+ }
+
+ if ((devc->output_pipe =
+ udi_usb_alloc_request (midic->usbdev, midic->out_endpoint_handle,
+ 1, UDI_USBXFER_BULK_WRITE)) == NULL)
+ {
+ cmn_err (CE_WARN, "usbmidi: Failed to allocate output pipe\n");
+ }
+
+ devc->playbuf =
+ CONTIG_MALLOC (devc->osdev, PLAYBUF_SIZE, MEMLIMIT_32BITS, &phaddr, devc->playbuf_dma_handle);
+
+ devc->output_busy = 0;
+ devc->q_nbytes = 0;
+ }
+
+ if (mode & OPEN_READ)
+ {
+ int err;
+
+ if ((midic->in_endpoint_handle =
+ udi_open_endpoint (midic->usbdev,
+ midic->in_endpoint_desc)) == NULL)
+ {
+ usb_midi_close (dev, mode);
+ cmn_err (CE_WARN, "Cannot open midi input pipe\n");
+ return OSS_ENOMEM;
+ }
+ if ((devc->input_pipe =
+ udi_usb_alloc_request (midic->usbdev, midic->in_endpoint_handle, 1,
+ UDI_USBXFER_BULK_READ)) == NULL)
+ {
+ cmn_err (CE_WARN, "usbmidi: Failed to allocate input pipe\n");
+ }
+ devc->recbuf =
+ CONTIG_MALLOC (devc->osdev, RECBUF_SIZE, MEMLIMIT_32BITS, &phaddr, devc->recbuf_dma_handle);
+
+ if ((err = usb_midi_start_input (devc, midic)) < 0)
+ {
+ cmn_err (CE_WARN, "usbmidi: Input error %d\n", err);
+ usb_midi_close (dev, mode);
+ return OSS_EIO;
+ }
+ }
+
+ return 0;
+}
+
+static int
+usb_midi_out (int dev, unsigned char data)
+{
+ ossusb_midic *midic = midi_devs[dev]->devc;
+ ossusb_devc *devc;
+ oss_native_word flags;
+ unsigned char *buf;
+
+ devc = midic->devc;
+
+ cmn_err (CE_CONT, "Send %02x\n", data);
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if ((devc->q_nbytes + 4) >= Q_MAX)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+ }
+
+ buf = devc->queue + devc->q_nbytes;
+
+ memset (buf, 0, 4);
+ buf[0] = 0x0f;
+ buf[1] = data;
+
+ devc->q_nbytes += 4;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ usb_midi_start_output (devc, midic);
+ return 1;
+}
+
+ /*ARGSUSED*/ static int
+usb_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t usb_midi_driver = {
+ usb_midi_open,
+ usb_midi_close,
+ usb_midi_ioctl,
+ usb_midi_out,
+};
+
+ /*ARGSUSED*/
+ ossusb_devc *
+ossusb_init_midistream (ossusb_devc * devc, udi_usb_devc * usbdev, int inum,
+ int reinit)
+{
+ int i, n;
+ int p, l;
+ char tmp[64];
+ unsigned char *in_endpoints[16], *out_endpoints[16];
+ void *in_endpoint_desc = NULL, *out_endpoint_desc = NULL;
+ int num_in_endpoints = 0, num_out_endpoints = 0;
+ int cin = 0, cout = 0;
+ ossusb_midic *midic;
+ unsigned char *desc, *d;
+ int desc_len;
+
+ for (i = 0; i < 32; i++)
+ if ((desc = udi_usbdev_get_endpoint (usbdev, 0, i, &desc_len)) != NULL)
+ {
+ unsigned char *ep;
+
+ if (desc_len > 100)
+ desc_len = 100;
+
+ cmn_err (CE_CONT, "Endpoint %d (%d)", i, desc_len);
+ ossusb_dump_desc (desc, desc_len);
+ ep = desc;
+
+ if (desc[2] & 0x80)
+ {
+ in_endpoints[num_in_endpoints++] = ep;
+ }
+ else
+ {
+ out_endpoints[num_out_endpoints++] = ep;
+ }
+ }
+
+ cmn_err (CE_CONT, "%d input endpoints: ", num_in_endpoints);
+ for (i = 0; i < num_in_endpoints; i++)
+ cmn_err (CE_CONT, "%02x ", in_endpoints[i][2]);
+ cmn_err (CE_CONT, "\n");
+ cmn_err (CE_CONT, "%d input endpoints: ", num_out_endpoints);
+ for (i = 0; i < num_out_endpoints; i++)
+ cmn_err (CE_CONT, "%02x ", out_endpoints[i][2]);
+ cmn_err (CE_CONT, "\n");
+
+ cmn_err (CE_CONT, "USB MIDI stream\n");
+ desc = udi_usbdev_get_altsetting (usbdev, 0, &desc_len);
+ if (desc == NULL || desc_len < 3)
+ {
+ cmn_err (CE_WARN, "usbmidi: bad altsetting\n");
+ return NULL;
+ }
+ // ossusb_dump_desc (desc, desc_len);
+ p = 0;
+ while (p < desc_len)
+ {
+ d = desc + p;
+
+ l = *d;
+ //if (usb_trace > 1)
+ {
+ cmn_err (CE_CONT, "MIDI streaming desc: ");
+ for (i = 0; i < l; i++)
+ cmn_err (CE_CONT, "%02x ", d[i]);
+ cmn_err (CE_CONT, "\n");
+ }
+
+ if (d[1] != CS_INTERFACE)
+ {
+ cmn_err (CE_WARN, "usbmidi: Unrecognized descriptor: \n");
+ ossusb_dump_desc (d, l);
+ p += l;
+ continue;
+ }
+
+ switch (d[2])
+ {
+ case MS_HEADER:
+ cmn_err (CE_CONT, "MS_HEADER: ");
+ cmn_err (CE_CONT, "v%x.%02x ", d[3], d[4]);
+ break;
+
+ case MIDI_IN_JACK:
+ cmn_err (CE_CONT, "MIDI_IN_JACK: ");
+ cmn_err (CE_CONT, "Type %d, ID %02x, iJack %d\n", d[3], d[4], d[5]);
+ in_endpoint_desc = in_endpoints[cin];
+ if (cin < num_in_endpoints - 1)
+ cin++;
+ break;
+
+ case MIDI_OUT_JACK:
+ cmn_err (CE_CONT, "MIDI_OUT_JACK: ");
+ cmn_err (CE_CONT, "Type %d, ID %02x, iJack %d\n", d[3], d[4], d[5]);
+ n = d[5];
+ cmn_err (CE_CONT, "\t%d inputs: ", n);
+ for (i = 0; i < n; i++)
+ cmn_err (CE_CONT, "%02x/%02x ", d[6 + i * 2], d[6 + i * 2 + 1]);
+ cmn_err (CE_CONT, "\n");
+ out_endpoint_desc = out_endpoints[cout];
+ if (cout < num_out_endpoints - 1)
+ cout++;
+ break;
+
+ case ELEMENT:
+ cmn_err (CE_CONT, "ELEMENT\n");
+ break;
+ }
+
+ p += l;
+ }
+
+
+#if 1
+ if (reinit)
+ for (i = 0; i < devc->num_mididevs; i++)
+ if (devc->midic[i].in_endpoint_desc == in_endpoint_desc) /* Already registered this */
+ if (devc->midic[i].out_endpoint_desc == out_endpoint_desc) /* Already registered this */
+ {
+ return devc;
+ }
+#endif
+
+ midic = &devc->midic[devc->num_mididevs];
+
+ devc->osdev = devc->osdev;
+ midic->devc = devc;
+ midic->usbdev = usbdev;
+ midic->in_endpoint_desc = in_endpoint_desc;
+ midic->out_endpoint_desc = out_endpoint_desc;
+
+ strcpy (tmp, devc->dev_name);
+
+ midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "USBMIDI", tmp,
+ &usb_midi_driver, sizeof (midi_driver_t),
+ 0, midic, devc->osdev);
+ devc->num_mididevs++;
+
+ return devc;
+}
+
+ /*ARGSUSED*/ void
+ossusb_disconnect_midistream (ossusb_devc * devc)
+{
+}
diff --git a/kernel/drv/oss_usb/ossusb_midisport.c b/kernel/drv/oss_usb/ossusb_midisport.c
new file mode 100644
index 0000000..bbeee14
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb_midisport.c
@@ -0,0 +1,957 @@
+/*
+ * Purpose: Dedicated driver for M-Audio/Midiman MIDISPORT USB MIDI family
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+#include "ossusb.h"
+#include "midisport2x2_fw.h"
+#include "midisport1x1_fw.h"
+#include "oxygen8_fw.h"
+
+/*
+ * Audiosport Quattro also use the same packet protocol (no FW load).
+ * Out EP 2 is the output and in EP 1 is the input (check this).
+ */
+#define RECBUF_SIZE (10*4)
+#define DLBUF_SIZE 63
+#define MAX_PACK 32
+#define PLAYBUF_SIZE (MAX_PACK*4)
+#define QUEUE_ENTRIES 17
+#define QUEUE_SIZE (QUEUE_ENTRIES*PLAYBUF_SIZE)
+#define MAX_PORTS 9
+
+static int instance_num = 0;
+
+typedef struct midisport_devc midisport_devc;
+
+typedef unsigned char playbuf_t[PLAYBUF_SIZE];
+
+typedef struct
+{
+ oss_mutex_t mutex;
+ midisport_devc *devc;
+ int open_count;
+ int busy;
+ int max_out_blocks; /* Num of 4(3) byte blocks allowed in single message */
+
+ playbuf_t *playbuf; /* QUEUE_SIZE */
+ oss_dma_handle_t playbuf_dma_handle;
+ int playbuf_h, playbuf_t;
+
+ unsigned char *out_ep_desc;
+ udi_usb_request_t *output_pipe;
+ udi_endpoint_handle_t *output_endpoint_handle;
+} midisport_outqueue_t;
+
+typedef struct
+{
+ midisport_devc *devc;
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+
+ int portnum;
+ int midi_dev;
+ int open_mode;
+ oss_midi_inputbyte_t midi_input_intr;
+ playbuf_t output_buf;
+ int outbuf_p;
+
+ int outqueue_ix; /* Output queue 0 or 1 */
+ oss_midi_outputintr_t outputintr;
+} midisport_midic;
+
+static int alphabethic_numbering = 1;
+
+struct midisport_devc
+{
+ special_unload_t unload_func;
+ int is_dummy;
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+ ossusb_devc *usb_devc;
+ udi_usb_devc *usbdev;
+
+ int instance_num;
+
+ unsigned char *in_ep_desc;
+
+ int num_inputs, num_outputs;
+ int open_inputs;
+ midisport_midic in_midic[MAX_PORTS];
+ midisport_midic out_midic[MAX_PORTS];
+
+ unsigned char *recbuf;
+ oss_dma_handle_t recbuf_dma_handle;
+ udi_usb_request_t *input_pipe;
+ udi_endpoint_handle_t *input_endpoint_handle;
+
+ int num_queues;
+ midisport_outqueue_t out_queues[2];
+};
+
+static void
+load_firmware (midisport_devc * devc, const struct setup_request *setup,
+ char *name)
+{
+ int err;
+
+ if (setup == NULL)
+ {
+ cmn_err (CE_WARN, "midisport: No firmware available\n");
+ return;
+ }
+
+ while (setup->pData != NULL)
+ {
+#if 0
+ cmn_err (CE_CONT, "Load(%x, Rq=%x, Rqt=%x, Val=%x, Ix=%x, data=%x, len=%d\n", devc->usbdev, setup->bRequest, /* Request */
+ setup->bmRequestType, /* Rqtype */
+ setup->wValue, /* Value */
+ setup->wIndex, /* Index */
+ setup->pData, /* Data */
+ setup->wLength); /* Len */
+#endif
+
+ err = udi_usb_snd_control_msg (devc->usbdev, 0, /* Endpoint */
+ setup->bRequest, /* Request */
+ setup->bmRequestType, /* Rqtype */
+ setup->wValue, /* Value */
+ setup->wIndex, /* Index */
+ (void *) setup->pData, /* Data */
+ setup->wLength, /* Len */
+ OSS_HZ);
+ if (err < 0)
+ {
+ cmn_err (CE_WARN, "%s: Firmware download failed (%d)\n", name, err);
+ return;
+ }
+
+ setup++;
+ }
+}
+
+static void
+midisport_unload (void *d)
+{
+ midisport_devc *devc = d;
+
+ if (devc->is_dummy)
+ {
+ return;
+ }
+
+ MUTEX_CLEANUP (devc->mutex);
+}
+
+void *
+midisport_init (ossusb_devc * usb_devc)
+{
+ midisport_devc *devc;
+ unsigned int devid;
+ char *name = "Unknown device";
+ const struct setup_request *setup = NULL;
+
+ devid = (usb_devc->vendor << 16) | usb_devc->product;
+
+ switch (devid)
+ {
+ case 0x07631001:
+ name = "MIDISPORT 2x2";
+ setup = midisport2x2_setupRequest;
+ break;
+ case 0x07631014:
+ name = "Oxygen8";
+ setup = oxygen8_setupRequest;
+ break;
+ case 0x07631010:
+ name = "MIDISPORT 1x1";
+ setup = midisport1x1_setupRequest;
+ break;
+ }
+
+ cmn_err (CE_CONT, "%s firmware load started\n", name);
+
+ if ((devc = PMALLOC (usb_devc->osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "midisport: Out of memory\n");
+ return NULL;
+ }
+
+ memset (devc, 0, sizeof (*devc));
+
+ devc->unload_func = midisport_unload;
+ devc->is_dummy = 1;
+ devc->osdev = usb_devc->osdev;
+ devc->usb_devc = usb_devc;
+ devc->usbdev = usb_devc->last_usbdev;
+
+ load_firmware (devc, setup, name);
+
+ cmn_err (CE_CONT, "%s firmware load completed\n", name);
+ return devc;
+}
+
+static int midisport_start_input (midisport_devc * devc);
+
+static void
+record_callback (udi_usb_request_t * request, void *arg)
+{
+ midisport_devc *devc = arg;
+ int i, l, p;
+ unsigned char *data;
+ data = udi_usb_request_actdata (request);
+
+ l = udi_usb_request_actlen (request);
+ if (l == 0)
+ goto restart;
+
+ for (p = 0; p < l - 3; p += 4)
+ {
+ unsigned char *buf, cmd;
+ int nbytes, src;
+ midisport_midic *midic;
+
+ buf = data + p;
+ cmd = buf[3];
+ nbytes = cmd & 0x0f;
+ src = (cmd >> 4) & 0x0f;
+
+ if (nbytes == 0) /* End of data */
+ break;
+
+ if (nbytes > 3 || src >= devc->num_inputs)
+ continue; /* No data or error */
+
+ midic = &devc->in_midic[src];
+
+ if (!(midic->open_mode & OPEN_READ) || midic->midi_input_intr == NULL)
+ continue; /* This device is not recording */
+
+ for (i = 0; i < nbytes; i++)
+ {
+ midic->midi_input_intr (midic->midi_dev, buf[i]);
+ }
+ }
+
+restart:
+ midisport_start_input (devc);
+}
+
+static int
+midisport_start_input (midisport_devc * devc)
+{
+ oss_native_word flags;
+ int err = 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if ((err =
+ udi_usb_submit_request (devc->input_pipe, record_callback, devc,
+ devc->input_endpoint_handle,
+ UDI_USBXFER_INTR_READ, devc->recbuf,
+ RECBUF_SIZE)) < 0)
+ {
+ cmn_err (CE_WARN, "udi_usb_submit_request failed, err=%d\n", err);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return err;
+}
+
+static void submit_output (midisport_devc * devc, midisport_outqueue_t * q);
+
+ /*ARGSUSED*/ static void
+play_callback (udi_usb_request_t * request, void *arg)
+{
+ midisport_outqueue_t *q = arg;
+ midisport_devc *devc = q->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (q->mutex, flags);
+ q->busy = 0;
+ submit_output (devc, q);
+ MUTEX_EXIT_IRQRESTORE (q->mutex, flags);
+}
+
+ /*ARGSUSED*/ static void
+submit_output (midisport_devc * devc, midisport_outqueue_t * q)
+{
+ int err;
+ int max_bytes;
+ unsigned char *qbuf;
+
+ if (q->busy)
+ return;
+
+ if (q->playbuf_h == q->playbuf_t) /* Queue empty */
+ return;
+
+ qbuf = q->playbuf[q->playbuf_h];
+ max_bytes = q->max_out_blocks * 4;
+
+ q->playbuf_h = (q->playbuf_h + 1) % QUEUE_ENTRIES;
+ q->busy = 1;
+
+ if ((err =
+ udi_usb_submit_request (q->output_pipe, play_callback, q,
+ q->output_endpoint_handle,
+ UDI_USBXFER_BULK_WRITE, qbuf, max_bytes)) < 0)
+ {
+ cmn_err (CE_WARN, "udi_usb_submit_request (play) failed, err=%d\n",
+ err);
+ }
+}
+
+ /*ARGSUSED*/ static void
+midisport_close_input (int dev, int mode)
+{
+ oss_native_word flags;
+ midisport_midic *midic;
+ midisport_devc *devc;
+ int do_stop = 0;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->open_inputs--;
+ if (devc->open_inputs == 0)
+ do_stop = 1;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (do_stop)
+ {
+ udi_usb_free_request (devc->input_pipe);
+ udi_close_endpoint (devc->input_endpoint_handle);
+ if (devc->recbuf != NULL)
+ CONTIG_FREE (midic->osdev, devc->recbuf, RECBUF_SIZE, devc->recbuf_dma_handle);
+ }
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+ /*ARGSUSED*/ static int
+midisport_open_input (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags;
+ midisport_midic *midic;
+ midisport_devc *devc;
+ oss_native_word phaddr;
+ int do_start = 0;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->midi_input_intr = inputbyte;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ devc->open_inputs++;
+ if (devc->open_inputs == 1)
+ do_start = 1;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ if (do_start)
+ {
+ int err;
+
+ devc->recbuf =
+ CONTIG_MALLOC (devc->osdev, RECBUF_SIZE, MEMLIMIT_32BITS, &phaddr, devc->recbuf_dma_handle);
+ if (devc->recbuf == NULL)
+ {
+ cmn_err (CE_CONT, "Failed to allocate the recording buffer\n");
+ return OSS_ENOMEM;
+ }
+
+ if ((devc->input_endpoint_handle =
+ udi_open_endpoint (devc->usbdev, devc->in_ep_desc)) == NULL)
+ {
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ cmn_err (CE_WARN, "Cannot open audio pipe\n");
+ return OSS_ENOMEM;
+ }
+ if ((devc->input_pipe =
+ udi_usb_alloc_request (devc->usbdev, devc->input_endpoint_handle,
+ 1, UDI_USBXFER_INTR_READ)) == NULL)
+ {
+ return OSS_EIO;
+ }
+
+ if ((err = midisport_start_input (devc)) < 0)
+ {
+ cmn_err (CE_WARN, "midisport: Input error %d\n", err);
+ midisport_close_input (dev, mode);
+ return OSS_EIO;
+ }
+ }
+
+ return 0;
+}
+
+static int
+open_output_queue (midisport_devc * devc, int queue_ix)
+{
+ oss_native_word flags;
+ midisport_outqueue_t *q;
+ int open_count;
+ oss_native_word phaddr;
+
+ if (queue_ix < 0 || queue_ix >= devc->num_queues)
+ {
+ cmn_err (CE_WARN, "Bad output queue index %d\n", queue_ix);
+ return OSS_EIO;
+ }
+
+ q = &devc->out_queues[queue_ix];
+
+ MUTEX_ENTER_IRQDISABLE (q->mutex, flags);
+ open_count = q->open_count++;
+
+ if (open_count == 0) /* First open */
+ {
+ q->playbuf_h = q->playbuf_t = 0;
+ q->busy = 0;
+ }
+ MUTEX_EXIT_IRQRESTORE (q->mutex, flags);
+
+ if (open_count == 0) /* First open */
+ {
+ if ((q->playbuf =
+ CONTIG_MALLOC (devc->osdev, QUEUE_SIZE, MEMLIMIT_32BITS,
+ &phaddr, q->playbuf_dma_handle)) == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate output buffer (%d bytes)\n",
+ QUEUE_SIZE);
+ q->open_count--;
+ return OSS_ENOMEM;
+ }
+
+ if ((q->output_endpoint_handle =
+ udi_open_endpoint (devc->usbdev, q->out_ep_desc)) == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to open output endpoint\n");
+ q->open_count--;
+ return OSS_EIO;
+ }
+
+ if ((q->output_pipe =
+ udi_usb_alloc_request (devc->usbdev, q->output_endpoint_handle, 1,
+ UDI_USBXFER_BULK_WRITE)) == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate output request\n");
+ q->open_count--;
+ return OSS_EIO;
+ }
+
+ }
+ return 0;
+}
+
+static void
+close_output_queue (midisport_devc * devc, int queue_ix)
+{
+ oss_native_word flags;
+ midisport_outqueue_t *q;
+ int open_count;
+
+ if (queue_ix < 0 || queue_ix >= devc->num_queues)
+ {
+ cmn_err (CE_WARN, "Bad output queue index %d\n", queue_ix);
+ return;
+ }
+
+ q = &devc->out_queues[queue_ix];
+
+ if (q->open_count <= 0) /* Was not opened at all */
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (q->mutex, flags);
+ open_count = q->open_count--;
+ MUTEX_EXIT_IRQRESTORE (q->mutex, flags);
+
+ if (open_count <= 1) /* Queue not needed any more */
+ {
+ udi_usb_free_request (q->output_pipe);
+ udi_close_endpoint (q->output_endpoint_handle);
+ if (q->playbuf != NULL)
+ CONTIG_FREE (devc->osdev, q->playbuf, QUEUE_SIZE, q->playbuf_dma_handle);
+ }
+}
+
+ /*ARGSUSED*/ static void
+midisport_close_output (int dev, int mode)
+{
+ oss_native_word flags;
+ midisport_midic *midic;
+ midisport_devc *devc;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ close_output_queue (devc, midic->outqueue_ix);
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midic->open_mode = 0;
+ midic->outputintr = NULL;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+ /*ARGSUSED*/ static int
+midisport_open_output (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags;
+ midisport_midic *midic;
+ midisport_devc *devc;
+ int err;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->midi_input_intr = NULL, midic->outputintr = outputintr;
+ midic->outbuf_p = 0;
+ memset (midic->output_buf, 0, sizeof (midic->output_buf));
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ if ((err = open_output_queue (devc, midic->outqueue_ix)) < 0)
+ {
+ cmn_err (CE_WARN, "Failed to open the output queue (%d)\n", err);
+ midisport_close_output (dev, mode);
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+do_flush (midisport_devc * devc, midisport_midic * midic,
+ midisport_outqueue_t * q)
+{
+ int next;
+ unsigned char *qbuf;
+ int max_bytes;
+
+ /*
+ * Move stuff from the intermediate buffer to the EP queue
+ */
+ max_bytes = q->max_out_blocks * 4;
+ next = (q->playbuf_t + 1) % QUEUE_ENTRIES;
+ if (next == q->playbuf_h) /* No more space in any of the buffers */
+ {
+ return 0;
+ }
+
+ qbuf = q->playbuf[q->playbuf_t];
+ memcpy (qbuf, midic->output_buf, max_bytes);
+ memset (midic->output_buf, 0, max_bytes);
+ midic->outbuf_p = 0;
+ q->playbuf_t = next;
+
+ submit_output (devc, q);
+
+ return 1;
+}
+
+#if 0
+static void
+midisport_flush_output (int dev)
+{
+ midisport_midic *midic = midi_devs[dev]->devc;
+ midisport_devc *devc = midic->devc;
+ midisport_outqueue_t *q;
+ oss_native_word flags;
+ oss_native_word qflags;
+
+ q = &devc->out_queues[midic->outqueue_ix];
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ MUTEX_ENTER_IRQDISABLE (q->mutex, qflags);
+ do_flush (devc, midic, q);
+ MUTEX_EXIT_IRQRESTORE (q->mutex, qflags);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+#endif
+
+static int
+midisport_bulk_write (int dev, unsigned char *buf, int len)
+{
+ midisport_midic *midic = midi_devs[dev]->devc;
+ midisport_devc *devc = midic->devc;
+ oss_native_word flags;
+ oss_native_word qflags;
+ int i, l = 0, n = 0, p;
+ //int max_bytes;
+ midisport_outqueue_t *q;
+ unsigned char *outbuf;
+
+ if (midic->outqueue_ix < 0 || midic->outqueue_ix >= devc->num_queues)
+ {
+ cmn_err (CE_WARN, "Bad output queue index %d\n", midic->outqueue_ix);
+ return OSS_EIO;
+ }
+
+ q = &devc->out_queues[midic->outqueue_ix];
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+
+ //max_bytes = q->max_out_blocks * 4;
+
+ for (i = 0; i < len; i += 3)
+ {
+ l = len - i;
+ if (l > 3)
+ l = 3;
+ p = midic->outbuf_p;
+
+ if ((p + 4) >= q->max_out_blocks)
+ {
+ int next;
+ MUTEX_ENTER_IRQDISABLE (q->mutex, qflags);
+
+ next = (q->playbuf_t + 1) % QUEUE_ENTRIES;
+ if (next == q->playbuf_h) /* No more space in any of the buffers */
+ {
+ MUTEX_EXIT_IRQRESTORE (q->mutex, qflags);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return n;
+ }
+
+ if (!do_flush (devc, midic, q)) /* Output FIFO full */
+ {
+ MUTEX_EXIT_IRQRESTORE (q->mutex, qflags);
+ return n;
+ }
+ p = midic->outbuf_p;
+ MUTEX_EXIT_IRQRESTORE (q->mutex, qflags);
+ }
+
+ outbuf = midic->output_buf + p;
+ memcpy (outbuf, buf, l);
+ outbuf[3] = (midic->portnum << 4) | l;
+ midic->outbuf_p += 4;
+ if (midic->outbuf_p >= q->max_out_blocks)
+ do_flush (devc, midic, q);
+ n += l;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ return n;
+}
+
+ /*ARGSUSED*/ static int
+midisport_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t midisport_midi_input_driver = {
+ midisport_open_input,
+ midisport_close_input,
+ midisport_ioctl
+};
+
+static midi_driver_t midisport_midi_output_driver = {
+ midisport_open_output,
+ midisport_close_output,
+ midisport_ioctl,
+ NULL,
+ midisport_bulk_write,
+ 8 * 3 /* 8 packets of 3 bytes */
+};
+
+static void
+create_inputs (midisport_devc * devc, char *name, int ep, int ninputs)
+{
+ int desc_len;
+ int i, ix = ep;
+ char portid = 'A';
+ unsigned char *desc;
+ int flags = MFLAG_INPUT;
+
+ for (i = 0; i < 32; i++)
+ if ((desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, i, &desc_len)) != NULL)
+ {
+ if (desc[2] == (ep | 0x80))
+ ix = i;
+ }
+
+ if (!alphabethic_numbering)
+ portid = '1';
+
+ if (ninputs > MAX_PORTS)
+ {
+ cmn_err (CE_WARN, "Too many input ports %d\n", ninputs);
+ return;
+ }
+
+ if ((devc->in_ep_desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, ix, &desc_len)) == NULL)
+ {
+ cmn_err (CE_WARN, "Bad endpoint %d\n", ep);
+ return;
+ }
+
+ if (!(devc->in_ep_desc[2] & 0x80))
+ {
+ cmn_err (CE_WARN, "Bad endpoint %d - not input\n", ep);
+ }
+
+ for (i = 0; i < ninputs; i++)
+ {
+ midisport_midic *midic = midic = &devc->in_midic[i];
+ char tmp[128];
+
+ midic->devc = devc;
+ midic->osdev = devc->osdev;
+ MUTEX_INIT (devc->osdev, midic->mutex, MH_DRV + 1);
+ midic->portnum = i;
+ devc->num_inputs++;
+
+ if (i == 8)
+ {
+ sprintf (tmp, "%s SMPTE status", name);
+ flags = MFLAG_MTC;
+ }
+ else
+ sprintf (tmp, "%s input %c", name, portid + i);
+
+ midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "MIDISPORT", tmp,
+ &midisport_midi_input_driver,
+ sizeof (midi_driver_t),
+ flags, midic, midic->osdev);
+ }
+}
+
+static void
+create_output (midisport_devc * devc, char *name, int queue_ix)
+{
+ int n;
+ midisport_midic *midic = NULL;
+ char tmp[128];
+ char portid = 'A';
+ int flags = MFLAG_OUTPUT;
+
+ if (!alphabethic_numbering)
+ portid = '1';
+
+ n = devc->num_outputs++;
+ midic = &devc->out_midic[n];
+ midic->devc = devc;
+ MUTEX_INIT (devc->osdev, midic->mutex, MH_DRV + 1);
+ midic->osdev = devc->osdev;
+ midic->portnum = n;
+ midic->outqueue_ix = queue_ix;
+
+ if (n == 8)
+ {
+ sprintf (tmp, "%s SMPTE control", name);
+ flags = MFLAG_MTC;
+ }
+ else
+ sprintf (tmp, "%s output %c", name, portid + n);
+
+ midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "MIDISPORT", tmp,
+ &midisport_midi_output_driver,
+ sizeof (midi_driver_t),
+ flags, midic, midic->osdev);
+}
+
+static void
+init_outqueue (midisport_devc * devc, int ix, int ep, int max_blocks)
+{
+ int desc_len;
+ midisport_outqueue_t *q;
+ int i, epix = ep;
+
+ unsigned char *desc;
+
+ for (i = 0; i < 32; i++)
+ if ((desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, i, &desc_len)) != NULL)
+ {
+ if (desc[2] == ep)
+ epix = i;
+ }
+
+ if (ix < 0 || ix > devc->num_queues)
+ {
+ cmn_err (CE_WARN, "Endpoint index outside bounds\n");
+ return;
+ }
+
+ q = &devc->out_queues[ix];
+ MUTEX_INIT (devc->osdev, q->mutex, MH_DRV + 2);
+ q->max_out_blocks = max_blocks;
+ q->devc = devc;
+
+ if ((q->out_ep_desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, epix, &desc_len)) == NULL)
+ {
+ cmn_err (CE_WARN, "Bad endpoint %d\n", ep);
+ return;
+ }
+
+ if (q->out_ep_desc[2] & 0x80)
+ {
+ cmn_err (CE_WARN, "Bad endpoint %d - not output\n", ep);
+ }
+ cmn_err (CE_CONT, "Attaching output endpoint %d=%02x\n", ep,
+ q->out_ep_desc[2]);
+}
+
+void *
+midisport_driver (ossusb_devc * usb_devc)
+{
+ midisport_devc *devc;
+ char *name;
+ unsigned int devid;
+ int i;
+ unsigned char *desc;
+ int desc_len;
+
+ devid = (usb_devc->vendor << 16) | usb_devc->product;
+
+ if ((devc = PMALLOC (usb_devc->osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "midisport: Out of memory\n");
+ return NULL;
+ }
+
+ memset (devc, 0, sizeof (*devc));
+
+ devc->unload_func = midisport_unload;
+ devc->osdev = usb_devc->osdev;
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+
+ devc->usb_devc = usb_devc;
+ devc->usbdev = usb_devc->last_usbdev;
+ devc->instance_num = instance_num++;
+
+ for (i = 0; i < 32; i++)
+ if ((desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, i, &desc_len)) != NULL)
+ {
+ if (desc[2] & 0x80)
+ {
+ cmn_err (CE_CONT, "Input endpoint %02x\n", desc[2]);
+ }
+ else
+ {
+ cmn_err (CE_CONT, "Output endpoint %02x\n", desc[2]);
+ }
+ }
+
+ alphabethic_numbering = 1;
+
+ devc->num_queues = 2;
+
+ switch (devid)
+ {
+ case 0x07631002:
+ name = "Midisport 2x2";
+ create_inputs (devc, name, 1, 2);
+ init_outqueue (devc, 0, 2, 8);
+ init_outqueue (devc, 1, 4, 8);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ break;
+
+ case 0x07631011:
+ name = "Midisport 1x1";
+ devc->num_queues = 1;
+ init_outqueue (devc, 0, 2, 8);
+ create_inputs (devc, name, 1, 1);
+ create_output (devc, name, 0);
+ break;
+
+ case 0x07631015:
+ name = "Oxygen8";
+ devc->num_queues = 1;
+ create_inputs (devc, name, 1, 1);
+ init_outqueue (devc, 0, 2, 8);
+ create_output (devc, name, 0);
+ break;
+
+ case 0x07632001:
+ name = "Quattro";
+ devc->num_queues = 1;
+ create_inputs (devc, name, 1, 1);
+ init_outqueue (devc, 0, 2, 8);
+ create_output (devc, name, 0);
+ break;
+
+ case 0x07631031:
+ name = "Midisport 8x8";
+ alphabethic_numbering = 0;
+ create_inputs (devc, name, 2, 9);
+ init_outqueue (devc, 0, 2, 10);
+ init_outqueue (devc, 1, 4, 8);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0); /* SMPTE control */
+ break;
+
+ case 0x07631021:
+ name = "Midisport 4x4";
+ create_inputs (devc, name, 2, 4);
+ init_outqueue (devc, 0, 2, 16);
+ init_outqueue (devc, 1, 4, 16);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ create_output (devc, name, 0);
+ create_output (devc, name, 1);
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Unrecognized MIDI device %08x\n", devid);
+ }
+
+ return devc;
+}
diff --git a/kernel/drv/oss_usb/ossusb_ymhmidi.c b/kernel/drv/oss_usb/ossusb_ymhmidi.c
new file mode 100644
index 0000000..89f749b
--- /dev/null
+++ b/kernel/drv/oss_usb/ossusb_ymhmidi.c
@@ -0,0 +1,653 @@
+/*
+ * Purpose: Dedicated driver for Yamaha USB MIDI devices
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+#include "ossusb.h"
+#include "midiparser.h"
+
+typedef struct ymhusb_devc ymhusb_devc;
+
+#define MAX_INDEVS 1
+#define MAX_OUTDEVS 1
+#define TMPBUF_SIZE 64
+#define TMPBUF_NSLOTS 24
+
+typedef unsigned char tmpbuf_slot_t[TMPBUF_SIZE];
+#define OUTBUF_SIZE (TMPBUF_NSLOTS*TMPBUF_SIZE)
+
+typedef struct
+{
+ ymhusb_devc *devc;
+ oss_device_t *osdev;
+ udi_usb_devc *usbdev;
+ oss_mutex_t mutex;
+
+ int portnum;
+ int midi_dev;
+ int open_mode;
+
+ void *endpoint_desc;
+ udi_endpoint_handle_t *endpoint_handle;
+ udi_usb_request_t *datapipe;
+
+ oss_midi_inputbyte_t midi_input_intr;
+ unsigned char *tmpbuf;
+ oss_dma_handle_t tmpbuf_dma_handle;
+ int tmp_len;
+ midiparser_common_p parser;
+
+ volatile int output_busy;
+
+ /* Output buffer */
+ tmpbuf_slot_t *outbuf;
+ oss_dma_handle_t outbuf_dma_handle;
+ int buf_t, buf_h;
+} ymhusb_midic;
+
+struct ymhusb_devc
+{
+ special_unload_t unload_func;
+
+ oss_device_t *osdev;
+ udi_usb_devc *usbdev;
+
+ oss_mutex_t mutex;
+
+ int n_inputs, n_outputs;
+ ymhusb_midic indevs[MAX_INDEVS], outdevs[MAX_OUTDEVS];
+};
+
+static void
+ymhusb_unload (void *d)
+{
+ ymhusb_devc *devc = (ymhusb_devc *) d;
+ int i;
+
+ for (i = 0; i < devc->n_inputs; i++)
+ {
+ MUTEX_CLEANUP (devc->indevs[i].mutex);
+ }
+ for (i = 0; i < devc->n_outputs; i++)
+ {
+ MUTEX_CLEANUP (devc->outdevs[i].mutex);
+ }
+ MUTEX_CLEANUP (devc->mutex);
+}
+
+static int ymhmidi_start_input (ymhusb_devc * devc, ymhusb_midic * midic);
+
+void
+ymhmidi_record_callback (udi_usb_request_t * request, void *arg)
+{
+ ymhusb_midic *midic = arg;
+ ymhusb_devc *devc = midic->devc;
+ unsigned char *data;
+ int l;
+
+ l = udi_usb_request_actlen (request);
+ data = udi_usb_request_actdata (request);
+
+ if (l == 0)
+ goto restart;
+
+ if (midi_devs[midic->midi_dev]->event_input != NULL)
+ midi_devs[midic->midi_dev]->event_input (midic->midi_dev, data, l);
+
+restart:
+ if (midic->open_mode & OPEN_READ)
+ ymhmidi_start_input (devc, midic);
+}
+
+static int ymhmidi_submit_output (ymhusb_devc * devc, ymhusb_midic * midic);
+
+ /*ARGSUSED*/ void
+ymhmidi_play_callback (udi_usb_request_t * request, void *arg)
+{
+ ymhusb_midic *midic = arg;
+ ymhusb_devc *devc = midic->devc;
+
+ midic->output_busy = 0;
+ ymhmidi_submit_output (devc, midic);
+}
+
+ /*ARGSUSED*/ static int
+ymhmidi_start_input (ymhusb_devc * devc, ymhusb_midic * midic)
+{
+ int err;
+
+ if ((err =
+ udi_usb_submit_request (midic->datapipe, ymhmidi_record_callback,
+ midic, midic->endpoint_handle,
+ UDI_USBXFER_BULK_READ, midic->tmpbuf,
+ TMPBUF_SIZE)) < 0)
+ {
+ return err;
+ }
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static int
+ymhmidi_submit_output (ymhusb_devc * devc, ymhusb_midic * midic)
+{
+ int err;
+ int n = midic->buf_t;
+
+ if (midic->buf_h == midic->buf_t)
+ return 0;
+
+ if ((err =
+ udi_usb_submit_request (midic->datapipe, ymhmidi_play_callback, midic,
+ midic->endpoint_handle, UDI_USBXFER_BULK_WRITE,
+ midic->outbuf[n], TMPBUF_SIZE)) < 0)
+ {
+ cmn_err (CE_WARN, "Submit USB MIDI request failed\n");
+ return err;
+ }
+
+ midic->buf_t = (n + 1) % TMPBUF_NSLOTS;;
+ midic->output_busy = 1;
+
+ return 0;
+}
+
+static int
+ymhmidi_put_output (ymhusb_devc * devc, ymhusb_midic * midic)
+{
+ int n = midic->buf_h;
+
+ midic->buf_h = (n + 1) % TMPBUF_NSLOTS;
+
+ memcpy (midic->outbuf[n], midic->tmpbuf, TMPBUF_SIZE);
+ midic->tmp_len = 0;
+ memset (midic->tmpbuf, 0, TMPBUF_SIZE);
+
+ if (midic->output_busy)
+ return 0;
+
+ ymhmidi_submit_output (devc, midic);
+
+ return 0;
+}
+
+ /*ARGSUSED*/ static void
+ymhusb_close_input (int dev, int mode)
+{
+ oss_native_word flags;
+ ymhusb_midic *midic;
+
+ midic = midi_devs[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ udi_usb_free_request (midic->datapipe);
+ udi_close_endpoint (midic->endpoint_handle);
+ if (midic->tmpbuf != NULL)
+ CONTIG_FREE (midic->osdev, midic->tmpbuf, TMPBUF_SIZE, midic->tmpbuf_dma_handle);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+ /*ARGSUSED*/ static int
+ymhusb_open_input (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags, phaddr;
+ ymhusb_midic *midic;
+ ymhusb_devc *devc;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->midi_input_intr = inputbyte;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ midic->tmpbuf =
+ CONTIG_MALLOC (midic->osdev, TMPBUF_SIZE, MEMLIMIT_32BITS, &phaddr, midic->tmpbuf_dma_handle);
+ memset (midic->tmpbuf, 0, TMPBUF_SIZE);
+
+ if ((midic->endpoint_handle =
+ udi_open_endpoint (midic->usbdev, midic->endpoint_desc)) == NULL)
+ {
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ cmn_err (CE_WARN, "Cannot open audio pipe\n");
+ return OSS_ENOMEM;
+ }
+ if ((midic->datapipe =
+ udi_usb_alloc_request (midic->usbdev, midic->endpoint_handle, 1,
+ UDI_USBXFER_BULK_READ)) == NULL)
+ {
+ return OSS_EIO;
+ }
+
+ return ymhmidi_start_input (devc, midic);
+}
+
+static void
+ymhusb_flush_output (int dev)
+{
+ oss_native_word flags;
+ ymhusb_midic *midic;
+ ymhusb_devc *devc;
+ int next;
+
+ midic = midi_devs[dev]->devc;
+ devc = midic->devc;
+
+ if (midic->tmp_len == 0)
+ return;
+ next = (midic->buf_t + 1) % TMPBUF_NSLOTS;
+ if (next == midic->buf_h) /* Buffer full */
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ ymhmidi_put_output (devc, midic);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+static int
+ymhusb_wait_output (int dev)
+{
+ ymhusb_midic *midic;
+
+ ymhusb_flush_output (dev);
+
+ midic = midi_devs[dev]->devc;
+
+ if (midic->output_busy)
+ return 1;
+
+ if (midic->buf_t == midic->buf_h)
+ return 0; /* Not busy */
+
+ return 1;
+}
+
+ /*ARGSUSED*/ static void
+ymhusb_close_output (int dev, int mode)
+{
+ oss_native_word flags;
+ ymhusb_midic *midic;
+
+ midic = midi_devs[dev]->devc;
+
+ ymhusb_flush_output (dev);
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ udi_usb_free_request (midic->datapipe);
+ udi_close_endpoint (midic->endpoint_handle);
+ if (midic->outbuf != NULL)
+ CONTIG_FREE (midic->osdev, midic->outbuf, OUTBUF_SIZE, midic->outbuf_dma_handle);
+ if (midic->tmpbuf != NULL)
+ KERNEL_FREE (midic->tmpbuf);
+ midiparser_unalloc (midic->parser);
+ midic->parser = NULL;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+}
+
+static void
+out_event (ymhusb_midic * midic, unsigned char a, unsigned char b,
+ unsigned char c, unsigned char d)
+{
+ unsigned char *e;
+ ymhusb_devc *devc = midic->devc;
+
+ if (midic->tmp_len > TMPBUF_SIZE - 4)
+ ymhmidi_put_output (devc, midic);
+
+ e = midic->tmpbuf + midic->tmp_len;
+ *e++ = a;
+ *e++ = b;
+ *e++ = c;
+ *e++ = d;
+
+ midic->tmp_len += 4;
+
+ if (midic->tmp_len >= TMPBUF_SIZE)
+ ymhmidi_put_output (devc, midic);
+}
+
+void
+parser_cb (void *context, int category, unsigned char msg, unsigned char ch,
+ unsigned char *parms, int len)
+{
+ ymhusb_midic *midic = context;
+
+ if (category == CAT_VOICE)
+ {
+ switch (msg)
+ {
+ case MIDI_NOTEON:
+ out_event (midic, 0x9, msg | ch, parms[0], parms[1]);
+ break;
+
+ case MIDI_NOTEOFF:
+ out_event (midic, 0x8, msg | ch, parms[0], parms[1]);
+ break;
+
+ case MIDI_KEY_PRESSURE:
+ out_event (midic, 0xa, msg | ch, parms[0], parms[1]);
+ break;
+ }
+
+ return;
+ }
+
+ if (category == CAT_CHN)
+ {
+ switch (msg)
+ {
+ case MIDI_CTL_CHANGE:
+ out_event (midic, 0xb, msg | ch, parms[0], parms[1]);
+ break;
+
+ case MIDI_PGM_CHANGE:
+ out_event (midic, 0xc, msg | ch, parms[0], 0);
+ break;
+
+ case MIDI_CHN_PRESSURE:
+ out_event (midic, 0xd, msg | ch, parms[0], 0);
+ break;
+
+ case MIDI_PITCH_BEND:
+ out_event (midic, 0xe, msg | ch, parms[0], parms[1]);
+ break;
+ }
+ return;
+ }
+
+ if (category == CAT_REALTIME)
+ {
+ out_event (midic, 0xf, msg | ch, 0, 0);
+ return;
+ }
+
+ if (category == CAT_MTC)
+ {
+ out_event (midic, 0x2, 0xf1, parms[0], 0);
+ return;
+ }
+
+ if (category == CAT_SYSEX)
+ {
+ int l = len, n;
+ unsigned char *d = parms;
+
+ while (l > 0)
+ {
+ n = l;
+ if (n > 3)
+ n = 3;
+
+ switch (n)
+ {
+ case 3:
+ out_event (midic, 0x4, d[0], d[1], d[2]);
+ break;
+ case 2:
+ out_event (midic, 0x6, d[0], d[1], 0);
+ break;
+ case 1:
+ out_event (midic, 0x5, d[0], 0, 0);
+ break;
+ }
+
+ l -= n;
+ d += n;
+ }
+ return;
+ }
+}
+
+ /*ARGSUSED*/ static int
+ymhusb_open_output (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr)
+{
+ oss_native_word flags, phaddr;
+ ymhusb_midic *midic;
+
+ midic = midi_devs[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ if (midic->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ midic->open_mode = mode;
+ midic->output_busy = 0;
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ midic->tmpbuf = KERNEL_MALLOC (TMPBUF_SIZE);
+ memset (midic->tmpbuf, 0, TMPBUF_SIZE);
+ midic->outbuf =
+ CONTIG_MALLOC (midic->osdev, OUTBUF_SIZE, MEMLIMIT_32BITS, &phaddr, midic->outbuf_dma_handle);
+ midic->tmp_len = 0;
+ midic->buf_h = midic->buf_t = 0; /* Empty buffer */
+ memset (midic->outbuf, 0, OUTBUF_SIZE);
+
+ if ((midic->parser = midiparser_create (parser_cb, midic)) == NULL)
+ {
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ cmn_err (CE_WARN, "Cannot create MIDI parser\n");
+ return OSS_ENOMEM;
+ }
+
+ if ((midic->endpoint_handle =
+ udi_open_endpoint (midic->usbdev, midic->endpoint_desc)) == NULL)
+ {
+ midic->open_mode = 0;
+ midic->midi_input_intr = NULL;
+ cmn_err (CE_WARN, "Cannot open audio pipe\n");
+ return OSS_ENOMEM;
+ }
+ if ((midic->datapipe =
+ udi_usb_alloc_request (midic->usbdev, midic->endpoint_handle, 1,
+ UDI_USBXFER_BULK_WRITE)) == NULL)
+ {
+ return OSS_EIO;
+ }
+
+ return 0;
+}
+
+static int
+ymhusb_out (int dev, unsigned char midi_byte)
+{
+ ymhusb_midic *midic = midi_devs[dev]->devc;
+ oss_native_word flags;
+ int next;
+
+ next = (midic->buf_t + 1) % TMPBUF_NSLOTS;
+ if (next == midic->buf_h) /* Buffer full */
+ return 0; /* Try again later */
+
+ MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
+ midiparser_input (midic->parser, midi_byte);
+ MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
+
+ return 1;
+}
+
+ /*ARGSUSED*/ static int
+ymhusb_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t ymhusb_input_driver = {
+ ymhusb_open_input,
+ ymhusb_close_input,
+ ymhusb_ioctl,
+ ymhusb_out,
+};
+
+static void
+add_input_device (ymhusb_devc * devc, char *name, void *desc, int caps)
+{
+ int n;
+ ymhusb_midic *midic;
+ char tmp[128];
+
+ if (devc->n_inputs >= MAX_INDEVS)
+ {
+ cmn_err (CE_WARN, "Yamaha MIDI: Too many inputs\n");
+ return;
+ }
+
+ n = devc->n_inputs++;
+
+ midic = &devc->indevs[n];
+
+ midic->devc = devc;
+ midic->osdev = devc->osdev;
+ MUTEX_INIT (midic->osdev, midic->mutex, MH_DRV + 1);
+ midic->endpoint_desc = desc;
+ midic->portnum = n;
+ midic->usbdev = devc->usbdev;
+
+ sprintf (tmp, "%s input %d", name, n);
+ if ((midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "YMHMIDI", tmp,
+ &ymhusb_input_driver,
+ sizeof (ymhusb_input_driver),
+ MFLAG_INPUT, midic, midic->osdev)) < 0)
+ {
+ cmn_err (CE_CONT, "Failed to install MIDI device\n");
+ return;
+ }
+ midi_devs[midic->midi_dev]->caps |= caps;
+}
+
+static midi_driver_t ymhusb_output_driver = {
+ ymhusb_open_output,
+ ymhusb_close_output,
+ ymhusb_ioctl,
+ ymhusb_out,
+ NULL,
+ 0,
+ ymhusb_flush_output,
+ ymhusb_wait_output
+};
+
+static void
+add_output_device (ymhusb_devc * devc, char *name, void *desc, int caps)
+{
+ int n;
+ ymhusb_midic *midic;
+ char tmp[128];
+
+ if (devc->n_outputs >= MAX_OUTDEVS)
+ {
+ cmn_err (CE_WARN, "Yamaha MIDI: Too many outputs\n");
+ return;
+ }
+
+ n = devc->n_outputs++;
+
+ midic = &devc->outdevs[n];
+
+ midic->devc = devc;
+ midic->osdev = devc->osdev;
+ MUTEX_INIT (midic->osdev, midic->mutex, MH_DRV + 1);
+ midic->endpoint_desc = desc;
+ midic->portnum = n;
+ midic->usbdev = devc->usbdev;
+
+ sprintf (tmp, "%s output %d", name, n);
+ if ((midic->midi_dev =
+ oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "YMHMIDI", tmp,
+ &ymhusb_output_driver,
+ sizeof (ymhusb_output_driver),
+ MFLAG_OUTPUT, midic, midic->osdev)) < 0)
+ {
+ cmn_err (CE_CONT, "Failed to install MIDI device\n");
+ return;
+ }
+
+ midi_devs[midic->midi_dev]->caps |= caps;
+}
+
+void *
+yamaha_usb_midi_driver (ossusb_devc * usb_devc)
+{
+ ymhusb_devc *devc;
+ int i;
+ unsigned char *desc;
+ int desc_len;
+ int caps = MIDI_CAP_EXTERNAL;
+ unsigned int devid;
+
+ char *name = "Yamaha USB MIDI";
+
+ if (usb_devc->dev_name != NULL)
+ name = usb_devc->dev_name;
+
+ if ((devc = PMALLOC (usb_devc->osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Yamaha MIDI: Out of memory\n");
+ return NULL;
+ }
+
+ memset (devc, 0, sizeof (*devc));
+
+ devc->unload_func = ymhusb_unload;
+ devc->osdev = usb_devc->osdev;
+ devc->usbdev = usb_devc->last_usbdev;
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ devid = (usb_devc->vendor << 16) | usb_devc->product;
+
+ DDB (cmn_err
+ (CE_CONT, "Attaching Yamaha MIDI device %08x (%s)\n", devid, name));
+
+ switch (devid)
+ {
+ case 0x0499101e: /* PSR-K1 keyboard */
+ caps |= MIDI_CAP_PTOP;
+ break;
+ }
+
+ for (i = 0; i < 32; i++)
+ if ((desc =
+ udi_usbdev_get_endpoint (devc->usbdev, 0, i, &desc_len)) != NULL)
+ {
+ if (desc[2] & 0x80)
+ {
+ add_input_device (devc, name, desc, caps);
+ }
+ else
+ {
+ add_output_device (devc, name, desc, caps);
+ }
+ }
+
+ return devc;
+}
diff --git a/kernel/drv/oss_usb/oxygen8_fw.h b/kernel/drv/oss_usb/oxygen8_fw.h
new file mode 100755
index 0000000..a5fe5e6
--- /dev/null
+++ b/kernel/drv/oss_usb/oxygen8_fw.h
@@ -0,0 +1,678 @@
+/*
+ * Purpose: Firmware download for M-Audio Oxygen8 MIDI keyboard
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+const struct setup_request oxygen8_setupRequest[] = {
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x146C, 0x0000, 0x0010, 0x0010,
+ "\xC2\x00\x90\x7F\xA5\xE0\x54\x18\xFF\x13\x13\x13\x54\x1F\x44\x50"},
+ {0x40, 0xA0, 0x147C, 0x0000, 0x0010, 0x0010,
+ "\xF5\x1C\x13\x92\x01\xD2\xE8\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9"},
+ {0x40, 0xA0, 0x148C, 0x0000, 0x0010, 0x0010,
+ "\xF0\x90\x7F\xAA\xF0\x53\x91\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90"},
+ {0x40, 0xA0, 0x149C, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAF\xE0\x44\x01\xF0\x90\x7F\xAE\xE0\x44\x05\xF0\xD2\xAF\x12"},
+ {0x40, 0xA0, 0x14AC, 0x0000, 0x000D, 0x000D,
+ "\x17\x5F\x30\x00\xFD\x12\x11\x00\xC2\x00\x80\xF6\x22"},
+ {0x40, 0xA0, 0x1100, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x24\x5D\x60\x0D\x14\x70\x03\x02\x12\x44\x24\x02"},
+ {0x40, 0xA0, 0x1110, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x12\x4A\x90\x7F\xEA\xE0\x75\x08\x00\xF5\x09\xA3\xE0"},
+ {0x40, 0xA0, 0x1120, 0x0000, 0x0010, 0x0010,
+ "\xFE\xE4\x25\x09\xF5\x09\xEE\x35\x08\xF5\x08\x90\x7F\xEE\xE0\x75"},
+ {0x40, 0xA0, 0x1130, 0x0000, 0x0010, 0x0010,
+ "\x0A\x00\xF5\x0B\xA3\xE0\xFE\xE4\x25\x0B\xF5\x0B\xEE\x35\x0A\xF5"},
+ {0x40, 0xA0, 0x1140, 0x0000, 0x0010, 0x0010,
+ "\x0A\x90\x7F\xE8\xE0\x64\xC0\x60\x03\x02\x11\xD4\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x1150, 0x0000, 0x0010, 0x0010,
+ "\x70\x03\x02\x12\x4A\xC3\xE5\x0B\x94\x40\xE5\x0A\x94\x00\x50\x08"},
+ {0x40, 0xA0, 0x1160, 0x0000, 0x0010, 0x0010,
+ "\x85\x0A\x0C\x85\x0B\x0D\x80\x06\x75\x0C\x00\x75\x0D\x40\x90\x7F"},
+ {0x40, 0xA0, 0x1170, 0x0000, 0x0010, 0x0010,
+ "\xE9\xE0\xB4\xA3\x25\xAE\x0C\xAF\x0D\xAA\x08\xA9\x09\x7B\x01\xC0"},
+ {0x40, 0xA0, 0x1180, 0x0000, 0x0010, 0x0010,
+ "\x03\xC0\x02\xC0\x01\x7A\x7F\x79\x00\x78\x00\x7C\x7F\xAD\x03\xD0"},
+ {0x40, 0xA0, 0x1190, 0x0000, 0x0010, 0x0010,
+ "\x01\xD0\x02\xD0\x03\x12\x13\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D"},
+ {0x40, 0xA0, 0x11A0, 0x0000, 0x0010, 0x0010,
+ "\x7A\x7F\x79\x00\x7B\x00\x12\x15\xA4\x90\x7F\xB5\xE5\x0D\xF0\xE5"},
+ {0x40, 0xA0, 0x11B0, 0x0000, 0x0010, 0x0010,
+ "\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5\x0B\x95\x0D"},
+ {0x40, 0xA0, 0x11C0, 0x0000, 0x0010, 0x0010,
+ "\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x20\xE2\x03\x02"},
+ {0x40, 0xA0, 0x11D0, 0x0000, 0x0010, 0x0010,
+ "\x11\x4C\x80\xF4\x90\x7F\xE8\xE0\x64\x40\x70\x6E\xE5\x0B\x45\x0A"},
+ {0x40, 0xA0, 0x11E0, 0x0000, 0x0010, 0x0010,
+ "\x60\x68\xE4\x90\x7F\xC5\xF0\x90\x7F\xB4\xE0\x20\xE3\xF9\x90\x7F"},
+ {0x40, 0xA0, 0x11F0, 0x0000, 0x0010, 0x0010,
+ "\xC5\xE0\x75\x0C\x00\xF5\x0D\x90\x7F\xE9\xE0\xB4\xA3\x15\xAE\x0C"},
+ {0x40, 0xA0, 0x1200, 0x0000, 0x0010, 0x0010,
+ "\xAF\x0D\xA8\x09\xAC\x08\x7D\x01\x7B\x01\x7A\x7E\x79\xC0\x12\x13"},
+ {0x40, 0xA0, 0x1210, 0x0000, 0x0010, 0x0010,
+ "\x56\x80\x0F\xAF\x09\xAE\x08\xAD\x0D\x7A\x7F\x79\x00\x7B\x00\x12"},
+ {0x40, 0xA0, 0x1220, 0x0000, 0x0010, 0x0010,
+ "\x14\xB9\xE5\x0D\x25\x09\xF5\x09\xE5\x0C\x35\x08\xF5\x08\xC3\xE5"},
+ {0x40, 0xA0, 0x1230, 0x0000, 0x0010, 0x0010,
+ "\x0B\x95\x0D\xF5\x0B\xE5\x0A\x95\x0C\xF5\x0A\x90\x7F\xB4\xE0\x44"},
+ {0x40, 0xA0, 0x1240, 0x0000, 0x000A, 0x000A,
+ "\x02\xF0\x80\x98\x90\x7F\xEA\xE0\xF5\x1C"},
+ {0x40, 0xA0, 0x124A, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x1558, 0x0000, 0x0006, 0x0006, "\xAB\x07\xAA\x06\xAC\x05"},
+ {0x40, 0xA0, 0x155E, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x11\xEA\xFF\xAE\x05\x0D\xEE\x24\x00\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x156E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEF\xF0\xEB\xAE\x05\x0D\x74\x00\x2E\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x157E, 0x0000, 0x0010, 0x0010,
+ "\x34\xE0\xF5\x83\xEB\xF0\xAF\x05\x0D\x74\x00\x2F\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x158E, 0x0000, 0x0010, 0x0010,
+ "\xE0\xF5\x83\xEC\xF0\xAF\x1C\x7A\xE0\x7B\x00\x12\x17\x20\x7F\x0A"},
+ {0x40, 0xA0, 0x159E, 0x0000, 0x0005, 0x0005, "\x7E\x00\x12\x17\x3C"},
+ {0x40, 0xA0, 0x15A3, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x14B9, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x14C3, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x13\xE5\x13\xC3\x95\x10\x50\x20\x05\x0F\xE5\x0F\xAE\x0E"},
+ {0x40, 0xA0, 0x14D3, 0x0000, 0x0010, 0x0010,
+ "\x70\x02\x05\x0E\x14\xFF\xE5\x12\x25\x13\xF5\x82\xE4\x35\x11\xF5"},
+ {0x40, 0xA0, 0x14E3, 0x0000, 0x000A, 0x000A,
+ "\x83\xE0\xFD\x12\x15\x58\x05\x13\x80\xD9"},
+ {0x40, 0xA0, 0x14ED, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x15A4, 0x0000, 0x000A, 0x000A,
+ "\x8E\x0E\x8F\x0F\x8D\x10\x8A\x11\x8B\x12"},
+ {0x40, 0xA0, 0x15AE, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFD\x30\x01\x12\xE5\x0E\xFF\xAE\x05\x0D\xEE\x24\x03\xF5\x82"},
+ {0x40, 0xA0, 0x15BE, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\xE0\xF5\x83\xEF\xF0\xE5\x0F\xAE\x05\x0D\x74\x03\x2E\xF5"},
+ {0x40, 0xA0, 0x15CE, 0x0000, 0x0010, 0x0010,
+ "\x82\xE4\x34\xE0\xF5\x83\xE5\x0F\xF0\xAF\x1C\x7A\xE0\x7B\x03\x12"},
+ {0x40, 0xA0, 0x15DE, 0x0000, 0x000D, 0x000D,
+ "\x17\x20\xAF\x1C\xAD\x10\xAB\x12\xAA\x11\x12\x17\x04"},
+ {0x40, 0xA0, 0x15EB, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x166E, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x167E, 0x0000, 0x0010, 0x0010,
+ "\x00\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x168E, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1644, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x1654, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x1664, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1695, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16A5, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x02\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16B5, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x16BA, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16CA, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16DA, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x14FF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x16DF, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x16EF, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x16FF, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1767, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1768, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1769, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176A, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176B, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176C, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176D, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176E, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x176F, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1770, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1771, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1772, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1773, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1774, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1775, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x1776, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x15\x00"},
+ {0x40, 0xA0, 0x1500, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\x6E\x00\x02\x16\x95\x00\x02\x16\x44\x00\x02\x16\xDF\x00"},
+ {0x40, 0xA0, 0x1510, 0x0000, 0x0010, 0x0010,
+ "\x02\x16\xBA\x00\x02\x14\xFF\x00\x02\x17\x67\x00\x02\x17\x68\x00"},
+ {0x40, 0xA0, 0x1520, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x69\x00\x02\x17\x6A\x00\x02\x17\x6B\x00\x02\x17\x6C\x00"},
+ {0x40, 0xA0, 0x1530, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x6D\x00\x02\x17\x6E\x00\x02\x17\x6F\x00\x02\x17\x70\x00"},
+ {0x40, 0xA0, 0x1540, 0x0000, 0x0010, 0x0010,
+ "\x02\x17\x71\x00\x02\x17\x72\x00\x02\x17\x73\x00\x02\x17\x74\x00"},
+ {0x40, 0xA0, 0x1550, 0x0000, 0x0008, 0x0008,
+ "\x02\x17\x75\x00\x02\x17\x76\x00"},
+ {0x40, 0xA0, 0x173C, 0x0000, 0x0010, 0x0010,
+ "\x8E\x14\x8F\x15\xE5\x15\x15\x15\xAE\x14\x70\x02\x15\x14\x4E\x60"},
+ {0x40, 0xA0, 0x174C, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x14\xEE\x80\xEE\x22"},
+ {0x40, 0xA0, 0x175F, 0x0000, 0x0008, 0x0008,
+ "\xE4\xF5\x1B\xD2\xE9\xD2\xAF\x22"},
+ {0x40, 0xA0, 0x1619, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x23\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x1629, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A\x18\x89"},
+ {0x40, 0xA0, 0x1639, 0x0000, 0x000B, 0x000B,
+ "\x19\xE4\xF5\x1A\x75\x1B\x01\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x15EC, 0x0000, 0x0010, 0x0010,
+ "\xA9\x07\xE5\x1B\x70\x25\x90\x7F\xA5\xE0\x44\x80\xF0\xE9\x25\xE0"},
+ {0x40, 0xA0, 0x15FC, 0x0000, 0x0010, 0x0010,
+ "\x44\x01\x90\x7F\xA6\xF0\x8D\x16\xAF\x03\xA9\x07\x75\x17\x01\x8A"},
+ {0x40, 0xA0, 0x160C, 0x0000, 0x000D, 0x000D,
+ "\x18\x89\x19\xE4\xF5\x1A\x75\x1B\x03\xD3\x22\xC3\x22"},
+ {0x40, 0xA0, 0x004B, 0x0000, 0x0003, 0x0003, "\x02\x13\x7F"},
+ {0x40, 0xA0, 0x137F, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x138F, 0x0000, 0x0010, 0x0010,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x01\xC0\x02\xC0\x03\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x139F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xA5\xE0\x30\xE2\x06\x75\x1B\x06\x02\x14\x4E\x90\x7F\xA5"},
+ {0x40, 0xA0, 0x13AF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x20\xE1\x0C\xE5\x1B\x64\x02\x60\x06\x75\x1B\x07\x02\x14\x4E"},
+ {0x40, 0xA0, 0x13BF, 0x0000, 0x0010, 0x0010,
+ "\xAF\x1B\xEF\x24\xFE\x60\x48\x14\x60\x2C\x24\xFE\x60\x77\x24\x04"},
+ {0x40, 0xA0, 0x13CF, 0x0000, 0x0010, 0x0010,
+ "\x60\x03\x02\x14\x4E\xAB\x17\xAA\x18\xA9\x19\xAF\x1A\x05\x1A\x8F"},
+ {0x40, 0xA0, 0x13DF, 0x0000, 0x0010, 0x0010,
+ "\x82\x75\x83\x00\x12\x12\x4B\x90\x7F\xA6\xF0\xE5\x1A\x65\x16\x70"},
+ {0x40, 0xA0, 0x13EF, 0x0000, 0x0010, 0x0010,
+ "\x5E\x75\x1B\x05\x80\x59\x90\x7F\xA6\xE0\xAB\x17\xAA\x18\xA9\x19"},
+ {0x40, 0xA0, 0x13FF, 0x0000, 0x0010, 0x0010,
+ "\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12\x78\x75\x1B\x02\x80\x40\xE5"},
+ {0x40, 0xA0, 0x140F, 0x0000, 0x0010, 0x0010,
+ "\x16\x24\xFE\xB5\x1A\x07\x90\x7F\xA5\xE0\x44\x20\xF0\xE5\x16\x14"},
+ {0x40, 0xA0, 0x141F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x1A\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x90\x7F\xA6"},
+ {0x40, 0xA0, 0x142F, 0x0000, 0x0010, 0x0010,
+ "\xE0\xAB\x17\xAA\x18\xA9\x19\xAE\x1A\x8E\x82\x75\x83\x00\x12\x12"},
+ {0x40, 0xA0, 0x143F, 0x0000, 0x0010, 0x0010,
+ "\x78\x05\x1A\x80\x0A\x90\x7F\xA5\xE0\x44\x40\xF0\x75\x1B\x00\x53"},
+ {0x40, 0xA0, 0x144F, 0x0000, 0x0010, 0x0010,
+ "\x91\xDF\xD0\x07\xD0\x06\xD0\x03\xD0\x02\xD0\x01\xD0\x00\xD0\xD0"},
+ {0x40, 0xA0, 0x145F, 0x0000, 0x000D, 0x000D,
+ "\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x1704, 0x0000, 0x0010, 0x0010,
+ "\x12\x15\xEC\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1714, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x1720, 0x0000, 0x0010, 0x0010,
+ "\x12\x16\x19\xE5\x1B\x24\xFA\x60\x0E\x14\x60\x06\x24\x07\x70\xF3"},
+ {0x40, 0xA0, 0x1730, 0x0000, 0x000C, 0x000C,
+ "\xD3\x22\xE4\xF5\x1B\xD3\x22\xE4\xF5\x1B\xD3\x22"},
+ {0x40, 0xA0, 0x14EE, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x14FE, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x17\x53"},
+ {0x40, 0xA0, 0x1753, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x20\x02\x14\x6C"},
+ {0x40, 0xA0, 0x124B, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x125B, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x126B, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x1278, 0x0000, 0x0010, 0x0010,
+ "\xF8\xBB\x01\x0D\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE8\xF0"},
+ {0x40, 0xA0, 0x1288, 0x0000, 0x0010, 0x0010,
+ "\x22\x50\x06\xE9\x25\x82\xC8\xF6\x22\xBB\xFE\x05\xE9\x25\x82\xC8"},
+ {0x40, 0xA0, 0x1298, 0x0000, 0x0002, 0x0002, "\xF2\x22"},
+ {0x40, 0xA0, 0x129A, 0x0000, 0x0010, 0x0010,
+ "\xE7\x09\xF6\x08\xDF\xFA\x80\x46\xE7\x09\xF2\x08\xDF\xFA\x80\x3E"},
+ {0x40, 0xA0, 0x12AA, 0x0000, 0x0010, 0x0010,
+ "\x88\x82\x8C\x83\xE7\x09\xF0\xA3\xDF\xFA\x80\x32\xE3\x09\xF6\x08"},
+ {0x40, 0xA0, 0x12BA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x6E\xE3\x09\xF2\x08\xDF\xFA\x80\x66\x88\x82\x8C\x83"},
+ {0x40, 0xA0, 0x12CA, 0x0000, 0x0010, 0x0010,
+ "\xE3\x09\xF0\xA3\xDF\xFA\x80\x5A\x89\x82\x8A\x83\xE0\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x12DA, 0x0000, 0x0010, 0x0010,
+ "\xDF\xFA\x80\x4E\x89\x82\x8A\x83\xE0\xA3\xF2\x08\xDF\xFA\x80\x42"},
+ {0x40, 0xA0, 0x12EA, 0x0000, 0x0010, 0x0010,
+ "\x80\xD2\x80\xFA\x80\xC6\x80\xD4\x80\x55\x80\xF2\x80\x29\x80\x10"},
+ {0x40, 0xA0, 0x12FA, 0x0000, 0x0010, 0x0010,
+ "\x80\xA6\x80\xEA\x80\x9A\x80\xA8\x80\xDA\x80\xE2\x80\xCA\x80\x29"},
+ {0x40, 0xA0, 0x130A, 0x0000, 0x0010, 0x0010,
+ "\x88\x84\x8C\x85\x89\x82\x8A\x83\xE4\x93\xA3\x05\x86\xF0\xA3\x05"},
+ {0x40, 0xA0, 0x131A, 0x0000, 0x0010, 0x0010,
+ "\x86\xDF\xF5\xDE\xF3\x80\x0B\x89\x82\x8A\x83\xE4\x93\xA3\xF6\x08"},
+ {0x40, 0xA0, 0x132A, 0x0000, 0x0010, 0x0010,
+ "\xDF\xF9\xEC\xFA\xA9\xF0\xED\xFB\x22\x88\x84\x8C\x85\x89\x82\x8A"},
+ {0x40, 0xA0, 0x133A, 0x0000, 0x0010, 0x0010,
+ "\x83\xE0\xA3\x05\x86\xF0\xA3\x05\x86\xDF\xF6\xDE\xF4\x80\xE3\x89"},
+ {0x40, 0xA0, 0x134A, 0x0000, 0x0010, 0x0010,
+ "\x82\x8A\x83\xE4\x93\xA3\xF2\x08\xDF\xF9\x80\xD6\x88\xF0\xED\x24"},
+ {0x40, 0xA0, 0x135A, 0x0000, 0x0010, 0x0010,
+ "\x02\xB4\x04\x00\x50\xCC\xF5\x82\xEB\x24\x02\xB4\x04\x00\x50\xC2"},
+ {0x40, 0xA0, 0x136A, 0x0000, 0x0010, 0x0010,
+ "\x23\x23\x45\x82\xF5\x82\xEF\x4E\x60\xB8\xEF\x60\x01\x0E\xE5\x82"},
+ {0x40, 0xA0, 0x137A, 0x0000, 0x0005, 0x0005, "\x23\x90\x12\xEA\x73"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x0100, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0110, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0120, 0x0000, 0x0010, 0x0010,
+ "\x4D\x69\x64\x69\x6D\x61\x6E\x20\x55\x53\x42\x20\x4D\x69\x64\x69"},
+ {0x40, 0xA0, 0x0130, 0x0000, 0x0010, 0x0010,
+ "\x53\x70\x6F\x72\x74\x20\x31\x78\x31\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0140, 0x0000, 0x0010, 0x0010,
+ "\x46\x69\x72\x6D\x77\x61\x72\x65\x20\x52\x65\x6C\x65\x61\x73\x65"},
+ {0x40, 0xA0, 0x0150, 0x0000, 0x0010, 0x0010,
+ "\x20\x31\x2E\x32\x31\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0160, 0x0000, 0x0010, 0x0010,
+ "\x28\x63\x29\x20\x32\x30\x30\x30\x2D\x32\x30\x30\x31\x2C\x20\x4D"},
+ {0x40, 0xA0, 0x0170, 0x0000, 0x0010, 0x0010,
+ "\x69\x64\x69\x6D\x61\x6E\x20\x49\x6E\x63\x2E\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x0180, 0x0000, 0x0010, 0x0010,
+ "\x41\x6C\x6C\x20\x72\x69\x67\x68\x74\x73\x20\x72\x65\x73\x65\x72"},
+ {0x40, 0xA0, 0x0190, 0x0000, 0x0010, 0x0010,
+ "\x76\x65\x64\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01A0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x01B0, 0x0000, 0x0010, 0x0010,
+ "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"},
+ {0x40, 0xA0, 0x08B2, 0x0000, 0x0003, 0x0003, "\x01\x1C\x00"},
+ {0x40, 0xA0, 0x040D, 0x0000, 0x0010, 0x0010,
+ "\xC2\x01\xC2\x00\xC2\x04\xC2\x03\x12\x09\xE1\xD2\xE8\x43\xD8\x20"},
+ {0x40, 0xA0, 0x041D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xAB\x74\xFF\xF0\x90\x7F\xA9\xF0\x90\x7F\xAA\xF0\x53\x91"},
+ {0x40, 0xA0, 0x042D, 0x0000, 0x0010, 0x0010,
+ "\xEF\x90\x7F\x95\xE0\x44\xC0\xF0\x90\x7F\xAF\xE0\x44\x01\xF0\x90"},
+ {0x40, 0xA0, 0x043D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xAE\xE0\x44\x1D\xF0\x90\x7F\x92\xE0\x44\x02\xF0\x90\x7F\x95"},
+ {0x40, 0xA0, 0x044D, 0x0000, 0x0010, 0x0010,
+ "\xE0\x44\x01\xF0\x90\x7F\x9E\xE0\x54\xFE\xF0\x90\x7F\x95\xE0\x44"},
+ {0x40, 0xA0, 0x045D, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x90\x7F\x9E\xE0\x44\x02\xF0\x90\x7F\x95\xE0\x54\x83\xF0"},
+ {0x40, 0xA0, 0x046D, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\x9E\xE0\x44\x7C\xF0\x90\x7F\x94\xE0\x54\xFE\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x047D, 0x0000, 0x0010, 0x0010,
+ "\x9D\xE0\x44\x01\xF0\x90\x7F\x9A\xE0\x44\x01\x90\x7F\x97\xF0\x43"},
+ {0x40, 0xA0, 0x048D, 0x0000, 0x0010, 0x0010,
+ "\x21\x20\x43\x21\x40\x43\x21\x10\x53\x89\xF0\xE4\xF5\x8C\xF5\x8A"},
+ {0x40, 0xA0, 0x049D, 0x0000, 0x0010, 0x0010,
+ "\xD2\x8C\xD2\xA9\x12\x0B\xAE\xD2\xAF\xE5\x89\x54\x0F\x24\x20\xF5"},
+ {0x40, 0xA0, 0x04AD, 0x0000, 0x0010, 0x0010,
+ "\x89\x75\x8D\xFE\x75\x8B\xFE\xD2\x8E\xC2\xAC\x75\x98\x50\xC2\x98"},
+ {0x40, 0xA0, 0x04BD, 0x0000, 0x0010, 0x0010,
+ "\xC2\x99\xD2\xAC\x53\x21\xDF\x53\x21\xBF\x53\x21\xEF\x90\x7F\x9A"},
+ {0x40, 0xA0, 0x04CD, 0x0000, 0x0010, 0x0010,
+ "\xE0\x54\xFE\x90\x7F\x97\xF0\x90\x7F\x98\xE5\x21\xF0\x75\x24\x3D"},
+ {0x40, 0xA0, 0x04DD, 0x0000, 0x0010, 0x0010,
+ "\xE5\x24\x70\xFC\x43\x21\x20\x43\x21\x40\x43\x21\x10\x90\x7F\x98"},
+ {0x40, 0xA0, 0x04ED, 0x0000, 0x0010, 0x0010,
+ "\xE5\x21\xF0\x20\x01\x3C\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9"},
+ {0x40, 0xA0, 0x04FD, 0x0000, 0x0010, 0x0010,
+ "\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9\x75\x24\xF4\xE5\x24\x60"},
+ {0x40, 0xA0, 0x050D, 0x0000, 0x0010, 0x0010,
+ "\x03\x30\x01\xF9\x75\x24\xF4\xE5\x24\x60\x03\x30\x01\xF9\x75\x24"},
+ {0x40, 0xA0, 0x051D, 0x0000, 0x0010, 0x0010,
+ "\xF4\xE5\x24\x60\x03\x30\x01\xF9\x20\x01\xC8\xD2\x06\x12\x0A\xE0"},
+ {0x40, 0xA0, 0x052D, 0x0000, 0x0010, 0x0010,
+ "\x80\xC1\x30\x01\x0C\x12\x01\xFF\xC2\x01\x90\x7F\xAE\xE0\x44\x02"},
+ {0x40, 0xA0, 0x053D, 0x0000, 0x0010, 0x0010,
+ "\xF0\x30\x04\x1A\x12\x0B\x91\x50\x13\x12\x0B\x05\x20\x03\x07\x90"},
+ {0x40, 0xA0, 0x054D, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD6\xE0\x20\xE7\xF3\x12\x0B\x26\x12\x0B\xB2\xC2\x04\x05\x1C"},
+ {0x40, 0xA0, 0x055D, 0x0000, 0x0010, 0x0010,
+ "\xE5\x1C\xC3\x94\x06\x40\x03\xE4\xF5\x1C\xE5\x1C\x75\xF0\x03\xA4"},
+ {0x40, 0xA0, 0x056D, 0x0000, 0x000E, 0x000E,
+ "\x24\x0A\xF8\x08\xE6\xFA\x08\xE6\xF9\x12\x07\x11\x80\xB4"},
+ {0x40, 0xA0, 0x057B, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0033, 0x0000, 0x0003, 0x0003, "\x02\x0B\xAA"},
+ {0x40, 0xA0, 0x0BAA, 0x0000, 0x0004, 0x0004, "\x53\xD8\xEF\x32"},
+ {0x40, 0xA0, 0x0023, 0x0000, 0x0003, 0x0003, "\x02\x07\x17"},
+ {0x40, 0xA0, 0x0717, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x0727, 0x0000, 0x000C, 0x000C,
+ "\xD0\x75\xD0\x00\xC0\x00\xC0\x05\xC0\x06\xC0\x07"},
+ {0x40, 0xA0, 0x0733, 0x0000, 0x0010, 0x0010,
+ "\x30\x99\x23\xC2\x99\xE5\x68\x60\x1B\xAF\x67\x05\x67\x74\x00\x2F"},
+ {0x40, 0xA0, 0x0743, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x0F\xF5\x83\xE0\xF5\x99\x15\x68\x53\x21\xBF\x75"},
+ {0x40, 0xA0, 0x0753, 0x0000, 0x0010, 0x0010,
+ "\x23\x0C\x80\x02\xD2\x02\x30\x98\x1E\xC2\x98\xAF\x99\xE5\x66\x04"},
+ {0x40, 0xA0, 0x0763, 0x0000, 0x0010, 0x0010,
+ "\x54\x3F\xFE\x65\x65\x60\x0A\xAD\x66\x74\x25\x2D\xF8\xA6\x07\x8E"},
+ {0x40, 0xA0, 0x0773, 0x0000, 0x0007, 0x0007,
+ "\x66\x53\x21\xDF\x75\x22\x0C"},
+ {0x40, 0xA0, 0x077A, 0x0000, 0x0010, 0x0010,
+ "\xD0\x07\xD0\x06\xD0\x05\xD0\x00\xD0\xD0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x078A, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0A17, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAC\x92\x06\xC2\xAC\x30\x02\x0C\xC2\x02\x8F\x99\x53\x21\xBF"},
+ {0x40, 0xA0, 0x0A27, 0x0000, 0x0010, 0x0010,
+ "\x75\x23\x0C\x80\x12\xAE\x69\x05\x69\x74\x00\x2E\xF5\x82\xE4\x34"},
+ {0x40, 0xA0, 0x0A37, 0x0000, 0x000B, 0x000B,
+ "\x0F\xF5\x83\xEF\xF0\x05\x68\xA2\x06\x92\xAC"},
+ {0x40, 0xA0, 0x0A42, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x01C0, 0x0000, 0x0010, 0x0010,
+ "\x12\x01\x00\x01\x00\x00\x00\x40\x63\x07\x15\x10\x21\x01\x00\x00"},
+ {0x40, 0xA0, 0x01D0, 0x0000, 0x0010, 0x0010,
+ "\x00\x01\x09\x02\x27\x00\x01\x01\x00\xA0\x00\x09\x04\x00\x00\x03"},
+ {0x40, 0xA0, 0x01E0, 0x0000, 0x0010, 0x0010,
+ "\xFF\x00\x00\x00\x07\x05\x81\x03\x20\x00\x01\x07\x05\x82\x02\x20"},
+ {0x40, 0xA0, 0x01F0, 0x0000, 0x000F, 0x000F,
+ "\x00\x00\x07\x05\x02\x02\x20\x00\x00\x04\x03\x09\x04\x00\x00"},
+ {0x40, 0xA0, 0x08B5, 0x0000, 0x0010, 0x0010,
+ "\x01\x24\x00\xC1\x01\x01\x22\x00\x01\x21\xFF\x01\x23\x00\xC1\x82"},
+ {0x40, 0xA0, 0x08C5, 0x0000, 0x000F, 0x000F,
+ "\x01\x65\x00\x01\x66\x00\x01\x67\x00\x01\x69\x00\x01\x68\x00"},
+ {0x40, 0xA0, 0x0043, 0x0000, 0x0003, 0x0003, "\x02\x09\x00"},
+ {0x40, 0xA0, 0x0900, 0x0000, 0x0010, 0x0010,
+ "\x02\x0A\x6D\x00\x02\x08\x03\x00\x02\x0A\x43\x00\x02\x0A\x94\x00"},
+ {0x40, 0xA0, 0x0910, 0x0000, 0x0010, 0x0010,
+ "\x02\x0A\xBB\x00\x02\x0B\xBE\x00\x02\x0B\xBF\x00\x02\x0B\xC0\x00"},
+ {0x40, 0xA0, 0x0920, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC1\x00\x02\x0B\xC2\x00\x02\x0B\xC3\x00\x02\x0B\xC4\x00"},
+ {0x40, 0xA0, 0x0930, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC5\x00\x02\x0B\xC6\x00\x02\x0B\xC7\x00\x02\x0B\xC8\x00"},
+ {0x40, 0xA0, 0x0940, 0x0000, 0x0010, 0x0010,
+ "\x02\x0B\xC9\x00\x02\x0B\xCA\x00\x02\x0B\xCB\x00\x02\x0B\xCC\x00"},
+ {0x40, 0xA0, 0x0950, 0x0000, 0x0008, 0x0008,
+ "\x02\x0B\xCD\x00\x02\x0B\xCE\x00"},
+ {0x40, 0xA0, 0x08D4, 0x0000, 0x0010, 0x0010,
+ "\x12\x0A\xFF\x07\x91\xFF\x06\x08\xFF\x09\x58\xFF\x07\x91\xFF\x06"},
+ {0x40, 0xA0, 0x08E4, 0x0000, 0x000A, 0x000A,
+ "\x08\xFF\x0B\x57\x01\x08\xFF\x01\x09\x00"},
+ {0x40, 0xA0, 0x0791, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB6\xE0\x20\xE1\x6A\x7A\x7E\x79\x80\x7E\x7E\x7F\x80\x74"},
+ {0x40, 0xA0, 0x07A1, 0x0000, 0x0010, 0x0010,
+ "\x7E\x90\x7F\xE3\xF0\x74\x80\x90\x7F\xE4\xF0\xE4\xFF\xE5\x66\x65"},
+ {0x40, 0xA0, 0x07B1, 0x0000, 0x0010, 0x0010,
+ "\x65\x60\x43\xEF\xC3\x94\x08\x50\x3D\xE4\xFD\xE5\x66\x65\x65\x60"},
+ {0x40, 0xA0, 0x07C1, 0x0000, 0x0010, 0x0010,
+ "\x1B\xED\xC3\x94\x03\x50\x15\x74\x25\x25\x65\xF8\xE6\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x07D1, 0x0000, 0x0010, 0x0010,
+ "\xF0\x05\x65\xE5\x65\x54\x3F\xF5\x65\x0D\x80\xDF\xED\x60\xCE\xFE"},
+ {0x40, 0xA0, 0x07E1, 0x0000, 0x0010, 0x0010,
+ "\xEE\xC3\x94\x03\x50\x08\xE4\x90\x7F\xE5\xF0\x0E\x80\xF2\x90\x7F"},
+ {0x40, 0xA0, 0x07F1, 0x0000, 0x0010, 0x0010,
+ "\xE5\xED\xF0\x0F\x80\xB7\xEF\x60\x08\x25\xE0\x25\xE0\x90\x7F\xB7"},
+ {0x40, 0xA0, 0x0801, 0x0000, 0x0001, 0x0001, "\xF0"},
+ {0x40, 0xA0, 0x0802, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0958, 0x0000, 0x0010, 0x0010,
+ "\xE5\x08\x60\x16\x14\x60\x2A\x80\x00\x12\x08\xFD\xEF\x65\x09\x60"},
+ {0x40, 0xA0, 0x0968, 0x0000, 0x0010, 0x0010,
+ "\x36\x12\x08\xFD\x8F\x09\xE4\xF5\x08\x22\xE5\x22\x60\x10\xD5\x22"},
+ {0x40, 0xA0, 0x0978, 0x0000, 0x0010, 0x0010,
+ "\x0D\xA2\xAF\x92\x06\xC2\xAF\x43\x21\x20\xA2\x06\x92\xAF\x05\x08"},
+ {0x40, 0xA0, 0x0988, 0x0000, 0x0010, 0x0010,
+ "\x22\xE5\x23\x60\x10\xD5\x23\x0D\xA2\xAF\x92\x06\xC2\xAF\x43\x21"},
+ {0x40, 0xA0, 0x0998, 0x0000, 0x0007, 0x0007,
+ "\x40\xA2\x06\x92\xAF\x05\x08"},
+ {0x40, 0xA0, 0x099F, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B57, 0x0000, 0x0010, 0x0010,
+ "\xA2\xAF\x92\x06\xC2\xAF\x90\x7F\x98\xE5\x21\xF0\xA2\x06\x92\xAF"},
+ {0x40, 0xA0, 0x0B67, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0608, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xC8\xE0\x30\xE1\x03\x02\x06\x92\x90\x7F\xC9\xE0\xF5\x6A"},
+ {0x40, 0xA0, 0x0618, 0x0000, 0x0010, 0x0010,
+ "\xC3\xE4\x95\x68\xFF\x74\x01\x94\x00\xFE\xC3\xE5\x6A\x9F\xE4\x9E"},
+ {0x40, 0xA0, 0x0628, 0x0000, 0x0010, 0x0010,
+ "\x50\x68\xE4\xF5\x6B\xE5\x6B\xC3\x95\x6A\x50\x59\x74\xC3\x25\x6B"},
+ {0x40, 0xA0, 0x0638, 0x0000, 0x0010, 0x0010,
+ "\xF5\x82\xE4\x34\x7D\xF5\x83\xE0\x54\x0F\xFD\x60\x48\x74\xC0\x25"},
+ {0x40, 0xA0, 0x0648, 0x0000, 0x0010, 0x0010,
+ "\x6B\xF5\x82\xE4\x34\x7D\x90\x7F\xE3\xF0\x74\xC0\x25\x6B\xF5\x82"},
+ {0x40, 0xA0, 0x0658, 0x0000, 0x0010, 0x0010,
+ "\xE4\x34\x7D\xE5\x82\x90\x7F\xE4\xF0\xAF\x05\xED\x14\x60\x16\x14"},
+ {0x40, 0xA0, 0x0668, 0x0000, 0x0010, 0x0010,
+ "\x60\x0B\x14\x70\x18\x90\x7F\xE5\xE0\xFF\x12\x0A\x17\x90\x7F\xE5"},
+ {0x40, 0xA0, 0x0678, 0x0000, 0x0010, 0x0010,
+ "\xE0\xFF\x12\x0A\x17\x90\x7F\xE5\xE0\xFF\x12\x0A\x17\x74\x04\x25"},
+ {0x40, 0xA0, 0x0688, 0x0000, 0x000A, 0x000A,
+ "\x6B\xF5\x6B\x80\xA0\xE4\x90\x7F\xC9\xF0"},
+ {0x40, 0xA0, 0x0692, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x08EE, 0x0000, 0x0003, 0x0003, "\x01\x1D\x00"},
+ {0x40, 0xA0, 0x000B, 0x0000, 0x0003, 0x0003, "\x02\x0B\x84"},
+ {0x40, 0xA0, 0x0B84, 0x0000, 0x000D, 0x000D,
+ "\xC0\xE0\x05\x1D\xE5\x24\x60\x02\x15\x24\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x08FD, 0x0000, 0x0003, 0x0003, "\xAF\x1D\x22"},
+ {0x40, 0xA0, 0x0BAE, 0x0000, 0x0004, 0x0004, "\xE4\xF5\x1D\x22"},
+ {0x40, 0xA0, 0x08F1, 0x0000, 0x000B, 0x000B,
+ "\x01\x72\x01\x01\x73\x01\xC1\x85\x01\x74\x02"},
+ {0x40, 0xA0, 0x01FF, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xE9\xE0\x70\x03\x02\x02\xD4\x14\x70\x03\x02\x03\x4F\x24"},
+ {0x40, 0xA0, 0x020F, 0x0000, 0x0010, 0x0010,
+ "\xFE\x70\x03\x02\x03\xA8\x24\xFB\x70\x03\x02\x02\xCE\x14\x70\x03"},
+ {0x40, 0xA0, 0x021F, 0x0000, 0x0010, 0x0010,
+ "\x02\x02\xC8\x14\x70\x03\x02\x02\xBC\x14\x70\x03\x02\x02\xC2\x24"},
+ {0x40, 0xA0, 0x022F, 0x0000, 0x0010, 0x0010,
+ "\x05\x60\x03\x02\x03\xFA\x12\x0B\xB4\x40\x03\x02\x04\x05\x90\x7F"},
+ {0x40, 0xA0, 0x023F, 0x0000, 0x0010, 0x0010,
+ "\xEB\xE0\x24\xFE\x60\x16\x14\x60\x3F\x24\x02\x70\x67\x74\x01\x90"},
+ {0x40, 0xA0, 0x024F, 0x0000, 0x0010, 0x0010,
+ "\x7F\xD4\xF0\x74\xC0\x90\x7F\xD5\xF0\x02\x04\x05\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x025F, 0x0000, 0x0010, 0x0010,
+ "\xFF\x12\x08\x63\x8B\x6A\x8A\x6B\x89\x6C\xEA\x49\x60\x11\xAE\x02"},
+ {0x40, 0xA0, 0x026F, 0x0000, 0x0010, 0x0010,
+ "\xEE\x90\x7F\xD4\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x05\x90"},
+ {0x40, 0xA0, 0x027F, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\x74\x01\xF0\x02\x04\x05\x90\x7F\xEA\xE0\xFF\x12\x09\xA0"},
+ {0x40, 0xA0, 0x028F, 0x0000, 0x0010, 0x0010,
+ "\x8B\x6A\x8A\x6B\x89\x6C\xEA\x49\x60\x11\xAE\x02\xEE\x90\x7F\xD4"},
+ {0x40, 0xA0, 0x029F, 0x0000, 0x0010, 0x0010,
+ "\xF0\xAF\x01\xEF\x90\x7F\xD5\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01"},
+ {0x40, 0xA0, 0x02AF, 0x0000, 0x0010, 0x0010,
+ "\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05\x12\x0B\x76"},
+ {0x40, 0xA0, 0x02BF, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x05\x12\x0B\xA2\x02\x04\x05\x12\x0B\x9A\x02\x04\x05\x12"},
+ {0x40, 0xA0, 0x02CF, 0x0000, 0x0010, 0x0010,
+ "\x0B\x68\x02\x04\x05\x12\x0B\xB6\x40\x03\x02\x04\x05\x90\x7F\xE8"},
+ {0x40, 0xA0, 0x02DF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x24\x7F\x60\x24\x14\x60\x31\x24\x02\x70\x5B\xA2\x03\xE4\x33"},
+ {0x40, 0xA0, 0x02EF, 0x0000, 0x0010, 0x0010,
+ "\xFF\x25\xE0\xFF\xA2\x00\xE4\x33\x4F\x90\x7F\x00\xF0\xE4\xA3\xF0"},
+ {0x40, 0xA0, 0x02FF, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x05\xE4\x90\x7F\x00\xF0\xA3\xF0"},
+ {0x40, 0xA0, 0x030F, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xB5\x74\x02\xF0\x02\x04\x05\x90\x7F\xEC\xE0\xF4\x54\x80"},
+ {0x40, 0xA0, 0x031F, 0x0000, 0x0010, 0x0010,
+ "\xFF\xC4\x54\x0F\xFF\xE0\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4"},
+ {0x40, 0xA0, 0x032F, 0x0000, 0x0010, 0x0010,
+ "\x34\x7F\xF5\x83\xE0\x54\xFD\x90\x7F\x00\xF0\xE4\xA3\xF0\x90\x7F"},
+ {0x40, 0xA0, 0x033F, 0x0000, 0x0010, 0x0010,
+ "\xB5\x74\x02\xF0\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05"},
+ {0x40, 0xA0, 0x034F, 0x0000, 0x0010, 0x0010,
+ "\x12\x0B\xB8\x40\x03\x02\x04\x05\x90\x7F\xE8\xE0\x24\xFE\x60\x1C"},
+ {0x40, 0xA0, 0x035F, 0x0000, 0x0010, 0x0010,
+ "\x24\x02\x60\x03\x02\x04\x05\x90\x7F\xEA\xE0\xB4\x01\x05\xC2\x03"},
+ {0x40, 0xA0, 0x036F, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x05\x90\x7F\xC4\x74\x01\xF0\x02\x04\x05\x90\x7F\xEA\xE0"},
+ {0x40, 0xA0, 0x037F, 0x0000, 0x0010, 0x0010,
+ "\x70\x1F\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0\x54"},
+ {0x40, 0xA0, 0x038F, 0x0000, 0x0010, 0x0010,
+ "\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\xE4\xF0\x80"},
+ {0x40, 0xA0, 0x039F, 0x0000, 0x0010, 0x0010,
+ "\x65\x90\x7F\xC4\x74\x01\xF0\x80\x5D\x12\x0B\xBA\x50\x58\x90\x7F"},
+ {0x40, 0xA0, 0x03AF, 0x0000, 0x0010, 0x0010,
+ "\xE8\xE0\x24\xFE\x60\x17\x24\x02\x70\x4C\x90\x7F\xEA\xE0\xB4\x01"},
+ {0x40, 0xA0, 0x03BF, 0x0000, 0x0010, 0x0010,
+ "\x04\xD2\x03\x80\x41\x90\x7F\xC4\x74\x01\xF0\x80\x39\x90\x7F\xEA"},
+ {0x40, 0xA0, 0x03CF, 0x0000, 0x0010, 0x0010,
+ "\xE0\x70\x20\x90\x7F\xEC\xE0\xF4\x54\x80\xFF\xC4\x54\x0F\xFF\xE0"},
+ {0x40, 0xA0, 0x03DF, 0x0000, 0x0010, 0x0010,
+ "\x54\x07\x2F\x25\xE0\x24\xB4\xF5\x82\xE4\x34\x7F\xF5\x83\x74\x01"},
+ {0x40, 0xA0, 0x03EF, 0x0000, 0x0010, 0x0010,
+ "\xF0\x80\x13\x90\x7F\xC4\x74\x01\xF0\x80\x0B\x12\x0B\xBC\x50\x06"},
+ {0x40, 0xA0, 0x03FF, 0x0000, 0x000D, 0x000D,
+ "\x90\x7F\xC4\x74\x01\xF0\x90\x7F\xB4\xE0\x44\x02\xF0"},
+ {0x40, 0xA0, 0x040C, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x09E1, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xDE\x74\x06\xF0\x90\x7F\xDF\x74\x04\xF0\x90\x7F\xDD\x74"},
+ {0x40, 0xA0, 0x09F1, 0x0000, 0x0010, 0x0010,
+ "\x18\xF0\x90\x7F\xB6\x74\x02\xF0\x90\x7F\xB8\xF0\x90\x7F\xBA\xF0"},
+ {0x40, 0xA0, 0x0A01, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xBC\xF0\x90\x7F\xBE\xF0\x90\x7F\xC0\xF0\x90\x7F\xC2\xF0"},
+ {0x40, 0xA0, 0x0A11, 0x0000, 0x0006, 0x0006, "\xE4\x90\x7F\xC9\xF0\x22"},
+ {0x40, 0xA0, 0x0B91, 0x0000, 0x0009, 0x0009,
+ "\x90\x7F\xAF\xE0\x44\x08\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BB2, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BB4, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0B9A, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x76\xD3\x22"},
+ {0x40, 0xA0, 0x0B68, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x76\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BA2, 0x0000, 0x0008, 0x0008,
+ "\x90\x7F\xEA\xE0\xF5\x75\xD3\x22"},
+ {0x40, 0xA0, 0x0B76, 0x0000, 0x000E, 0x000E,
+ "\x90\x7F\x00\xE5\x75\xF0\x90\x7F\xB5\x74\x01\xF0\xD3\x22"},
+ {0x40, 0xA0, 0x0BB6, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BB8, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BBA, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0BBC, 0x0000, 0x0002, 0x0002, "\xD3\x22"},
+ {0x40, 0xA0, 0x0A6D, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0A7D, 0x0000, 0x0010, 0x0010,
+ "\x01\x53\x91\xEF\x90\x7F\xAB\x74\x01\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0A8D, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0A43, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x90"},
+ {0x40, 0xA0, 0x0A53, 0x0000, 0x0010, 0x0010,
+ "\x7F\xC4\xE4\xF0\x53\x91\xEF\x90\x7F\xAB\x74\x04\xF0\xD0\x86\xD0"},
+ {0x40, 0xA0, 0x0A63, 0x0000, 0x000A, 0x000A,
+ "\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0803, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xC0"},
+ {0x40, 0xA0, 0x0813, 0x0000, 0x0001, 0x0001, "\xD0"},
+ {0x40, 0xA0, 0x0814, 0x0000, 0x0010, 0x0010,
+ "\x53\x91\xEF\x90\x7F\xAB\x74\x02\xF0\x30\x05\x14\x15\x72\xE5\x72"},
+ {0x40, 0xA0, 0x0824, 0x0000, 0x0010, 0x0010,
+ "\x70\x2E\x43\x21\x10\xC2\x05\xC3\x74\x1E\x95\x74\xF5\x72\x80\x20"},
+ {0x40, 0xA0, 0x0834, 0x0000, 0x0010, 0x0010,
+ "\xD5\x72\x1D\x53\x21\xEF\xD2\x05\xE5\x73\x25\x74\xF5\x74\x64\x02"},
+ {0x40, 0xA0, 0x0844, 0x0000, 0x0010, 0x0010,
+ "\x60\x05\xE5\x74\xB4\x1C\x06\xE5\x73\xF4\x04\xF5\x73\x85\x74\x72"},
+ {0x40, 0xA0, 0x0854, 0x0000, 0x000F, 0x000F,
+ "\xD0\xD0\xD0\x86\xD0\x84\xD0\x85\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0ABB, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\x53"},
+ {0x40, 0xA0, 0x0ACB, 0x0000, 0x0010, 0x0010,
+ "\x91\xEF\x90\x7F\xAB\x74\x10\xF0\xD0\x86\xD0\x84\xD0\x85\xD0\x82"},
+ {0x40, 0xA0, 0x0ADB, 0x0000, 0x0005, 0x0005, "\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BBE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0A94, 0x0000, 0x0010, 0x0010,
+ "\xC0\xE0\xC0\x83\xC0\x82\xC0\x85\xC0\x84\xC0\x86\x75\x86\x00\xD2"},
+ {0x40, 0xA0, 0x0AA4, 0x0000, 0x0010, 0x0010,
+ "\x04\x53\x91\xEF\x90\x7F\xAB\x74\x08\xF0\xD0\x86\xD0\x84\xD0\x85"},
+ {0x40, 0xA0, 0x0AB4, 0x0000, 0x0007, 0x0007,
+ "\xD0\x82\xD0\x83\xD0\xE0\x32"},
+ {0x40, 0xA0, 0x0BBF, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC0, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC1, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC2, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC3, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC4, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC5, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC6, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC7, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC8, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BC9, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCA, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCB, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCC, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCD, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0BCE, 0x0000, 0x0001, 0x0001, "\x32"},
+ {0x40, 0xA0, 0x0B26, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x30\xE7\x12\xE0\x44\x01\xF0\x7F\x14\x7E\x00\x12"},
+ {0x40, 0xA0, 0x0B36, 0x0000, 0x000A, 0x000A,
+ "\x0B\x40\x90\x7F\xD6\xE0\x54\xFE\xF0\x22"},
+ {0x40, 0xA0, 0x0B05, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x44\x80\xF0\x43\x87\x01\x00\x00\x00\x00\x00\x22"},
+ {0x40, 0xA0, 0x0AE0, 0x0000, 0x0010, 0x0010,
+ "\x90\x7F\xD6\xE0\x54\xFB\xF0\xE0\x44\x08\xF0\x30\x06\x04\xE0\x44"},
+ {0x40, 0xA0, 0x0AF0, 0x0000, 0x0010, 0x0010,
+ "\x02\xF0\x7F\xF4\x7E\x01\x12\x0B\x40\x90\x7F\xD6\xE0\x54\xF7\xF0"},
+ {0x40, 0xA0, 0x0B00, 0x0000, 0x0005, 0x0005, "\xE0\x44\x04\xF0\x22"},
+ {0x40, 0xA0, 0x09A0, 0x0000, 0x0002, 0x0002, "\x8F\x6D"},
+ {0x40, 0xA0, 0x09A2, 0x0000, 0x0010, 0x0010,
+ "\xE4\xF5\x6E\x75\x6F\xFF\x75\x70\x01\x75\x71\xF9\xAB\x6F\xAA\x70"},
+ {0x40, 0xA0, 0x09B2, 0x0000, 0x0010, 0x0010,
+ "\xA9\x71\x90\x00\x01\x12\x06\xAC\xB4\x03\x1D\xAF\x6E\x05\x6E\xEF"},
+ {0x40, 0xA0, 0x09C2, 0x0000, 0x0010, 0x0010,
+ "\xB5\x6D\x01\x22\x12\x06\x93\x7E\x00\x29\xFF\xEE\x3A\xA9\x07\x75"},
+ {0x40, 0xA0, 0x09D2, 0x0000, 0x000E, 0x000E,
+ "\x6F\xFF\xF5\x70\x89\x71\x80\xD4\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x09E0, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0863, 0x0000, 0x0010, 0x0010,
+ "\xE4\xFE\x75\x6F\xFF\x75\x70\x01\x75\x71\xD2\xAB\x6F\xAA\x70\xA9"},
+ {0x40, 0xA0, 0x0873, 0x0000, 0x0010, 0x0010,
+ "\x71\x90\x00\x01\x12\x06\xAC\x64\x02\x70\x2D\xAD\x06\x0E\xED\xB5"},
+ {0x40, 0xA0, 0x0883, 0x0000, 0x0010, 0x0010,
+ "\x07\x01\x22\x90\x00\x02\x12\x06\xD9\x85\xF0\x6D\xF5\x6E\x62\x6D"},
+ {0x40, 0xA0, 0x0893, 0x0000, 0x0010, 0x0010,
+ "\xE5\x6D\x62\x6E\xE5\x6E\x62\x6D\x29\xFD\xE5\x6D\x3A\xA9\x05\x75"},
+ {0x40, 0xA0, 0x08A3, 0x0000, 0x000E, 0x000E,
+ "\x6F\xFF\xF5\x70\x89\x71\x80\xC3\x7B\x00\x7A\x00\x79\x00"},
+ {0x40, 0xA0, 0x08B1, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0B40, 0x0000, 0x0010, 0x0010,
+ "\x8E\x6A\x8F\x6B\xE5\x6B\x15\x6B\xAE\x6A\x70\x02\x15\x6A\x4E\x60"},
+ {0x40, 0xA0, 0x0B50, 0x0000, 0x0007, 0x0007,
+ "\x05\x12\x0B\x15\x80\xEE\x22"},
+ {0x40, 0xA0, 0x0B15, 0x0000, 0x0010, 0x0010,
+ "\x74\x00\xF5\x86\x90\xFD\xA5\x7C\x05\xA3\xE5\x82\x45\x83\x70\xF9"},
+ {0x40, 0xA0, 0x0B25, 0x0000, 0x0001, 0x0001, "\x22"},
+ {0x40, 0xA0, 0x0000, 0x0000, 0x0003, 0x0003, "\x02\x05\x7C"},
+ {0x40, 0xA0, 0x057C, 0x0000, 0x000C, 0x000C,
+ "\x78\x7F\xE4\xF6\xD8\xFD\x75\x81\x76\x02\x05\xC3"},
+ {0x40, 0xA0, 0x0693, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x06\x89\x82\x8A\x83\xE0\x22\x50\x02\xE7\x22\xBB\xFE\x02"},
+ {0x40, 0xA0, 0x06A3, 0x0000, 0x0009, 0x0009,
+ "\xE3\x22\x89\x82\x8A\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x06AC, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x0C\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\x22\x50"},
+ {0x40, 0xA0, 0x06BC, 0x0000, 0x0010, 0x0010,
+ "\x06\xE9\x25\x82\xF8\xE6\x22\xBB\xFE\x06\xE9\x25\x82\xF8\xE2\x22"},
+ {0x40, 0xA0, 0x06CC, 0x0000, 0x000D, 0x000D,
+ "\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE4\x93\x22"},
+ {0x40, 0xA0, 0x06D9, 0x0000, 0x0010, 0x0010,
+ "\xBB\x01\x10\xE5\x82\x29\xF5\x82\xE5\x83\x3A\xF5\x83\xE0\xF5\xF0"},
+ {0x40, 0xA0, 0x06E9, 0x0000, 0x0010, 0x0010,
+ "\xA3\xE0\x22\x50\x09\xE9\x25\x82\xF8\x86\xF0\x08\xE6\x22\xBB\xFE"},
+ {0x40, 0xA0, 0x06F9, 0x0000, 0x0010, 0x0010,
+ "\x0A\xE9\x25\x82\xF8\xE2\xF5\xF0\x08\xE2\x22\xE5\x83\x2A\xF5\x83"},
+ {0x40, 0xA0, 0x0709, 0x0000, 0x0008, 0x0008,
+ "\xE9\x93\xF5\xF0\xA3\xE9\x93\x22"},
+ {0x40, 0xA0, 0x0711, 0x0000, 0x0006, 0x0006, "\x8A\x83\x89\x82\xE4\x73"},
+ {0x40, 0xA0, 0x0588, 0x0000, 0x0010, 0x0010,
+ "\x02\x04\x0D\xE4\x93\xA3\xF8\xE4\x93\xA3\x40\x03\xF6\x80\x01\xF2"},
+ {0x40, 0xA0, 0x0598, 0x0000, 0x0010, 0x0010,
+ "\x08\xDF\xF4\x80\x29\xE4\x93\xA3\xF8\x54\x07\x24\x0C\xC8\xC3\x33"},
+ {0x40, 0xA0, 0x05A8, 0x0000, 0x0010, 0x0010,
+ "\xC4\x54\x0F\x44\x20\xC8\x83\x40\x04\xF4\x56\x80\x01\x46\xF6\xDF"},
+ {0x40, 0xA0, 0x05B8, 0x0000, 0x0010, 0x0010,
+ "\xE4\x80\x0B\x01\x02\x04\x08\x10\x20\x40\x80\x90\x08\xB2\xE4\x7E"},
+ {0x40, 0xA0, 0x05C8, 0x0000, 0x0010, 0x0010,
+ "\x01\x93\x60\xBC\xA3\xFF\x54\x3F\x30\xE5\x09\x54\x1F\xFE\xE4\x93"},
+ {0x40, 0xA0, 0x05D8, 0x0000, 0x0010, 0x0010,
+ "\xA3\x60\x01\x0E\xCF\x54\xC0\x25\xE0\x60\xA8\x40\xB8\xE4\x93\xA3"},
+ {0x40, 0xA0, 0x05E8, 0x0000, 0x0010, 0x0010,
+ "\xFA\xE4\x93\xA3\xF8\xE4\x93\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA"},
+ {0x40, 0xA0, 0x05F8, 0x0000, 0x0010, 0x0010,
+ "\xF0\xA3\xC8\xC5\x82\xC8\xCA\xC5\x83\xCA\xDF\xE9\xDE\xE7\x80\xBE"},
+ {0x40, 0xA0, 0x08FC, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x01"},
+ {0x40, 0xA0, 0x7F92, 0x0000, 0x0001, 0x0001, "\x00"},
+ {0x00, 0x05, 0x0002, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x09, 0x0001, 0x0000, 0x0000, 0x0000, ""},
+ {0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x0000, NULL}
+};
diff --git a/kernel/drv/oss_userdev/.config b/kernel/drv/oss_userdev/.config
new file mode 100644
index 0000000..828bd4f
--- /dev/null
+++ b/kernel/drv/oss_userdev/.config
@@ -0,0 +1,2 @@
+bus=VIRTUAL
+targetcpu=any
diff --git a/kernel/drv/oss_userdev/.devices b/kernel/drv/oss_userdev/.devices
new file mode 100644
index 0000000..41dd8b4
--- /dev/null
+++ b/kernel/drv/oss_userdev/.devices
@@ -0,0 +1 @@
+oss_userdev oss_userdev OSS user space audio driver I/O module
diff --git a/kernel/drv/oss_userdev/.name b/kernel/drv/oss_userdev/.name
new file mode 100644
index 0000000..4d501dc
--- /dev/null
+++ b/kernel/drv/oss_userdev/.name
@@ -0,0 +1 @@
+OSS loopback audio driver
diff --git a/kernel/drv/oss_userdev/.params b/kernel/drv/oss_userdev/.params
new file mode 100644
index 0000000..45f9032
--- /dev/null
+++ b/kernel/drv/oss_userdev/.params
@@ -0,0 +1,11 @@
+int userdev_visible_clientnodes=0;
+/*
+ * By default the oss_userdev driver will not create private device nodes
+ * for the client side devices. Instead all client devices will share
+ * the same device node (/dev/oss/oss_userdev/client).
+ *
+ * If userdev_visible_clientnodes is set to 1 then each oss_userdev instance
+ * will have private device node (/dev/oss/oss_userdev0/pcmN) that can be
+ * opened directly. This mode can be used when the oss_userdev driver is used
+ * for multiple purposes in the same system.
+ */
diff --git a/kernel/drv/oss_userdev/oss_userdev.c b/kernel/drv/oss_userdev/oss_userdev.c
new file mode 100644
index 0000000..c026ff3
--- /dev/null
+++ b/kernel/drv/oss_userdev/oss_userdev.c
@@ -0,0 +1,352 @@
+/*
+ * Purpose: Kernel space support module for user land audio/mixer drivers
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_userdev_cfg.h"
+#include <oss_userdev_exports.h>
+#include "userdev.h"
+
+oss_device_t *userdev_osdev = NULL;
+static int client_dev = -1, server_dev = -1; /* Control devces */
+
+char *userdev_client_devnode = "/dev/oss/oss_userdev0/client";
+char *userdev_server_devnode = "/dev/oss/oss_userdev0/server";
+
+/*
+ * Global device lists and the mutex that protects them.
+ */
+oss_mutex_t userdev_global_mutex;
+
+/*
+ * The oss_userdev driver creates new device pairs on-demand. All device
+ * pairs that are not in use will be kept in the userdev_free_device_list
+ * (linked) list. If this list contains any entries then they will be
+ * reused whenever a new device pair is required.
+ */
+userdev_devc_t *userdev_free_device_list = NULL;
+
+/*
+ * Linked list for device pairs that have a server attached. These device
+ * pairs are available for the clients.
+ */
+userdev_devc_t *userdev_active_device_list = NULL;
+
+/*ARGSUSED*/
+static int
+userdev_server_redirect (int dev, int mode, int open_flags)
+{
+/*
+ * Purpose: This entry point is used to create new userdev instances and to redirect clients to them.
+ */
+ int server_engine;
+
+
+ if ((server_engine=usrdev_find_free_device_pair()) >= 0)
+ {
+ userdev_devc_t *devc = audio_engines[server_engine]->devc;
+
+ userdev_reinit_instance(devc);
+ return server_engine;
+ }
+
+ return userdev_create_device_pair();
+}
+
+/*ARGSUSED*/
+static int
+userdev_client_redirect (int dev, int mode, int open_flags)
+{
+/*
+ * Purpose: This entry point is used to create new userdev instances and to redirect clients to them.
+ */
+
+ userdev_devc_t *devc;
+ oss_native_word flags;
+
+ uid_t uid;
+
+ uid = oss_get_procinfo(OSS_GET_PROCINFO_UID);
+
+ MUTEX_ENTER_IRQDISABLE(userdev_global_mutex, flags);
+ devc=userdev_active_device_list;
+
+ while (devc != NULL)
+ {
+ int ok=1;
+
+ switch (devc->match_method)
+ {
+ case UD_MATCH_UID:
+ if (devc->match_key != uid) /* Wrong UID */
+ ok=0;
+ break;
+ }
+
+ if (ok)
+ {
+ MUTEX_EXIT_IRQRESTORE(userdev_global_mutex, flags);
+ return devc->client_portc.audio_dev;
+ }
+
+ devc = devc->next_instance;
+ }
+
+ MUTEX_EXIT_IRQRESTORE(userdev_global_mutex, flags);
+ return OSS_EIO;
+}
+
+/*
+ * Dummy audio driver entrypoint functions.
+ *
+ * Functionality of the control device is handled by userdev_[client|server]_redirect().
+ * The other entry points are not used for any purpose but the audio core
+ * framework expects to see them.
+ */
+/*ARGSUSED*/
+static int
+userdev_control_set_rate (int dev, int arg)
+{
+ /* Dumy routine - Not actually used */
+ return 48000;
+}
+
+/*ARGSUSED*/
+static short
+userdev_control_set_channels (int dev, short arg)
+{
+ /* Dumy routine - Not actually used */
+ return 2;
+}
+
+/*ARGSUSED*/
+static unsigned int
+userdev_control_set_format (int dev, unsigned int arg)
+{
+ /* Dumy routine - Not actually used */
+ return AFMT_S16_NE;
+}
+
+static void
+userdev_control_reset (int dev)
+{
+ /* Dumy routine - Not actually used */
+}
+
+/*ARGSUSED*/
+static int
+userdev_control_open (int dev, int mode, int open_flags)
+{
+ /* Dumy routine - Not actually used */
+ return OSS_EIO;
+}
+
+/*ARGSUSED*/
+static void
+userdev_control_close (int dev, int mode)
+{
+ /* Dumy routine - Not actually used */
+}
+
+/*ARGSUSED*/
+static int
+userdev_control_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ /* Dumy routine - Not actually used */
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static void
+userdev_control_output_block (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+ /* Dumy routine - Not actually used */
+}
+
+/*ARGSUSED*/
+static void
+userdev_control_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+ /* Dumy routine - Not actually used */
+}
+
+/*ARGSUSED*/
+static int
+userdev_control_prepare_for_input (int dev, int bsize, int bcount)
+{
+ /* Dumy routine - Not actually used */
+ return OSS_EIO;
+}
+
+/*ARGSUSED*/
+static int
+userdev_control_prepare_for_output (int dev, int bsize, int bcount)
+{
+ /* Dumy routine - Not actually used */
+ return OSS_EIO;
+}
+
+static audiodrv_t userdev_server_control_driver = {
+ userdev_control_open,
+ userdev_control_close,
+ userdev_control_output_block,
+ userdev_control_start_input,
+ userdev_control_ioctl,
+ userdev_control_prepare_for_input,
+ userdev_control_prepare_for_output,
+ userdev_control_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* trigger */
+ userdev_control_set_rate,
+ userdev_control_set_format,
+ userdev_control_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ userdev_server_redirect
+};
+
+static audiodrv_t userdev_client_control_driver = {
+ userdev_control_open,
+ userdev_control_close,
+ userdev_control_output_block,
+ userdev_control_start_input,
+ userdev_control_ioctl,
+ userdev_control_prepare_for_input,
+ userdev_control_prepare_for_output,
+ userdev_control_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* trigger */
+ userdev_control_set_rate,
+ userdev_control_set_format,
+ userdev_control_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ userdev_client_redirect
+};
+
+static void
+attach_control_device(void)
+{
+/*
+ * Create the control device files that are used to create client/server
+ * device pairs and to redirect access to them.
+ */
+ userdev_devc_t *devc = (userdev_devc_t*)0xdeadcafe; /* This should never get referenced */
+
+ if ((client_dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ userdev_osdev,
+ userdev_osdev,
+ "User space audio device client side",
+ &userdev_client_control_driver,
+ sizeof (audiodrv_t),
+ ADEV_AUTOMODE, AFMT_S16_NE, devc, -1,
+ "client")) < 0)
+ {
+ return;
+ }
+ userdev_server_devnode = audio_engines[server_dev]->devnode;
+ audio_engines[client_dev]->vmix_mixer=NULL;
+
+ if ((server_dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ userdev_osdev,
+ userdev_osdev,
+ "User space audio device server side",
+ &userdev_server_control_driver,
+ sizeof (audiodrv_t),
+ ADEV_AUTOMODE, AFMT_S16_NE, devc, -1,
+ "server")) < 0)
+ {
+ return;
+ }
+ audio_engines[server_dev]->caps |= PCM_CAP_HIDDEN;
+ audio_engines[server_dev]->vmix_mixer=NULL;
+ userdev_client_devnode = audio_engines[client_dev]->devnode;
+}
+
+int
+oss_userdev_attach (oss_device_t * osdev)
+{
+ userdev_osdev = osdev;
+
+ osdev->devc = NULL;
+ MUTEX_INIT (osdev, userdev_global_mutex, MH_DRV);
+
+ oss_register_device (osdev, "User space audio driver subsystem");
+
+ attach_control_device();
+
+ return 1;
+}
+
+int
+oss_userdev_detach (oss_device_t * osdev)
+{
+ userdev_devc_t *devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ devc = userdev_free_device_list;
+
+ while (devc != NULL)
+ {
+ userdev_devc_t *next = devc->next_instance;
+
+ userdev_delete_device_pair(devc);
+
+ devc = next;
+ }
+
+ oss_unregister_device (osdev);
+
+ MUTEX_CLEANUP(userdev_global_mutex);
+
+ return 1;
+}
diff --git a/kernel/drv/oss_userdev/oss_userdev.man b/kernel/drv/oss_userdev/oss_userdev.man
new file mode 100644
index 0000000..cdb0d12
--- /dev/null
+++ b/kernel/drv/oss_userdev/oss_userdev.man
@@ -0,0 +1,37 @@
+NAME
+oss_userdev - OSS client/server audio pseudo device.
+
+NOTICE
+This audio device is not designed to be used as-is by the users. It requires
+a specially designed server application that implements the actual service
+(please see the OSS programming documentation for more info). The server
+application will then create the audio devices that can be used to record
+and/or play audio.
+
+DESCRIPTION
+The oss_userdev driver is a special purpose loop back audio device that can be
+used when implementing OSS audio devices based on a server running in the
+background.
+
+OPTIONS
+
+o userdev_visible_clientnodes=0|1
+By default (0) common client device node (/dev/oss/oss_userdev0/client) will
+be created for all server instances. The clients will then get directed to the
+right instance based on some search criteria (for example UID). This
+alternative is best when using single server application that can serve large
+number of different sesions.
+
+If this option
+is set to 1 then OSS will create separate client device nodes for each
+instance. Applications will have to open the right device nodes. This
+alternative is best when oss_userdev is used to create different kind of
+services in one system. In this way for example a VoIP link can be accessed
+by opening a different device node than when opening some other service.
+
+FILES
+CONFIGFILEPATH/oss_userdev.conf Device configuration file.
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_userdev/oss_userdev_devicepair.c b/kernel/drv/oss_userdev/oss_userdev_devicepair.c
new file mode 100644
index 0000000..8119cb9
--- /dev/null
+++ b/kernel/drv/oss_userdev/oss_userdev_devicepair.c
@@ -0,0 +1,1255 @@
+/*
+ * Purpose: Client/server audio device pair for oss_userdev
+ *
+ * This file implements the actual client/server device pair. There will be
+ * separate oss_userdev instance for each process that has opened the
+ * client side.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_userdev_cfg.h"
+#include <oss_userdev_exports.h>
+#include "userdev.h"
+static void userdev_free_device_pair (userdev_devc_t *devc);
+
+extern int userdev_visible_clientnodes;
+
+static void
+transfer_audio (userdev_portc_t * server_portc, dmap_t * dmap_from,
+ dmap_t * dmap_to)
+{
+ int l = dmap_from->fragment_size;
+ unsigned char *fromp, *top;
+
+ if (dmap_to->fragment_size != l)
+ {
+ cmn_err (CE_WARN, "Fragment size mismatch (%d != %d)\n",
+ dmap_to->fragment_size, l);
+
+ /* Perform emergency stop */
+ server_portc->input_triggered = 0;
+ server_portc->output_triggered = 0;
+ server_portc->peer->input_triggered = 0;
+ server_portc->peer->output_triggered = 0;
+ return;
+ }
+
+ fromp =
+ dmap_from->dmabuf + (dmap_from->byte_counter % dmap_from->bytes_in_use);
+ top = dmap_to->dmabuf + (dmap_to->byte_counter % dmap_to->bytes_in_use);
+
+ memcpy (top, fromp, l);
+
+}
+
+static void
+handle_input (userdev_portc_t * server_portc)
+{
+ userdev_portc_t *client_portc = server_portc->peer;
+
+ if (client_portc->output_triggered)
+ {
+ transfer_audio (server_portc,
+ audio_engines[client_portc->audio_dev]->dmap_out,
+ audio_engines[server_portc->audio_dev]->dmap_in);
+ oss_audio_outputintr (client_portc->audio_dev, 0);
+ }
+
+ oss_audio_inputintr (server_portc->audio_dev, 0);
+}
+
+static void
+handle_output (userdev_portc_t * server_portc)
+{
+ userdev_portc_t *client_portc = server_portc->peer;
+
+ if (client_portc->input_triggered)
+ {
+ transfer_audio (server_portc,
+ audio_engines[server_portc->audio_dev]->dmap_out,
+ audio_engines[client_portc->audio_dev]->dmap_in);
+ oss_audio_inputintr (client_portc->audio_dev, 0);
+ }
+
+ oss_audio_outputintr (server_portc->audio_dev, 0);
+}
+
+static void
+userdev_cb (void *pc)
+{
+/*
+ * This timer callback routine will get called 100 times/second. It handles
+ * movement of audio data between the client and server sides.
+ */
+ userdev_portc_t *server_portc = pc;
+ userdev_devc_t *devc = server_portc->devc;
+ int tmout = devc->poll_ticks;
+
+ if (tmout < 1)
+ tmout = 1;
+
+ devc->timeout_id = 0; /* No longer valid */
+
+ if (server_portc->input_triggered)
+ handle_input (server_portc);
+
+ if (server_portc->output_triggered)
+ handle_output (server_portc);
+
+ /* Retrigger timer callback */
+ if (server_portc->input_triggered || server_portc->output_triggered)
+ devc->timeout_id = timeout (userdev_cb, server_portc, tmout);
+}
+
+static int
+userdev_check_input (int dev)
+{
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ if (!portc->peer->output_triggered)
+ {
+ return OSS_ECONNRESET;
+ }
+ return 0;
+}
+
+static int
+userdev_check_output (int dev)
+{
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+
+ if (!portc->peer->input_triggered)
+ {
+ return OSS_ECONNRESET;
+ }
+
+ if (portc->peer->open_mode == 0)
+ return OSS_EIO;
+ return 0;
+}
+
+static void
+setup_sample_format (userdev_portc_t * portc)
+{
+ adev_t *adev;
+ userdev_devc_t *devc = portc->devc;
+ int fragsize, frame_size;
+
+ frame_size = devc->channels * devc->fmt_bytes;
+ if (frame_size == 0)
+ frame_size = 4;
+
+ fragsize = (devc->rate * frame_size * devc->poll_ticks) / OSS_HZ; /* Number of bytes/fragment */
+ devc->rate = fragsize * 100 / frame_size;
+
+/* Setup the server side */
+ adev = audio_engines[portc->audio_dev];
+ adev->min_block = adev->max_block = fragsize;
+
+/* Setup the client side */
+ adev = audio_engines[portc->peer->audio_dev];
+ adev->min_block = adev->max_block = fragsize;
+
+ adev->max_rate = adev->min_rate = devc->rate;
+ adev->iformat_mask = devc->fmt;
+ adev->oformat_mask = devc->fmt;
+ adev->xformat_mask = devc->fmt;
+ adev->min_channels = adev->max_channels = devc->channels;
+}
+
+static int
+userdev_server_set_rate (int dev, int arg)
+{
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ adev_t *client_adev = audio_engines[portc->peer->audio_dev];
+
+ if (arg == 0)
+ return devc->rate;
+
+ if (portc->peer->input_triggered || portc->peer->output_triggered)
+ return devc->rate;
+
+ if (arg < 5000)
+ arg = 5000;
+ if (arg > MAX_RATE)
+ arg = MAX_RATE;
+
+ /* Force the sample rate to be multiple of 100 */
+ arg = (arg / 100) * 100;
+
+ devc->rate = arg;
+
+ client_adev->min_rate = arg;
+ client_adev->max_rate = arg;
+
+ setup_sample_format (portc);
+
+ return devc->rate = arg;
+}
+
+/*ARGSUSED*/
+static int
+userdev_client_set_rate (int dev, int arg)
+{
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ return devc->rate;
+}
+
+static short
+userdev_server_set_channels (int dev, short arg)
+{
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ adev_t *client_adev = audio_engines[portc->peer->audio_dev];
+
+ if (arg == 0)
+ return devc->channels;
+
+ if (portc->peer->input_triggered || portc->peer->output_triggered)
+ return devc->channels;
+
+ if (arg < 1)
+ arg = 1;
+ if (arg > MAX_CHANNELS)
+ arg = MAX_CHANNELS;
+
+ devc->channels = arg;
+ client_adev->min_channels=client_adev->max_channels=arg;
+
+ setup_sample_format (portc);
+
+ return devc->channels;
+}
+
+/*ARGSUSED*/
+static short
+userdev_client_set_channels (int dev, short arg)
+{
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ return devc->channels; /* Server side channels */
+}
+
+static unsigned int
+userdev_server_set_format (int dev, unsigned int arg)
+{
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ adev_t *client_adev = audio_engines[portc->peer->audio_dev];
+
+ if (arg == 0)
+ return devc->fmt;
+
+ if (portc->peer->input_triggered || portc->peer->output_triggered)
+ return devc->fmt;
+
+ switch (arg)
+ {
+ case AFMT_S16_NE:
+ devc->fmt_bytes = 2;
+ break;
+
+ case AFMT_S32_NE:
+ devc->fmt_bytes = 4;
+ break;
+
+ default: /* Unsupported format */
+ arg = AFMT_S16_NE;
+ devc->fmt_bytes = 2;
+
+ }
+
+ devc->fmt = arg;
+
+ client_adev->oformat_mask = arg;
+ client_adev->iformat_mask = arg;
+
+ setup_sample_format (portc);
+
+ return devc->fmt;
+}
+
+/*ARGSUSED*/
+static unsigned int
+userdev_client_set_format (int dev, unsigned int arg)
+{
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ return devc->fmt; /* Server side sample format */
+}
+
+static void userdev_trigger (int dev, int state);
+
+static void
+userdev_reset (int dev)
+{
+ userdev_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static int
+userdev_server_open (int dev, int mode, int open_flags)
+{
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ if (portc == NULL || portc->peer == NULL)
+ return OSS_ENXIO;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ devc->open_count++;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+userdev_client_open (int dev, int mode, int open_flags)
+{
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ if (portc == NULL || portc->peer == NULL)
+ return OSS_ENXIO;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ devc->open_count++;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static void
+wipe_audio_buffers(userdev_devc_t *devc)
+{
+/*
+ * Write silence to the audio buffers when only one of the sides
+ * is open. This prevents the device from looping the last fragments
+ * written to the device.
+ */
+ dmap_t *dmap;
+
+ dmap = audio_engines[devc->client_portc.audio_dev]->dmap_out;
+ if (dmap != NULL && dmap->dmabuf != NULL)
+ memset(dmap->dmabuf, 0, dmap->buffsize);
+
+ dmap = audio_engines[devc->client_portc.audio_dev]->dmap_in;
+ if (dmap != NULL && dmap->dmabuf != NULL)
+ memset(dmap->dmabuf, 0, dmap->buffsize);
+
+ dmap = audio_engines[devc->server_portc.audio_dev]->dmap_out;
+ if (dmap != NULL && dmap->dmabuf != NULL)
+ memset(dmap->dmabuf, 0, dmap->buffsize);
+
+ dmap = audio_engines[devc->server_portc.audio_dev]->dmap_in;
+ if (dmap != NULL && dmap->dmabuf != NULL)
+ memset(dmap->dmabuf, 0, dmap->buffsize);
+}
+
+/*ARGSUSED*/
+static void
+userdev_server_close (int dev, int mode)
+{
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ int open_count;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->open_mode = 0;
+
+ /* Stop the client side because there is no server */
+ portc->peer->input_triggered = 0;
+ portc->peer->output_triggered = 0;
+ open_count = --devc->open_count;
+
+ if (open_count == 0)
+ userdev_free_device_pair (devc);
+ else
+ wipe_audio_buffers(devc);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static void
+userdev_client_close (int dev, int mode)
+{
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+ int open_count;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->open_mode = 0;
+
+ open_count = --devc->open_count;
+
+ if (open_count == 0)
+ userdev_free_device_pair (devc);
+ else
+ wipe_audio_buffers(devc);
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+userdev_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ switch (cmd)
+ {
+ case SNDCTL_GETLABEL:
+ {
+ /*
+ * Return an empty string so that this feature can be tested.
+ * Complete functionality is to be implemented later.
+ */
+ oss_label_t *s = (oss_label_t *) arg;
+ memset (s, 0, sizeof (oss_label_t));
+ return 0;
+ }
+ break;
+
+ case SNDCTL_GETSONG:
+ {
+ /*
+ * Return an empty string so that this feature can be tested.
+ * Complete functionality is to be implemented later.
+ */
+ oss_longname_t *s = (oss_longname_t *) arg;
+ memset (s, 0, sizeof (oss_longname_t));
+ return 0;
+ }
+ break;
+ }
+
+ return OSS_EINVAL;
+}
+
+static void
+set_adev_name(int dev, const char *name)
+{
+ adev_t *adev = audio_engines[dev];
+
+ strcpy(adev->name, name);
+
+#ifdef CONFIG_OSS_VMIX
+ if (adev->vmix_mixer != NULL)
+ vmix_change_devnames(adev->vmix_mixer, name);
+#endif
+
+}
+
+static int
+create_instance(int dev, userdev_create_t *crea)
+{
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ char tmp_name[64];
+
+ devc->match_method = crea->match_method;
+ devc->match_key = crea->match_key;
+ devc->create_flags = crea->flags;
+
+ devc->poll_ticks = (crea->poll_interval * OSS_HZ) / 1000;
+
+ if (devc->poll_ticks < 1)
+ devc->poll_ticks = 1;
+
+ crea->poll_interval = (1000*devc->poll_ticks) / OSS_HZ;
+
+ if (crea->poll_interval<1)
+ crea->poll_interval = 1;
+
+ crea->name[sizeof(crea->name)-1]=0; /* Overflow protectgion */
+
+ sprintf(tmp_name, "%s (server)", crea->name);
+ tmp_name[49]=0;
+ set_adev_name (devc->client_portc.audio_dev, crea->name);
+ set_adev_name (devc->server_portc.audio_dev, tmp_name);
+
+ strcpy(crea->devnode, audio_engines[devc->client_portc.audio_dev]->devnode);
+
+ return 0;
+}
+
+static int
+userdev_set_control (int dev, int ctl, unsigned int cmd, int value)
+{
+ userdev_devc_t *devc = mixer_devs[dev]->devc;
+
+ if (ctl < 0 || ctl >= USERDEV_MAX_MIXERS)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return devc->mixer_values[ctl];
+ }
+
+ devc->mixer_values[ctl] = value;
+ devc->modify_counter++;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+userdev_server_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ switch (cmd)
+ {
+ case USERDEV_CREATE_INSTANCE:
+ {
+ userdev_create_t *crea = (userdev_create_t *)arg;
+
+ return create_instance(dev, crea);
+ }
+ break;
+
+ case USERDEV_GET_CLIENTCOUNT:
+ {
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ return *arg = (devc->client_portc.open_mode != 0);
+ }
+ break;
+
+ /*
+ * Mixer related ioctl calls
+ */
+
+ case USERDEV_CREATE_MIXGROUP:
+ {
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ userdev_mixgroup_t *grp=(userdev_mixgroup_t*)arg;
+ int group;
+
+ grp->name[sizeof(grp->name)-1]=0; /* Buffer overflow protection */
+ if ((group=mixer_ext_create_group(devc->mixer_dev, grp->parent, grp->name))<0)
+ return group;
+ grp->num = group;
+ return 0;
+ }
+ break;
+
+ case USERDEV_CREATE_MIXCTL:
+ {
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ userdev_mixctl_t *c=(userdev_mixctl_t*)arg;
+ oss_mixext *ext;
+ int ctl;
+
+ c->name[sizeof(c->name)-1]=0; /* Buffer overflow protection */
+
+ if (c->index < 0 || c->index >= USERDEV_MAX_MIXERS)
+ return OSS_EINVAL;
+
+ if ((ctl = mixer_ext_create_control (devc->mixer_dev,
+ c->parent,
+ c->index,
+ userdev_set_control,
+ c->type,
+ c->name,
+ c->maxvalue,
+ c->flags)) < 0)
+ return ctl;
+
+ c->num = ctl;
+ ext = mixer_find_ext (devc->mixer_dev, ctl);
+
+ ext->minvalue = c->offset;
+ ext->control_no= c->control_no;
+ ext->rgbcolor = c->rgbcolor;
+
+ if (c->type == MIXT_ENUM)
+ {
+ memcpy(ext->enum_present, c->enum_present, sizeof(ext->enum_present));
+ mixer_ext_set_strings (devc->mixer_dev, ctl, c->enum_choises, 0);
+ }
+
+ return 0;
+ }
+ break;
+
+ case USERDEV_GET_MIX_CHANGECOUNT:
+ {
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ return *arg = devc->modify_counter;
+ }
+ break;
+
+ case USERDEV_SET_MIXERS:
+ {
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ memcpy(devc->mixer_values, arg, sizeof(devc->mixer_values));
+ mixer_devs[devc->mixer_dev]->modify_counter++;
+//cmn_err(CE_CONT, "Set %08x %08x\n", devc->mixer_values[0], devc->mixer_values[1]);
+ return 0;
+ }
+ break;
+
+ case USERDEV_GET_MIXERS:
+ {
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ memcpy(arg, devc->mixer_values, sizeof(devc->mixer_values));
+ return 0;
+ }
+ break;
+
+ }
+
+ return userdev_ioctl(dev, cmd, arg);
+}
+
+/*ARGSUSED*/
+static void
+userdev_output_block (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+userdev_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+static void
+userdev_trigger (int dev, int state)
+{
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ if (portc->open_mode & OPEN_READ) /* Handle input */
+ {
+ portc->input_triggered = !!(state & OPEN_READ);
+ }
+
+ if (portc->open_mode & OPEN_WRITE) /* Handle output */
+ {
+ portc->output_triggered = !!(state & OPEN_WRITE);
+ }
+
+ if (portc->output_triggered || portc->input_triggered) /* Something is going on */
+ {
+ int tmout = devc->poll_ticks;
+
+ if (tmout < 1)
+ tmout = 1;
+
+ if (portc->port_type != PT_SERVER)
+ portc = portc->peer; /* Switch to the server side */
+
+ if (portc->output_triggered || portc->input_triggered) /* Something is going on */
+ if (devc->timeout_id == 0)
+ {
+ devc->timeout_id = timeout (userdev_cb, portc, tmout);
+ }
+ }
+ else
+ {
+ if (portc->port_type == PT_SERVER)
+ if (devc->timeout_id != 0)
+ {
+ untimeout (devc->timeout_id);
+ devc->timeout_id = 0;
+ }
+ }
+}
+
+/*ARGSUSED*/
+static int
+userdev_server_prepare_for_input (int dev, int bsize, int bcount)
+{
+ oss_native_word flags;
+
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->input_triggered = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+userdev_server_prepare_for_output (int dev, int bsize, int bcount)
+{
+ oss_native_word flags;
+
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->output_triggered = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+userdev_client_prepare_for_input (int dev, int bsize, int bcount)
+{
+ oss_native_word flags;
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->input_triggered = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+userdev_client_prepare_for_output (int dev, int bsize, int bcount)
+{
+ oss_native_word flags;
+ userdev_portc_t *portc = audio_engines[dev]->portc;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ portc->output_triggered = 0;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+userdev_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+#define MY_BUFFSIZE (64*1024)
+ if (dmap->dmabuf != NULL)
+ return 0;
+ dmap->dmabuf_phys = 0; /* Not mmap() capable */
+ dmap->dmabuf = KERNEL_MALLOC (MY_BUFFSIZE);
+ if (dmap->dmabuf == NULL)
+ return OSS_ENOSPC;
+ dmap->buffsize = MY_BUFFSIZE;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+userdev_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ if (dmap->dmabuf == NULL)
+ return 0;
+ KERNEL_FREE (dmap->dmabuf);
+
+ dmap->dmabuf = NULL;
+ return 0;
+}
+
+#if 0
+static int
+userdev_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+}
+#endif
+
+/*ARGSUSED*/
+static int
+userdev_ioctl_override (int dev, unsigned int cmd, ioctl_arg arg)
+{
+/*
+ * Purpose of this ioctl override function is to intercept mixer
+ * ioctl calls made on the client side and to hide everything
+ * outside the userdev instance from the application.
+ *
+ * Note that this ioctl is related with the client side audio device. However
+ * if /dev/mixer points to this (audio) device then all mixer acess will
+ * be redirected too. Also the vmix driver will redirect mixer/system ioctl
+ * calls to this function.
+ */
+ int err;
+ userdev_devc_t *devc = audio_engines[dev]->devc;
+ adev_t *adev = audio_engines[devc->client_portc.audio_dev];
+
+ switch (cmd)
+ {
+ case SNDCTL_MIX_NRMIX:
+ return *arg=1;
+ break;
+
+ case SNDCTL_MIX_NREXT:
+ *arg = devc->mixer_dev;
+ return OSS_EAGAIN; /* Continue with the default handler */
+ break;
+
+ case SNDCTL_SYSINFO:
+ {
+ /*
+ * Fake SNDCTL_SYSINFO to report just one mixer device which is
+ * the one associated with the client.
+ */
+ oss_sysinfo *info = (oss_sysinfo *) arg;
+ int i;
+
+ if ((err=oss_mixer_ext(dev, OSS_DEV_DSP_ENGINE, cmd, arg))<0)
+ return err;
+
+ /*
+ * Hide all non-oss_userdev devices
+ */
+ strcpy (info->product, "OSS (userdev)");
+ info->nummixers = 1;
+ info->numcards = 1;
+ info->numaudios = 1;
+ for (i = 0; i < 8; i++)
+ info->openedaudio[i] = 0;
+
+ return 0;
+ }
+ break;
+
+ case SNDCTL_MIXERINFO:
+ {
+ oss_mixerinfo *info = (oss_mixerinfo *) arg;
+
+ info->dev = devc->mixer_dev; /* Redirect to oss_userdev mixer */
+
+ if ((err=oss_mixer_ext(dev, OSS_DEV_DSP_ENGINE, cmd, arg))<0)
+ return err;
+
+ strcpy(info->name, adev->name);
+ info->card_number = 0;
+ return 0;
+ }
+
+ case SNDCTL_AUDIOINFO:
+ case SNDCTL_AUDIOINFO_EX:
+ {
+ oss_audioinfo *info = (oss_audioinfo *) arg;
+
+ info->dev = devc->client_portc.audio_dev;
+
+ cmd = SNDCTL_ENGINEINFO;
+
+ if ((err=oss_mixer_ext(dev, OSS_DEV_DSP_ENGINE, cmd, arg))<0)
+ return err;
+
+ info->card_number = 0;
+ return 0;
+ }
+
+ case SNDCTL_CARDINFO:
+ {
+ oss_card_info *info = (oss_card_info *) arg;
+
+ info->card = adev->card_number; /* Redirect to oss_userdev0 */
+
+ if ((err=oss_mixer_ext(dev, OSS_DEV_DSP_ENGINE, cmd, arg))<0)
+ return err;
+
+ info->card = 0;
+ return 0;
+ }
+
+ case SNDCTL_MIX_EXTINFO:
+ {
+ oss_mixext *ext = (oss_mixext*)arg;
+
+ ext->dev = devc->mixer_dev;
+
+ if ((err=oss_mixer_ext(dev, OSS_DEV_DSP_ENGINE, cmd, arg))<0)
+ return err;
+
+ if (ext->type == MIXT_DEVROOT)
+ {
+ oss_mixext_root *root = (oss_mixext_root *) ext->data;
+ strncpy(root->name, adev->name, 48);
+ root->name[47]=0;
+ }
+
+ return 0;
+ }
+ break;
+
+ case SNDCTL_MIX_READ:
+ case SNDCTL_MIX_WRITE:
+ {
+ oss_mixer_value *ent = (oss_mixer_value*)arg;
+
+ ent->dev = devc->mixer_dev;
+
+ return OSS_EAGAIN; /* Redirect */
+ }
+ break;
+
+ default:
+ return OSS_EAGAIN;
+ }
+}
+
+static audiodrv_t userdev_server_driver = {
+ userdev_server_open,
+ userdev_server_close,
+ userdev_output_block,
+ userdev_start_input,
+ userdev_server_ioctl,
+ userdev_server_prepare_for_input,
+ userdev_server_prepare_for_output,
+ userdev_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ userdev_trigger,
+ userdev_server_set_rate,
+ userdev_server_set_format,
+ userdev_server_set_channels,
+ NULL,
+ NULL,
+ userdev_check_input,
+ userdev_check_output,
+ userdev_alloc_buffer,
+ userdev_free_buffer,
+ NULL,
+ NULL,
+ NULL /* userdev_get_buffer_pointer */
+};
+
+static audiodrv_t userdev_client_driver = {
+ userdev_client_open,
+ userdev_client_close,
+ userdev_output_block,
+ userdev_start_input,
+ userdev_ioctl,
+ userdev_client_prepare_for_input,
+ userdev_client_prepare_for_output,
+ userdev_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ userdev_trigger,
+ userdev_client_set_rate,
+ userdev_client_set_format,
+ userdev_client_set_channels,
+ NULL,
+ NULL,
+ userdev_check_input,
+ userdev_check_output,
+ userdev_alloc_buffer,
+ userdev_free_buffer,
+ NULL,
+ NULL,
+ NULL, // userdev_get_buffer_pointer
+ NULL, // userdev_calibrate_speed
+ NULL, // userdev_sync_control
+ NULL, // userdev_prepare_to_stop
+ NULL, // userdev_get_input_pointer
+ NULL, // userdev_get_output_pointer
+ NULL, // userdev_bind
+ NULL, // userdev_setup_fragments
+ NULL, // userdev_redirect
+ userdev_ioctl_override
+};
+
+static int
+userdev_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+
+ if (cmd == SOUND_MIXER_READ_CAPS)
+ return *arg = SOUND_CAP_NOLEGACY;
+
+#if 0
+ if (cmd == SOUND_MIXER_READ_DEVMASK ||
+ cmd == SOUND_MIXER_READ_RECMASK || cmd == SOUND_MIXER_READ_RECSRC)
+ return *arg = 0;
+
+ if (cmd == SOUND_MIXER_READ_VOLUME || cmd == SOUND_MIXER_READ_PCM)
+ return *arg = 100 | (100 << 8);
+ if (cmd == SOUND_MIXER_WRITE_VOLUME || cmd == SOUND_MIXER_WRITE_PCM)
+ return *arg = 100 | (100 << 8);
+#endif
+ return OSS_EINVAL;
+}
+
+static mixer_driver_t userdev_mixer_driver = {
+ userdev_mixer_ioctl
+};
+
+static int
+install_server (userdev_devc_t * devc)
+{
+ userdev_portc_t *portc = &devc->server_portc;
+ int adev;
+
+ int opts =
+ ADEV_STEREOONLY | ADEV_16BITONLY | ADEV_VIRTUAL |
+ ADEV_FIXEDRATE | ADEV_SPECIAL | ADEV_HIDDEN | ADEV_DUPLEX;
+
+ memset (portc, 0, sizeof (*portc));
+
+ portc->devc = devc;
+ portc->port_type = PT_SERVER;
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "User space audio device server side",
+ &userdev_server_driver,
+ sizeof (audiodrv_t),
+ opts, SUPPORTED_FORMATS, devc, -1)) < 0)
+ {
+ return adev;
+ }
+
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = MAX_RATE;
+ audio_engines[adev]->min_channels = 1;
+ audio_engines[adev]->max_channels = MAX_CHANNELS;
+ audio_engines[adev]->vmix_mixer=NULL;
+ strcpy(audio_engines[adev]->devnode, userdev_server_devnode);
+
+ portc->audio_dev = adev;
+
+ return adev;
+}
+
+static int
+null_mixer_init(int de)
+{
+ return 0;
+}
+
+static void
+userdev_create_mixer(userdev_devc_t * devc)
+{
+ if ((devc->mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "OSS userdev mixer",
+ &userdev_mixer_driver,
+ sizeof (mixer_driver_t), devc)) < 0)
+ {
+ devc->mixer_dev = -1;
+ return;
+ }
+ mixer_ext_set_init_fn (devc->mixer_dev, null_mixer_init, USERDEV_MAX_MIXERS*2);
+}
+
+static int
+install_client (userdev_devc_t * devc)
+{
+ userdev_portc_t *portc = &devc->client_portc;
+ int adev;
+
+ int opts =
+ ADEV_STEREOONLY | ADEV_16BITONLY | ADEV_VIRTUAL | ADEV_DUPLEX |
+ ADEV_FIXEDRATE | ADEV_SPECIAL | ADEV_LOOP;
+
+ memset (portc, 0, sizeof (*portc));
+
+ userdev_create_mixer(devc);
+
+ portc->devc = devc;
+ portc->port_type = PT_CLIENT;
+
+ if (!userdev_visible_clientnodes && !(devc->create_flags & USERDEV_F_VMIX_PRIVATENODE))
+ {
+ opts |= ADEV_HIDDEN;
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ "User space audio device",
+ &userdev_client_driver,
+ sizeof (audiodrv_t),
+ opts, SUPPORTED_FORMATS, devc, -1)) < 0)
+ {
+ return adev;
+ }
+
+ if (!userdev_visible_clientnodes) /* Invisible client device nodes */
+ strcpy(audio_engines[adev]->devnode, userdev_client_devnode);
+
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->mixer_dev = devc->mixer_dev;
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = MAX_RATE;
+ audio_engines[adev]->min_channels = 1;
+ audio_engines[adev]->max_channels = MAX_CHANNELS;
+
+ portc->audio_dev = adev;
+#ifdef CONFIG_OSS_VMIX
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+
+ return adev;
+}
+
+int
+userdev_create_device_pair(void)
+{
+ int client_engine, server_engine;
+ userdev_devc_t *devc;
+ oss_native_word flags;
+
+ if ((devc=PMALLOC(userdev_osdev, sizeof (*devc))) == NULL)
+ return OSS_ENOMEM;
+ memset(devc, 0, sizeof(*devc));
+
+ devc->osdev = userdev_osdev;
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ devc->active=1;
+
+ devc->rate = 48000;
+ devc->fmt = AFMT_S16_NE;
+ devc->fmt_bytes = 2;
+ devc->channels = 2;
+ devc->poll_ticks = 10;
+
+ if ((server_engine=install_server (devc)) < 0)
+ return server_engine;
+
+ if ((client_engine=install_client (devc)) < 0)
+ return client_engine;
+
+ devc->client_portc.peer = &devc->server_portc;
+ devc->server_portc.peer = &devc->client_portc;
+
+ /*
+ * Insert the device to the list of available devices
+ */
+ MUTEX_ENTER_IRQDISABLE(userdev_global_mutex, flags);
+ devc->next_instance = userdev_active_device_list;
+ userdev_active_device_list = devc;
+ MUTEX_EXIT_IRQRESTORE(userdev_global_mutex, flags);
+
+ return server_engine;
+}
+
+static void
+userdev_free_device_pair (userdev_devc_t *devc)
+{
+ oss_native_word flags;
+
+ set_adev_name(devc->client_portc.audio_dev, "User space audio device");
+ set_adev_name(devc->server_portc.audio_dev, "User space audio device server side");
+
+ MUTEX_ENTER_IRQDISABLE(userdev_global_mutex, flags);
+
+ devc->match_method = 0;
+ devc->match_key = 0;
+
+ /*
+ * Add to the free device pair list.
+ */
+ devc->next_instance = userdev_free_device_list;
+ userdev_free_device_list = devc;
+
+ /*
+ * Remove the device pair from the active device list.
+ */
+
+ if (userdev_active_device_list == devc) /* First device in the list */
+ {
+ userdev_active_device_list = userdev_active_device_list->next_instance;
+ }
+ else
+ {
+ userdev_devc_t *this = userdev_active_device_list, *prev = NULL;
+
+ while (this != NULL)
+ {
+ if (this == devc)
+ {
+ prev->next_instance = this->next_instance; /* Remove */
+ break;
+ }
+
+ prev = this;
+ this = this->next_instance;
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE(userdev_global_mutex, flags);
+}
+
+void
+userdev_reinit_instance(userdev_devc_t *devc)
+{
+ if (devc->mixer_dev < 0)
+ return;
+
+ mixer_ext_rebuild_all (devc->mixer_dev, null_mixer_init, USERDEV_MAX_MIXERS*2);
+}
+
+void
+userdev_delete_device_pair(userdev_devc_t *devc)
+{
+ if (!devc->active)
+ return;
+
+ devc->active = 0;
+ MUTEX_CLEANUP(devc->mutex);
+}
+
+int
+usrdev_find_free_device_pair(void)
+{
+ oss_native_word flags;
+ userdev_devc_t *devc;
+
+ MUTEX_ENTER_IRQDISABLE(userdev_global_mutex, flags);
+
+ if (userdev_free_device_list != NULL)
+ {
+ devc = userdev_free_device_list;
+ userdev_free_device_list = userdev_free_device_list->next_instance;
+
+ devc->next_instance = userdev_active_device_list;
+ userdev_active_device_list = devc;
+
+ MUTEX_EXIT_IRQRESTORE(userdev_global_mutex, flags);
+ return devc->server_portc.audio_dev;
+ }
+ MUTEX_EXIT_IRQRESTORE(userdev_global_mutex, flags);
+
+ return OSS_ENXIO;
+}
diff --git a/kernel/drv/oss_userdev/userdev.h b/kernel/drv/oss_userdev/userdev.h
new file mode 100644
index 0000000..1ed1040
--- /dev/null
+++ b/kernel/drv/oss_userdev/userdev.h
@@ -0,0 +1,81 @@
+/*
+ * Purpose: Definition file for the oss_userdev driver
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+#define MAX_RATE 192000
+#define MAX_CHANNELS 64
+#define SUPPORTED_FORMATS (AFMT_S16_NE|AFMT_S32_NE)
+
+typedef struct _userdev_devc_t userdev_devc_t;
+typedef struct _userdev_portc_t userdev_portc_t;
+
+struct _userdev_portc_t
+{
+ userdev_devc_t *devc;
+ userdev_portc_t *peer;
+ int audio_dev;
+ int open_mode;
+ int port_type;
+#define PT_CLIENT 1
+#define PT_SERVER 2
+
+ /* State variables */
+ int input_triggered, output_triggered;
+};
+
+struct _userdev_devc_t
+{
+ oss_device_t *osdev;
+ int active;
+ oss_mutex_t mutex;
+
+ int open_count; /* 0=not in use, 2=both client and server in use */
+
+ int create_flags; /* Flags from ioctl(USERDEV_CREATE_INSTANCE) */
+
+ unsigned int poll_ticks; /* Number of clock tickes (OSS_HZ) between polls. */
+
+ unsigned int match_method;
+ unsigned int match_key;
+ int mixer_dev;
+
+ userdev_devc_t *next_instance;
+
+ int rate;
+ int channels;
+ unsigned int fmt, fmt_bytes;
+ timeout_id_t timeout_id;
+
+ userdev_portc_t client_portc;
+ userdev_portc_t server_portc;
+
+ /*
+ * Mixer related fields
+ */
+ int modify_counter;
+ int mixer_values[USERDEV_MAX_MIXERS];
+};
+
+extern oss_device_t *userdev_osdev;
+extern oss_mutex_t userdev_global_mutex;
+extern userdev_devc_t *userdev_active_device_list;
+extern userdev_devc_t *userdev_free_device_list;
+
+extern int userdev_create_device_pair(void);
+extern void userdev_delete_device_pair(userdev_devc_t *devc);
+extern int usrdev_find_free_device_pair(void);
+extern void userdev_reinit_instance(userdev_devc_t *devc);
+
+extern char *userdev_client_devnode;
+extern char *userdev_server_devnode;
diff --git a/kernel/drv/oss_via823x/.config b/kernel/drv/oss_via823x/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_via823x/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_via823x/.devices b/kernel/drv/oss_via823x/.devices
new file mode 100644
index 0000000..dfb8b74
--- /dev/null
+++ b/kernel/drv/oss_via823x/.devices
@@ -0,0 +1,5 @@
+oss_via823x pci1106,3059 VIA VT8233/8235/8237
+oss_via823x pci1106,4551 VIA VT5432B
+oss_via823x pci1106,7059 VIA VT8233A
+oss_via823x pcs1462,3800 MSI K7T266
+oss_via823x pcs1462,4720 MSI KT3 Ultra
diff --git a/kernel/drv/oss_via823x/.name b/kernel/drv/oss_via823x/.name
new file mode 100644
index 0000000..e947b9d
--- /dev/null
+++ b/kernel/drv/oss_via823x/.name
@@ -0,0 +1 @@
+VIA VT8233/8235/8237 motherboard audio
diff --git a/kernel/drv/oss_via823x/oss_via823x.c b/kernel/drv/oss_via823x/oss_via823x.c
new file mode 100644
index 0000000..096a72a
--- /dev/null
+++ b/kernel/drv/oss_via823x/oss_via823x.c
@@ -0,0 +1,1013 @@
+/*
+ * Purpose: Driver for the VIA8233/8235 AC97 audio controller
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_via823x_cfg.h"
+#include <oss_pci.h>
+#include <ac97.h>
+#include "via8233.h"
+
+
+static void feed_sgd (via8233_devc * devc, dmap_t * dmap, engine_desc * eng);
+
+static int
+ac97_read (void *devc_, int wIndex)
+{
+ oss_native_word flags;
+ unsigned int dwWriteValue = 0, dwTmpValue, i = 0;
+ via8233_devc *devc = devc_;
+
+
+ /* Index has only 7 bit */
+ if (wIndex > 0x7F)
+ return 0;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ dwWriteValue = ((unsigned int) wIndex << 16) + CODEC_RD;
+ OUTL (devc->osdev, dwWriteValue, devc->base + AC97CODEC);
+ oss_udelay (100);
+ /* Check AC CODEC access time out */
+ for (i = 0; i < CODEC_TIMEOUT_COUNT; i++)
+ {
+ /* if send command over, break */
+ if (INL (devc->osdev, devc->base + AC97CODEC) & STA_VALID)
+ break;
+ oss_udelay (50);
+ }
+ if (i == CODEC_TIMEOUT_COUNT)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+ }
+
+ /* Check if Index still ours? If yes, return data, else return FAIL */
+ dwTmpValue = INL (devc->osdev, devc->base + AC97CODEC);
+ OUTB (devc->osdev, 0x02, devc->base + AC97CODEC + 3);
+ if (((dwTmpValue & CODEC_INDEX) >> 16) == wIndex)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ((int) dwTmpValue & CODEC_DATA);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+
+}
+
+static int
+ac97_write (void *devc_, int wIndex, int wData)
+{
+ oss_native_word flags;
+ unsigned int dwWriteValue = 0, i = 0;
+ via8233_devc *devc = devc_;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ dwWriteValue = ((unsigned int) wIndex << 16) + wData;
+ OUTL (devc->osdev, dwWriteValue, devc->base + AC97CODEC);
+ oss_udelay (100);
+
+ /* Check AC CODEC access time out */
+ for (i = 0; i < CODEC_TIMEOUT_COUNT; i++)
+ {
+ /* if send command over, break */
+ if (!(INL (devc->osdev, devc->base + AC97CODEC) & IN_CMD))
+ break;
+ oss_udelay (50);
+ }
+ if (i == CODEC_TIMEOUT_COUNT)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 1;
+}
+
+static int
+via8233intr (oss_device_t * osdev)
+{
+ int serviced = 0, i;
+ via8233_devc *devc = osdev->devc;
+ via8233_portc *portc;
+ engine_desc *eng;
+ unsigned int engine_stat;
+ unsigned int status = 0;
+ oss_native_word flags;
+
+ MUTEX_ENTER (devc->mutex, flags);
+ status = INL (devc->osdev, devc->base + 0x84);
+#if 0
+ // This is reported to cause hang because some status register bits
+ // may be turned on even ehen the device is not interrupting.
+ if (status == 0)
+ {
+ /*
+ * No interrupts are pending so we can stop without
+ * polling all the individual status registers.
+ */
+ MUTEX_EXIT (devc->mutex, flags);
+ return 0;
+ }
+#endif
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+ eng = portc->play_engine;
+
+ if (eng != NULL)
+ if ((eng->mode & OPEN_WRITE)
+ && (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ engine_stat = INB (devc->osdev, eng->base + 0x00);
+ if (engine_stat & 0x01)
+ {
+ oss_audio_outputintr (portc->audiodev, 1);
+ feed_sgd (devc, audio_engines[portc->audiodev]->dmap_out,
+ eng);
+ serviced = 1;
+ }
+ OUTB (devc->osdev, engine_stat, eng->base + 0x00);
+ }
+
+ eng = portc->rec_engine;
+ if (eng != NULL)
+ if ((eng->mode & OPEN_READ)
+ && (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ engine_stat = INB (devc->osdev, eng->base + 0x00);
+ if (engine_stat & 0x01)
+ {
+ oss_audio_inputintr (portc->audiodev, 0);
+ feed_sgd (devc, audio_engines[portc->audiodev]->dmap_in, eng);
+ serviced = 1;
+ }
+ OUTB (devc->osdev, engine_stat, eng->base + 0x00);
+ }
+ }
+ MUTEX_EXIT (devc->mutex, flags);
+
+ return serviced;
+}
+
+/*
+ * Audio routines
+ */
+
+static int
+via8233_audio_set_rate (int dev, int arg)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
+ arg = 48000;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+via8233_audio_set_channels (int dev, short arg)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+
+ if (arg > 6)
+ arg=6;
+
+ if ((arg != 1) && (arg != 2) && (arg != 4) && (arg != 6))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+via8233_audio_set_format (int dev, unsigned int arg)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE | AFMT_AC3)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+via8233_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void via8233_audio_trigger (int dev, int state);
+
+static void
+via8233_audio_reset (int dev)
+{
+ via8233_audio_trigger (dev, 0);
+}
+
+static void
+via8233_audio_reset_input (int dev)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+ via8233_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+via8233_audio_reset_output (int dev)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+ via8233_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+via8233_audio_open (int dev, int mode, int open_flags)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+ via8233_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode |= mode;
+
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+via8233_audio_close (int dev, int mode)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+ via8233_devc *devc = audio_engines[dev]->devc;
+
+ via8233_audio_reset (dev);
+ portc->open_mode = 0;
+ devc->open_mode &= ~mode;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+via8233_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+
+}
+
+/*ARGSUSED*/
+static void
+via8233_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+}
+
+static void
+via8233_audio_trigger (int dev, int state)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+ via8233_devc *devc = audio_engines[dev]->devc;
+ engine_desc *eng;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if ((portc->open_mode & OPEN_WRITE) && portc->play_engine != NULL)
+ {
+ eng = portc->play_engine;
+
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ /* Start with autoinit and SGD flag interrupts enabled */
+ OUTB (devc->osdev, 0xa1, eng->base + 0x01);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ OUTB (devc->osdev, 0x40, eng->base + 0x01); /* Stop */
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ }
+ }
+ }
+
+ if ((portc->open_mode & OPEN_READ) && portc->rec_engine != NULL)
+ {
+ eng = portc->rec_engine;
+
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ /* Start with autoinit and SGD flag interrupts enabled */
+ OUTB (devc->osdev, 0xa1, eng->base + 0x01);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ OUTB (devc->osdev, 0x40, eng->base + 0x01); /* Stop */
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static void
+feed_sgd (via8233_devc * devc, dmap_t * dmap, engine_desc * eng)
+{
+ unsigned int addr, p, tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ addr = dmap->dmabuf_phys + eng->cfrag * dmap->fragment_size;
+ p = eng->sgd_ptr;
+
+ eng->sgd[p].phaddr = addr;
+ eng->sgd[p].flags = dmap->fragment_size | SGD_FLAG;
+ if (p == (SGD_SIZE - 1))
+ eng->sgd[p].flags |= SGD_EOL;
+
+ /* Update the last entry ptr */
+ tmp = INL (devc->osdev, eng->base + 0x08);
+ tmp &= 0x00ffffff;
+ tmp |= (p << 24);
+ OUTL (devc->osdev, tmp, eng->base + 0x08);
+
+ eng->prev_sgd = p;
+ eng->frags[p] = eng->cfrag;
+ eng->cfrag = (eng->cfrag + 1) % dmap->nfrags;
+ eng->sgd_ptr = (eng->sgd_ptr + 1) % SGD_SIZE;
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+via8233_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ via8233_devc *devc = audio_engines[dev]->devc;
+ via8233_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ engine_desc *eng;
+ int i;
+ unsigned int fmt;
+ oss_native_word flags;
+
+ if (portc->rec_engine == NULL)
+ {
+ cmn_err (CE_WARN, "No rec engine (dev=%d)\n", dev);
+ return OSS_EIO;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ eng = portc->rec_engine;
+
+ OUTB (devc->osdev, 0x40, eng->base + 0x01); /* Stop */
+
+ eng->cfrag = 0;
+ eng->sgd_ptr = 0;
+ eng->prevpos = 0xffffffff;
+
+ for (i = 0; i < 2; i++)
+ feed_sgd (devc, dmap, eng);
+
+ OUTL (devc->osdev, eng->sgd_phys, eng->base + 0x04);
+
+ fmt = 0;
+ if (portc->bits == AFMT_S16_LE)
+ fmt |= (1 << 21);
+ if (portc->channels == 2)
+ fmt |= (1 << 20);
+
+ if (devc->chip_type != CHIP_8233A)
+ {
+ if (portc->speed == 48000)
+ fmt |= (1 << 20) - 1;
+ else
+ fmt |= ((1024 * portc->speed + 24000) / 48000) * 1024;
+ }
+
+ fmt |= (eng->prev_sgd << 24);
+ OUTL (devc->osdev, fmt, eng->base + 0x08);
+ ac97_recrate (&devc->ac97devc, portc->speed);
+
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+via8233_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ via8233_devc *devc = audio_engines[dev]->devc;
+ via8233_portc *portc = audio_engines[dev]->portc;
+ dmap_p dmap = audio_engines[dev]->dmap_out;
+
+ engine_desc *eng;
+ int i, tmp;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ eng = portc->play_engine;
+
+ OUTB (devc->osdev, 0x40, eng->base + 0x01); /* Stop */
+
+ eng->cfrag = 0;
+ eng->sgd_ptr = 0;
+ eng->prevpos = 0xffffffff;
+
+ for (i = 0; i < 2; i++)
+ feed_sgd (devc, dmap, eng);
+
+ OUTL (devc->osdev, eng->sgd_phys, eng->base + 0x4);
+
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_AUDIO, SNDCTL_MIX_WRITE, 0);
+
+ if (portc->bits == AFMT_AC3)
+ {
+ portc->channels = 2;
+ portc->bits = 16;
+ }
+ ac97_spdif_setup (devc->mixer_dev, portc->speed, portc->bits);
+
+ tmp = (portc->bits == AFMT_U8) ? 0 : 0x80;
+ tmp |= portc->channels << 4;
+ OUTB (devc->osdev, tmp, eng->base + 0x02);
+
+ /* Select channel assignment - not valid for 8233A */
+ tmp = 0;
+ if (devc->chip_type != CHIP_8233A)
+ {
+ switch (portc->channels)
+ {
+ case 1:
+ tmp = (1 << 0) | (1 << 4);
+ break;
+ case 2:
+ tmp = (1 << 0) | (2 << 4);
+ break;
+ case 4:
+ tmp = (1 << 0) | (2 << 4) | (3 << 8) | (4 << 12);
+ break;
+ case 6:
+ tmp =
+ (1 << 0) | (2 << 4) | (5 << 8) | (6 << 12) | (3 << 16) | (4 <<
+ 20);
+ break;
+ default:
+ tmp = 0;
+ break;
+ }
+ }
+ tmp |= 0xFF000000;
+ OUTL (devc->osdev, tmp, eng->base + 0x08);
+ /* need to set the speed twice - for some odd reason */
+ ac97_playrate (&devc->ac97devc, portc->speed);
+ ac97_playrate (&devc->ac97devc, portc->speed);
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+via8233_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ int err;
+ via8233_devc *devc = audio_engines[dev]->devc;
+ via8233_portc *portc = audio_engines[dev]->portc;
+ engine_desc *eng;
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+ if ((err = oss_alloc_dmabuf (dev, dmap, direction)) < 0)
+ return err;
+
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ eng = &devc->engines[REC_SGD_NUM];
+ eng->mode = OPEN_READ;
+ portc->rec_engine = eng;
+ }
+ else
+ {
+ eng = &devc->engines[PLAY_SGD_NUM];
+ eng->mode = OPEN_WRITE;
+ portc->play_engine = eng;
+ }
+
+ return 0;
+}
+
+
+/*ARGSUSED*/
+static int
+via8233_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+
+ if (dmap->dmabuf == NULL)
+ return 0;
+ oss_free_dmabuf (dev, dmap);
+
+ dmap->dmabuf = NULL;
+ dmap->dmabuf_phys = 0;
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ portc->play_engine = NULL;
+
+ if (direction == PCM_ENABLE_INPUT)
+ portc->rec_engine = NULL;
+
+ return 0;
+}
+
+static int
+via8233_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ via8233_portc *portc = audio_engines[dev]->portc;
+ via8233_devc *devc = audio_engines[dev]->devc;
+ unsigned int ptr, pos, tmp;
+ engine_desc *eng;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ int status;
+ /* int this_sgd, prev_sgd */ ;
+
+ if (portc->play_engine == NULL
+ || !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+ eng = portc->play_engine;
+
+ ptr = INL (devc->osdev, eng->base + 0x0c);
+ status = INB (devc->osdev, eng->base + 0x00);
+ if (!(status & 0x80)) /* SGD not triggered */
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("rawpos=%d", ptr);
+#endif
+#if 0
+ this_sgd = ptr >> 24;
+ prev_sgd = eng->prevpos >> 24;
+ prev_sgd = (prev_sgd + 1) % SGD_SIZE; /* Increment */
+ /* Chip bug catcher */
+ if (((ptr & 0xffffff) == 0) &&
+ ((eng->prevpos & 0xffffff) == 0) && (this_sgd == prev_sgd))
+ ptr = eng->prevpos;
+ else
+ eng->prevpos = ptr;
+#endif
+
+ tmp = ptr & 0xffffff;
+ ptr >>= 24;
+
+ pos = eng->frags[ptr] * dmap->fragment_size;
+ pos += (dmap->fragment_size - tmp) & ~3;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Playpos=%d", pos);
+#endif
+ pos = pos % dmap->bytes_in_use;
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return pos;
+ }
+
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ int status;
+ /* int this_sgd, prev_sgd; */
+
+ if (portc->rec_engine == NULL
+ || !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+ eng = portc->rec_engine;
+
+ ptr = INL (devc->osdev, eng->base + 0x0c);
+ status = INB (devc->osdev, eng->base + 0x00);
+ if (!(status & 0x80)) /* SGD not triggered */
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+#if 0
+ this_sgd = ptr >> 24;
+ prev_sgd = eng->prevpos >> 24;
+ prev_sgd = (prev_sgd + 1) % SGD_SIZE; /* Increment */
+
+ /* Chip bug catcher */
+ if (((ptr & 0xffffff) == 0) &&
+ ((eng->prevpos & 0xffffff) == 0) && (this_sgd == prev_sgd))
+ ptr = eng->prevpos;
+ else
+ eng->prevpos = ptr;
+#endif
+
+ tmp = ptr & 0xffffff;
+ ptr >>= 24;
+
+ pos = eng->frags[ptr] * dmap->fragment_size;
+ pos += (dmap->fragment_size - tmp) & ~3;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Recpos=%d", pos);
+#endif
+ pos = pos % dmap->bytes_in_use;
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return pos;
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+static const audiodrv_t via8233_audio_driver = {
+ via8233_audio_open,
+ via8233_audio_close,
+ via8233_audio_output_block,
+ via8233_audio_start_input,
+ via8233_audio_ioctl,
+ via8233_audio_prepare_for_input,
+ via8233_audio_prepare_for_output,
+ via8233_audio_reset,
+ NULL,
+ NULL,
+ via8233_audio_reset_input,
+ via8233_audio_reset_output,
+ via8233_audio_trigger,
+ via8233_audio_set_rate,
+ via8233_audio_set_format,
+ via8233_audio_set_channels,
+ NULL,
+ NULL,
+ NULL, /* via8233_check_input, */
+ NULL, /* via8233_check_output, */
+ via8233_alloc_buffer,
+ via8233_free_buffer,
+ NULL,
+ NULL,
+ via8233_get_buffer_pointer
+};
+
+static int
+via8233_alloc_engines (via8233_devc * devc)
+{
+ engine_desc *eng;
+ oss_native_word phaddr;
+ int i;
+
+ for (i = 0; i < MAX_ENGINES; i++)
+ {
+ if (i)
+ {
+ eng = &devc->engines[REC_SGD_NUM];
+ eng->base = devc->base + 0x60;
+ }
+ else
+ {
+ eng = &devc->engines[PLAY_SGD_NUM];
+ eng->base = devc->base + 0x40;
+ }
+
+ if (eng->sgd == NULL)
+ {
+ eng->sgd =
+ CONTIG_MALLOC (devc->osdev, SGD_ALLOC, MEMLIMIT_32BITS, &phaddr, eng->sgd_dma_handle);
+
+ if (eng->sgd == NULL)
+ {
+ cmn_err (CE_WARN, "can't allocate SGD table\n");
+ return OSS_ENOSPC;
+ }
+ eng->sgd_phys = phaddr;
+ }
+ }
+ return 0;
+}
+
+static int
+via8233_init (via8233_devc * devc)
+{
+ int my_mixer, adev, opts;
+ via8233_portc *portc;
+ int i;
+ char tmp_name[50];
+ int first_dev = 0;
+
+ /* allocate the Scatter Gather Engine buffers */
+ if (via8233_alloc_engines (devc) < 0)
+ {
+ cmn_err (CE_WARN, "Unable to allocate engines\n");
+ return OSS_ENOSPC;
+ }
+
+ /*
+ * Init mixer
+ */
+ my_mixer =
+ ac97_install (&devc->ac97devc, "VIA823x AC97 Mixer", ac97_read,
+ ac97_write, devc, devc->osdev);
+
+ if (my_mixer == -1)
+ {
+ cmn_err (CE_WARN, "AC97 mixer installation failed\n");
+ return 0; /* No mixer */
+ }
+
+ devc->mixer_dev = my_mixer;
+ mixer_devs[my_mixer]->priority = 10; /* Known motherboard device */
+
+ /* enable S/PDIF */
+ devc->ac97devc.spdif_slot = SPDIF_SLOT34;
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 1);
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ opts = ADEV_AUTOMODE;
+
+ if (!ac97_varrate (&devc->ac97devc))
+ {
+ opts |= ADEV_FIXEDRATE;
+ }
+
+ portc = &devc->portc[i];
+ if (i == 0)
+ {
+ opts |= ADEV_DUPLEX;
+ strcpy (tmp_name, devc->chip_name);
+ }
+ else
+ {
+ opts |= ADEV_DUPLEX | ADEV_SHADOW;
+ strcpy (tmp_name, devc->chip_name);
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &via8233_audio_driver,
+ sizeof (audiodrv_t),
+ opts,
+ AFMT_U8 | AFMT_S16_LE | AFMT_AC3,
+ devc, -1)) < 0)
+ {
+ adev = -1;
+ return 1;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->min_rate = 8000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ audio_engines[adev]->min_channels = 2;
+ audio_engines[adev]->max_channels = 6;
+ if (opts & ADEV_FIXEDRATE)
+ {
+ audio_engines[adev]->fixed_rate = 48000;
+ audio_engines[adev]->min_rate = 48000;
+ audio_engines[adev]->max_rate = 48000;
+ }
+
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+ portc->audiodev = adev;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+ }
+
+ return 1;
+}
+
+int
+oss_via823x_attach (oss_device_t * osdev)
+{
+ unsigned char pci_irq_line, pci_revision, bTmp /*, pci_latency */ ;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ via8233_devc *devc;
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ DDB (cmn_err
+ (CE_CONT, "oss_via823x_attach(Vendor %x, device %x)\n", vendor, device));
+ if ((vendor != VIA_VENDOR_ID)
+ || (device != VIA_8233_ID && device != VIA_8233A_ID))
+ {
+
+ cmn_err (CE_WARN, "Hardware not recognized (vendor=%x, dev=%x)\n",
+ vendor, device);
+ return 0;
+ }
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->open_mode = 0;
+
+ devc->chip_type = CHIP_8233;
+ devc->chip_name = "VIA VT8233";
+
+ if (pci_revision == 0x50)
+ devc->chip_name = "VIA VT8235";
+
+ if (pci_revision == 0x60)
+ devc->chip_name = "VIA VT8237";
+
+ if ((device == VIA_8233A_ID) ||
+ (device == VIA_8233_ID && pci_revision == 0x40))
+ {
+ devc->chip_type = CHIP_8233A;
+ devc->chip_name = "VIA VT8233A";
+ }
+
+ pci_write_config_byte (osdev, 0x41, 0xc0); /*ENAC97 & deassert RESET */
+
+ oss_udelay (10);
+ pci_read_config_byte (osdev, 0x41, &bTmp);
+ oss_udelay (10);
+ if (devc->chip_type == CHIP_8233A)
+ bTmp |= 0x0C; /* Enable var rate support */
+ else
+ bTmp |= 0x0f; /* enable VRA,SB,DX */
+ pci_write_config_byte (osdev, 0x41, bTmp);
+ oss_udelay (10);
+
+ if (devc->chip_type == CHIP_8233A)
+ {
+ pci_read_config_byte (osdev, 0x49, &bTmp);
+ oss_udelay (10);
+ pci_write_config_byte (osdev, 0x49, 0x0);
+ }
+ else
+ {
+ /* set slot 3,4 as SPDIF on VIA8235 - AC3 passthrough magic! */
+ pci_write_config_byte (osdev, 0x49, 0x1);
+ }
+
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+ /* Remove I/O space marker in bit 0. */
+ devc->base &= ~0x3;
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ devc->irq = pci_irq_line;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if (oss_register_interrupts (devc->osdev, 0, via8233intr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Unable to register interrupts\n");
+ return 0;
+ }
+
+ return via8233_init (devc); /* Detected */
+}
+
+int
+oss_via823x_detach (oss_device_t * osdev)
+{
+ via8233_devc *devc = (via8233_devc *) osdev->devc;
+ engine_desc *eng;
+ int i;
+
+ if (oss_disable_device (devc->osdev) < 0)
+ return 0;
+
+
+ /* disable S/PDIF */
+ if (devc->mixer_dev > 0)
+ ac97_spdifout_ctl (devc->mixer_dev, SPDIFOUT_ENABLE, SNDCTL_MIX_WRITE, 0);
+
+ oss_unregister_interrupts (devc->osdev);
+
+ for (i = 0; i < MAX_ENGINES; i++)
+ {
+ eng = &devc->engines[i];
+ if (eng->sgd != NULL)
+ {
+ CONTIG_FREE (devc->osdev, eng->sgd, SGD_ALLOC, eng->sgd_dma_handle);
+ eng->sgd = NULL;
+ }
+ }
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_via823x/oss_via823x.man b/kernel/drv/oss_via823x/oss_via823x.man
new file mode 100644
index 0000000..90aa34c
--- /dev/null
+++ b/kernel/drv/oss_via823x/oss_via823x.man
@@ -0,0 +1,20 @@
+NAME
+oss_via823x - Open Sound System driver for VIA 8233/8235/8237 audio controllers.
+
+DESCRIPTION
+
+VIA823x device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo/4/5.1 (Dolby) playback
+ o mono/stereo recording
+ o 8KHz to 48Khz sample rate.
+ o SPDIF input/output capability based on AC97 codec attech to the
+ VIA823x controller.
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_via823x.conf Device configuration
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_via823x/via8233.h b/kernel/drv/oss_via823x/via8233.h
new file mode 100644
index 0000000..7d2ad37
--- /dev/null
+++ b/kernel/drv/oss_via823x/via8233.h
@@ -0,0 +1,97 @@
+/*
+ * Purpose: Definitions for the via8233 driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+#define VIA_VENDOR_ID 0x1106
+#define VIA_8233_ID 0x3059
+#define VIA_8233A_ID 0x7059
+
+#define PLAY_SGD_NUM 1
+#define REC_SGD_NUM 0
+#define MAX_ENGINES 2
+#define MAX_PORTC 2
+
+#define SGD_SIZE 256
+#define SGD_ALLOC 4096
+#define SGD_EOL 0x80000000
+#define SGD_FLAG 0x40000000
+
+#define CODEC_TIMEOUT_COUNT 500
+#define AC97CODEC 0x80 /*Access AC97 Codec */
+#define IN_CMD 0x01000000 /*busy in sending */
+#define STA_VALID 0x02000000 /*1:status data is valid */
+#define CODEC_RD 0x00800000 /*Read CODEC status */
+#define CODEC_INDEX 0x007F0000 /*Index of command register to access */
+#define CODEC_DATA 0x0000FFFF /*AC97 status register data */
+
+typedef struct
+{
+ unsigned int phaddr;
+ unsigned int flags;
+}
+SGD_entry;
+
+struct via8233_portc;
+
+typedef struct
+{
+ int sgd_num, base;
+ oss_dma_handle_t sgd_dma_handle;
+ int mode;
+ SGD_entry *sgd;
+ oss_native_word sgd_phys;
+ int sgd_ptr;
+ int prev_sgd;
+ int cfrag;
+ unsigned int prevpos;
+ short frags[SGD_SIZE];
+ struct via8233_portc *portc;
+}
+engine_desc;
+
+typedef struct via8233_portc
+{
+ int audiodev;
+ int open_mode;
+ int mode_mask;
+ int speed, bits, channels;
+ engine_desc *play_engine, *rec_engine;
+ int trigger_bits;
+ int audio_enabled;
+}
+via8233_portc;
+
+
+typedef struct via8233_devc
+{
+ oss_device_t *osdev;
+ int chip_type;
+#define CHIP_8233 0
+#define CHIP_8233A 1
+ char *chip_name;
+ int multi_channel_active;
+ oss_native_word base;
+ int irq;
+ int open_mode;
+ oss_mutex_t mutex; /* For normal locking */
+ oss_mutex_t low_mutex; /* For low level routines */
+/*
+ * Mixer
+ */
+ ac97_devc ac97devc;
+ int mixer_dev;
+
+ via8233_portc portc[MAX_PORTC];
+ engine_desc engines[MAX_ENGINES];
+}
+via8233_devc;
diff --git a/kernel/drv/oss_via97/.config b/kernel/drv/oss_via97/.config
new file mode 100644
index 0000000..5280084
--- /dev/null
+++ b/kernel/drv/oss_via97/.config
@@ -0,0 +1 @@
+platform=i86pc
diff --git a/kernel/drv/oss_via97/.devices b/kernel/drv/oss_via97/.devices
new file mode 100644
index 0000000..d2dfc0f
--- /dev/null
+++ b/kernel/drv/oss_via97/.devices
@@ -0,0 +1 @@
+oss_via97 pci1106,3058 VIA VT82C686
diff --git a/kernel/drv/oss_via97/.name b/kernel/drv/oss_via97/.name
new file mode 100644
index 0000000..3860aeb
--- /dev/null
+++ b/kernel/drv/oss_via97/.name
@@ -0,0 +1 @@
+VIA VT82C686 (via97)
diff --git a/kernel/drv/oss_via97/oss_via97.c b/kernel/drv/oss_via97/oss_via97.c
new file mode 100644
index 0000000..ce79841
--- /dev/null
+++ b/kernel/drv/oss_via97/oss_via97.c
@@ -0,0 +1,944 @@
+/*
+ * uPurpose: Driver for the VIA VT82C686A AC97 audio controller
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_via97_cfg.h"
+#include "oss_pci.h"
+#include "ac97.h"
+
+#define VIA_VENDOR_ID 0x1106
+#define VIA_82C686 0x3058
+
+#define CODEC_TIMEOUT_COUNT 500
+#define AC97CODEC 0x80 /*Access AC97 Codec */
+#define IN_CMD 0x01000000 /*busy in sending */
+#define STA_VALID 0x02000000 /*1:status data is valid */
+#define CODEC_RD 0x00800000 /*Read CODEC status */
+#define CODEC_INDEX 0x007F0000 /*Index of command register to access */
+#define CODEC_DATA 0x0000FFFF /*AC97 status register data */
+
+typedef struct
+{
+ unsigned int phaddr;
+ unsigned int flags;
+}
+SGD_entry;
+
+typedef struct
+{
+ int open_mode;
+ int speed, bits, channels;
+ int audiodev;
+ int audio_enabled;
+ int trigger_bits;
+}
+via97_portc;
+
+typedef struct via97_devc
+{
+ oss_device_t *osdev;
+ oss_native_word base;
+ int irq;
+ int open_mode;
+ char *chip_name;
+/*
+ * Mixer
+ */
+ ac97_devc ac97devc;
+
+/*
+ * MIDI
+ */
+
+ int mpu_base;
+ int mpu_attached;
+
+ /* Audio parameters */
+ via97_portc portc[2];
+ oss_mutex_t mutex; /* For normal locking */
+ oss_mutex_t low_mutex; /* For low level routines */
+
+ /* Memory allocation and scatter/gather info */
+#define BUFFER_SIZE (128*1024)
+
+/* NOTE! Check SGD_ALLOC if changing SGD_SIZE */
+#define MIN_BLOCK 64
+#define SGD_SIZE (BUFFER_SIZE/MIN_BLOCK)
+#define SGD_TOTAL_SIZE (2*SGD_SIZE)
+#define SGD_ALLOC (SGD_TOTAL_SIZE*8)
+
+ SGD_entry *SGD_table;
+ oss_native_word SGD_table_phys;
+ int play_sgd_ptr, rec_sgd_ptr;
+ oss_dma_handle_t sgd_dma_handle;
+ unsigned int play_sgd_phys, rec_sgd_phys;
+}
+via97_devc;
+
+static int
+ac97_read (void *devc_, int wIndex)
+{
+ oss_native_word dwWriteValue = 0, dwTmpValue;
+ unsigned int i = 0;
+ oss_native_word flags;
+ via97_devc *devc = devc_;
+
+ /* Index has only 7 bit */
+ if (wIndex > 0x7F)
+ return 0;
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ dwWriteValue = ((oss_native_word) wIndex << 16) + CODEC_RD;
+ OUTL (devc->osdev, dwWriteValue, devc->base + AC97CODEC);
+ oss_udelay (100);
+ /* Check AC CODEC access time out */
+ for (i = 0; i < CODEC_TIMEOUT_COUNT; i++)
+ {
+ /* if send command over, break */
+ if (INL (devc->osdev, devc->base + AC97CODEC) & STA_VALID)
+ break;
+ oss_udelay (50);
+ }
+ if (i == CODEC_TIMEOUT_COUNT)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+ }
+
+ /* Check if Index still ours? If yes, return data, else return FAIL */
+ dwTmpValue = INL (devc->osdev, devc->base + AC97CODEC);
+ OUTB (devc->osdev, 0x02, devc->base + AC97CODEC + 3);
+ if (((dwTmpValue & CODEC_INDEX) >> 16) == wIndex)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ((int) dwTmpValue & CODEC_DATA);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+
+}
+
+static int
+ac97_write (void *devc_, int wIndex, int wData)
+{
+ oss_native_word dwWriteValue = 0;
+ unsigned int i = 0;
+ oss_native_word flags;
+ via97_devc *devc = devc_;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ dwWriteValue = ((oss_native_word) wIndex << 16) + wData;
+ OUTL (devc->osdev, dwWriteValue, devc->base + AC97CODEC);
+ oss_udelay (100);
+
+ /* Check AC CODEC access time out */
+ for (i = 0; i < CODEC_TIMEOUT_COUNT; i++)
+ {
+ /* if send command over, break */
+ if (!(INL (devc->osdev, devc->base + AC97CODEC) & IN_CMD))
+ break;
+ oss_udelay (50);
+ }
+ if (i == CODEC_TIMEOUT_COUNT)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return (-1);
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 1;
+}
+
+static int
+via97intr (oss_device_t * osdev)
+{
+ via97_devc *devc = (via97_devc *) osdev->devc;
+ via97_portc *portc;
+ unsigned char status;
+ int serviced = 0;
+ int i;
+
+#ifdef OBSOLETED_STUFF
+ if (devc->mpu_attached)
+ {
+ if (uart401intr (INT_HANDLER_CALL (devc->irq)))
+ serviced = 1;
+ }
+#endif
+
+ /* Handle playback interrupt */
+ status = INB (devc->osdev, devc->base + 0x00);
+
+ if (status & 0x01)
+ {
+ serviced = 1;
+ for (i = 0; i < 2; i++)
+ {
+ portc = &devc->portc[i];
+ /* IOC Interrupt */
+ if ((portc->trigger_bits & PCM_ENABLE_OUTPUT) && (status & 0x01))
+ oss_audio_outputintr (portc->audiodev, 0);
+ }
+ }
+ OUTB (devc->osdev, status | 0x01, devc->base + 0x00);
+
+
+ /* Handle record interrupt */
+ status = INB (devc->osdev, devc->base + 0x10);
+
+ if (status & 0x01)
+ {
+ serviced = 1;
+ for (i = 0; i < 2; i++)
+ {
+ portc = &devc->portc[i];
+ /* IOC Interrupt */
+ if ((portc->trigger_bits & PCM_ENABLE_INPUT) && (status & 0x01))
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ }
+
+ OUTB (devc->osdev, status | 0x01, devc->base + 0x10);
+ return serviced;
+}
+
+/*
+ * Audio routines
+ */
+
+static int
+via97_audio_set_rate (int dev, int arg)
+{
+ via97_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (audio_engines[dev]->flags & ADEV_FIXEDRATE)
+ arg = 48000;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+via97_audio_set_channels (int dev, short arg)
+{
+ via97_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->channels;
+
+
+ if ((arg != 1) && (arg != 2))
+ return portc->channels = 2;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+via97_audio_set_format (int dev, unsigned int arg)
+{
+ via97_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE)))
+ return portc->bits = AFMT_S16_LE;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+via97_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void via97_audio_trigger (int dev, int state);
+
+static void
+via97_audio_reset (int dev)
+{
+ via97_audio_trigger (dev, 0);
+}
+
+static void
+via97_audio_reset_input (int dev)
+{
+ via97_portc *portc = audio_engines[dev]->portc;
+ via97_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+via97_audio_reset_output (int dev)
+{
+ via97_portc *portc = audio_engines[dev]->portc;
+ via97_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+via97_audio_open (int dev, int mode, int open_flags)
+{
+ via97_portc *portc = audio_engines[dev]->portc;
+ via97_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ if (devc->open_mode & mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ devc->open_mode |= mode;
+
+ portc->open_mode = mode;
+ portc->audio_enabled &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+via97_audio_close (int dev, int mode)
+{
+ via97_portc *portc = audio_engines[dev]->portc;
+ via97_devc *devc = audio_engines[dev]->devc;
+
+ via97_audio_reset (dev);
+ portc->open_mode = 0;
+ devc->open_mode &= ~mode;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+via97_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ via97_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+}
+
+/*ARGSUSED*/
+static void
+via97_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ via97_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+}
+
+static void
+via97_audio_trigger (int dev, int state)
+{
+ via97_devc *devc = audio_engines[dev]->devc;
+ via97_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ OUTB (devc->osdev, 0x80, devc->base + 0x01);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ OUTB (devc->osdev, 0x40, devc->base + 0x01);
+ }
+ }
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+
+ OUTB (devc->osdev, 0x80, devc->base + 0x11);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ OUTB (devc->osdev, 0x40, devc->base + 0x11);
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+via97_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ via97_devc *devc = audio_engines[dev]->devc;
+ via97_portc *portc = audio_engines[dev]->portc;
+ int i, sgd_ptr;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ unsigned char tmp;
+ oss_native_word flags;
+
+ if (audio_engines[dev]->dmap_in->dmabuf_phys == 0)
+ return OSS_ENOSPC;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ tmp = 0x81; /* Auto start at EOL, interrupt on FLAG */
+
+ if (portc->bits != AFMT_U8)
+ tmp |= 0x20;
+ if (portc->channels != 1)
+ tmp |= 0x10;
+ OUTB (devc->osdev, tmp, devc->base + 0x12);
+
+ ac97_recrate (&devc->ac97devc, portc->speed);
+
+ sgd_ptr = devc->rec_sgd_ptr;
+ for (i = 0; i < dmap->nfrags; i++)
+ {
+ if (sgd_ptr >= SGD_TOTAL_SIZE)
+ {
+ cmn_err (CE_WARN, "Out of Record SGD entries\n");
+ return OSS_ENOSPC;
+ }
+
+ devc->SGD_table[sgd_ptr].phaddr =
+ dmap->dmabuf_phys + (i * dmap->fragment_size);
+ devc->SGD_table[sgd_ptr].flags = 0x40000000 | dmap->fragment_size;
+
+ sgd_ptr++;
+ }
+
+ devc->SGD_table[sgd_ptr - 1].flags |= 0x80000000; /* EOL */
+ devc->rec_sgd_phys =
+ devc->SGD_table_phys + devc->rec_sgd_ptr * sizeof (SGD_entry);
+ OUTL (devc->osdev, devc->rec_sgd_phys, devc->base + 0x14);
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+via97_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ via97_devc *devc = audio_engines[dev]->devc;
+ via97_portc *portc = audio_engines[dev]->portc;
+ int i, sgd_ptr;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+ unsigned char tmp;
+ oss_native_word flags;
+
+ if (audio_engines[dev]->dmap_out->dmabuf_phys == 0)
+ return OSS_ENOSPC;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ tmp = 0x81; /* Auto start at EOL, interrupt on FLAG */
+
+ if (portc->bits != AFMT_U8)
+ tmp |= 0x20;
+ if (portc->channels != 1)
+ tmp |= 0x10;
+ OUTB (devc->osdev, tmp, devc->base + 0x02);
+
+ ac97_playrate (&devc->ac97devc, portc->speed);
+
+ sgd_ptr = devc->play_sgd_ptr;
+
+ for (i = 0; i < dmap->nfrags; i++)
+ {
+ if (sgd_ptr >= SGD_TOTAL_SIZE)
+ {
+ cmn_err (CE_WARN, "Out of Playback SGD entries\n");
+ return OSS_ENOSPC;
+ }
+
+ devc->SGD_table[sgd_ptr].phaddr =
+ dmap->dmabuf_phys + (i * dmap->fragment_size);
+ devc->SGD_table[sgd_ptr].flags = 0x40000000 | dmap->fragment_size;
+
+ sgd_ptr++;
+ }
+
+ devc->SGD_table[sgd_ptr - 1].flags |= 0x80000000; /* EOL */
+ devc->play_sgd_phys =
+ devc->SGD_table_phys + devc->play_sgd_ptr * sizeof (SGD_entry);
+ OUTL (devc->osdev, devc->play_sgd_phys, devc->base + 0x04);
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+static int
+via97_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ int err;
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+ if ((err = oss_alloc_dmabuf (dev, dmap, direction)) < 0)
+ return err;
+
+ if (dmap->buffsize > BUFFER_SIZE)
+ {
+ cmn_err (CE_WARN, "Too large DMA buffer (%d/%d) - truncated\n",
+ dmap->buffsize, BUFFER_SIZE);
+ dmap->buffsize = BUFFER_SIZE;
+ }
+
+ return 0;
+}
+
+static int
+via97_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+/*
+ * Unfortunately the VIA chip seems to raise interrupt about 32 bytes before
+ * the DMA pointer moves to a new fragment. This means that the bytes value
+ * returned by SNDCTL_DSP_GET[]PTR will be bogus during few samples before
+ * the pointer wraps back to the beginning of buffer.
+ *
+ * If mmap() is not being used this routine will return 0 during this period.
+ */
+ via97_devc *devc = audio_engines[dev]->devc;
+ unsigned int ptr, sgd;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ ptr = INL (devc->osdev, devc->base + 0x0c) & 0xffffff;
+ sgd =
+ ((INL (devc->osdev, devc->base + 0x04) - devc->play_sgd_phys) / 8) -
+ 1;
+
+ ptr = dmap->fragment_size - ptr;
+ ptr = ptr + (sgd * dmap->fragment_size);
+//cmn_err(CE_CONT, "%d/%d\n", sgd, ptr);
+ }
+ else
+ {
+ ptr = INL (devc->osdev, devc->base + 0x1c) & 0xffffff;
+ sgd =
+ ((INL (devc->osdev, devc->base + 0x14) - devc->rec_sgd_phys) / 8) - 1;
+
+ ptr = dmap->fragment_size - ptr;
+ ptr = ptr + (sgd * dmap->fragment_size);
+ }
+
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return ptr;
+}
+
+static const audiodrv_t via97_audio_driver = {
+ via97_audio_open,
+ via97_audio_close,
+ via97_audio_output_block,
+ via97_audio_start_input,
+ via97_audio_ioctl,
+ via97_audio_prepare_for_input,
+ via97_audio_prepare_for_output,
+ via97_audio_reset,
+ NULL,
+ NULL,
+ via97_audio_reset_input,
+ via97_audio_reset_output,
+ via97_audio_trigger,
+ via97_audio_set_rate,
+ via97_audio_set_format,
+ via97_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ via97_alloc_buffer,
+ NULL, /* via97_free_buffer, */
+ NULL,
+ NULL,
+ via97_get_buffer_pointer
+};
+
+#ifdef OBSOLETED_STUFF
+/*
+ * This device has "ISA style" MIDI and FM subsystems. Such devices don't
+ * use PCI config space for the I/O ports and interrupts. Instead the driver
+ * needs to allocate proper resources itself. This functionality is no longer
+ * possible. For this reason the MIDI and FM parts are not accessible.
+ */
+static void
+attach_mpu (via97_devc * devc)
+{
+ struct address_info hw_config;
+
+ hw_config.io_base = devc->mpu_base;
+ hw_config.irq = -devc->irq;
+ hw_config.dma = -1;
+ hw_config.dma2 = -1;
+ hw_config.always_detect = 0;
+ hw_config.name = "VIA97 external MIDI";
+ hw_config.driver_use_1 = 0;
+ hw_config.driver_use_2 = 0;
+ hw_config.osdev = devc->osdev;
+#ifdef CREATE_OSP
+ CREATE_OSP (hw_config.osdev);
+#endif
+ hw_config.card_subtype = 0;
+#if 1
+ if (!probe_uart401 (&hw_config))
+ {
+ cmn_err (CE_WARN, "MPU-401 was not detected\n");
+ return;
+ }
+#endif
+ DDB (cmn_err (CE_WARN, "MPU-401 detected - Good\n"));
+ attach_uart401 (&hw_config);
+ devc->mpu_attached = 1;
+}
+
+static void
+unload_mpu (via97_devc * devc)
+{
+ struct address_info hw_config;
+
+ if (devc == NULL || !devc->mpu_attached)
+ return;
+
+ devc->mpu_attached = 0;
+ hw_config.io_base = devc->mpu_base;
+ hw_config.irq = devc->irq;
+ hw_config.dma = -1;
+ hw_config.dma2 = -1;
+ hw_config.always_detect = 0;
+ hw_config.name = "VIA97";
+ hw_config.driver_use_1 = 0;
+ hw_config.driver_use_2 = 0;
+ hw_config.osdev = devc->osdev;
+#ifdef CREATE_OSP
+ CREATE_OSP (hw_config.osdev);
+#endif
+ hw_config.card_subtype = 0;
+
+ unload_uart401 (&hw_config);
+
+}
+#endif
+
+static int
+init_via97 (via97_devc * devc)
+{
+ int my_mixer, adev, opts, i;
+ int first_dev = 0;
+ oss_native_word phaddr;
+
+
+/*
+ * Allocate the SGD buffers
+ */
+
+ if (devc->SGD_table == NULL)
+ {
+ devc->SGD_table =
+ CONTIG_MALLOC (devc->osdev, SGD_ALLOC, MEMLIMIT_32BITS, &phaddr, devc->sgd_dma_handle);
+
+ if (devc->SGD_table == NULL)
+ return OSS_ENOSPC;
+ devc->SGD_table_phys = phaddr;
+ }
+
+ /*
+ * Allocate SGD entries for recording and playback.
+ */
+ devc->rec_sgd_ptr = 0;
+ devc->play_sgd_ptr = SGD_SIZE;
+/*
+ * Init mixer
+ */
+ my_mixer =
+ ac97_install (&devc->ac97devc, "VIA82C686 AC97 Mixer", ac97_read,
+ ac97_write, devc, devc->osdev);
+ if (my_mixer == -1)
+ return 0; /* No mixer */
+
+ mixer_devs[my_mixer]->priority = 10; /* Known motherboard device */
+
+ /* enable variable rate */
+ ac97_write (devc, 0x2a, 0x01);
+
+#ifdef OBSOLETED_STUFF
+ DDB (cmn_err (CE_WARN, "Probing UART401 at 0x%x\n", devc->mpu_base));
+ attach_mpu (devc);
+#endif
+
+ for (i = 0; i < 2; i++)
+ {
+ via97_portc *portc = &devc->portc[i];
+ char tmp_name[100];
+
+ opts = ADEV_AUTOMODE;
+
+ if (!ac97_varrate (&devc->ac97devc))
+ {
+ opts |= ADEV_FIXEDRATE;
+ }
+
+ if (i == 0)
+ {
+ opts |= ADEV_DUPLEX;
+ strcpy (tmp_name, "VIA 82C686 AC97 Controller");
+ }
+ else
+ {
+ opts |= ADEV_DUPLEX | ADEV_SHADOW;
+ strcpy (tmp_name, "VIA 82C686 AC97 Controller");
+ }
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &via97_audio_driver,
+ sizeof (audiodrv_t),
+ opts,
+ AFMT_U8 | AFMT_S16_LE, devc, -1)) < 0)
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->min_rate = 8000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ portc->open_mode = 0;
+ portc->audio_enabled = 0;
+ portc->audiodev = adev;
+ audio_engines[adev]->min_block = MIN_BLOCK;
+ audio_engines[adev]->max_block = 4 * 1024;
+ audio_engines[adev]->max_fragments = SGD_SIZE;
+ if (opts & ADEV_FIXEDRATE)
+ {
+ audio_engines[adev]->fixed_rate = 48000;
+ audio_engines[adev]->min_rate = 48000;
+ audio_engines[adev]->max_rate = 48000;
+ }
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+ }
+ return 1;
+}
+
+int
+oss_via97_attach (oss_device_t * osdev)
+{
+ unsigned char tmp, pci_irq_line, pci_revision /*, pci_latency */ ;
+ unsigned short pci_command, vendor, device;
+ unsigned int pci_ioaddr;
+ int mpu_base;
+ via97_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered VT82C686 probe routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (vendor != VIA_VENDOR_ID || device != VIA_82C686)
+ return 0;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_BASE_ADDRESS_0, &pci_ioaddr);
+
+ if (pci_ioaddr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
+ return 0;
+ }
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+ devc->chip_name = "VIA VT82C686";
+
+ /* Enable codec, etc */
+
+ pci_write_config_byte (osdev, 0x41, 0xc0);
+ oss_udelay (10);
+ pci_read_config_byte (osdev, 0x41, &tmp);
+ pci_write_config_byte (osdev, 0x41, tmp | 0x0c);
+ oss_udelay (10);
+
+ /* setup game port/MIDI */
+ pci_write_config_byte (osdev, 0x42, 0x2a);
+ /* disable FM io */
+ pci_write_config_byte (osdev, 0x48, 0x00);
+
+ /* Enable interrupt on FLAG and on EOL */
+ tmp = INB (devc->osdev, devc->base + 0x22);
+ OUTB (devc->osdev, tmp | 0x83, devc->base + 0x22);
+
+
+ /* Enable MPU401 */
+ pci_read_config_byte (osdev, 0x8, &tmp);
+ if ((tmp & 0xff) >= 0x20)
+ {
+ pci_read_config_byte (osdev, 0x42, &tmp);
+ pci_write_config_byte (osdev, 0x42, tmp & 0x3f);
+ }
+
+ pci_read_config_byte (osdev, 0x43, &tmp);
+ switch ((tmp & 0x0c) >> 2)
+ {
+ case 0:
+ mpu_base = 0x300;
+ break;
+ case 1:
+ mpu_base = 0x310;
+ break;
+ case 2:
+ mpu_base = 0x320;
+ break;
+ default:
+ mpu_base = 0x330;
+ break;
+ }
+
+ /* map PCI IO address space */
+ devc->base = MAP_PCI_IOADDR (devc->osdev, 0, pci_ioaddr);
+ /* Remove I/O space marker in bit 0. */
+ devc->base &= ~0x3;
+
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ devc->irq = pci_irq_line;
+ devc->mpu_base = mpu_base;
+ devc->SGD_table = NULL;
+ devc->mpu_attached = 0;
+ devc->open_mode = 0;
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if (oss_register_interrupts (devc->osdev, 0, via97intr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Unable to register interrupts\n");
+ return 0;
+ }
+
+ return init_via97 (devc); /* Detected */
+}
+
+
+int
+oss_via97_detach (oss_device_t * osdev)
+{
+ via97_devc *devc = (via97_devc *) osdev->devc;
+
+
+ if (oss_disable_device (devc->osdev) < 0)
+ return 0;
+
+ OUTB (devc->osdev, 0x40, devc->base + 0x01);
+ OUTB (devc->osdev, 0x40, devc->base + 0x11);
+ OUTB (devc->osdev, 0, devc->base + 0x02);
+ OUTB (devc->osdev, 0, devc->base + 0x12);
+ OUTL (devc->osdev, 0, devc->base + 0x04);
+ OUTL (devc->osdev, 0, devc->base + 0x14);
+ OUTL (devc->osdev, 0, devc->base + 0x22);
+ oss_udelay (30);
+
+#ifdef OBSOLETED_STUFF
+ if (devc->mpu_attached)
+ unload_mpu (devc);
+#endif
+
+ oss_unregister_interrupts (devc->osdev);
+
+ if (devc->SGD_table != NULL)
+ {
+ CONTIG_FREE (devc->osdev, devc->SGD_table, SGD_ALLOC, devc->sgd_dma_handle);
+ devc->SGD_table = NULL;
+ }
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+ UNMAP_PCI_IOADDR (devc->osdev, 0);
+
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_via97/oss_via97.man b/kernel/drv/oss_via97/oss_via97.man
new file mode 100644
index 0000000..075390b
--- /dev/null
+++ b/kernel/drv/oss_via97/oss_via97.man
@@ -0,0 +1,19 @@
+NAME
+oss_via97 - VIA 82C686 audio driver
+
+DESCRIPTION
+Open Sound System driver for VIA 82C686A and 82C686B audio controllers.
+
+VIA97 device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo playback/recording
+ o 8KHz to 48Khz sample rate.
+
+OPTIONS
+None
+
+FILES
+CONFIGFILEPATH/oss_via97.conf Device configuration file.
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/drv/oss_ymf7xx/.devices b/kernel/drv/oss_ymf7xx/.devices
new file mode 100644
index 0000000..fd55bd0
--- /dev/null
+++ b/kernel/drv/oss_ymf7xx/.devices
@@ -0,0 +1,7 @@
+oss_ymf7xx pci1073,10 Yamaha DS-XG YMF744
+oss_ymf7xx pci1073,12 Yamaha DS-XG YMF754
+oss_ymf7xx pci1073,4 Yamaha DS-XG YMF724
+oss_ymf7xx pci1073,5 Yamaha DS-XG YMF734
+oss_ymf7xx pci1073,a Yamaha DS-XG YMF740
+oss_ymf7xx pci1073,c Yamaha DS-XG YMF740C
+oss_ymf7xx pci1073,d Yamaha DS-XG YMF724F
diff --git a/kernel/drv/oss_ymf7xx/.name b/kernel/drv/oss_ymf7xx/.name
new file mode 100644
index 0000000..5544929
--- /dev/null
+++ b/kernel/drv/oss_ymf7xx/.name
@@ -0,0 +1 @@
+Yamaha DS-XG YMF7xx
diff --git a/kernel/drv/oss_ymf7xx/.params b/kernel/drv/oss_ymf7xx/.params
new file mode 100644
index 0000000..26f99d1
--- /dev/null
+++ b/kernel/drv/oss_ymf7xx/.params
@@ -0,0 +1,17 @@
+int yamaha_mpu_ioaddr=0;
+/*
+ * Yamaha DSXG MPU I/O Address
+ * Values: 0x300, 0x330, 0x332, 0x334 Default: 0
+ */
+
+int yamaha_mpu_irq=0;
+/*
+ * Yamaha DSXG MPU IRQ
+ * Values: 5, 7, 9, 10, 11 Default: 0
+ */
+
+int yamaha_fm_ioaddr=0;
+/*
+ * Yamaha DSXG FM IO Address
+ * Values: 0x388, 0x398, 0x3a0, 0x3a8 Default: 0
+ */
diff --git a/kernel/drv/oss_ymf7xx/oss_ymf7xx.c b/kernel/drv/oss_ymf7xx/oss_ymf7xx.c
new file mode 100644
index 0000000..8369c2a
--- /dev/null
+++ b/kernel/drv/oss_ymf7xx/oss_ymf7xx.c
@@ -0,0 +1,1625 @@
+/*
+ * Purpose: Driver for Yamaha YMF7xx PCI audio controller.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_ymf7xx_cfg.h"
+#include "ymf7xx.h"
+#include "oss_pci.h"
+#include "ac97.h"
+#include "uart401.h"
+
+#define YAMAHA_VENDOR_ID 0x1073
+#define YAMAHA_YMF724_ID 0x0004
+#define YAMAHA_YMF724F_ID 0x000d
+#define YAMAHA_YMF734_ID 0x0005
+#define YAMAHA_YMF740_ID 0x000a
+#define YAMAHA_YMF740C_ID 0x000c
+#define YAMAHA_YMF744_ID 0x0010
+#define YAMAHA_YMF754_ID 0x0012
+
+#define WRITEB(a,d) devc->bRegister[a] = d
+#define READB(a) devc->bRegister[a]
+#define WRITEW(a,d) devc->wRegister[a>>1] = d
+#define READW(a) devc->wRegister[a>>1]
+#define WRITEL(a,d) devc->dwRegister[a>>2] = d
+#define READL(a) (devc->dwRegister[a>>2])
+
+#ifdef OSS_BIG_ENDIAN
+static __inline__ unsigned int
+ymf_swap (unsigned int x)
+{
+ return ((x & 0x000000ff) << 24) |
+ ((x & 0x0000ff00) << 8) |
+ ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
+}
+
+#define LSWAP(x) ymf_swap(x)
+#else
+#define LSWAP(x) x
+#endif
+
+#define MAX_PORTC 8
+
+extern int yamaha_mpu_ioaddr;
+extern int yamaha_mpu_irq;
+extern int yamaha_fm_ioaddr;
+
+
+typedef struct ymf7xx_portc
+{
+ int speed, bits, channels;
+ int open_mode;
+ int trigger_bits;
+ int audio_enabled;
+ int audiodev;
+ int devs_opened;
+ int devnum;
+ PLAY_BANK *bank1, *bank2, *bank3, *bank4;
+ EFFECT_CNTRL_SLOT effectslot;
+ REC_CNTRL_SLOT recslot;
+ int dacfmt;
+}
+ymf7xx_portc;
+
+typedef struct ymf7xx_devc
+{
+ oss_device_t *osdev;
+ char *chip_name;
+ int deviceid;
+ unsigned int base0addr;
+ unsigned int *base0virt;
+ volatile unsigned int *dwRegister;
+ volatile unsigned short *wRegister;
+ volatile unsigned char *bRegister;
+ int irq;
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ /* Legacy */
+ int mpu_base, mpu_irq;
+ int fm_base;
+ int fm_attached, mpu_attached;
+
+ /* Mixer parameters */
+ ac97_devc ac97devc, ac97devc2;
+ int mixer_dev;
+ int mixlevels[10];
+
+ /* Audio parameters */
+ int audio_initialized;
+ ymf7xx_portc portc[MAX_PORTC];
+
+ /* Play Table */
+ volatile oss_native_word slt;
+ oss_native_word slt_phys;
+ volatile unsigned int *tab;
+ oss_native_word play_table;
+ oss_native_word play_table_virt;
+ unsigned char *dmabuf1;
+ oss_dma_handle_t dmabuf1_dma_handle;
+
+ /* Effect Table */
+ volatile unsigned int *effecttab;
+ oss_native_word effect_table;
+ oss_native_word effect_table_virt, eff_buf_phys;
+ unsigned char *dmabuf2, *eff_buf;
+ oss_dma_handle_t dmabuf2_dma_handle;
+ oss_dma_handle_t eff_buf_dma_handle;
+
+ /* Recording Table */
+ volatile unsigned int *rectab;
+ oss_native_word rec_table;
+ oss_native_word rec_table_virt;
+ unsigned char *dmabuf3;
+ oss_dma_handle_t dmabuf3_dma_handle;
+ int spdif_in;
+}
+ymf7xx_devc;
+
+int SetupPlaySlot (int dev, int slot);
+int ymf7xx_spdif_control (int dev, int ctrl, unsigned int cmd, int value);
+
+static int
+ac97_read (void *devc_, int addr)
+{
+ ymf7xx_devc *devc = devc_;
+ int count;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ WRITEW (AC97_CMD_ADDRESS, addr | 0x8000);
+
+ for (count = 0; count < 1000; count++)
+ if ((READW (AC97_STATUS_ADDRESS) >> 15) == 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return READW (AC97_STATUS_DATA);
+ }
+ DDB (cmn_err (CE_WARN, "AC97 mixer read timed out\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return OSS_EIO;
+}
+
+static int
+ac97_write (void *devc_, int addr, int data)
+{
+ ymf7xx_devc *devc = devc_;
+ oss_native_word flags;
+ int count;
+
+ MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
+ WRITEW (AC97_CMD_ADDRESS, addr);
+ WRITEW (AC97_CMD_DATA, data);
+
+ for (count = 0; count < 1000; count++)
+ if ((READW (AC97_STATUS_ADDRESS) >> 15) == 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 1;
+ }
+ DDB (cmn_err (CE_WARN, "AC97 mixer write timed out\n"));
+ MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
+ return 0;
+}
+
+static void
+install_ucode (ymf7xx_devc * devc, int addr, unsigned int *src, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ WRITEL (addr, *src);
+ addr += 4;
+ src++;
+ }
+}
+
+static int
+ymf7xxintr (oss_device_t * osdev)
+{
+ ymf7xx_devc *devc = (ymf7xx_devc *) osdev->devc;
+ ymf7xx_portc *portc;
+ dmap_t *dmapin, *dmapout;
+ unsigned int status;
+ int i, n;
+ int currdac = 0;
+ int curradc = 0;
+ int serviced = 0;
+
+
+ status = READL (STATUS);
+
+ if ((status & 0x80000000))
+ {
+ serviced = 1;
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ portc = &devc->portc[i];
+
+ if (portc->trigger_bits & PCM_ENABLE_OUTPUT)
+ {
+ dmapout = audio_engines[portc->audiodev]->dmap_out;
+ currdac = LSWAP (portc->bank1->PgStart);
+ currdac /= dmapout->fragment_size / portc->dacfmt;
+
+ if (currdac < 0 || currdac >= dmapout->nfrags)
+ currdac = 0;
+ n = 0;
+ while (dmap_get_qhead (dmapout) != currdac
+ && n++ < dmapout->nfrags)
+ oss_audio_outputintr (portc->audiodev, 1);
+ }
+ if (portc->trigger_bits & PCM_ENABLE_INPUT)
+ {
+ dmapin = audio_engines[portc->audiodev]->dmap_in;
+
+ if (devc->spdif_in)
+ curradc = LSWAP (portc->recslot.bank1->PgStartAdr);
+ else
+ curradc = LSWAP (portc->recslot.bank3->PgStartAdr);
+
+ curradc /= dmapin->fragment_size;
+
+ if (curradc < 0 || curradc >= dmapin->nfrags)
+ curradc = 0;
+ n = 0;
+ while (dmap_get_qtail (dmapin) != curradc
+ && n++ < dmapin->nfrags)
+ oss_audio_inputintr (portc->audiodev, 0);
+ }
+ WRITEL (STATUS, 0x80000000);
+ WRITEL (MODE, READL (MODE) | 0x00000002);
+ }
+ }
+
+ return serviced;
+}
+
+/*
+ *****************************************************************************
+ */
+
+static int
+ymf7xx_audio_set_rate (int dev, int arg)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->speed;
+
+ if (arg > 48000)
+ arg = 48000;
+ if (arg < 5000)
+ arg = 5000;
+ portc->speed = arg;
+ return portc->speed;
+}
+
+static short
+ymf7xx_audio_set_channels (int dev, short arg)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+
+ if ((arg != 1) && (arg != 2))
+ return portc->channels;
+ portc->channels = arg;
+
+ return portc->channels;
+}
+
+static unsigned int
+ymf7xx_audio_set_format (int dev, unsigned int arg)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->bits;
+
+ if (!(arg & (AFMT_U8 | AFMT_S16_LE | AFMT_AC3)))
+ return portc->bits;
+ portc->bits = arg;
+
+ return portc->bits;
+}
+
+/*ARGSUSED*/
+static int
+ymf7xx_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void ymf7xx_audio_trigger (int dev, int state);
+
+static void
+ymf7xx_audio_reset (int dev)
+{
+ ymf7xx_audio_trigger (dev, 0);
+}
+
+static void
+ymf7xx_audio_reset_input (int dev)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+ ymf7xx_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_INPUT);
+}
+
+static void
+ymf7xx_audio_reset_output (int dev)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+ ymf7xx_audio_trigger (dev, portc->trigger_bits & ~PCM_ENABLE_OUTPUT);
+}
+
+/*ARGSUSED*/
+static int
+ymf7xx_audio_open (int dev, int mode, int open_flags)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+ ymf7xx_devc *devc = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ if (portc->open_mode)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ portc->audio_enabled = ~mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static void
+ymf7xx_audio_close (int dev, int mode)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+
+ ymf7xx_audio_reset (dev);
+ portc->open_mode = 0;
+ portc->audio_enabled &= ~mode;
+}
+
+/*ARGSUSED*/
+static void
+ymf7xx_audio_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+}
+
+/*ARGSUSED*/
+static void
+ymf7xx_audio_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+
+ portc->audio_enabled |= PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+}
+
+static void
+ymf7xx_audio_trigger (int dev, int state)
+{
+ ymf7xx_devc *devc = audio_engines[dev]->devc;
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (state & PCM_ENABLE_OUTPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->devs_opened = SetupPlaySlot (dev, portc->devnum);
+
+ WRITEL (CONTROL_SELECT, 1);
+ WRITEL (MODE, READL (MODE) | 0x00000003);
+ portc->trigger_bits |= PCM_ENABLE_OUTPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_OUTPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_OUTPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+
+ devc->tab[portc->devs_opened] = 0;
+ if (portc->channels > 1)
+ devc->tab[portc->devs_opened - 1] = 0;
+ }
+ }
+ }
+
+ if ((portc->open_mode & OPEN_READ)
+ && !(audio_engines[dev]->flags & ADEV_NOINPUT))
+ {
+ if (state & PCM_ENABLE_INPUT)
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ !(portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ /* 0x01 = REC SLOT, 0x02 = ADC SLOT */
+ if (devc->spdif_in)
+ WRITEL (MAP_OF_REC, 0x1);
+ else
+ WRITEL (MAP_OF_REC, 0x2);
+ WRITEL (CONTROL_SELECT, 0);
+ WRITEL (MODE, READL (MODE) | 0x00000003);
+ portc->trigger_bits |= PCM_ENABLE_INPUT;
+ }
+ }
+ else
+ {
+ if ((portc->audio_enabled & PCM_ENABLE_INPUT) &&
+ (portc->trigger_bits & PCM_ENABLE_INPUT))
+ {
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+
+ /* set the map of rec 0 */
+ WRITEL (MAP_OF_REC, 0x0);
+ }
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static unsigned int
+SetFormatField (ymf7xx_portc * portc)
+{
+ unsigned int val;
+
+ val = 0x00000000;
+ if (portc->bits == 8)
+ val |= 0x80000000;
+ if (portc->channels > 1)
+ val |= 0x00010000;
+ return val;
+}
+
+static unsigned int
+SetPgDeltaField (ymf7xx_portc * portc)
+{
+ unsigned int val;
+
+#if 0
+ double x;
+ x = (double) portc->speed / 48000.0;
+ val = (int) (x * (1 << 28)) & 0x7FFFFF00;
+#else
+ oss_native_word x;
+ x = (portc->speed * (1 << 15) + 187) / 375;
+ val = (x * (1 << 6)) & 0x7FFFFF00;
+#endif
+ return val;
+}
+
+static unsigned int
+SetLpfKField (ymf7xx_portc * portc)
+{
+ unsigned int i, val = 0, sr = portc->speed;
+ int freq[8] = { 100, 2000, 8000, 11025, 16000, 22050, 32000, 48000 };
+ int LpfK[8] =
+ { 0x0057, 0x06aa, 0x18B2, 0x2093, 0x2b9a, 0x35a1, 0x3eaa, 0x4000 };
+
+ if (sr == 44100)
+ {
+ val = 0x4646 << 16;
+ }
+ else
+ {
+ for (i = 0; i < 8; i++)
+ {
+ if (sr <= freq[i])
+ {
+ val = LpfK[i] << 16;
+ break;
+ }
+ }
+ }
+ return val;
+}
+
+static unsigned int
+SetLpfQField (ymf7xx_portc * portc)
+{
+ unsigned int i, val = 0, sr = portc->speed;
+ int freq[8] = { 100, 2000, 8000, 11025, 16000, 22050, 32000, 48000 };
+ int LpfQ[8] =
+ { 0x3528, 0x34a7, 0x3202, 0x3177, 0x3139, 0x31c9, 0x33d0, 0x4000 };
+
+ if (sr == 44100)
+ {
+ val = 0x370A << 16;
+ }
+ else
+ {
+ for (i = 0; i < 8; i++)
+ {
+ if (sr <= freq[i])
+ {
+ val = LpfQ[i] << 16;
+ break;
+ }
+ }
+ }
+ return val;
+}
+
+void
+SetupRecSlot (int dev)
+{
+ ymf7xx_devc *devc = audio_engines[dev]->devc;
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+ int banksize;
+
+ banksize = READL (REC_CNTRL_SIZE);
+ portc->recslot.base = (devc->rec_table_virt);
+
+ /* banks 1 and 2 are for REC Slot and 3 and 4 are for ADC Slot */
+ if (devc->spdif_in)
+ {
+ portc->recslot.bank1 =
+ (REC_BANK *) (portc->recslot.base + (banksize * 0));
+ portc->recslot.bank2 =
+ (REC_BANK *) (portc->recslot.base + (banksize * 4));
+
+ WRITEB (REC_FORMAT,
+ (unsigned char) ((portc->channels & 0x02) +
+ ((portc->bits & 0x08) >> 3)));
+ WRITEW (REC_SAMPLING_RATE,
+ (unsigned short) (48000 * 4096 / portc->speed) - 1);
+
+ portc->recslot.bank1->PgBase = portc->recslot.bank2->PgBase = LSWAP (dmap->dmabuf_phys); /* use the REC slot */
+
+ portc->recslot.bank1->PgLoopEndAdr = portc->recslot.bank2->PgLoopEndAdr = LSWAP (dmap->bytes_in_use); /* use the REC slot */
+ }
+ else
+ {
+ portc->recslot.bank3 =
+ (REC_BANK *) (portc->recslot.base + (banksize * 8));
+ portc->recslot.bank4 =
+ (REC_BANK *) (portc->recslot.base + (banksize * 12));
+
+ WRITEB (ADC_FORMAT,
+ (unsigned char) ((portc->channels & 0x02) +
+ ((portc->bits & 0x08) >> 3)));
+ WRITEW (ADC_SAMPLING_RATE,
+ (unsigned short) (48000 * 4096 / portc->speed) - 1);
+
+ portc->recslot.bank3->PgBase = portc->recslot.bank4->PgBase = LSWAP (dmap->dmabuf_phys); /* use the ADC slot */
+
+ portc->recslot.bank3->PgLoopEndAdr = portc->recslot.bank4->PgLoopEndAdr = LSWAP (dmap->bytes_in_use); /* use the ADC slot */
+ }
+
+}
+
+/*ARGSUSED*/
+static int
+ymf7xx_audio_prepare_for_input (int dev, int bsize, int bcount)
+{
+ ymf7xx_devc *devc = audio_engines[dev]->devc;
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ SetupRecSlot (dev);
+
+ /* set the input level to max and go! */
+ WRITEL (NATIVE_REC_INPUT, 0xffffffff);
+ WRITEL (NATIVE_ADC_INPUT, 0xffffffff);
+ portc->audio_enabled &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+void
+SetupEffectSlot (int dev)
+{
+ ymf7xx_devc *devc = audio_engines[dev]->devc;
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+
+ int banksize;
+
+ banksize = READL (EFF_CNTRL_SIZE);
+ portc->effectslot.base = (devc->effect_table_virt);
+
+ /* slots 1-5 each having 2 banks */
+ portc->effectslot.bank1 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 0));
+ portc->effectslot.bank2 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 4));
+ portc->effectslot.bank3 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 8));
+ portc->effectslot.bank4 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 12));
+ portc->effectslot.bank5 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 16));
+ portc->effectslot.bank6 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 20));
+ portc->effectslot.bank7 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 24));
+ portc->effectslot.bank8 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 28));
+ portc->effectslot.bank9 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 32));
+ portc->effectslot.bank10 =
+ (EFFECT_BANK *) (portc->effectslot.base + (banksize * 36));
+
+#if 0
+/* Dry Left Channel */
+ portc->effectslot.bank1->PgBase = portc->effectslot.bank2->PgBase =
+ LSWAP (devc->eff_buf_phys + 0 * 8192);
+ portc->effectslot.bank1->PgLoopEnd = portc->effectslot.bank2->PgLoopEnd =
+ LSWAP (4096);
+ portc->effectslot.bank1->PgStart = portc->effectslot.bank2->PgStart = 0;
+
+/* Dry Right Channel */
+ portc->effectslot.bank3->PgBase = portc->effectslot.bank4->PgBase =
+ LSWAP (devc->eff_buf_phys + 1 * 8192);
+ portc->effectslot.bank3->PgLoopEnd = portc->effectslot.bank4->PgLoopEnd =
+ LSWAP (4096);
+ portc->effectslot.bank3->PgStart = portc->effectslot.bank4->PgStart = 0;
+
+/* Effect 1 */
+ portc->effectslot.bank5->PgBase = portc->effectslot.bank6->PgBase =
+ LSWAP (devc->eff_buf_phys + 2 * 8192);
+ portc->effectslot.bank5->PgLoopEnd = portc->effectslot.bank6->PgLoopEnd =
+ LSWAP (4096);
+ portc->effectslot.bank5->PgStart = portc->effectslot.bank6->PgStart = 0;
+
+#endif
+
+/* Effect 2 */
+ portc->effectslot.bank7->PgBase = portc->effectslot.bank8->PgBase =
+ LSWAP (devc->eff_buf_phys + 0 * 8192);
+ portc->effectslot.bank7->PgLoopEnd = portc->effectslot.bank8->PgLoopEnd =
+ LSWAP (4096);
+ portc->effectslot.bank7->PgStart = portc->effectslot.bank8->PgStart = 0;
+
+/* Effect 3 */
+ portc->effectslot.bank9->PgBase = portc->effectslot.bank10->PgBase =
+ LSWAP (devc->eff_buf_phys + 1 * 8192);
+ portc->effectslot.bank9->PgLoopEnd = portc->effectslot.bank10->PgLoopEnd =
+ LSWAP (4096);
+ portc->effectslot.bank9->PgStart = portc->effectslot.bank10->PgStart = 0;
+
+ WRITEL (AC97_SEC_CONFIG, (READL (AC97_SEC_CONFIG) & ~0x0030) | 0x0010);
+ WRITEL (MAP_OF_EFFECTS, 0x18); /* effect 2,3 */
+ WRITEL (MODE, READL (MODE) | (1 << 30)); /* AC3 Setup */
+}
+
+
+void
+SetupPlayBank (int dev, int slot, oss_native_word sbase)
+{
+ ymf7xx_devc *devc = audio_engines[dev]->devc;
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+
+ PLAY_BANK *bank1;
+ PLAY_BANK *bank2;
+ bank1 = (PLAY_BANK *) sbase;
+ bank2 =
+ (PLAY_BANK *) (sbase + READL (PLAY_CNTRL_SIZE) * sizeof (unsigned int));
+
+ memset ((void *) bank1, 0, sizeof (PLAY_BANK));
+ memset ((void *) bank2, 0, sizeof (PLAY_BANK));
+
+ if (slot == 2)
+ {
+ portc->bank3 = bank1;
+ portc->bank4 = bank2;
+ }
+ else
+ {
+ portc->bank1 = bank1;
+ portc->bank2 = bank2;
+ }
+
+ /* setup format field */
+ bank1->Format = LSWAP (SetFormatField (portc));
+ bank1->EgGain = bank1->EgGainEnd = LSWAP (0x40000000);
+
+ if (portc->channels == 1)
+ {
+ /* Gain */
+ bank1->LchGain = bank1->LchGainEnd = LSWAP (0x40000000);
+ bank1->RchGain = bank1->RchGainEnd = LSWAP (0x40000000);
+ bank1->Effect2Gain = bank1->Effect2GainEnd = LSWAP (0x40000000);
+ bank1->Effect3Gain = bank1->Effect3GainEnd = LSWAP (0x40000000);
+ }
+ else
+ {
+ if (slot == 2)
+ {
+ bank1->Format = LSWAP (LSWAP (bank1->Format) + 1);
+ bank1->RchGain = bank1->RchGainEnd = LSWAP (0x40000000);
+ bank1->Effect2Gain = bank1->Effect2GainEnd = LSWAP (0x40000000);
+ }
+ else
+ {
+ bank1->LchGain = bank1->LchGainEnd = LSWAP (0x40000000);
+ bank1->Effect3Gain = bank1->Effect3GainEnd = LSWAP (0x40000000);
+ }
+ }
+
+ bank1->LoopDefault = 0;
+ bank1->NumOfFrames = 0;
+ bank1->LoopCount = 0;
+ bank1->PgStart = 0;
+ bank1->PgLoop = 0;
+
+ /* PgBase */
+ bank1->PgBase = LSWAP (dmap->dmabuf_phys);
+
+ /* PgLoopEnd */
+ bank1->PgLoopEnd = LSWAP (dmap->bytes_in_use / portc->dacfmt);
+
+ /* PgDelta & PgDeltaEnd */
+ bank1->PgDelta = bank1->PgDeltaEnd = LSWAP (SetPgDeltaField (portc));
+
+ if (portc->channels == 4)
+ bank1->PgDelta = bank1->PgDeltaEnd *= 2;
+
+ /* LpfK & LpfKEnd */
+ bank1->LpfK = bank1->LpfKEnd = LSWAP (SetLpfKField (portc));
+
+ /* LpfQ */
+ bank1->LpfQ = LSWAP (SetLpfQField (portc));
+
+ memcpy (bank2, bank1, sizeof (PLAY_BANK));
+}
+
+int
+SetupPlaySlot (int dev, int slot)
+{
+ int tmp;
+ oss_native_word sltbase;
+ oss_native_word physbase;
+
+ ymf7xx_devc *devc = audio_engines[dev]->devc;
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+
+ tmp = slot * 2 + 1;
+ sltbase = (oss_native_word) devc->slt + (tmp * 0x120);
+ physbase = devc->slt_phys + (tmp * 0x120);
+ SetupPlayBank (dev, 1, sltbase);
+ devc->tab[tmp] = LSWAP (physbase);
+
+ if (portc->channels > 1)
+ {
+ sltbase += 0x120;
+ physbase += 0x120;
+ SetupPlayBank (dev, 2, sltbase);
+ tmp++;
+ devc->tab[tmp] = LSWAP (physbase);
+ }
+ return tmp;
+}
+
+/*ARGSUSED*/
+static int
+ymf7xx_audio_prepare_for_output (int dev, int bsize, int bcount)
+{
+ ymf7xx_devc *devc = audio_engines[dev]->devc;
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (portc->bits == AFMT_AC3)
+ {
+ portc->channels = 2;
+ portc->bits = 16;
+ ymf7xx_spdif_control (devc->mixer_dev, 1, SNDCTL_MIX_WRITE, 1); /* enable SPDIF */
+ ymf7xx_spdif_control (devc->mixer_dev, 4, SNDCTL_MIX_WRITE, 1); /* enable AC3 */
+ }
+ else
+ ymf7xx_spdif_control (devc->mixer_dev, 4, SNDCTL_MIX_WRITE, 0); /* enable AC3 */
+
+
+ portc->dacfmt = portc->channels * (portc->bits / 8);
+
+ if (portc->dacfmt > 4)
+ portc->dacfmt = 4;
+ /* portc->devs_opened = SetupPlaySlot (dev, portc->devnum); -> trigger */
+ /* set effects slot */
+ SetupEffectSlot (dev);
+
+ if (portc->bits != AFMT_AC3)
+ WRITEL (NATIVE_DAC, 0xFFFFFFFF);
+ else
+ WRITEL (NATIVE_DAC, 0x00000000);
+
+ portc->audio_enabled &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+ymf7xx_get_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ ymf7xx_portc *portc = audio_engines[dev]->portc;
+
+ unsigned int ptr = 0;
+
+ if (direction == PCM_ENABLE_OUTPUT)
+ {
+ ptr = LSWAP (portc->bank1->PgStart);
+ ptr *= portc->dacfmt;
+ }
+ if (direction == PCM_ENABLE_INPUT)
+ {
+ ptr = LSWAP (portc->recslot.bank3->PgStartAdr);
+ }
+ return ptr;
+}
+
+static audiodrv_t ymf7xx_audio_driver = {
+ ymf7xx_audio_open,
+ ymf7xx_audio_close,
+ ymf7xx_audio_output_block,
+ ymf7xx_audio_start_input,
+ ymf7xx_audio_ioctl,
+ ymf7xx_audio_prepare_for_input,
+ ymf7xx_audio_prepare_for_output,
+ ymf7xx_audio_reset,
+ NULL,
+ NULL,
+ ymf7xx_audio_reset_input,
+ ymf7xx_audio_reset_output,
+ ymf7xx_audio_trigger,
+ ymf7xx_audio_set_rate,
+ ymf7xx_audio_set_format,
+ ymf7xx_audio_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* ymf7xx_alloc_buffer */
+ NULL, /* ymf7xx_free_buffer */
+ NULL,
+ NULL,
+ ymf7xx_get_buffer_pointer
+};
+
+#if 0
+static void
+init_audio (ymf7xx_devc * devc)
+{
+ devc->audio_initialized = 1;
+}
+
+uninit_audio (ymf7xx_devc * devc)
+{
+ devc->audio_initialized = 0;
+ WRITEL (CONFIG, 0);
+ WRITEL (MODE, 0);
+}
+#endif
+
+#ifdef OBSOLETED_STUFF
+/*
+ * This device has "ISA style" MIDI and FM subsystems. Such devices don't
+ * use PCI config space for the I/O ports and interrupts. Instead the driver
+ * needs to allocate proper resources itself. This functionality is no longer
+ * possible. For this reason the MIDI and FM parts are not accessible.
+ */
+static void
+attach_fm (ymf7xx_devc * devc)
+{
+ devc->fm_attached = 0;
+ if (!opl3_detect (0x388, devc->osdev))
+ {
+ cmn_err (CE_WARN, "OPL3 not detected\n");
+ return;
+ }
+ opl3_init (0x388, devc->osdev);
+ devc->fm_attached = 1;
+}
+
+
+static void
+attach_mpu (ymf7xx_devc * devc)
+{
+ struct address_info hw_config;
+
+ hw_config.io_base = devc->mpu_base;
+ hw_config.irq = devc->mpu_irq;
+ hw_config.dma = -1;
+ hw_config.dma2 = -1;
+ hw_config.always_detect = 0;
+ hw_config.name = "Yamaha DS-XG MPU401";
+ hw_config.driver_use_1 = 0;
+ hw_config.driver_use_2 = 0;
+ hw_config.osdev = devc->osdev;
+#ifdef CREATE_OSP
+ CREATE_OSP (hw_config.osdev);
+#endif
+ hw_config.card_subtype = 0;
+
+ if (!probe_uart401 (&hw_config))
+ {
+ cmn_err (CE_WARN, "MPU-401 was not detected\n");
+ return;
+ }
+ DDB (cmn_err (CE_WARN, "MPU-401 detected - Good\n"));
+ devc->mpu_attached = 1;
+ attach_uart401 (&hw_config);
+}
+
+static void
+unload_mpu (ymf7xx_devc * devc)
+{
+ struct address_info hw_config;
+
+ hw_config.io_base = devc->mpu_base;
+ hw_config.irq = devc->mpu_irq;
+ hw_config.dma = -1;
+ hw_config.dma2 = -1;
+ hw_config.always_detect = 0;
+ hw_config.name = "Yahama DS-XG MPU401";
+ hw_config.driver_use_1 = 0;
+ hw_config.driver_use_2 = 0;
+ hw_config.osdev = devc->osdev;
+#ifdef CREATE_OSP
+ CREATE_OSP (hw_config.osdev);
+#endif
+ hw_config.card_subtype = 0;
+
+ devc->mpu_attached = 0;
+ unload_uart401 (&hw_config);
+}
+#endif
+
+int
+ymf7xx_spdif_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ ymf7xx_devc *devc = mixer_devs[dev]->hw_devc;
+/* int left, right; */
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case 1: /* S/PDIF Enable/Disable */
+ value = READL (SPDIFOUT_CONTROL) & 0x1;
+ break;
+
+ case 2: /* S/PDIF Record Enable */
+ value = devc->spdif_in;
+ break;
+
+ case 3: /* S/PDIF Loopback */
+ value = READL (SPDIFIN_CONTROL) & (1 << 4);
+ break;
+
+ case 4: /* AC3 Output */
+ value = READL (SPDIFOUT_CONTROL) & (1 << 1);
+ break;
+#if 0
+ case 5: /* CopyProtection Bit */
+ value = READL (SPDIFOUT_STATUS) & (1 << 2);
+ break;
+ case 6: /* SPDIF OUTVOL */
+ value = devc->mixlevels[0];
+ break;
+ case 7: /* SPDIF LOOPVOL */
+ value = devc->mixlevels[1];
+ break;
+ case 8: /* SPDIF AC3VOL */
+ value = devc->mixlevels[2];
+ break;
+#endif
+ }
+ }
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case 1: /* S/PDIF OUTPUT ENABLE/DISABLE */
+ if (value)
+ WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) | 0x1);
+ else
+ WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) & ~0x1);
+ break;
+
+ case 2: /* Record S/PDIF IN ENABLE DISABLE */
+ if (value)
+ {
+ WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) | 0x1);
+ devc->spdif_in = 1;
+ }
+ else
+ {
+ WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) & ~0x1);
+ devc->spdif_in = 0;
+ }
+ break;
+
+ case 3: /* S/PDIF Loopback Mode */
+ if (value)
+ WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) | (1 << 4));
+ else
+ WRITEL (SPDIFIN_CONTROL, READL (SPDIFIN_CONTROL) & ~(1 << 4));
+ break;
+
+ case 4: /* AC3 Output Mode */
+ if (value)
+ WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) | (1 << 1));
+ else
+ WRITEL (SPDIFOUT_CONTROL, READL (SPDIFOUT_CONTROL) & ~(1 << 1));
+ break;
+
+#if 0
+ case 5: /* Copy Protect Mode */
+ {
+ int ac3_mode;
+
+ ac3_mode = READL (SPDIFOUT_CONTROL) & (1 << 1);
+
+ if (value)
+ {
+ if (ac3_mode)
+ WRITEL (SPDIFOUT_STATUS,
+ READL (SPDIFOUT_STATUS) | (1 << 1));
+ else
+ WRITEL (SPDIFOUT_STATUS, READL (SPDIFOUT_STATUS) & ~0x3E);
+ }
+ else
+ {
+ if (ac3_mode)
+ WRITEL (SPDIFOUT_STATUS,
+ READL (SPDIFOUT_STATUS) | (3 << 1));
+ else
+
+ WRITEL (SPDIFOUT_STATUS,
+ READL (SPDIFOUT_STATUS) | (1 << 2));
+ }
+ }
+ break;
+
+ case 6:
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ left = left * 0xFFFF / 100;
+ right = right * 0xFFFF / 100;
+ WRITEL (SPDIFOUTVOL, left << 16 | right);
+ devc->mixlevels[0] = value;
+ break;
+ case 7:
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ left = left * 0xFFFF / 100;
+ right = right * 0xFFFF / 100;
+ WRITEL (SPDIFLOOPVOL, left << 16 | right);
+ devc->mixlevels[1] = value;
+ break;
+ case 8:
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ left = left * 0xFFFF / 100;
+ right = right * 0xFFFF / 100;
+ WRITEL (AC3_OUTPUT, left << 16 | right);
+ devc->mixlevels[2] = value;
+ break;
+#endif
+ }
+ }
+ return value;
+}
+
+static int
+ymf7xx_mix_init (int dev)
+{
+ int group, err;
+
+ if ((group = mixer_ext_create_group (dev, 0, "SPDIF")) < 0)
+ return group;
+
+ if ((err = mixer_ext_create_control (dev, group, 1, ymf7xx_spdif_control,
+ MIXT_ONOFF, "ENABLE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 2, ymf7xx_spdif_control,
+ MIXT_ONOFF, "RECORD", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 3, ymf7xx_spdif_control,
+ MIXT_ONOFF, "LOOP", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+#if 0
+ if ((err = mixer_ext_create_control (dev, group, 4, ymf7xx_spdif_control,
+ MIXT_ONOFF, "AC3", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ if ((err = mixer_ext_create_control (dev, group, 5, ymf7xx_spdif_control,
+ MIXT_ONOFF, "COPYPROT", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group, 6, ymf7xx_spdif_control,
+ MIXT_STEREOSLIDER, "OUTVOL", 100,
+ MIXF_MAINVOL | MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ if ((err = mixer_ext_create_control (dev, group, 7, ymf7xx_spdif_control,
+ MIXT_STEREOSLIDER, "LOOPVOL", 100,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ if ((err = mixer_ext_create_control (dev, group, 8, ymf7xx_spdif_control,
+ MIXT_STEREOSLIDER, "AC3VOL", 100,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+#endif
+
+ return 0;
+}
+
+static int
+init_ymf7xx (ymf7xx_devc * devc)
+{
+
+ int my_mixer, i;
+ int first_dev = 0;
+
+ WRITEL (NATIVE_DAC, 0x00000000);
+ WRITEL (MODE, 0x00010000);
+ WRITEL (MODE, 0x00000000);
+ WRITEL (MAP_OF_REC, 0x00000000);
+ WRITEL (MAP_OF_EFFECTS, 0x00000000);
+ WRITEL (PLAY_CNTRL_BASE, 0x00000000);
+ WRITEL (REC_CNTRL_BASE, 0x00000000);
+ WRITEL (EFF_CNTRL_BASE, 0x00000000);
+ WRITEL (CONTROL_SELECT, 1);
+ WRITEL (GLOBAL_CONTROL, READL (GLOBAL_CONTROL) & ~0x0007);
+ WRITEL (ZVOUTVOL, 0xFFFFFFFF);
+ WRITEL (ZVLOOPVOL, 0xFFFFFFFF);
+ WRITEL (SPDIFOUTVOL, 0xFFFFFFFF);
+ WRITEL (SPDIFLOOPVOL, 0x3FFF3FFF);
+ devc->spdif_in = 0;
+
+ if (ac97_read (devc, 0x02) == 0xFFFF)
+ {
+ for (i = 0; i < 100; i++)
+ if (ac97_read (devc, 0x02) != 0xFFFF)
+ {
+ break;
+ }
+ }
+
+ install_ucode (devc, 0x1000, dsp, dsp_size);
+ switch (devc->deviceid)
+ {
+ case YAMAHA_YMF724F_ID:
+ case YAMAHA_YMF740C_ID:
+ case YAMAHA_YMF744_ID:
+ case YAMAHA_YMF754_ID:
+ install_ucode (devc, 0x4000, cntrl1E, cntrl1E_size);
+ break;
+ default:
+ install_ucode (devc, 0x4000, cntrl, cntrl_size);
+ }
+ WRITEL (CONFIG, 1);
+
+/* add an extra reset to init the mixers */
+ ac97_write (devc, 0x02, 0x0000);
+ ac97_write (devc, 0x18, 0x0808);
+
+/* Now check to see if the DSP is started or not */
+ {
+ int fEnd;
+ i = 10000;
+ do
+ {
+ if (i-- <= 0)
+ {
+ cmn_err (CE_WARN, "CTR/DSP Init/ TimeOut\n");
+ return 0;
+ }
+ fEnd = READL (CONTROL_SELECT) & 0x1;
+ }
+ while (fEnd == 0x1);
+ }
+
+ my_mixer =
+ ac97_install (&devc->ac97devc, "Yamaha DS-XG", ac97_read, ac97_write,
+ devc, devc->osdev);
+ if (my_mixer >= 0)
+ {
+ devc->mixer_dev = my_mixer;
+ mixer_ext_set_init_fn (my_mixer, ymf7xx_mix_init, 20);
+ }
+ else
+ return 0;
+
+#ifdef OBSOLETED_STUFF
+ if (devc->fm_base > 0)
+ attach_fm (devc);
+ if (devc->mpu_base > 0)
+ attach_mpu (devc);
+#endif
+
+ if (devc->play_table_virt == 0)
+ {
+ /* Allocate the Play Table */
+ oss_native_word phaddr;
+ devc->dmabuf1 =
+ CONTIG_MALLOC (devc->osdev, 0x1000, MEMLIMIT_32BITS, &phaddr, devc->dmabuf1_dma_handle);
+ devc->play_table_virt = (oss_native_word) devc->dmabuf1;
+ devc->play_table = phaddr;
+
+ /* Allocate Effect Table */
+ devc->dmabuf2 =
+ CONTIG_MALLOC (devc->osdev, 1024, MEMLIMIT_32BITS, &phaddr, devc->dmabuf2_dma_handle);
+ devc->effect_table_virt = (oss_native_word) devc->dmabuf2;
+ devc->effect_table = phaddr;
+
+ /* Allocate Effect Scratch Buffer */
+ devc->eff_buf =
+ CONTIG_MALLOC (devc->osdev, 2 * 8192, MEMLIMIT_32BITS, &phaddr, devc->eff_buf_dma_handle);
+ devc->eff_buf_phys = phaddr;
+
+ /* Allocate the Record Table */
+ devc->dmabuf3 =
+ CONTIG_MALLOC (devc->osdev, 1024, MEMLIMIT_32BITS, &phaddr, devc->dmabuf3_dma_handle);
+ devc->rec_table_virt = (oss_native_word) devc->dmabuf3;
+ devc->rec_table = phaddr;
+
+ /* Setup Play Table */
+ devc->tab = (unsigned int *) devc->play_table_virt;
+ devc->slt = (oss_native_word) (devc->play_table_virt + 0x100);
+ devc->slt_phys = (devc->play_table + 0x100);
+ memset ((void *) devc->tab, 0, 0x1000);
+ WRITEL (PLAY_CNTRL_BASE, (unsigned int) devc->play_table);
+ devc->tab[0] = LSWAP (20); /* setup 20 slots for 8 playback devices */
+ /* Setup Effect Table and init Effect Slots */
+ devc->effecttab = (unsigned int *) devc->effect_table_virt;
+ memset ((void *) devc->effecttab, 0, 1024);
+ WRITEL (EFF_CNTRL_BASE, (unsigned int) devc->effect_table);
+
+ //SetupEffectSlot (dev);
+
+ /* Setup Record Table */
+ devc->rectab = (unsigned int *) devc->rec_table_virt;
+ memset ((void *) devc->rectab, 0, 1024);
+ WRITEL (REC_CNTRL_BASE, (unsigned int) devc->rec_table);
+ }
+
+ for (i = 0; i < MAX_PORTC; i++)
+ {
+ int adev;
+ char tmp_name[100];
+ ymf7xx_portc *portc = &devc->portc[i];
+ int caps = ADEV_AUTOMODE | ADEV_NOVIRTUAL;
+
+ if (i == 0)
+ {
+ strcpy (tmp_name, devc->chip_name);
+ caps |= ADEV_DUPLEX;
+ }
+ else
+ {
+ strcpy (tmp_name, devc->chip_name);
+ caps |= ADEV_NOINPUT;
+ if (i > 1)
+ caps |= ADEV_SHADOW;
+ }
+
+
+ if ((adev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ tmp_name,
+ &ymf7xx_audio_driver,
+ sizeof (audiodrv_t),
+ caps,
+ AFMT_U8 | AFMT_S16_LE | AFMT_AC3,
+ devc, -1)) < 0)
+ {
+ adev = -1;
+ return 0;
+ }
+ else
+ {
+ if (i == 0)
+ first_dev = adev;
+ audio_engines[adev]->mixer_dev = my_mixer;
+ audio_engines[adev]->portc = portc;
+ audio_engines[adev]->rate_source = first_dev;
+ audio_engines[adev]->min_block = 64;
+ audio_engines[adev]->min_rate = 5000;
+ audio_engines[adev]->max_rate = 48000;
+ audio_engines[adev]->vmix_flags |= VMIX_MULTIFRAG;
+ audio_engines[adev]->caps |= PCM_CAP_FREERATE;
+ audio_engines[adev]->min_channels = 2;
+ audio_engines[adev]->max_channels = 4;
+ portc->open_mode = 0;
+ portc->audiodev = adev;
+ portc->devnum = i;
+#ifdef CONFIG_OSS_VMIX
+ if (i == 0)
+ vmix_attach_audiodev(devc->osdev, adev, -1, 0);
+#endif
+ }
+ }
+ return 1;
+}
+
+int
+oss_ymf7xx_attach (oss_device_t * osdev)
+{
+
+
+ unsigned char pci_irq_line, pci_revision;
+ unsigned short pci_command, vendor, device;
+ unsigned char pci_reset;
+ unsigned short pci_legacy;
+ ymf7xx_devc *devc;
+
+ DDB (cmn_err (CE_WARN, "Entered DS-XG attach routine\n"));
+
+ pci_read_config_word (osdev, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word (osdev, PCI_DEVICE_ID, &device);
+
+ if (((vendor != YAMAHA_VENDOR_ID)) ||
+ (device != YAMAHA_YMF740_ID &&
+ device != YAMAHA_YMF744_ID &&
+ device != YAMAHA_YMF754_ID &&
+ device != YAMAHA_YMF740C_ID &&
+ device != YAMAHA_YMF724_ID &&
+ device != YAMAHA_YMF734_ID && device != YAMAHA_YMF724F_ID))
+ return 0;
+
+ oss_pci_byteswap (osdev, 1);
+
+ if ((devc = PMALLOC (osdev, sizeof (*devc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return 0;
+ }
+
+ devc->osdev = osdev;
+ osdev->devc = devc;
+
+ pci_read_config_byte (osdev, PCI_REVISION_ID, &pci_revision);
+ pci_read_config_word (osdev, PCI_COMMAND, &pci_command);
+ pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line);
+ pci_read_config_dword (osdev, PCI_MEM_BASE_ADDRESS_0, &devc->base0addr);
+
+ if (devc->base0addr == 0)
+ {
+ cmn_err (CE_WARN, "I/O address not assigned by BIOS.\n");
+ return 0;
+ }
+
+ if (pci_irq_line == 0)
+ {
+ cmn_err (CE_WARN, "IRQ not assigned by BIOS (%d).\n", pci_irq_line);
+ return 0;
+ }
+
+ DDB (cmn_err
+ (CE_WARN, "rev %x I/O base %04x\n", pci_revision, devc->base0addr));
+
+ devc->deviceid = device;
+ switch (device)
+ {
+ case YAMAHA_YMF724_ID:
+ devc->chip_name = "Yamaha YMF724";
+ break;
+
+ case YAMAHA_YMF724F_ID:
+ devc->chip_name = "Yamaha YMF724F";
+ break;
+
+ case YAMAHA_YMF734_ID:
+ devc->chip_name = "Yamaha YMF734";
+ break;
+
+ case YAMAHA_YMF740_ID:
+ devc->chip_name = "Yamaha YMF740";
+ break;
+
+ case YAMAHA_YMF740C_ID:
+ devc->chip_name = "Yamaha YMF740C";
+ break;
+
+ case YAMAHA_YMF744_ID:
+ devc->chip_name = "Yamaha YMF744";
+ break;
+
+ case YAMAHA_YMF754_ID:
+ devc->chip_name = "Yamaha YMF754";
+ break;
+
+ default:
+ devc->chip_name = "Yamaha DS-XG";
+ }
+
+ devc->fm_base = yamaha_fm_ioaddr;
+ devc->mpu_base = yamaha_mpu_ioaddr;
+ devc->mpu_irq = yamaha_mpu_irq;
+
+ /* reset the device */
+ pci_read_config_byte (osdev, 0x48, &pci_reset);
+
+ if (pci_reset & 0x03)
+ {
+ pci_write_config_byte (osdev, 0x48, pci_reset & 0xFC);
+ pci_write_config_byte (osdev, 0x48, pci_reset | 0x03);
+ pci_write_config_byte (osdev, 0x48, pci_reset & 0xFC);
+ }
+
+/* Legacy I/O setup - setup MPU and FM io/irq values */
+ devc->fm_attached = 0;
+ devc->mpu_attached = 0;
+ /*pcipci_legacy = 0x0020|0x00C0|0x0004; // 10 bit address decode and Joystick */
+ pci_legacy = 0x4;
+ if (devc->fm_base)
+ pci_legacy |= 0x0002; /* FM enable */
+
+ if (devc->mpu_base)
+ {
+ pci_legacy |= 0x0008; /* MPU I/O enable */
+
+ switch (devc->mpu_irq)
+ {
+ case 5:
+ pci_legacy |= 0x0010;
+ break;
+ case 7:
+ pci_legacy |= 0x0810;
+ break;
+ case 9:
+ pci_legacy |= 0x1010;
+ break;
+ case 10:
+ pci_legacy |= 0x1810;
+ break;
+ case 11:
+ pci_legacy |= 0x2010;
+ break;
+ default:
+ devc->mpu_irq = 0;
+ }
+ }
+
+ pci_write_config_word (osdev, 0x40, pci_legacy);
+
+ pci_legacy = 0x0000;
+
+ switch (devc->fm_base)
+ {
+ case 0x388:
+ pci_legacy |= 0x0000;
+ break;
+ case 0x398:
+ pci_legacy |= 0x0001;
+ break;
+ case 0x3a0:
+ pci_legacy |= 0x0002;
+ break;
+ case 0x3a8:
+ pci_legacy |= 0x0003;
+ break;
+ default:
+ devc->fm_base = 0;
+ }
+
+ switch (devc->mpu_base)
+ {
+ case 0x330:
+ pci_legacy |= 0x0000;
+ break;
+ case 0x300:
+ pci_legacy |= 0x0010;
+ break;
+ case 0x332:
+ pci_legacy |= 0x0020;
+ break;
+ case 0x334:
+ pci_legacy |= 0x0020;
+ break;
+ default:
+ devc->mpu_base = 0;
+ }
+ pci_write_config_word (osdev, 0x42, pci_legacy);
+
+ /* activate the device */
+ pci_command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config_word (osdev, PCI_COMMAND, pci_command);
+
+ /* Map the shared memory area */
+ devc->base0virt =
+ (unsigned int *) MAP_PCI_MEM (devc->osdev, 0, devc->base0addr, 32 * 1024);
+ devc->dwRegister = (unsigned int *) devc->base0virt;
+ devc->wRegister = (unsigned short *) devc->base0virt;
+ devc->bRegister = (unsigned char *) devc->base0virt;
+
+
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV);
+ MUTEX_INIT (devc->osdev, devc->low_mutex, MH_DRV + 1);
+
+ oss_register_device (osdev, devc->chip_name);
+
+ if (oss_register_interrupts (devc->osdev, 0, ymf7xxintr, NULL) < 0)
+ {
+ cmn_err (CE_WARN, "Can't allocate IRQ%d\n", pci_irq_line);
+ return 0;
+ }
+
+ return init_ymf7xx (devc); /* Detected */
+}
+
+
+int
+oss_ymf7xx_detach (oss_device_t * osdev)
+{
+ ymf7xx_devc *devc = (ymf7xx_devc *) osdev->devc;
+
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ WRITEL (CONFIG, 0);
+ WRITEL (MODE, 0);
+
+ if (devc->dmabuf1)
+ {
+ CONTIG_FREE (devc->osdev, devc->dmabuf1, 0x1000, devc->dmabuf1_dma_handle);
+ devc->dmabuf1 = 0;
+ }
+
+ if (devc->dmabuf2)
+ {
+ CONTIG_FREE (devc->osdev, devc->dmabuf2, 1024, devc->dmabuf2_dma_handle);
+ devc->dmabuf2 = 0;
+ }
+
+ if (devc->eff_buf)
+ {
+ CONTIG_FREE (devc->osdev, devc->eff_buf, 16 * 1024, devc->eff_buf_dma_handle);
+ devc->eff_buf = 0;
+ }
+
+ if (devc->dmabuf3)
+ {
+ CONTIG_FREE (devc->osdev, devc->dmabuf3, 1024, devc->dmabuf3_dma_handle);
+ devc->dmabuf3 = 0;
+ }
+
+ devc->play_table_virt = 0;
+ devc->effect_table_virt = 0;
+ devc->rec_table_virt = 0;
+
+#ifdef OBSOLETED_STUFF
+ if (devc->mpu_attached)
+ {
+ unload_mpu (devc);
+ devc->mpu_attached = 0;
+ }
+#endif
+
+ oss_unregister_interrupts (devc->osdev);
+
+ MUTEX_CLEANUP (devc->mutex);
+ MUTEX_CLEANUP (devc->low_mutex);
+
+ if (devc->base0addr != 0)
+ {
+ UNMAP_PCI_MEM (devc->osdev, 0, devc->base0addr, devc->base0virt,
+ 32 * 1024);
+ devc->base0addr = 0;
+ }
+ oss_unregister_device (devc->osdev);
+ return 1;
+}
diff --git a/kernel/drv/oss_ymf7xx/oss_ymf7xx.man b/kernel/drv/oss_ymf7xx/oss_ymf7xx.man
new file mode 100644
index 0000000..fc62efb
--- /dev/null
+++ b/kernel/drv/oss_ymf7xx/oss_ymf7xx.man
@@ -0,0 +1,33 @@
+NAME
+oss_ymf7xx - Yamaha DS-XG audio driver.
+
+DESCRIPTION
+Open Sound System driver for Yamaha DS-XG YMF724/740/744/754 audio controllers.
+
+ymf7xx device characteristics:
+ o 8/16 bit playback/record
+ o mono/stereo/4 channel playback
+ o mono/stereo recording
+ o 8KHz to 48Khz sample rate.
+
+ MIXER
+The Yamaha DSXG models 744 and 754 supports SPDIF and AC3 multichannel output
+and the Mixer extentions will allow you to enable/disable SPDIF output.
+
+CONFIG OPTIONS
+o yamaha_mpu_ioaddr=<xxx>
+MPU I/O address. Refer to the device conf file (see below) for legal values.
+
+o yamaha_mpu_irq=<xx>
+MPU IRQ. Refer to device conf file (see below) for legal values
+
+o yamaha_fm_ioaddr=<xxx>
+Yamaha FM SYnthesizer IO address. Refer to driver conf file (see below) for
+possible values.
+
+FILES
+CONFIGFILEPATH/oss_ymf7xx.conf Device configuration file
+
+AUTHOR
+4Front Technologies
+
diff --git a/kernel/drv/oss_ymf7xx/ymf7xx.h b/kernel/drv/oss_ymf7xx/ymf7xx.h
new file mode 100644
index 0000000..2318e9e
--- /dev/null
+++ b/kernel/drv/oss_ymf7xx/ymf7xx.h
@@ -0,0 +1,1845 @@
+/*
+ * Purpose: Definitions for the ymf7xx driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* Global Control Register */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define INTERRUPT_FLAG 0x04
+#define ACTIVITY 0x06
+#define GLOBAL_CONTROL 0x08
+
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* Timer Control Register */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define TIMER_CONTROL 0x10
+#define TIMER_COUNT 0x12
+
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* SPDIF Control Register */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define SPDIFOUT_CONTROL 0x18
+#define SPDIFOUT_STATUS 0x1c
+#define SPDIFIN_CONTROL 0x34
+#define SPDIFIN_STATUS 0x38
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* EEPROM Control Register */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define EEPROM_CONTROL 0x2c
+
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* AC3 Control Register */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define AC3_DATA 0x40
+#define AC3_ADDRESS 0x42
+#define AC3_STATUS 0x44
+
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* AC97 Control Register */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define AC97_CMD_DATA 0x60
+#define AC97_CMD_ADDRESS 0x62
+#define AC97_STATUS_DATA 0x64
+#define AC97_STATUS_ADDRESS 0x66
+#define AC97_SEC_STATUS_DATA 0x68
+#define AC97_SEC_STATUS_ADDR 0x6A
+#define AC97_SEC_CONFIG 0x70
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* Volume Control Register */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define LEGACY_OUTPUT 0x80
+#define LEGACY_OUTPUT_LCH 0x80
+#define LEGACY_OUTPUT_RCH 0x82
+#define NATIVE_DAC 0x84
+#define NATIVE_DAC_LCH 0x84
+#define NATIVE_DAC_RCH 0x86
+#define ZVOUTVOL 0x88
+#define ZV_OUTPUT_LCH 0x88
+#define ZV_OUTPUT_RCH 0x8a
+#define AC3_OUTPUT 0x8c
+#define AC3_OUTPUT_LCH 0x8c
+#define AC3_OUTPUT_RCH 0x8e
+#define ADC_OUTPUT 0x90
+#define ADC_OUTPUT_LCH 0x90
+#define ADC_OUTPUT_RCH 0x92
+#define LEGACY_LOOPBACK 0x94
+#define LEGACY_LOOPBACK_LCH 0x94
+#define LEGACY_LOOPBACK_RCH 0x96
+#define NATIVE_LOOPBACK 0x98
+#define NATIVE_LOOPBACK_LCH 0x98
+#define NATIVE_LOOPBACK_RCH 0x9a
+#define ZVLOOPVOL 0x9c
+#define ZVLOOPBACK_LCH 0x9c
+#define ZVLOOPBACK_RCH 0x9e
+#define AC3_LOOPBACK 0xa0
+#define AC3_LOOPBACK_LCH 0xa0
+#define AC3_LOOPBACK_RCH 0xa2
+#define ADC_LOOPBACK 0xa4
+#define ADC_LOOPBACK_LCH 0xa4
+#define ADC_LOOPBACK_RCH 0xa6
+#define NATIVE_ADC_INPUT 0xa8
+#define NATIVE_ADC_INPUT_LCH 0xa8
+#define NATIVE_ADC_INPUT_RCH 0xaa
+#define NATIVE_REC_INPUT 0xac
+#define NATIVE_REC_INPUT_LCH 0xac
+#define NATIVE_REC_INPUT_RCH 0xae
+#define BUF441OUTVOL 0xB0
+#define BUF441OUTVOLL 0xB0
+#define BUF441OUTVOLR 0xB2
+#define BUF441LOOPVOL 0xB4
+#define BUF441LOOPVOLL 0xB4
+#define BUF441LOOPVOLR 0xB6
+#define SPDIFOUTVOL 0xB8
+#define SPDIFOUTVOLL 0xB8
+#define SPDIFOUTVOLR 0xBA
+#define SPDIFLOOPVOL 0xBC
+#define SPDIFLOOPVOLL 0xBC
+#define SPDIFLOOPVOLR 0xBE
+
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* Sampling Rate Control Register */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define ADC_SAMPLING_RATE 0xc0
+#define REC_SAMPLING_RATE 0xc4
+#define ADC_FORMAT 0xc8
+#define REC_FORMAT 0xcc
+
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* PCI Native Audio Control Register */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define STATUS 0x100
+#define CONTROL_SELECT 0x104
+#define MODE 0x108
+#define SAMPLE_COUNT 0x10c
+#define NUM_OF_SAMPLES 0x110
+#define CONFIG 0x114
+#define PLAY_CNTRL_SIZE 0x140
+#define REC_CNTRL_SIZE 0x144
+#define EFF_CNTRL_SIZE 0x148
+#define WORK_SIZE 0x14c
+#define MAP_OF_REC 0x150
+#define MAP_OF_EFFECTS 0x154
+#define PLAY_CNTRL_BASE 0x158
+#define REC_CNTRL_BASE 0x15c
+#define EFF_CNTRL_BASE 0x160
+#define WORK_BASE 0x164
+
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* Instruction RAM */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define DSP_INST_RAM 0x1000
+#define CONTROL_INST_RAM 0x4000
+
+
+ /*///////////////////////////////////////////////////////// */
+ /* */
+ /* Map Length */
+ /* */
+ /*///////////////////////////////////////////////////////// */
+#define MAP_LENGTH 0x8000
+
+
+/*============================================================================= */
+/* Copyright (c) 1997 Yamaha Corporation. All Rights Reserved. */
+/* */
+/* Title: */
+/* hwmcode.c */
+/* Desc: */
+/* micro-code for CTRL & DSP */
+/* HISTORY: */
+/* April 03, 1997: 1st try by M. Mukojima */
+/*============================================================================= */
+
+static unsigned int dsp_size = 0x0020;
+static unsigned int dsp[] = {
+ 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
+ 0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
+ 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
+ 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+static unsigned int cntrl_size = 0x0c00;
+static unsigned int cntrl[] = {
+ 0x000007, 0x240007, 0x0C0007, 0x1C0007,
+ 0x060007, 0x700002, 0x000020, 0x030040,
+ 0x007104, 0x004286, 0x030040, 0x000F0D,
+ 0x000810, 0x20043A, 0x000282, 0x00020D,
+ 0x000810, 0x20043A, 0x001282, 0x200E82,
+ 0x001A82, 0x033B8D, 0x000810, 0x10043A,
+ 0x02D90D, 0x000810, 0x18043A, 0x00010D,
+ 0x020015, 0x0000FD, 0x000020, 0x038860,
+ 0x039060, 0x038060, 0x038040, 0x038040,
+ 0x038040, 0x018040, 0x000A7D, 0x038040,
+ 0x038040, 0x018040, 0x200402, 0x000882,
+ 0x08001A, 0x000904, 0x015986, 0x000007,
+ 0x260007, 0x000007, 0x000007, 0x018A06,
+ 0x000007, 0x03120D, 0x000810, 0x18043A,
+ 0x260007, 0x00087D, 0x018042, 0x00160A,
+ 0x04A206, 0x000007, 0x00218D, 0x000810,
+ 0x08043A, 0x220A06, 0x000007, 0x0007FD,
+ 0x018042, 0x08000A, 0x000904, 0x029386,
+ 0x000195, 0x090D04, 0x000007, 0x000820,
+ 0x0000F5, 0x000B7D, 0x01F060, 0x0000FD,
+ 0x032206, 0x018040, 0x000A7D, 0x038042,
+ 0x13804A, 0x18000A, 0x001820, 0x059060,
+ 0x058860, 0x018040, 0x0000FD, 0x018042,
+ 0x70000A, 0x000115, 0x071144, 0x032386,
+ 0x030000, 0x007020, 0x034A06, 0x018040,
+ 0x00348D, 0x000810, 0x08043A, 0x223206,
+ 0x000007, 0x02D90D, 0x000810, 0x18043A,
+ 0x018206, 0x000007, 0x240007, 0x000F8D,
+ 0x000810, 0x00163A, 0x002402, 0x005C02,
+ 0x0028FD, 0x000020, 0x018040, 0x08000D,
+ 0x000815, 0x510984, 0x000007, 0x00004D,
+ 0x000E5D, 0x000E02, 0x00418D, 0x000810,
+ 0x08043A, 0x2CE206, 0x000007, 0x00008D,
+ 0x000924, 0x000F02, 0x00458D, 0x000810,
+ 0x08043A, 0x2CE206, 0x000007, 0x00387D,
+ 0x018042, 0x08000A, 0x001015, 0x010984,
+ 0x018386, 0x000007, 0x01AA06, 0x000007,
+ 0x0008FD, 0x018042, 0x18000A, 0x001904,
+ 0x21C886, 0x280007, 0x001810, 0x28043A,
+ 0x280C02, 0x00000D, 0x000810, 0x28143A,
+ 0x08808D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00020D, 0x189904, 0x000007,
+ 0x00402D, 0x0000BD, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x055A86, 0x000007,
+ 0x000100, 0x000A20, 0x00047D, 0x018040,
+ 0x018042, 0x20000A, 0x003015, 0x012144,
+ 0x034986, 0x000007, 0x002104, 0x034986,
+ 0x000007, 0x000F8D, 0x000810, 0x280C3A,
+ 0x023944, 0x06C986, 0x000007, 0x001810,
+ 0x28043A, 0x08810D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x002810, 0x78003A,
+ 0x00688D, 0x000810, 0x08043A, 0x28D206,
+ 0x000007, 0x00400D, 0x001015, 0x189904,
+ 0x292904, 0x393904, 0x000007, 0x060206,
+ 0x000007, 0x0004F5, 0x00007D, 0x000020,
+ 0x00008D, 0x010860, 0x018040, 0x00047D,
+ 0x038042, 0x21804A, 0x18000A, 0x021944,
+ 0x21A086, 0x000007, 0x004075, 0x71F104,
+ 0x000007, 0x010042, 0x28000A, 0x002904,
+ 0x216886, 0x000007, 0x003C0D, 0x30A904,
+ 0x000007, 0x00077D, 0x018042, 0x08000A,
+ 0x000904, 0x07DA86, 0x00057D, 0x002820,
+ 0x03B060, 0x07F206, 0x018040, 0x003020,
+ 0x03A860, 0x018040, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x07FA86, 0x000007,
+ 0x00057D, 0x018042, 0x28040A, 0x000E8D,
+ 0x000810, 0x280C3A, 0x00000D, 0x000810,
+ 0x28143A, 0x09000D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x003DFD, 0x000020,
+ 0x018040, 0x00107D, 0x008D8D, 0x000810,
+ 0x08043A, 0x28D206, 0x000007, 0x000815,
+ 0x08001A, 0x010984, 0x095186, 0x00137D,
+ 0x200500, 0x280F20, 0x338F60, 0x3B8F60,
+ 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
+ 0x038A60, 0x018040, 0x007FBD, 0x383DC4,
+ 0x000007, 0x001A7D, 0x001375, 0x018042,
+ 0x09004A, 0x10000A, 0x0B8D04, 0x139504,
+ 0x000007, 0x000820, 0x019060, 0x001104,
+ 0x216886, 0x010040, 0x0017FD, 0x018042,
+ 0x08000A, 0x000904, 0x216A86, 0x000007,
+ 0x00197D, 0x038042, 0x09804A, 0x10000A,
+ 0x000924, 0x001664, 0x0011FD, 0x038042,
+ 0x2B804A, 0x19804A, 0x30000A, 0x00008D,
+ 0x218944, 0x000007, 0x002244, 0x0AF186,
+ 0x000007, 0x001A64, 0x002A24, 0x003664,
+ 0x00197D, 0x080102, 0x100122, 0x000820,
+ 0x039060, 0x018040, 0x003DFD, 0x00008D,
+ 0x000820, 0x018040, 0x001375, 0x001A7D,
+ 0x010042, 0x09804A, 0x10000A, 0x00021D,
+ 0x0189E4, 0x2992E4, 0x309144, 0x000007,
+ 0x00060D, 0x000A15, 0x000C1D, 0x001025,
+ 0x00A9E4, 0x012BE4, 0x000464, 0x01B3E4,
+ 0x0232E4, 0x000464, 0x000464, 0x000464,
+ 0x000464, 0x00040D, 0x08B1C4, 0x000007,
+ 0x000820, 0x000BF5, 0x030040, 0x00197D,
+ 0x038042, 0x09804A, 0x000A24, 0x08000A,
+ 0x080E64, 0x000007, 0x100122, 0x000820,
+ 0x031060, 0x010040, 0x0064AC, 0x00027D,
+ 0x000020, 0x018040, 0x00107D, 0x018042,
+ 0x0011FD, 0x3B804A, 0x09804A, 0x20000A,
+ 0x000095, 0x1A1144, 0x00A144, 0x0D3086,
+ 0x00040D, 0x00B984, 0x0D3186, 0x0018FD,
+ 0x018042, 0x0010FD, 0x09804A, 0x28000A,
+ 0x000095, 0x010924, 0x002A64, 0x0D2186,
+ 0x000007, 0x002904, 0x0D3286, 0x000007,
+ 0x0D3A06, 0x080002, 0x00008D, 0x00387D,
+ 0x000820, 0x018040, 0x00127D, 0x018042,
+ 0x10000A, 0x003904, 0x0DE186, 0x00080D,
+ 0x7FFFB5, 0x00B984, 0x0DB186, 0x000025,
+ 0x0E8A06, 0x00002D, 0x000015, 0x00082D,
+ 0x02CD0D, 0x000820, 0x0ED206, 0x00000D,
+ 0x7F8035, 0x00B984, 0x0E8186, 0x400025,
+ 0x00008D, 0x110944, 0x000007, 0x00018D,
+ 0x109504, 0x000007, 0x009164, 0x000424,
+ 0x000424, 0x000424, 0x100102, 0x280002,
+ 0x02CC0D, 0x000820, 0x0ED206, 0x00018D,
+ 0x00042D, 0x00008D, 0x109504, 0x000007,
+ 0x00020D, 0x109184, 0x000007, 0x02CC8D,
+ 0x000820, 0x00008D, 0x0038FD, 0x018040,
+ 0x003BFD, 0x001020, 0x03A860, 0x000815,
+ 0x313184, 0x212184, 0x000007, 0x03B060,
+ 0x03A060, 0x018040, 0x0022FD, 0x000095,
+ 0x010924, 0x000424, 0x000424, 0x001264,
+ 0x100102, 0x000820, 0x039060, 0x018040,
+ 0x001924, 0x00FC8D, 0x00397D, 0x000820,
+ 0x058040, 0x038042, 0x09844A, 0x000606,
+ 0x08040A, 0x000424, 0x000424, 0x00117D,
+ 0x018042, 0x08000A, 0x000A24, 0x280502,
+ 0x280C02, 0x09800D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x0022FD, 0x018042,
+ 0x08000A, 0x000095, 0x280DC4, 0x011924,
+ 0x00197D, 0x018042, 0x0011FD, 0x09804A,
+ 0x10000A, 0x0000B5, 0x113144, 0x0A8D04,
+ 0x000007, 0x080A44, 0x129504, 0x000007,
+ 0x0023FD, 0x001020, 0x038040, 0x101244,
+ 0x000007, 0x000820, 0x039060, 0x018040,
+ 0x0002FD, 0x018042, 0x08000A, 0x000904,
+ 0x110A86, 0x000007, 0x003BFD, 0x000100,
+ 0x000A10, 0x0B807A, 0x13804A, 0x090984,
+ 0x000007, 0x000095, 0x013D04, 0x119086,
+ 0x10000A, 0x100002, 0x090984, 0x000007,
+ 0x038042, 0x11804A, 0x090D04, 0x000007,
+ 0x10000A, 0x090D84, 0x000007, 0x00257D,
+ 0x000820, 0x018040, 0x00010D, 0x000810,
+ 0x28143A, 0x00127D, 0x018042, 0x20000A,
+ 0x00197D, 0x018042, 0x00117D, 0x31804A,
+ 0x10000A, 0x003124, 0x01290D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x300102, 0x003124,
+ 0x000424, 0x000424, 0x001224, 0x280502,
+ 0x001A4C, 0x131186, 0x700002, 0x00002D,
+ 0x030000, 0x00387D, 0x018042, 0x10000A,
+ 0x133A06, 0x002124, 0x0000AD, 0x100002,
+ 0x00010D, 0x000924, 0x006B24, 0x01378D,
+ 0x00397D, 0x000820, 0x058040, 0x038042,
+ 0x09844A, 0x000606, 0x08040A, 0x003264,
+ 0x00008D, 0x000A24, 0x001020, 0x00227D,
+ 0x018040, 0x013D0D, 0x000810, 0x08043A,
+ 0x2A1A06, 0x000007, 0x002820, 0x00207D,
+ 0x018040, 0x00387D, 0x018042, 0x08000A,
+ 0x000904, 0x166286, 0x000007, 0x00117D,
+ 0x038042, 0x13804A, 0x33800A, 0x018042,
+ 0x28000A, 0x00008D, 0x030964, 0x01498D,
+ 0x00397D, 0x000820, 0x058040, 0x038042,
+ 0x09844A, 0x000606, 0x08040A, 0x380102,
+ 0x000424, 0x000424, 0x001224, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x14C286,
+ 0x000007, 0x280502, 0x001A4C, 0x166186,
+ 0x000007, 0x032164, 0x002E64, 0x00632C,
+ 0x003DFD, 0x018042, 0x08000A, 0x000095,
+ 0x090904, 0x000007, 0x000820, 0x001A4C,
+ 0x158986, 0x018040, 0x030000, 0x15A206,
+ 0x002124, 0x00010D, 0x000924, 0x006B24,
+ 0x015E0D, 0x00397D, 0x000820, 0x058040,
+ 0x038042, 0x09844A, 0x000606, 0x08040A,
+ 0x003A64, 0x000095, 0x001224, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x160286,
+ 0x000007, 0x01650D, 0x000810, 0x08043A,
+ 0x2A1A06, 0x000007, 0x14F206, 0x000007,
+ 0x007020, 0x08010A, 0x10012A, 0x0020FD,
+ 0x038860, 0x039060, 0x018040, 0x00227D,
+ 0x018042, 0x003DFD, 0x31844A, 0x18008B,
+ 0x00324C, 0x172386, 0x000007, 0x001904,
+ 0x172086, 0x000007, 0x000095, 0x199144,
+ 0x00222C, 0x003124, 0x002E64, 0x00636C,
+ 0x000E3D, 0x001375, 0x000BFD, 0x010042,
+ 0x09804A, 0x10000A, 0x038AEC, 0x0393EC,
+ 0x00224C, 0x17A186, 0x000007, 0x00008D,
+ 0x189904, 0x00226C, 0x00322C, 0x002E6C,
+ 0x00227D, 0x018042, 0x08000A, 0x000904,
+ 0x17E086, 0x000007, 0x00312C, 0x002A2C,
+ 0x30050A, 0x301DAB, 0x002083, 0x0018FD,
+ 0x018042, 0x08000A, 0x018924, 0x300502,
+ 0x001083, 0x001875, 0x010042, 0x10000A,
+ 0x00008D, 0x010924, 0x001375, 0x330542,
+ 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
+ 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
+ 0x006083, 0x0002F5, 0x010042, 0x08000A,
+ 0x000904, 0x18B286, 0x000007, 0x001E2D,
+ 0x0005FD, 0x058042, 0x08000A, 0x028924,
+ 0x280502, 0x00060D, 0x000810, 0x280C3A,
+ 0x00008D, 0x000810, 0x28143A, 0x0A808D,
+ 0x000820, 0x0002F5, 0x010040, 0x220007,
+ 0x002275, 0x010042, 0x20000A, 0x002104,
+ 0x1A2886, 0x000007, 0x0002F5, 0x010042,
+ 0x08000A, 0x000904, 0x199A86, 0x000007,
+ 0x002010, 0x30043A, 0x000083, 0x018042,
+ 0x08000A, 0x028924, 0x280502, 0x280C02,
+ 0x0A810D, 0x000820, 0x0002F5, 0x010040,
+ 0x220007, 0x001275, 0x030042, 0x21004A,
+ 0x28000A, 0x00008D, 0x1A0944, 0x000007,
+ 0x01A88D, 0x000810, 0x08043A, 0x2B6A06,
+ 0x000007, 0x0001F5, 0x030042, 0x0D004A,
+ 0x10000A, 0x089144, 0x000007, 0x000820,
+ 0x010040, 0x0025F5, 0x0A3144, 0x000007,
+ 0x000820, 0x032860, 0x030040, 0x00217D,
+ 0x038042, 0x0B804A, 0x10000A, 0x000820,
+ 0x031060, 0x030040, 0x00008D, 0x000124,
+ 0x00012C, 0x000E64, 0x001A64, 0x00636C,
+ 0x08010A, 0x10012A, 0x000820, 0x031060,
+ 0x030040, 0x0020FD, 0x018042, 0x08000A,
+ 0x00227D, 0x018042, 0x10000A, 0x000820,
+ 0x031060, 0x030040, 0x00197D, 0x018042,
+ 0x08000A, 0x0022FD, 0x038042, 0x10000A,
+ 0x000820, 0x031060, 0x030040, 0x090D04,
+ 0x000007, 0x000820, 0x030040, 0x038042,
+ 0x0B804A, 0x10000A, 0x000820, 0x031060,
+ 0x030040, 0x038042, 0x13804A, 0x19804A,
+ 0x110D04, 0x198D04, 0x000007, 0x08000A,
+ 0x001020, 0x031860, 0x030860, 0x030040,
+ 0x00008D, 0x0B0944, 0x000007, 0x000820,
+ 0x010040, 0x0005F5, 0x030042, 0x08000A,
+ 0x000820, 0x010040, 0x0000F5, 0x010042,
+ 0x08000A, 0x000904, 0x1D6886, 0x001E75,
+ 0x030042, 0x01044A, 0x000C0A, 0x1D7A06,
+ 0x000007, 0x000402, 0x000C02, 0x00177D,
+ 0x001AF5, 0x018042, 0x03144A, 0x031C4A,
+ 0x03244A, 0x032C4A, 0x03344A, 0x033C4A,
+ 0x03444A, 0x004C0A, 0x00043D, 0x0013F5,
+ 0x001AFD, 0x030042, 0x0B004A, 0x1B804A,
+ 0x13804A, 0x20000A, 0x089144, 0x19A144,
+ 0x0389E4, 0x0399EC, 0x005502, 0x005D0A,
+ 0x030042, 0x0B004A, 0x1B804A, 0x13804A,
+ 0x20000A, 0x089144, 0x19A144, 0x0389E4,
+ 0x0399EC, 0x006502, 0x006D0A, 0x030042,
+ 0x0B004A, 0x19004A, 0x2B804A, 0x13804A,
+ 0x21804A, 0x30000A, 0x089144, 0x19A144,
+ 0x2AB144, 0x0389E4, 0x0399EC, 0x007502,
+ 0x007D0A, 0x03A9E4, 0x000702, 0x00107D,
+ 0x000415, 0x018042, 0x08000A, 0x0109E4,
+ 0x000F02, 0x002AF5, 0x0019FD, 0x010042,
+ 0x09804A, 0x10000A, 0x000934, 0x001674,
+ 0x0029F5, 0x010042, 0x10000A, 0x00917C,
+ 0x002075, 0x010042, 0x08000A, 0x000904,
+ 0x1FDA86, 0x0026F5, 0x0027F5, 0x030042,
+ 0x09004A, 0x10000A, 0x000A3C, 0x00167C,
+ 0x801A75, 0x800BFD, 0x810042, 0xD1804A,
+ 0xC8000A, 0x960007, 0x801075, 0x810042,
+ 0xA82C0A, 0xA81D12, 0xA82512, 0x801F32,
+ 0x9E0007, 0x8E0007, 0x801975, 0x810042,
+ 0x802DF5, 0x8D004A, 0x90000A, 0x809144,
+ 0xA0BA86, 0x810042, 0xA8340A, 0x800E5D,
+ 0x80008D, 0x800375, 0x800820, 0x810040,
+ 0x85D2F4, 0xD4D104, 0x800007, 0x80735C,
+ 0xA16386, 0x800007, 0x8C0007, 0x880007,
+ 0x8A0007, 0x82150D, 0x800810, 0x88043A,
+ 0xB40A06, 0x800007, 0xA16A06, 0x800007,
+ 0x880007, 0x8004FD, 0x818042, 0xF0000A,
+ 0x830000, 0x807020, 0x86FA06, 0x818040,
+ 0x821C8D, 0x800810, 0x88043A, 0xAB6A06,
+ 0x800007, 0x8002FD, 0x818042, 0x88000A,
+ 0x800904, 0xA1D286, 0x800007, 0x81F206,
+ 0x800007, 0x800875, 0x8009FD, 0x80010D,
+ 0xA25206, 0x800295, 0x800B75, 0x80097D,
+ 0x80000D, 0x800515, 0x810042, 0x98000A,
+ 0x801904, 0xA8C086, 0x8006F5, 0x801020,
+ 0x810040, 0x8004F5, 0x800820, 0x810040,
+ 0x800775, 0x810042, 0x89804A, 0x90000A,
+ 0x801124, 0x800904, 0xA30286, 0x800815,
+ 0x880102, 0x901204, 0xA32206, 0x800575,
+ 0x881204, 0x800007, 0x900102, 0x800575,
+ 0x800425, 0x821124, 0x900102, 0x800820,
+ 0x831060, 0x810040, 0x801924, 0xA8C086,
+ 0x80008D, 0x800464, 0x809D04, 0xA7D086,
+ 0x980102, 0x800575, 0x810042, 0xA8040A,
+ 0x80018D, 0x800924, 0xA80D02, 0x80000D,
+ 0x800924, 0xA81502, 0x90000D, 0x800820,
+ 0x8002F5, 0x810040, 0xA00007, 0x801175,
+ 0x8002FD, 0x818042, 0x88000A, 0x800904,
+ 0xA40A86, 0x800007, 0x800100, 0x880B20,
+ 0x930B60, 0x9B0B60, 0x830A60, 0x810040,
+ 0x850042, 0xBD004A, 0xB5004A, 0xAD004A,
+ 0xA0000A, 0x8006F5, 0x810042, 0xA8140A,
+ 0x8004F5, 0x810042, 0x88000A, 0x800315,
+ 0x810D04, 0xA51286, 0x804015, 0x800095,
+ 0x810D04, 0xA50086, 0x900022, 0x90002A,
+ 0xA52A06, 0x800007, 0xB33104, 0xAAA904,
+ 0x800007, 0x832124, 0xA80502, 0x801124,
+ 0x800424, 0x800424, 0x803224, 0x80292C,
+ 0x80636C, 0xA63B86, 0x800007, 0x82B164,
+ 0x800464, 0x800464, 0x80008D, 0x800A64,
+ 0xA80D02, 0x90008D, 0x800820, 0x8002F5,
+ 0x810040, 0xA20007, 0x80008D, 0xB8B904,
+ 0x800007, 0x83296C, 0xB0010A, 0x8002F5,
+ 0x810042, 0x88000A, 0x800904, 0xA60286,
+ 0x800007, 0x82312C, 0xA8050A, 0x80008D,
+ 0x81096C, 0xA80D0A, 0x90010D, 0x800820,
+ 0x8002F5, 0x810040, 0xA20007, 0x801124,
+ 0x800424, 0x800424, 0x803224, 0xB00102,
+ 0x832944, 0xA6C286, 0x800007, 0xB00002,
+ 0x8004F5, 0x810042, 0x88000A, 0x800315,
+ 0x810D04, 0xA70886, 0x803124, 0x800464,
+ 0xB00102, 0x8002F5, 0x810042, 0x88000A,
+ 0x800904, 0xA71286, 0x800007, 0x803124,
+ 0xB00502, 0x803924, 0xB00583, 0x800883,
+ 0x8005F5, 0x810042, 0xA8040A, 0x80008D,
+ 0x808124, 0xA80D02, 0x80008D, 0x808124,
+ 0xA81502, 0x90018D, 0x800820, 0x8002F5,
+ 0x810040, 0xA20007, 0x801025, 0x800575,
+ 0x830042, 0x89004A, 0x90000A, 0x8A0904,
+ 0x921104, 0x800007, 0x801020, 0x850860,
+ 0x850040, 0x8006FD, 0x818042, 0x89004A,
+ 0x90000A, 0x8000A5, 0x8A0904, 0x921104,
+ 0x800007, 0x800820, 0x819060, 0x810040,
+ 0x8002F5, 0x810042, 0x88000A, 0x800904,
+ 0xA88A86, 0x800007, 0xA35206, 0x800007,
+ 0x800606, 0x800007, 0x8002F5, 0x810042,
+ 0x88000A, 0x800904, 0xA8DA86, 0x800007,
+ 0x800100, 0x880B20, 0x938B60, 0x9B8B60,
+ 0xA38B60, 0xAB8B60, 0xB38B60, 0xBB8B60,
+ 0xC38B60, 0xCB8B60, 0xD38B60, 0xDB8B60,
+ 0xE38B60, 0xEB8B60, 0xF38B60, 0xFB8B60,
+ 0x838F60, 0x8B8F60, 0x938F60, 0x9B8F60,
+ 0xA38F60, 0xAB8F60, 0xB38F60, 0xBB8F60,
+ 0xC38F60, 0xCB8F60, 0xD38F60, 0xDB8F60,
+ 0xE38F60, 0xEB8F60, 0xF38F60, 0xFB8F60,
+ 0x838A60, 0x800606, 0x818040, 0x80008D,
+ 0x800A64, 0xA80D02, 0x800A24, 0x80027D,
+ 0x818042, 0x90000A, 0x801224, 0x8003FD,
+ 0x818042, 0x88000A, 0x800904, 0xAACA86,
+ 0x800007, 0x80018D, 0x800A24, 0x800464,
+ 0x800464, 0x880102, 0x800924, 0x800424,
+ 0x800424, 0x900102, 0x82000D, 0x809144,
+ 0xAB2186, 0x800007, 0x8001FD, 0x818042,
+ 0x88000A, 0x800A44, 0xAB0386, 0x818042,
+ 0x8A000D, 0x800820, 0x8002FD, 0x818040,
+ 0xA00007, 0x80027D, 0x801020, 0x800606,
+ 0x818040, 0x8002F5, 0x810042, 0x88000A,
+ 0x800904, 0xAB7286, 0x800007, 0x80037D,
+ 0x818042, 0x88000A, 0x800904, 0xABA286,
+ 0x800007, 0x800075, 0x802E7D, 0x810042,
+ 0x8B804A, 0x800020, 0x800904, 0x810040,
+ 0x800686, 0x800007, 0xB1844A, 0xB0048B,
+ 0x800883, 0x80008D, 0x800810, 0xA8143A,
+ 0x80008D, 0x800810, 0xA80C3A, 0x800675,
+ 0x810042, 0x88000A, 0x803815, 0x810924,
+ 0xA80502, 0x8B000D, 0x800820, 0x8002F5,
+ 0x810040, 0xA20007, 0x800606, 0x800007,
+ 0x800464, 0x800464, 0x800606, 0x800007,
+ 0x800134, 0x807F8D, 0x80093C, 0xA81D12,
+ 0xA82512, 0x801F32, 0x8E0007, 0x80010D,
+ 0x80037D, 0x800820, 0x818040, 0x85D2F4,
+ 0x800007, 0x880007, 0x80037D, 0x818042,
+ 0x88000A, 0x800904, 0xAD5A86, 0x800007,
+ 0x800606, 0x800007, 0x800007, 0x800012,
+ 0x900007, 0xB20007, 0xE00007, 0x900080,
+ 0xC8001A, 0x804904, 0xADB986, 0x800007,
+ 0x801210, 0xD8003A, 0x800145, 0xDC5D04,
+ 0x800007, 0x800080, 0xC8001A, 0x804904,
+ 0xAE0986, 0x800007, 0x801210, 0xD0003A,
+ 0x805904, 0xAE6086, 0x800045, 0x8000C5,
+ 0xFFFFF5, 0xFFFF7D, 0x87D524, 0x804224,
+ 0xD00102, 0xA00502, 0x800082, 0xC0001A,
+ 0x804104, 0xAE9186, 0x800007, 0x803865,
+ 0xC0001A, 0x804020, 0x80104D, 0x84C184,
+ 0xB07386, 0x800040, 0x840007, 0x800165,
+ 0x800145, 0x804020, 0x800040, 0x800765,
+ 0x880080, 0xC0001A, 0x804104, 0xAF2186,
+ 0x800007, 0x801210, 0xC0003A, 0x804104,
+ 0xAF7A86, 0x80004D, 0x8000CD, 0x804810,
+ 0xA0043A, 0x800882, 0xC0001A, 0x804104,
+ 0xAF8986, 0x800007, 0x804820, 0x805904,
+ 0xB06086, 0x800040, 0x8007E5, 0xA00480,
+ 0xA816A0, 0xB216E0, 0xBA16E0, 0xC216E0,
+ 0x821260, 0x800040, 0x800032, 0xC00075,
+ 0x80007D, 0x87D574, 0xA00512, 0x800082,
+ 0xC0001A, 0x804104, 0xB03986, 0x800007,
+ 0x837206, 0xE40007, 0x860007, 0x8000E5,
+ 0x800020, 0x800040, 0x800A65, 0x800020,
+ 0x820040, 0x820040, 0x800040, 0x800165,
+ 0x800042, 0xF0000A, 0x807104, 0xB0FA86,
+ 0x800007, 0x818206, 0xE40007, 0x850000,
+ 0x807020, 0x800040, 0x837206, 0xE40007,
+ 0x800007, 0x80306D, 0x828860, 0x829060,
+ 0x829860, 0x88000A, 0x828860, 0x880102,
+ 0x900122, 0x828860, 0x829060, 0x808040,
+ 0x900012, 0x801020, 0x803B6D, 0x808040,
+ 0x80100D, 0x809184, 0xB1E186, 0x800007,
+ 0x800E0D, 0x809184, 0xB2B986, 0x800007,
+ 0xB00007, 0x800080, 0x88001A, 0x800904,
+ 0xB1E986, 0x800007, 0x801220, 0x800DED,
+ 0x808040, 0x808042, 0x98000A, 0xC0000D,
+ 0x809D64, 0xA00502, 0x800082, 0x88001A,
+ 0x800904, 0xB25186, 0x800007, 0x803B6D,
+ 0x808042, 0x88000A, 0x800E15, 0x810984,
+ 0xE00007, 0xB33B86, 0x800007, 0x8003ED,
+ 0x808042, 0x88000A, 0x800904, 0xB31A86,
+ 0x800007, 0x88001A, 0x800C15, 0x810984,
+ 0xB31B86, 0x800007, 0x9A0007, 0x8002ED,
+ 0x800020, 0x808040, 0xE20007, 0x8032ED,
+ 0x828042, 0x88804A, 0x90000A, 0x800924,
+ 0x801664, 0x800007, 0x80306D, 0x828042,
+ 0x8A804A, 0x800820, 0x8A804A, 0x92804A,
+ 0x9A804A, 0x800606, 0x800007, 0x800007,
+ 0xA82512, 0x801F32, 0x85D2F4, 0xD4D104,
+ 0x80735C, 0x800786, 0x800007, 0x8C0007,
+ 0x8A0007, 0x9C0007, 0x803465, 0x820040,
+ 0x804820, 0x825060, 0xC0000A, 0x824060,
+ 0x800040, 0xC54944, 0x800007, 0x804020,
+ 0x803AE5, 0x800040, 0x8028E5, 0x820042,
+ 0xC8000A, 0x804904, 0xB9A886, 0x800007,
+ 0x800042, 0xC0000A, 0x804104, 0xB4E086,
+ 0x800007, 0x802402, 0xB7EA06, 0x805C02,
+ 0x802C65, 0x800042, 0xC0000A, 0x8000D5,
+ 0xC54104, 0x800007, 0x800655, 0x854504,
+ 0xB67286, 0x800007, 0x8001D5, 0x854504,
+ 0xB67086, 0x800007, 0x802B65, 0x800042,
+ 0xD0000A, 0x803AE5, 0x800042, 0xC0000A,
+ 0xC5C3D4, 0x800007, 0xC54504, 0x800007,
+ 0x803A65, 0x805820, 0x800040, 0x8000DD,
+ 0xC45944, 0x800007, 0xC54504, 0x800007,
+ 0x80015D, 0xD55944, 0x800007, 0x845144,
+ 0xB65186, 0x800007, 0x802C65, 0x800042,
+ 0xD8000A, 0xDDD104, 0x800007, 0x85C144,
+ 0xB65B86, 0x800007, 0x960007, 0x803A65,
+ 0x800042, 0xD8000A, 0x802CE5, 0x840042,
+ 0xC0000A, 0x804020, 0x800040, 0x8025E5,
+ 0x820042, 0xC0004A, 0xD0000A, 0x804274,
+ 0x805674, 0x802AE5, 0x800042, 0xC0000A,
+ 0x804274, 0xD00112, 0x8029E5, 0x800042,
+ 0xC0000A, 0x804234, 0xC54104, 0x800007,
+ 0x804020, 0x800040, 0x803EE5, 0x800020,
+ 0x800040, 0x802DE5, 0xC00152, 0xD0000A,
+ 0x845144, 0xB79286, 0x8000C5, 0x803EE5,
+ 0x804020, 0x800040, 0x802BE5, 0x800042,
+ 0xC0000A, 0xC04254, 0x800007, 0x802AE5,
+ 0x804020, 0x800040, 0xD00132, 0x840134,
+ 0x805674, 0x8029E5, 0x820042, 0xC2000A,
+ 0x800042, 0xD0000A, 0x85417C, 0x8000C5,
+ 0xCCC144, 0xB84086, 0x8026E5, 0x8027E5,
+ 0x820042, 0xC0004A, 0xD0000A, 0x80423C,
+ 0x80567C, 0x8028E5, 0x804820, 0x800040,
+ 0xA81D12, 0xA82512, 0x801F72, 0x802965,
+ 0x800042, 0xC0000A, 0x804104, 0xB8DA86,
+ 0x800007, 0x960007, 0x9E0007, 0x8E0007,
+ 0x803EE5, 0x800042, 0xC0000A, 0x804104,
+ 0xB92086, 0x802D65, 0x800042, 0xA8340A,
+ 0x803465, 0x820042, 0xC2004A, 0x804020,
+ 0xCA004A, 0xD0004A, 0x85D2F4, 0xD4D104,
+ 0x800007, 0x80735C, 0xB99186, 0x800007,
+ 0x800606, 0x880007, 0x8C0007, 0x880007,
+ 0x8A0007, 0x8001E5, 0x820045, 0x804020,
+ 0x800060, 0x800365, 0x800040, 0x802E65,
+ 0x801A20, 0x8A1A60, 0x800040, 0x803465,
+ 0x820042, 0xC2004A, 0x804020, 0xCA004A,
+ 0x800606, 0xD0004A, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000
+};
+
+static unsigned int cntrl1E_size = 0x0c00;
+static unsigned int cntrl1E[] = {
+ 0x000007, 0x240007, 0x0C0007, 0x1C0007,
+ 0x060007, 0x700002, 0x000020, 0x030040,
+ 0x007104, 0x004286, 0x030040, 0x000F0D,
+ 0x000810, 0x20043A, 0x000282, 0x00020D,
+ 0x000810, 0x20043A, 0x001282, 0x200E82,
+ 0x00800D, 0x000810, 0x20043A, 0x001A82,
+ 0x03460D, 0x000810, 0x10043A, 0x02EC0D,
+ 0x000810, 0x18043A, 0x00010D, 0x020015,
+ 0x0000FD, 0x000020, 0x038860, 0x039060,
+ 0x038060, 0x038040, 0x038040, 0x038040,
+ 0x018040, 0x000A7D, 0x038040, 0x038040,
+ 0x018040, 0x200402, 0x000882, 0x08001A,
+ 0x000904, 0x017186, 0x000007, 0x260007,
+ 0x400007, 0x000007, 0x03258D, 0x000810,
+ 0x18043A, 0x260007, 0x284402, 0x00087D,
+ 0x018042, 0x00160A, 0x05A206, 0x000007,
+ 0x440007, 0x00230D, 0x000810, 0x08043A,
+ 0x22FA06, 0x000007, 0x0007FD, 0x018042,
+ 0x08000A, 0x000904, 0x02AB86, 0x000195,
+ 0x090D04, 0x000007, 0x000820, 0x0000F5,
+ 0x000B7D, 0x01F060, 0x0000FD, 0x033A06,
+ 0x018040, 0x000A7D, 0x038042, 0x13804A,
+ 0x18000A, 0x001820, 0x059060, 0x058860,
+ 0x018040, 0x0000FD, 0x018042, 0x70000A,
+ 0x000115, 0x071144, 0x033B86, 0x030000,
+ 0x007020, 0x036206, 0x018040, 0x00360D,
+ 0x000810, 0x08043A, 0x232206, 0x000007,
+ 0x02EC0D, 0x000810, 0x18043A, 0x019A06,
+ 0x000007, 0x240007, 0x000F8D, 0x000810,
+ 0x00163A, 0x002402, 0x005C02, 0x0028FD,
+ 0x000020, 0x018040, 0x08000D, 0x000815,
+ 0x510984, 0x000007, 0x00004D, 0x000E5D,
+ 0x000E02, 0x00430D, 0x000810, 0x08043A,
+ 0x2E1206, 0x000007, 0x00008D, 0x000924,
+ 0x000F02, 0x00470D, 0x000810, 0x08043A,
+ 0x2E1206, 0x000007, 0x480480, 0x001210,
+ 0x28043A, 0x00778D, 0x000810, 0x280C3A,
+ 0x00068D, 0x000810, 0x28143A, 0x284402,
+ 0x03258D, 0x000810, 0x18043A, 0x07FF8D,
+ 0x000820, 0x0002FD, 0x018040, 0x260007,
+ 0x200007, 0x0002FD, 0x018042, 0x08000A,
+ 0x000904, 0x051286, 0x000007, 0x240007,
+ 0x02EC0D, 0x000810, 0x18043A, 0x00387D,
+ 0x018042, 0x08000A, 0x001015, 0x010984,
+ 0x019B86, 0x000007, 0x01B206, 0x000007,
+ 0x0008FD, 0x018042, 0x18000A, 0x001904,
+ 0x22B886, 0x280007, 0x001810, 0x28043A,
+ 0x280C02, 0x00000D, 0x000810, 0x28143A,
+ 0x08808D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00020D, 0x189904, 0x000007,
+ 0x00402D, 0x0000BD, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x065A86, 0x000007,
+ 0x000100, 0x000A20, 0x00047D, 0x018040,
+ 0x018042, 0x20000A, 0x003015, 0x012144,
+ 0x036186, 0x000007, 0x002104, 0x036186,
+ 0x000007, 0x000F8D, 0x000810, 0x280C3A,
+ 0x023944, 0x07C986, 0x000007, 0x001810,
+ 0x28043A, 0x08810D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x002810, 0x78003A,
+ 0x00788D, 0x000810, 0x08043A, 0x2A1206,
+ 0x000007, 0x00400D, 0x001015, 0x189904,
+ 0x292904, 0x393904, 0x000007, 0x070206,
+ 0x000007, 0x0004F5, 0x00007D, 0x000020,
+ 0x00008D, 0x010860, 0x018040, 0x00047D,
+ 0x038042, 0x21804A, 0x18000A, 0x021944,
+ 0x229086, 0x000007, 0x004075, 0x71F104,
+ 0x000007, 0x010042, 0x28000A, 0x002904,
+ 0x225886, 0x000007, 0x003C0D, 0x30A904,
+ 0x000007, 0x00077D, 0x018042, 0x08000A,
+ 0x000904, 0x08DA86, 0x00057D, 0x002820,
+ 0x03B060, 0x08F206, 0x018040, 0x003020,
+ 0x03A860, 0x018040, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x08FA86, 0x000007,
+ 0x00057D, 0x018042, 0x28040A, 0x000E8D,
+ 0x000810, 0x280C3A, 0x00000D, 0x000810,
+ 0x28143A, 0x09000D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x003DFD, 0x000020,
+ 0x018040, 0x00107D, 0x009D8D, 0x000810,
+ 0x08043A, 0x2A1206, 0x000007, 0x000815,
+ 0x08001A, 0x010984, 0x0A5186, 0x00137D,
+ 0x200500, 0x280F20, 0x338F60, 0x3B8F60,
+ 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
+ 0x038A60, 0x018040, 0x00107D, 0x018042,
+ 0x08000A, 0x000215, 0x010984, 0x3A8186,
+ 0x000007, 0x007FBD, 0x383DC4, 0x000007,
+ 0x001A7D, 0x001375, 0x018042, 0x09004A,
+ 0x10000A, 0x0B8D04, 0x139504, 0x000007,
+ 0x000820, 0x019060, 0x001104, 0x225886,
+ 0x010040, 0x0017FD, 0x018042, 0x08000A,
+ 0x000904, 0x225A86, 0x000007, 0x00197D,
+ 0x038042, 0x09804A, 0x10000A, 0x000924,
+ 0x001664, 0x0011FD, 0x038042, 0x2B804A,
+ 0x19804A, 0x00008D, 0x218944, 0x000007,
+ 0x002244, 0x0C1986, 0x000007, 0x001A64,
+ 0x002A24, 0x00197D, 0x080102, 0x100122,
+ 0x000820, 0x039060, 0x018040, 0x003DFD,
+ 0x00008D, 0x000820, 0x018040, 0x001375,
+ 0x001A7D, 0x010042, 0x09804A, 0x10000A,
+ 0x00021D, 0x0189E4, 0x2992E4, 0x309144,
+ 0x000007, 0x00060D, 0x000A15, 0x000C1D,
+ 0x001025, 0x00A9E4, 0x012BE4, 0x000464,
+ 0x01B3E4, 0x0232E4, 0x000464, 0x000464,
+ 0x000464, 0x000464, 0x00040D, 0x08B1C4,
+ 0x000007, 0x000820, 0x000BF5, 0x030040,
+ 0x00197D, 0x038042, 0x09804A, 0x000A24,
+ 0x08000A, 0x080E64, 0x000007, 0x100122,
+ 0x000820, 0x031060, 0x010040, 0x0064AC,
+ 0x00027D, 0x000020, 0x018040, 0x00107D,
+ 0x018042, 0x0011FD, 0x3B804A, 0x09804A,
+ 0x20000A, 0x000095, 0x1A1144, 0x00A144,
+ 0x0E5886, 0x00040D, 0x00B984, 0x0E5986,
+ 0x0018FD, 0x018042, 0x0010FD, 0x09804A,
+ 0x28000A, 0x000095, 0x010924, 0x002A64,
+ 0x0E4986, 0x000007, 0x002904, 0x0E5A86,
+ 0x000007, 0x0E6206, 0x080002, 0x00008D,
+ 0x00387D, 0x000820, 0x018040, 0x00127D,
+ 0x018042, 0x10000A, 0x003904, 0x0F0986,
+ 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986,
+ 0x000025, 0x0FB206, 0x00002D, 0x000015,
+ 0x00082D, 0x02E00D, 0x000820, 0x0FFA06,
+ 0x00000D, 0x7F8035, 0x00B984, 0x0FA986,
+ 0x400025, 0x00008D, 0x110944, 0x000007,
+ 0x00018D, 0x109504, 0x000007, 0x009164,
+ 0x000424, 0x000424, 0x000424, 0x100102,
+ 0x280002, 0x02DF0D, 0x000820, 0x0FFA06,
+ 0x00018D, 0x00042D, 0x00008D, 0x109504,
+ 0x000007, 0x00020D, 0x109184, 0x000007,
+ 0x02DF8D, 0x000820, 0x00008D, 0x0038FD,
+ 0x018040, 0x003BFD, 0x001020, 0x03A860,
+ 0x000815, 0x313184, 0x212184, 0x000007,
+ 0x03B060, 0x03A060, 0x018040, 0x0022FD,
+ 0x000095, 0x010924, 0x000424, 0x000424,
+ 0x001264, 0x100102, 0x000820, 0x039060,
+ 0x018040, 0x001924, 0x010F0D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x000424, 0x000424,
+ 0x00117D, 0x018042, 0x08000A, 0x000A24,
+ 0x280502, 0x280C02, 0x09800D, 0x000820,
+ 0x0002FD, 0x018040, 0x200007, 0x0022FD,
+ 0x018042, 0x08000A, 0x000095, 0x280DC4,
+ 0x011924, 0x00197D, 0x018042, 0x0011FD,
+ 0x09804A, 0x10000A, 0x0000B5, 0x113144,
+ 0x0A8D04, 0x000007, 0x080A44, 0x129504,
+ 0x000007, 0x0023FD, 0x001020, 0x038040,
+ 0x101244, 0x000007, 0x000820, 0x039060,
+ 0x018040, 0x0002FD, 0x018042, 0x08000A,
+ 0x000904, 0x123286, 0x000007, 0x003BFD,
+ 0x000100, 0x000A10, 0x0B807A, 0x13804A,
+ 0x090984, 0x000007, 0x000095, 0x013D04,
+ 0x12B886, 0x10000A, 0x100002, 0x090984,
+ 0x000007, 0x038042, 0x11804A, 0x090D04,
+ 0x000007, 0x10000A, 0x090D84, 0x000007,
+ 0x00257D, 0x000820, 0x018040, 0x00010D,
+ 0x000810, 0x28143A, 0x00127D, 0x018042,
+ 0x20000A, 0x00197D, 0x018042, 0x00117D,
+ 0x31804A, 0x10000A, 0x003124, 0x013B8D,
+ 0x00397D, 0x000820, 0x058040, 0x038042,
+ 0x09844A, 0x000606, 0x08040A, 0x300102,
+ 0x003124, 0x000424, 0x000424, 0x001224,
+ 0x280502, 0x001A4C, 0x143986, 0x700002,
+ 0x00002D, 0x030000, 0x00387D, 0x018042,
+ 0x10000A, 0x146206, 0x002124, 0x0000AD,
+ 0x100002, 0x00010D, 0x000924, 0x006B24,
+ 0x014A0D, 0x00397D, 0x000820, 0x058040,
+ 0x038042, 0x09844A, 0x000606, 0x08040A,
+ 0x003264, 0x00008D, 0x000A24, 0x001020,
+ 0x00227D, 0x018040, 0x014F8D, 0x000810,
+ 0x08043A, 0x2B5A06, 0x000007, 0x002820,
+ 0x00207D, 0x018040, 0x00117D, 0x038042,
+ 0x13804A, 0x33800A, 0x00387D, 0x018042,
+ 0x08000A, 0x000904, 0x177286, 0x000007,
+ 0x00008D, 0x030964, 0x015B0D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x380102, 0x000424,
+ 0x000424, 0x001224, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x15DA86, 0x000007,
+ 0x280502, 0x001A4C, 0x177186, 0x000007,
+ 0x032164, 0x00632C, 0x003DFD, 0x018042,
+ 0x08000A, 0x000095, 0x090904, 0x000007,
+ 0x000820, 0x001A4C, 0x169986, 0x018040,
+ 0x030000, 0x16B206, 0x002124, 0x00010D,
+ 0x000924, 0x006B24, 0x016F0D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x003A64, 0x000095,
+ 0x001224, 0x0002FD, 0x018042, 0x08000A,
+ 0x000904, 0x171286, 0x000007, 0x01760D,
+ 0x000810, 0x08043A, 0x2B5A06, 0x000007,
+ 0x160A06, 0x000007, 0x007020, 0x08010A,
+ 0x10012A, 0x0020FD, 0x038860, 0x039060,
+ 0x018040, 0x00227D, 0x018042, 0x003DFD,
+ 0x08000A, 0x31844A, 0x000904, 0x181086,
+ 0x18008B, 0x00008D, 0x189904, 0x00312C,
+ 0x18E206, 0x000007, 0x00324C, 0x186B86,
+ 0x000007, 0x001904, 0x186886, 0x000007,
+ 0x000095, 0x199144, 0x00222C, 0x003124,
+ 0x00636C, 0x000E3D, 0x001375, 0x000BFD,
+ 0x010042, 0x09804A, 0x10000A, 0x038AEC,
+ 0x0393EC, 0x00224C, 0x18E186, 0x000007,
+ 0x00008D, 0x189904, 0x00226C, 0x00322C,
+ 0x30050A, 0x301DAB, 0x002083, 0x0018FD,
+ 0x018042, 0x08000A, 0x018924, 0x300502,
+ 0x001083, 0x001875, 0x010042, 0x10000A,
+ 0x00008D, 0x010924, 0x001375, 0x330542,
+ 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
+ 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
+ 0x006083, 0x0002F5, 0x010042, 0x08000A,
+ 0x000904, 0x19B286, 0x000007, 0x001E2D,
+ 0x0005FD, 0x018042, 0x08000A, 0x028924,
+ 0x280502, 0x00060D, 0x000810, 0x280C3A,
+ 0x00008D, 0x000810, 0x28143A, 0x0A808D,
+ 0x000820, 0x0002F5, 0x010040, 0x220007,
+ 0x001275, 0x030042, 0x21004A, 0x00008D,
+ 0x1A0944, 0x000007, 0x01AB8D, 0x000810,
+ 0x08043A, 0x2CAA06, 0x000007, 0x0001F5,
+ 0x030042, 0x0D004A, 0x10000A, 0x089144,
+ 0x000007, 0x000820, 0x010040, 0x0025F5,
+ 0x0A3144, 0x000007, 0x000820, 0x032860,
+ 0x030040, 0x00217D, 0x038042, 0x0B804A,
+ 0x10000A, 0x000820, 0x031060, 0x030040,
+ 0x00008D, 0x000124, 0x00012C, 0x000E64,
+ 0x001A64, 0x00636C, 0x08010A, 0x10012A,
+ 0x000820, 0x031060, 0x030040, 0x0020FD,
+ 0x018042, 0x08000A, 0x00227D, 0x018042,
+ 0x10000A, 0x000820, 0x031060, 0x030040,
+ 0x00197D, 0x018042, 0x08000A, 0x0022FD,
+ 0x038042, 0x10000A, 0x000820, 0x031060,
+ 0x030040, 0x090D04, 0x000007, 0x000820,
+ 0x030040, 0x038042, 0x0B804A, 0x10000A,
+ 0x000820, 0x031060, 0x030040, 0x038042,
+ 0x13804A, 0x19804A, 0x110D04, 0x198D04,
+ 0x000007, 0x08000A, 0x001020, 0x031860,
+ 0x030860, 0x030040, 0x00008D, 0x0B0944,
+ 0x000007, 0x000820, 0x010040, 0x0005F5,
+ 0x030042, 0x08000A, 0x000820, 0x010040,
+ 0x0000F5, 0x010042, 0x08000A, 0x000904,
+ 0x1D9886, 0x001E75, 0x030042, 0x01044A,
+ 0x000C0A, 0x1DAA06, 0x000007, 0x000402,
+ 0x000C02, 0x00177D, 0x001AF5, 0x018042,
+ 0x03144A, 0x031C4A, 0x03244A, 0x032C4A,
+ 0x03344A, 0x033C4A, 0x03444A, 0x004C0A,
+ 0x00043D, 0x0013F5, 0x001AFD, 0x030042,
+ 0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
+ 0x089144, 0x19A144, 0x0389E4, 0x0399EC,
+ 0x005502, 0x005D0A, 0x030042, 0x0B004A,
+ 0x1B804A, 0x13804A, 0x20000A, 0x089144,
+ 0x19A144, 0x0389E4, 0x0399EC, 0x006502,
+ 0x006D0A, 0x030042, 0x0B004A, 0x19004A,
+ 0x2B804A, 0x13804A, 0x21804A, 0x30000A,
+ 0x089144, 0x19A144, 0x2AB144, 0x0389E4,
+ 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4,
+ 0x000702, 0x00107D, 0x000415, 0x018042,
+ 0x08000A, 0x0109E4, 0x000F02, 0x002AF5,
+ 0x0019FD, 0x010042, 0x09804A, 0x10000A,
+ 0x000934, 0x001674, 0x0029F5, 0x010042,
+ 0x10000A, 0x00917C, 0x002075, 0x010042,
+ 0x08000A, 0x000904, 0x200A86, 0x0026F5,
+ 0x0027F5, 0x030042, 0x09004A, 0x10000A,
+ 0x000A3C, 0x00167C, 0x001A75, 0x000BFD,
+ 0x010042, 0x51804A, 0x48000A, 0x160007,
+ 0x001075, 0x010042, 0x282C0A, 0x281D12,
+ 0x282512, 0x001F32, 0x1E0007, 0x0E0007,
+ 0x001975, 0x010042, 0x002DF5, 0x0D004A,
+ 0x10000A, 0x009144, 0x20EA86, 0x010042,
+ 0x28340A, 0x000E5D, 0x00008D, 0x000375,
+ 0x000820, 0x010040, 0x05D2F4, 0x54D104,
+ 0x00735C, 0x218B86, 0x000007, 0x0C0007,
+ 0x080007, 0x0A0007, 0x02178D, 0x000810,
+ 0x08043A, 0x34B206, 0x000007, 0x219206,
+ 0x000007, 0x080007, 0x002275, 0x010042,
+ 0x20000A, 0x002104, 0x225886, 0x001E2D,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x21CA86, 0x000007, 0x002010, 0x30043A,
+ 0x00057D, 0x0180C3, 0x08000A, 0x028924,
+ 0x280502, 0x280C02, 0x0A810D, 0x000820,
+ 0x0002F5, 0x010040, 0x220007, 0x0004FD,
+ 0x018042, 0x70000A, 0x030000, 0x007020,
+ 0x07FA06, 0x018040, 0x022B8D, 0x000810,
+ 0x08043A, 0x2CAA06, 0x000007, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x22C286,
+ 0x000007, 0x020206, 0x000007, 0x000875,
+ 0x0009FD, 0x00010D, 0x234206, 0x000295,
+ 0x000B75, 0x00097D, 0x00000D, 0x000515,
+ 0x010042, 0x18000A, 0x001904, 0x2A0086,
+ 0x0006F5, 0x001020, 0x010040, 0x0004F5,
+ 0x000820, 0x010040, 0x000775, 0x010042,
+ 0x09804A, 0x10000A, 0x001124, 0x000904,
+ 0x23F286, 0x000815, 0x080102, 0x101204,
+ 0x241206, 0x000575, 0x081204, 0x000007,
+ 0x100102, 0x000575, 0x000425, 0x021124,
+ 0x100102, 0x000820, 0x031060, 0x010040,
+ 0x001924, 0x2A0086, 0x00008D, 0x000464,
+ 0x009D04, 0x291086, 0x180102, 0x000575,
+ 0x010042, 0x28040A, 0x00018D, 0x000924,
+ 0x280D02, 0x00000D, 0x000924, 0x281502,
+ 0x10000D, 0x000820, 0x0002F5, 0x010040,
+ 0x200007, 0x001175, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x24FA86, 0x000007,
+ 0x000100, 0x080B20, 0x130B60, 0x1B0B60,
+ 0x030A60, 0x010040, 0x050042, 0x3D004A,
+ 0x35004A, 0x2D004A, 0x20000A, 0x0006F5,
+ 0x010042, 0x28140A, 0x0004F5, 0x010042,
+ 0x08000A, 0x000315, 0x010D04, 0x260286,
+ 0x004015, 0x000095, 0x010D04, 0x25F086,
+ 0x100022, 0x10002A, 0x261A06, 0x000007,
+ 0x333104, 0x2AA904, 0x000007, 0x032124,
+ 0x280502, 0x284402, 0x001124, 0x400102,
+ 0x000424, 0x000424, 0x003224, 0x00292C,
+ 0x00636C, 0x277386, 0x000007, 0x02B164,
+ 0x000464, 0x000464, 0x00008D, 0x000A64,
+ 0x280D02, 0x10008D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x00008D, 0x38B904,
+ 0x000007, 0x03296C, 0x30010A, 0x0002F5,
+ 0x010042, 0x08000A, 0x000904, 0x270286,
+ 0x000007, 0x00212C, 0x28050A, 0x00316C,
+ 0x00046C, 0x00046C, 0x28450A, 0x001124,
+ 0x006B64, 0x100102, 0x00008D, 0x01096C,
+ 0x280D0A, 0x10010D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x004124, 0x000424,
+ 0x000424, 0x003224, 0x300102, 0x032944,
+ 0x27FA86, 0x000007, 0x300002, 0x0004F5,
+ 0x010042, 0x08000A, 0x000315, 0x010D04,
+ 0x284086, 0x003124, 0x000464, 0x300102,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x284A86, 0x000007, 0x284402, 0x003124,
+ 0x300502, 0x003924, 0x300583, 0x000883,
+ 0x0005F5, 0x010042, 0x28040A, 0x00008D,
+ 0x008124, 0x280D02, 0x00008D, 0x008124,
+ 0x281502, 0x10018D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x001025, 0x000575,
+ 0x030042, 0x09004A, 0x10000A, 0x0A0904,
+ 0x121104, 0x000007, 0x001020, 0x050860,
+ 0x050040, 0x0006FD, 0x018042, 0x09004A,
+ 0x10000A, 0x0000A5, 0x0A0904, 0x121104,
+ 0x000007, 0x000820, 0x019060, 0x010040,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x29CA86, 0x000007, 0x244206, 0x000007,
+ 0x000606, 0x000007, 0x0002F5, 0x010042,
+ 0x08000A, 0x000904, 0x2A1A86, 0x000007,
+ 0x000100, 0x080B20, 0x138B60, 0x1B8B60,
+ 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60,
+ 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60,
+ 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60,
+ 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60,
+ 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60,
+ 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
+ 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60,
+ 0x038A60, 0x000606, 0x018040, 0x00008D,
+ 0x000A64, 0x280D02, 0x000A24, 0x00027D,
+ 0x018042, 0x10000A, 0x001224, 0x0003FD,
+ 0x018042, 0x08000A, 0x000904, 0x2C0A86,
+ 0x000007, 0x00018D, 0x000A24, 0x000464,
+ 0x000464, 0x080102, 0x000924, 0x000424,
+ 0x000424, 0x100102, 0x02000D, 0x009144,
+ 0x2C6186, 0x000007, 0x0001FD, 0x018042,
+ 0x08000A, 0x000A44, 0x2C4386, 0x018042,
+ 0x0A000D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00027D, 0x001020, 0x000606,
+ 0x018040, 0x0002F5, 0x010042, 0x08000A,
+ 0x000904, 0x2CB286, 0x000007, 0x00037D,
+ 0x018042, 0x08000A, 0x000904, 0x2CE286,
+ 0x000007, 0x000075, 0x002E7D, 0x010042,
+ 0x0B804A, 0x000020, 0x000904, 0x000686,
+ 0x010040, 0x31844A, 0x30048B, 0x000883,
+ 0x00008D, 0x000810, 0x28143A, 0x00008D,
+ 0x000810, 0x280C3A, 0x000675, 0x010042,
+ 0x08000A, 0x003815, 0x010924, 0x280502,
+ 0x0B000D, 0x000820, 0x0002F5, 0x010040,
+ 0x000606, 0x220007, 0x000464, 0x000464,
+ 0x000606, 0x000007, 0x000134, 0x007F8D,
+ 0x00093C, 0x281D12, 0x282512, 0x001F32,
+ 0x0E0007, 0x00010D, 0x00037D, 0x000820,
+ 0x018040, 0x05D2F4, 0x000007, 0x080007,
+ 0x00037D, 0x018042, 0x08000A, 0x000904,
+ 0x2E8A86, 0x000007, 0x000606, 0x000007,
+ 0x000007, 0x000012, 0x100007, 0x320007,
+ 0x600007, 0x460007, 0x100080, 0x48001A,
+ 0x004904, 0x2EF186, 0x000007, 0x001210,
+ 0x58003A, 0x000145, 0x5C5D04, 0x000007,
+ 0x000080, 0x48001A, 0x004904, 0x2F4186,
+ 0x000007, 0x001210, 0x50003A, 0x005904,
+ 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5,
+ 0x7FFF7D, 0x07D524, 0x004224, 0x500102,
+ 0x200502, 0x000082, 0x40001A, 0x004104,
+ 0x2FC986, 0x000007, 0x003865, 0x40001A,
+ 0x004020, 0x00104D, 0x04C184, 0x31AB86,
+ 0x000040, 0x040007, 0x000165, 0x000145,
+ 0x004020, 0x000040, 0x000765, 0x080080,
+ 0x40001A, 0x004104, 0x305986, 0x000007,
+ 0x001210, 0x40003A, 0x004104, 0x30B286,
+ 0x00004D, 0x0000CD, 0x004810, 0x20043A,
+ 0x000882, 0x40001A, 0x004104, 0x30C186,
+ 0x000007, 0x004820, 0x005904, 0x319886,
+ 0x000040, 0x0007E5, 0x200480, 0x2816A0,
+ 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260,
+ 0x000040, 0x000032, 0x400075, 0x00007D,
+ 0x07D574, 0x200512, 0x000082, 0x40001A,
+ 0x004104, 0x317186, 0x000007, 0x038A06,
+ 0x640007, 0x0000E5, 0x000020, 0x000040,
+ 0x000A65, 0x000020, 0x020040, 0x020040,
+ 0x000040, 0x000165, 0x000042, 0x70000A,
+ 0x007104, 0x323286, 0x000007, 0x060007,
+ 0x019A06, 0x640007, 0x050000, 0x007020,
+ 0x000040, 0x038A06, 0x640007, 0x000007,
+ 0x00306D, 0x028860, 0x029060, 0x08000A,
+ 0x028860, 0x008040, 0x100012, 0x00100D,
+ 0x009184, 0x32D186, 0x000E0D, 0x009184,
+ 0x33E186, 0x000007, 0x300007, 0x001020,
+ 0x003B6D, 0x008040, 0x000080, 0x08001A,
+ 0x000904, 0x32F186, 0x000007, 0x001220,
+ 0x000DED, 0x008040, 0x008042, 0x10000A,
+ 0x40000D, 0x109544, 0x000007, 0x001020,
+ 0x000DED, 0x008040, 0x008042, 0x20040A,
+ 0x000082, 0x08001A, 0x000904, 0x338186,
+ 0x000007, 0x003B6D, 0x008042, 0x08000A,
+ 0x000E15, 0x010984, 0x342B86, 0x600007,
+ 0x08001A, 0x000C15, 0x010984, 0x341386,
+ 0x000020, 0x1A0007, 0x0002ED, 0x008040,
+ 0x620007, 0x00306D, 0x028042, 0x0A804A,
+ 0x000820, 0x0A804A, 0x000606, 0x10804A,
+ 0x000007, 0x282512, 0x001F32, 0x05D2F4,
+ 0x54D104, 0x00735C, 0x000786, 0x000007,
+ 0x0C0007, 0x0A0007, 0x1C0007, 0x003465,
+ 0x020040, 0x004820, 0x025060, 0x40000A,
+ 0x024060, 0x000040, 0x454944, 0x000007,
+ 0x004020, 0x003AE5, 0x000040, 0x0028E5,
+ 0x000042, 0x48000A, 0x004904, 0x39F886,
+ 0x002C65, 0x000042, 0x40000A, 0x0000D5,
+ 0x454104, 0x000007, 0x000655, 0x054504,
+ 0x368286, 0x0001D5, 0x054504, 0x368086,
+ 0x002B65, 0x000042, 0x003AE5, 0x50004A,
+ 0x40000A, 0x45C3D4, 0x000007, 0x454504,
+ 0x000007, 0x0000CD, 0x444944, 0x000007,
+ 0x454504, 0x000007, 0x00014D, 0x554944,
+ 0x000007, 0x045144, 0x367986, 0x002C65,
+ 0x000042, 0x48000A, 0x4CD104, 0x000007,
+ 0x04C144, 0x368386, 0x000007, 0x160007,
+ 0x002CE5, 0x040042, 0x40000A, 0x004020,
+ 0x000040, 0x002965, 0x000042, 0x40000A,
+ 0x004104, 0x36F086, 0x000007, 0x002402,
+ 0x383206, 0x005C02, 0x0025E5, 0x000042,
+ 0x40000A, 0x004274, 0x002AE5, 0x000042,
+ 0x40000A, 0x004274, 0x500112, 0x0029E5,
+ 0x000042, 0x40000A, 0x004234, 0x454104,
+ 0x000007, 0x004020, 0x000040, 0x003EE5,
+ 0x000020, 0x000040, 0x002DE5, 0x400152,
+ 0x50000A, 0x045144, 0x37DA86, 0x0000C5,
+ 0x003EE5, 0x004020, 0x000040, 0x002BE5,
+ 0x000042, 0x40000A, 0x404254, 0x000007,
+ 0x002AE5, 0x004020, 0x000040, 0x500132,
+ 0x040134, 0x005674, 0x0029E5, 0x020042,
+ 0x42000A, 0x000042, 0x50000A, 0x05417C,
+ 0x0028E5, 0x000042, 0x48000A, 0x0000C5,
+ 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5,
+ 0x020042, 0x40004A, 0x50000A, 0x00423C,
+ 0x00567C, 0x0028E5, 0x004820, 0x000040,
+ 0x281D12, 0x282512, 0x001F72, 0x002965,
+ 0x000042, 0x40000A, 0x004104, 0x393A86,
+ 0x0E0007, 0x160007, 0x1E0007, 0x003EE5,
+ 0x000042, 0x40000A, 0x004104, 0x397886,
+ 0x002D65, 0x000042, 0x28340A, 0x003465,
+ 0x020042, 0x42004A, 0x004020, 0x4A004A,
+ 0x50004A, 0x05D2F4, 0x54D104, 0x00735C,
+ 0x39E186, 0x000007, 0x000606, 0x080007,
+ 0x0C0007, 0x080007, 0x0A0007, 0x0001E5,
+ 0x020045, 0x004020, 0x000060, 0x000365,
+ 0x000040, 0x002E65, 0x001A20, 0x0A1A60,
+ 0x000040, 0x003465, 0x020042, 0x42004A,
+ 0x004020, 0x4A004A, 0x000606, 0x50004A,
+ 0x0017FD, 0x018042, 0x08000A, 0x000904,
+ 0x225A86, 0x000007, 0x00107D, 0x018042,
+ 0x0011FD, 0x33804A, 0x19804A, 0x20000A,
+ 0x000095, 0x2A1144, 0x01A144, 0x3B9086,
+ 0x00040D, 0x00B184, 0x3B9186, 0x0018FD,
+ 0x018042, 0x0010FD, 0x09804A, 0x38000A,
+ 0x000095, 0x010924, 0x003A64, 0x3B8186,
+ 0x000007, 0x003904, 0x3B9286, 0x000007,
+ 0x3B9A06, 0x00000D, 0x00008D, 0x000820,
+ 0x00387D, 0x018040, 0x700002, 0x00117D,
+ 0x018042, 0x00197D, 0x29804A, 0x30000A,
+ 0x380002, 0x003124, 0x000424, 0x000424,
+ 0x002A24, 0x280502, 0x00068D, 0x000810,
+ 0x28143A, 0x00750D, 0x00B124, 0x002264,
+ 0x3D0386, 0x284402, 0x000810, 0x280C3A,
+ 0x0B800D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00758D, 0x00B124, 0x100102,
+ 0x012144, 0x3E4986, 0x001810, 0x10003A,
+ 0x00387D, 0x018042, 0x08000A, 0x000904,
+ 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD,
+ 0x00008D, 0x023164, 0x000A64, 0x280D02,
+ 0x0B808D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00387D, 0x018042, 0x08000A,
+ 0x000904, 0x3E3286, 0x030000, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x3D8286,
+ 0x000007, 0x002810, 0x28043A, 0x00750D,
+ 0x030924, 0x002264, 0x280D02, 0x02316C,
+ 0x28450A, 0x0B810D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x00008D, 0x000A24,
+ 0x3E4A06, 0x100102, 0x001810, 0x10003A,
+ 0x0000BD, 0x003810, 0x30043A, 0x00187D,
+ 0x018042, 0x0018FD, 0x09804A, 0x20000A,
+ 0x0000AD, 0x028924, 0x07212C, 0x001010,
+ 0x300583, 0x300D8B, 0x3014BB, 0x301C83,
+ 0x002083, 0x00137D, 0x038042, 0x33844A,
+ 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB,
+ 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083,
+ 0x001E0D, 0x0005FD, 0x018042, 0x20000A,
+ 0x020924, 0x00068D, 0x00A96C, 0x00009D,
+ 0x0002FD, 0x018042, 0x08000A, 0x000904,
+ 0x3F6A86, 0x000007, 0x280502, 0x280D0A,
+ 0x284402, 0x001810, 0x28143A, 0x0C008D,
+ 0x000820, 0x0002FD, 0x018040, 0x220007,
+ 0x003904, 0x225886, 0x001E0D, 0x00057D,
+ 0x018042, 0x20000A, 0x020924, 0x0000A5,
+ 0x0002FD, 0x018042, 0x08000A, 0x000904,
+ 0x402A86, 0x000007, 0x280502, 0x280C02,
+ 0x002010, 0x28143A, 0x0C010D, 0x000820,
+ 0x0002FD, 0x018040, 0x225A06, 0x220007,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000
+};
+
+#define PLAY_TABLE_SIZE 0x200
+#define DMA_BUFF_SIZE 0x2000
+#define RIGHT 0
+#define LEFT 1
+
+typedef struct
+{
+ unsigned int *table;
+}
+PLAY_CNTRL_TABLE;
+
+
+typedef struct
+{
+ unsigned int Format;
+ unsigned int LoopDefault;
+ unsigned int PgBase;
+ unsigned int PgLoop;
+ unsigned int PgLoopEnd;
+ unsigned int PgLoopFrac;
+ unsigned int PgDeltaEnd;
+ unsigned int LpfKEnd;
+ unsigned int EgGainEnd;
+ unsigned int LchGainEnd;
+ unsigned int RchGainEnd;
+ unsigned int Effect1GainEnd;
+ unsigned int Effect2GainEnd;
+ unsigned int Effect3GainEnd;
+ unsigned int LpfQ;
+ unsigned int Status;
+ unsigned int NumOfFrames;
+ unsigned int LoopCount;
+ unsigned int PgStart;
+ unsigned int PgStartFrac;
+ unsigned int PgDelta;
+ unsigned int LpfK;
+ unsigned int EgGain;
+ unsigned int LchGain;
+ unsigned int RchGain;
+ unsigned int Effect1Gain;
+ unsigned int Effect2Gain;
+ unsigned int Effect3Gain;
+ unsigned int LpfDelay1;
+ unsigned int LpfDelay2;
+}
+PLAY_BANK;
+
+typedef struct
+{
+ unsigned int PgBase;
+ unsigned int PgLoopEndAdr;
+ unsigned int PgStartAdr;
+ unsigned int NumOfLoops;
+}
+REC_BANK;
+
+typedef struct
+{
+ unsigned int PgBase;
+ unsigned int PgLoopEnd;
+ unsigned int PgStart;
+ unsigned int Temp;
+
+}
+EFFECT_BANK;
+
+typedef struct
+{
+ PLAY_BANK *bank1;
+ PLAY_BANK *bank2;
+}
+PLAY_CNTRL_SLOT;
+
+typedef struct
+{
+ oss_native_word base;
+ REC_BANK *bank1;
+ REC_BANK *bank2;
+ REC_BANK *bank3;
+ REC_BANK *bank4;
+}
+REC_CNTRL_SLOT;
+
+typedef struct
+{
+ oss_native_word base;
+ EFFECT_BANK *bank1;
+ EFFECT_BANK *bank2;
+ EFFECT_BANK *bank3;
+ EFFECT_BANK *bank4;
+ EFFECT_BANK *bank5;
+ EFFECT_BANK *bank6;
+ EFFECT_BANK *bank7;
+ EFFECT_BANK *bank8;
+ EFFECT_BANK *bank9;
+ EFFECT_BANK *bank10;
+}
+EFFECT_CNTRL_SLOT;
diff --git a/kernel/drv/osscore/.config b/kernel/drv/osscore/.config
new file mode 100644
index 0000000..95833c8
--- /dev/null
+++ b/kernel/drv/osscore/.config
@@ -0,0 +1,2 @@
+bus=VIRTUAL
+targetos=SunOS
diff --git a/kernel/drv/osscore/.devices b/kernel/drv/osscore/.devices
new file mode 100644
index 0000000..c435d26
--- /dev/null
+++ b/kernel/drv/osscore/.devices
@@ -0,0 +1 @@
+osscore OSSCORE OSS Core services
diff --git a/kernel/drv/osscore/.name b/kernel/drv/osscore/.name
new file mode 100644
index 0000000..8d69ed6
--- /dev/null
+++ b/kernel/drv/osscore/.name
@@ -0,0 +1 @@
+OSS Core services
diff --git a/kernel/drv/osscore/.params b/kernel/drv/osscore/.params
new file mode 100644
index 0000000..62e4af5
--- /dev/null
+++ b/kernel/drv/osscore/.params
@@ -0,0 +1,133 @@
+int detect_trace=0;
+/*
+ * Detect Trace will trace the audio device detection and operation. However
+ * this feature should only be enabled when requested by the technical support
+ * personnell.
+ */
+int max_intrate=100;
+/*
+ * Max intrate sets up the maximum number of interrupts/second. This
+ * in turn sets up the minimum buffer fragment size. The default value is 100
+ * It equals to about 50 fps frame rate which should be good for most
+ * applications (including games). However some special applications
+ * may require lower latencies. In such cases a higher value such as 500 or 1000
+ * may be needed. The minimum latency will be roughly 2/max_intrate
+ * seconds. However the exactl latency depends on what the application has
+ * requested using ioctl(SNDCTL_DSP_SETFRAGMENT). A value of zero means
+ * OSS doesn't try to limit interrupt rate.
+ *
+ * Lower latencies require higher interrupt rates which in turn causes higher
+ * system overhead. In addition using max_intrate values higher than system's
+ * internal clock rate (HZ) may not make any actual improvement.
+ *
+ * Some devices use fixed fragment size and this parameter will not have any
+ * effect with them. For example the Digi32 and Digi96 devices work in this way.
+ */
+int src_quality=3;
+/*
+ * The src_quality setting defines the precision of the software based sample
+ * rate conversion algorithm used by OSS. This setting doesn't affect possible
+ * hardware level conversions done by the devices themselves. Using higher
+ * quality setting gives better quality while lower settings consume less
+ * CPU time.
+ *
+ * Possible values are:
+ * 0 - D lowest quality (normally equals to 1=low quality)
+ * 1 - L low quality (spline interpolation)
+ * 2 - M medium quality (lagrange interpolation)
+ * 3 - H high quality (DEFAULT)
+ * 4 - HX high quality (high quality with extra precision)
+ * 5 - P production quality
+ * 6 - PX production quality (prod quality with extra precision)
+ */
+int ac97_amplifier=-1;
+/*
+ * When set to 1 this option enables the speaker power amplifier feature of
+ * AC97 codec (if available). Some boards have this inverted, so if necessary
+ * this feature can be disabled by setting this option to 0.
+ * Affects all AC97 based audio devices in the system.
+ * Default: -1=autodetect correct setting.
+ */
+int ac97_recselect=0;
+/*
+ * When set to 1 this option enables independent recording source
+ * selection for the left and the right channel on AC97 devices. In this way
+ * it's possible to record audio streams so that (for example) the left
+ * channel signal comes from the microphone and the right channel signal from
+ * line-in. However when this option is enabled it's only possible to
+ * select the recording source by using a fully OSS 4.0 compatible mixer
+ * program such as ossxmix.
+ */
+int cooked_enable=1;
+/*
+ * By default OSS will let applications to use sampling rates and formats
+ * that are not supported by the hardware. Instead OSS performs the necessary
+ * format conversions in software. Applications that don't tolerate this kind
+ * of conversions usually disable them by using features of the OSS API
+ * (SNDCTL_DSP_COOKEDMODE). If this option is set to 0 then the format
+ * conversions will be disabled for all applications and devices unless the
+ * application explicitly enables them. This option should not be changed
+ * without wery strong reason.
+ */
+int dma_buffsize=0;
+/*
+ * By default OSS will allocate audio DMA buffers with some system dependent
+ * default size (usually 64k but sometimes smaller). It is possible to change
+ * this default allocation by setting this option. Value of 0 means that the
+ * default size will be used. Value between 16 and 128 (kilobytes) can be used
+ * if the default size is not suitable for some reason. This option must not be
+ * changed unless it's absolutely necessary.
+ */
+int flat_device_model=0;
+/*
+ * OSS version 4.0 and later use two level device model where multiple audio
+ * engines supported by the device (hardware mixing or vmix) are hidden behind
+ * the same device file. When this device file is opened OSS will connect the
+ * application to the first available subdevice. In this way multiple
+ * applications can use the same device file at the same time.
+ *
+ * If this option is set to 0 OSS will use the earlier (OSS 3.x) device scheme
+ * where all devices are directly visible to the applications. This may be
+ * necessary with some custom applications that depend on the old
+ * behaviour.
+ */
+int vmix_disabled=0;
+/*
+ * The virtual mixer subsystem can be disabled by setting this configuration
+ * option to 1. By default the value is 0 which enables virtual mixer.
+ */
+int vmix_loopdevs=0;
+/*
+ * Optionally the virtual mixer subsystem can create special loopback audio
+ * devices that can be used to record the output mix sent to the device.
+ * This option tells how many loopback devices will be created (0, 1 or 2).
+ * If there are multiple audio devices in the system the all of them will have
+ * the same number of loopback devices. This setting should be left to 0 unless
+ * there are specific reasons to enable the loopback devices.
+ */
+int vmix_no_autoattach=0;
+/*
+ * By default (0) the low level drivers for most sound cards will automatically
+ * attach virtual mixer (vmix) to the primary audio devices of the cards.
+ * In some situations it may be necessary to attach virtual mixer using
+ * nonstandard parameters. If vmix_no_autoattach is set to 1 then user
+ * can use vmixctl attach command to attach virtual mixer manually to
+ * the device(s).
+ */
+int excl_policy=0;
+/*
+ * By default the O_EXCL open() flag can be used to bypass the virtual mixer.
+ * Setting excl_policy to 1 or 2 makes OSS ignore O_EXCL. A setting of 1
+ * ignores O_EXCL from all but root processes, while a setting of 2 always
+ * ignores O_EXCL.
+ */
+int mixer_muted=0;
+/*
+ * By default mixer volume controls will be set to audible levels
+ * when OSS drivers are loaded. However in some systems it may
+ * be necessary to default to lower levels to avoid feedback or
+ * noise. Set mixer_muted to 1 to use low default levels and to
+ * 0 to select audible levels.
+ *
+ * Note that just few OSS drivers support this option.
+ */
diff --git a/kernel/drv/osscore/osscore.c b/kernel/drv/osscore/osscore.c
new file mode 100644
index 0000000..30ee133
--- /dev/null
+++ b/kernel/drv/osscore/osscore.c
@@ -0,0 +1,39 @@
+/*
+ * Purpose: OSS core pseudo driver (for Solaris)
+ *
+ * The osscore driver is used under Solaris to load the configuration settings
+ * (osscore.conf) and to install the /dev/sndstat device.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "osscore_cfg.h"
+
+int
+osscore_attach (oss_device_t * osdev)
+{
+ oss_register_device (osdev, "OSS common devices");
+ install_sndstat (osdev);
+ install_dev_mixer (osdev);
+ return 1;
+}
+
+int
+osscore_detach (oss_device_t * osdev)
+{
+ if (oss_disable_device (osdev) < 0)
+ return 0;
+
+ oss_unregister_device (osdev);
+
+ return 1;
+}
diff --git a/kernel/drv/osscore/osscore.man b/kernel/drv/osscore/osscore.man
new file mode 100644
index 0000000..5af4ca2
--- /dev/null
+++ b/kernel/drv/osscore/osscore.man
@@ -0,0 +1,86 @@
+NAME
+osscore - Open Sound Sytem core audio framework.
+
+DESCRIPTION
+Open Sound System core audio support psudo driver. This driver implements the core Open Sound System API for audio, midi, mixer and synth functions. This driver also implements the OS driver interface as well as device configuration and setup.
+More information on programming on the OSS API is avaialable at:
+http://manuals.opensound.com/
+
+OPTIONS
+o ac97_recselect When set to 1 this option enables independent
+ recording source selection for the left and the right channel
+ on AC97 devices. In this way it's possible to record audio
+ streams so that (for example) the left channel signal comes
+ from the microphone and
+ the right channel signal from line-in. However when this
+ option is enabled it's only possible to select the recording
+ source by using a fully OSS 4.0 compatible mixer program such
+ as ossxmix.
+ Default: 0 - recording source is common to both channels.
+o ac97_amplifier When set to 1 this option enables the speaker power
+ amplifier feature of AC97 codec (if available).
+ Some boards have this inverted, so this feature can be
+ disabled by setting this option to 0.
+ Affects all AC97 based audio devices in the system.
+ Default: -1=autodetect correct setting.
+o cooked_enable By default OSS will let applications to use sampling
+ rates and formats that are not supported by the hardware.
+ Instead OSS performs the necessary format conversions in
+ software. Applications that don't tolerate this kind of
+ conversions usually disable them by using features of the OSS
+ API (SNDCTL_DSP_COOKEDMODE). If this option is set to 0 then
+ the format conversions will be disabled for all applications
+ and devices unless the application explicitly enables them.
+ Default: 1 - conversions are enabled.
+ This option should not be changed without very strong reasons.
+o detect_trace Internal debugging (do not change). Default: 0
+o dma_buffsize By default OSS will allocate audio DMA buffers with some
+ system dependent default size (usually 64k but sometimes
+ smaller). It is possible to change this default allocation by
+ setting this option. Value of 0 means that the default size
+ will be used. Value between 16 and 128 (kilobytes) can be used
+ if the default size is not suitable for some reason.
+ Default: 0 - system dependent buffsize.
+ This option mustn't be changed unless it's absolutely necessary.
+o max_intrate Set the maximum number of interrupts per second.
+ A value of 0 means the number is unlimited.
+ Default: 100 interrupts per second which equals to about
+ 10 msec minimum latencies.
+o vmix_disabled The virtual mixer subsystem can be disabled by setting
+ this configuration option to 1.
+ Default: 0 - virtual mixer is enabled.
+o vmix_loopdevs Optionally the virtual mixer subsystem can create
+ special loopback audio devices that can be used to record the
+ output mix sent to the device. This option tells how many
+ loopback devices will be created (0, 1 or 2). If there are
+ multiple audio devices in the system the all of them will have
+ the same number of loopback devices.
+ Default: 0 - no loopback devices are created.
+ This setting should be left to 0 unless there are specific
+ reasons to enable the loopback devices.
+o vmix_no_autoattach By default (0) the low level
+ drivers for most sound cards will automatically
+ attach virtual mixer (vmix) to the primary audio devices of the cards.
+ In some situations it may be necessary to attach virtual mixer using
+ nonstandard parameters. If vmix_no_autoattach is set to 1 then user
+ can use vmixctl attach command to attach virtual mixer manually to
+ the device(s).
+ Default: 0 - Automatically attach virtual mixer.
+o excl_policy The O_EXCL open() flag can be used by programs to bypass the
+ virtual mixer. Setting excl_policy to 1 or 2 makes OSS ignore O_EXCL.
+ A setting of 1 ignores O_EXCL from all but root processes,
+ while a setting of 2 always ignores O_EXCL.
+ Default: 0 - Do not ignore O_EXCL.
+o mixer_muted By default OSS will set most volume controls to audible level.
+ If this causes problems then it's possible to ask OSS to set
+ the levels to zero when the drivers are loaded. However the
+ levels saved with the savemixer utility will get loaded few
+ moments later when all OSS drivers have been started. Note that
+ just some of the OSS drivers honor this setting.
+ Values: 0 (default) - Use audible volumes, 1 - Set volumes to low.
+
+FILES
+CONFIGFILEPATH/osscore.conf Device configuration file
+
+AUTHOR
+4Front Technologies
diff --git a/kernel/framework/.config b/kernel/framework/.config
new file mode 100644
index 0000000..e44f78f
--- /dev/null
+++ b/kernel/framework/.config
@@ -0,0 +1 @@
+targetcpu=any
diff --git a/kernel/framework/ac97/.config b/kernel/framework/ac97/.config
new file mode 100644
index 0000000..e44f78f
--- /dev/null
+++ b/kernel/framework/ac97/.config
@@ -0,0 +1 @@
+targetcpu=any
diff --git a/kernel/framework/ac97/.params b/kernel/framework/ac97/.params
new file mode 100644
index 0000000..93a4f87
--- /dev/null
+++ b/kernel/framework/ac97/.params
@@ -0,0 +1,20 @@
+int ac97_amplifier=-1;
+/*
+ * AC97 codecs have a control output for an external audio output amplifier
+ * (necessary in some situations such as laptops). In some cases there may be
+ * need to turn this amplifier off.
+ *
+ * ac97_amplifier=-1 enables autodetection (default).
+ * ac97_amplifier=1 always enables the output amplifier stage.
+ * ac97_amplifier=0 disables it.
+ */
+
+int ac97_recselect=0;
+/*
+ * AC97 codecs support separate recording source selections for left and
+ * right channels. This feature can be enabled but that may cause some
+ * compatibility problems with certain applications.
+ *
+ * ac97_recselect=0 (default) selects common source selection for both channels.
+ * ac97_recselect=1 enables independent source selections.
+ */
diff --git a/kernel/framework/ac97/ac97_ext.inc b/kernel/framework/ac97/ac97_ext.inc
new file mode 100644
index 0000000..425dee7
--- /dev/null
+++ b/kernel/framework/ac97/ac97_ext.inc
@@ -0,0 +1,1453 @@
+
+/*
+ *
+ * Purpose: AC97 chip specific Mixer extension handlers
+ *
+ * This file is included from ac97.c and it implements codec specific
+ * extensions such as S/PDIF control.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+extern int ac97_recselect;
+
+void
+ac97_enable_spdif (ac97_devc * devc)
+{
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ codec_write (devc, 0x68, codec_read (devc, 0x68) | 0x8000);
+ break;
+ case CX_SPDIFOUT:
+ codec_write (devc, 0x5c, codec_read (devc, 0x5c) | 0x08);
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ codec_write (devc, 0x2a,
+ (codec_read (devc, 0x2a) & 0xffc3) | 0x4 | devc->
+ spdif_slot);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+ac97_disable_spdif (ac97_devc * devc)
+{
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ codec_write (devc, 0x68, codec_read (devc, 0x68) & ~0x8000);
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ codec_write (devc, 0x2a, (codec_read (devc, 0x2a) & 0xffc3) & ~0x4);
+ break;
+ case CX_SPDIFOUT:
+ codec_write (devc, 0x5c, codec_read (devc, 0x5c) & ~0x8);
+ break;
+ default:
+ break;
+ }
+}
+
+/********************AC97 SPDIFIN Control *************************/
+int
+ac97_spdifin_ctl (int dev, int ctrl, unsigned int cmd, int value)
+{
+ ac97_devc *devc = mixer_devs[dev]->devc;
+
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case SPDIFIN_ENABLE: /* Enable/disable SPDIF IN */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x7A) & 0x8000) ? 1 : 0;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x6c) & 0x1) ? 1 : 0;
+ break;
+ case SPDIFIN_PRO: /* Pro */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x60) & 0x1) ? 1 : 0;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x68) & 0x1) ? 1 : 0;
+ break;
+ case SPDIFIN_AUDIO: /* /Audio */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x60) & 0x2) ? 1 : 0;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x68) & 0x1) ? 1 : 0;
+ break;
+ case SPDIFIN_COPY: /* Copy */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x60) & 0x4) ? 1 : 0;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x68) & 0x4) ? 1 : 0;
+ break;
+ case SPDIFIN_PREEMPH: /* Pre */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x60) & 0x38) >> 3;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x68) & 0x38) >> 3;
+ break;
+ case SPDIFIN_MODE: /* Mode */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x60) & 0xc0) ? 1 : 0;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x68) & 0xc0) ? 1 : 0;
+ break;
+ case SPDIFIN_CATEGORY: /* Category */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x60) & 0x7f00) >> 8;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x68) & 0x7f00) >> 8;
+ break;
+ case SPDIFIN_GENERATION: /* Level */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x60) & 0x8000) ? 1 : 0;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x68) & 0x8000) ? 1 : 0;
+ break;
+ case SPDIFIN_SOURCE: /* Source */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = codec_read (devc, 0x62) & 0xf;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = codec_read (devc, 0x6a) & 0xf;
+ break;
+ case SPDIFIN_CHAN: /* Channel */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x62) & 0xf0) >> 4;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x6a) & 0xf0) >> 4;
+ break;
+ case SPDIFIN_RATE: /* Sampling Rate */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x62) & 0xf00) >> 8;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x6a) & 0xf00) >> 8;
+ switch (value)
+ {
+ case 0:
+ value = 44100;
+ break;
+ case 2:
+ value = 48000;
+ break;
+ case 3:
+ value = 32000;
+ break;
+ }
+ break;
+ case SPDIFIN_CLOCK: /* Clock Accuracy */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x62) & 0x3000) >> 12;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = (codec_read (devc, 0x6a) & 0x3000) >> 12;
+ break;
+ case SPDIFIN_SIGNAL: /* Lock */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x62) & 0x4000) ? 1 : 0;
+ break;
+ case SPDIFIN_VBIT: /* VBit */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = (codec_read (devc, 0x62) & 0x8000) ? 1 : 0;
+ break;
+
+ case SPDIFIN_MON: /* SPDIF Input Mon */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ value = codec_read (devc, 0x6A) & (1 << 13) ? 1 : 0;
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ value = codec_read (devc, 0x6c) & 0x8 ? 1 : 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case SPDIFIN_ENABLE: /* SPDIF Record Enable */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ {
+ if (value)
+ {
+ /* Set 0x7a enable SPDIF Input */
+ /* set 0x6a: PCM Input from SPDIFIN */
+ codec_write (devc, 0x7a, codec_read (devc, 0x7a) | 0x2);
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | 0x8000);
+ }
+ else
+ {
+ codec_write (devc, 0x7a, codec_read (devc, 0x7a) & ~0x2);
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) & ~0x8000);
+ }
+ }
+
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ {
+ if (value)
+ {
+ codec_write (devc, 0x6c, codec_read (devc, 0x6c) | 1);
+ codec_write (devc, 0x6c, codec_read (devc, 0x6c) | 0x10);
+ }
+ else
+ {
+ codec_write (devc, 0x6c, codec_read (devc, 0x6c) & ~1);
+ codec_write (devc, 0x6c, codec_read (devc, 0x6c) & ~0x10);
+ }
+ }
+ break;
+
+ case SPDIFIN_MON: /* SPDIF input monitor on analog DAC */
+ if (devc->spdifin_support == ALC_SPDIFIN)
+ {
+ if (value)
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | (1 << 13));
+ else
+ codec_write (devc, 0x6a,
+ codec_read (devc, 0x6a) & ~(1 << 13));
+ }
+
+ if (devc->spdifin_support == CMI_SPDIFIN)
+ {
+ if (value)
+ codec_write (devc, 0x6c, codec_read (devc, 0x6c) | 0x8);
+ else
+ codec_write (devc, 0x6c, codec_read (devc, 0x6c) & ~0x8);
+ }
+ break;
+
+ }
+ }
+ return value;
+}
+
+static int
+spdifin_ext_init (int dev)
+{
+ int group, err;
+
+ if ((group = mixer_ext_create_group_flags (dev, 0, "SPDIN", MIXF_FLAT)) < 0)
+ return group;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_ENABLE, ac97_spdifin_ctl,
+ MIXT_ONOFF, "SPDIN_Enable", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_MON, ac97_spdifin_ctl,
+ MIXT_ONOFF, "SPDIN_Monitor", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+#if 1
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_PRO, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_Pro", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_AUDIO, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_Audio", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_COPY, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_Copy", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_PREEMPH,
+ ac97_spdifin_ctl, MIXT_VALUE,
+ "SPDIN_Pre-emph", 1, MIXF_READABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_MODE, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_Mode", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_CATEGORY,
+ ac97_spdifin_ctl, MIXT_VALUE,
+ "SPDIN_CATEGORY", 1, MIXF_READABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_GENERATION,
+ ac97_spdifin_ctl, MIXT_VALUE,
+ "SPDIN_GenLevel", 1, MIXF_READABLE)) < 0)
+ return err;
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_SOURCE, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_Source", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_CHAN, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_Channel", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_RATE, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_Rate", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_CLOCK, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_Clock", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_SIGNAL, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_Signal", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFIN_VBIT, ac97_spdifin_ctl,
+ MIXT_VALUE, "SPDIN_VBit", 1,
+ MIXF_READABLE)) < 0)
+ return err;
+#endif
+ return 0;
+}
+
+/********************AC97 SPDIFOUT Control *************************/
+int
+ac97_spdifout_ctl (int dev, int ctrl, unsigned int cmd, int value)
+{
+ int tmp = 0;
+ static int flag;
+ ac97_devc *devc = mixer_devs[dev]->devc;
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case SPDIFOUT_ENABLE: /* SPDIF OUT */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ value = (codec_read (devc, 0x68) & 0x8000) ? 1 : 0;
+ break;
+ case CX_SPDIFOUT:
+ value = (codec_read (devc, 0x5c) & 0x08) ? 1 : 0;
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ value = (codec_read (devc, 0x2a) & 0x4) ? 1 : 0;
+ break;
+ }
+ break;
+
+ case SPDIFOUT_PRO: /* Consumer/PRO */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ value = (codec_read (devc, 0x68) & 0x1) ? 1 : 0;
+ break;
+ case CX_SPDIFOUT:
+ value = (codec_read (devc, 0x5c) & 0x1) ? 1 : 0;
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ value = (codec_read (devc, 0x3a) & 0x1) ? 1 : 0;
+ break;
+ }
+ break;
+
+ case SPDIFOUT_AUDIO: /* PCM/AC3 */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ value = (codec_read (devc, 0x68) & 0x2) ? 1 : 0;
+ break;
+ case CX_SPDIFOUT:
+ value = (codec_read (devc, 0x5c) & 0x2) ? 1 : 0;
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ value = (codec_read (devc, 0x3a) & 0x2) ? 1 : 0;
+ break;
+ }
+ break;
+
+ case SPDIFOUT_COPY: /* Copy Prot */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ value = (codec_read (devc, 0x68) & 0x4) ? 1 : 0;
+ break;
+ case CX_SPDIFOUT:
+ value = (codec_read (devc, 0x5c) & 0x4) ? 1 : 0;
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ value = (codec_read (devc, 0x3a) & 0x4) ? 1 : 0;
+ break;
+ }
+ break;
+
+ case SPDIFOUT_PREEMPH: /* Pre emphasis */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ value = codec_read (devc, 0x68) & 0x8 ? 1 : 0;
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ value = (codec_read (devc, 0x3a) & 0x8) ? 1 : 0;
+ break;
+ }
+ break;
+
+ case SPDIFOUT_RATE: /* Sampling Rate */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ {
+ tmp = codec_read (devc, 0x68) & 0x1000;
+ switch (tmp)
+ {
+ case 0x1000:
+ value = 0;
+ break;
+ case 0x0000:
+ value = 1;
+ break;
+ default:
+ cmn_err (CE_NOTE, "unsupported SPDIF F/S rate\n");
+ break;
+ }
+
+ }
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ {
+ tmp = codec_read (devc, 0x3a) & 0x3000;
+ switch (tmp)
+ {
+ case 0x2000:
+ value = 0;
+ break;
+ case 0x0000:
+ value = 1;
+ break;
+ case 0x3000:
+ value = 2;
+ break;
+ default:
+ cmn_err (CE_NOTE, "unsupported SPDIF F/S rate\n");
+ value = 0;
+ break;
+ }
+ }
+ break;
+ }
+ break;
+
+ case SPDIFOUT_VBIT: /* V Bit */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ value = codec_read (devc, 0x68) & 0x4000 ? 1 : 0;
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ value = codec_read (devc, 0x3a) & 0x8000 ? 1 : 0;
+ break;
+ }
+ break;
+
+ case SPDIFOUT_ADC: /* Analog In to SPDIF Out */
+ switch (devc->spdifout_support)
+ {
+ case ALC_SPDIFOUT:
+ value = codec_read (devc, 0x6a) & (1 << 12) ? 1 : 0;
+ break;
+
+ case AD_SPDIFOUT:
+ value = codec_read (devc, 0x74) & 0x4 ? 1 : 0;
+ break;
+
+ case CS_SPDIFOUT:
+ value = codec_read (devc, 0x5e) & (1 << 11) ? 1 : 0;
+ break;
+
+ case STAC_SPDIFOUT:
+ value = codec_read (devc, 0x6a) & 0x2 ? 1 : 0;
+ break;
+
+ case YMF_SPDIFOUT:
+ value = codec_read (devc, 0x66) & 0x2 ? 1 : 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ ac97_disable_spdif (devc);
+ switch (ctrl)
+ {
+ case SPDIFOUT_ENABLE: /* Enable SPDIF OUT */
+ if (value)
+ {
+ ac97_enable_spdif (devc);
+ flag = 1;
+ }
+ else
+ {
+ ac97_disable_spdif (devc);
+ flag = 0;
+ }
+ break;
+
+ case SPDIFOUT_PRO: /* consumer/pro audio */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x68, codec_read (devc, 0x68) | 1);
+ else
+ codec_write (devc, 0x68, codec_read (devc, 0x68) & ~1);
+ break;
+ case CX_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x5c, codec_read (devc, 0x5c) | 1);
+ else
+ codec_write (devc, 0x5c, codec_read (devc, 0x5c) & ~1);
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) | 1);
+ else
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) & ~1);
+ break;
+ }
+ break;
+
+ case SPDIFOUT_AUDIO: /* PCM/AC3 */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x68, codec_read (devc, 0x68) | 0x2);
+ else
+ codec_write (devc, 0x68, codec_read (devc, 0x68) & ~2);
+ break;
+ case CX_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x5c, codec_read (devc, 0x5c) | 0x2);
+ else
+ codec_write (devc, 0x5c, codec_read (devc, 0x5c) & ~2);
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) | 0x2);
+ else
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) & ~2);
+ break;
+ }
+ break;
+
+ case SPDIFOUT_COPY: /* copy prot */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x68, codec_read (devc, 0x68) | 4);
+ else
+ codec_write (devc, 0x68, codec_read (devc, 0x68) & ~4);
+ break;
+ case CX_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x5c, codec_read (devc, 0x5c) | 4);
+ else
+ codec_write (devc, 0x5c, codec_read (devc, 0x5c) & ~4);
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) | 4);
+ else
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) & ~4);
+ break;
+ }
+ break;
+
+ case SPDIFOUT_PREEMPH: /* preemphasis */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x68, codec_read (devc, 0x68) | 8);
+ else
+ codec_write (devc, 0x68, codec_read (devc, 0x68) & ~8);
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) | 8);
+ else
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) & ~8);
+ break;
+ }
+ break;
+
+ case SPDIFOUT_RATE: /* Frequency */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ switch (value)
+ {
+ case 0:
+ codec_write (devc, 0x68,
+ (codec_read (devc, 0x68) & 0xEFFF) | 0x1000);
+ break;
+ case 1:
+ codec_write (devc, 0x68,
+ (codec_read (devc, 0x68) & 0xEFFF) | 0);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ switch (value)
+ {
+ case 0: /* 48000 */
+ codec_write (devc, 0x3a,
+ (codec_read (devc, 0x3a) & 0xcfff) | 0x2000);
+ break;
+ case 1: /* 44100 */
+ codec_write (devc, 0x3a,
+ (codec_read (devc, 0x3a) & 0xcfff) | 0x0);
+ break;
+ case 2: /* 32000 */
+ codec_write (devc, 0x3a,
+ (codec_read (devc, 0x3a) & 0xcfff) | 0x3000);
+ break;
+
+ default:
+ break;
+ }
+ break;
+ }
+ break;
+
+ case SPDIFOUT_VBIT: /* V Bit */
+ switch (devc->spdifout_support)
+ {
+ case CS_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x68, codec_read (devc, 0x68) | 0x4000);
+ else
+ codec_write (devc, 0x68, codec_read (devc, 0x68) & ~0x4000);
+ break;
+ case AD_SPDIFOUT:
+ case ALC_SPDIFOUT:
+ case VIA_SPDIFOUT:
+ case STAC_SPDIFOUT:
+ case CMI_SPDIFOUT:
+ case YMF_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) | 0x8000);
+ else
+ codec_write (devc, 0x3a, codec_read (devc, 0x3a) & ~0x8000);
+ break;
+ }
+ break;
+
+ case SPDIFOUT_ADC: /* Analog In to SPDIF Out */
+ switch (devc->spdifout_support)
+ {
+ case ALC_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | (1 << 12));
+ else
+ codec_write (devc, 0x6a,
+ codec_read (devc, 0x6a) & ~(1 << 12));
+ break;
+
+ case AD_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x74, codec_read (devc, 0x74) | 0x4);
+ else
+ codec_write (devc, 0x74, codec_read (devc, 0x74) & ~0x4);
+ break;
+
+ case CS_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x5e, codec_read (devc, 0x5e) | (1 << 11));
+ else
+ codec_write (devc, 0x5e,
+ codec_read (devc, 0x5e) & ~(1 << 11));
+ break;
+
+ case STAC_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | 0x2);
+ else
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) & ~0x2);
+ break;
+
+ case CMI_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x6c, codec_read (devc, 0x6c) | 0x2);
+ else
+ codec_write (devc, 0x6c, codec_read (devc, 0x6c) & ~0x2);
+ break;
+
+ case YMF_SPDIFOUT:
+ if (value)
+ codec_write (devc, 0x66, codec_read (devc, 0x66) | 0x2);
+ else
+ codec_write (devc, 0x66, codec_read (devc, 0x66) & ~0x2);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ if (flag)
+ ac97_enable_spdif (devc);
+ }
+
+ return value;
+}
+
+static int
+spdifout_ext_init (int dev)
+{
+ int group, err;
+ if ((group =
+ mixer_ext_create_group_flags (dev, 0, "SPDOUT", MIXF_FLAT)) < 0)
+ return group;
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFOUT_ENABLE,
+ ac97_spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_ENABLE", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFOUT_ADC,
+ ac97_spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_ADC/DAC", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFOUT_PRO,
+ ac97_spdifout_ctl, MIXT_ENUM,
+ "SPDOUT_Pro", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFOUT_AUDIO,
+ ac97_spdifout_ctl, MIXT_ENUM,
+ "SPDOUT_Audio", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFOUT_COPY,
+ ac97_spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_Copy", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFOUT_PREEMPH,
+ ac97_spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_Pre-emph", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFOUT_RATE,
+ ac97_spdifout_ctl, MIXT_ENUM,
+ "SPDOUT_Rate", 3,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPDIFOUT_VBIT,
+ ac97_spdifout_ctl, MIXT_ONOFF,
+ "SPDOUT_VBit", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ return 0;
+}
+
+/**********************Mixer Extensions ********************/
+int
+ac97_mixext_ctl (int dev, int ctrl, unsigned int cmd, int value)
+{
+ int left, right;
+ ac97_devc *devc = mixer_devs[dev]->devc;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ value = 0;
+ switch (ctrl)
+ {
+ case VOL_CENTER: /* Left line in to output connection */
+ value = devc->extmixlevels[CENTER_VOL]; /* LFE/Center */
+ break;
+
+ case VOL_REAR:
+ value = devc->extmixlevels[REAR_VOL]; /* Rear/Surround */
+ break;
+
+ case VOL_SIDE:
+ value = devc->extmixlevels[SIDE_VOL]; /* Side Surround */
+ break;
+
+ case REAR2LINE: /* Rear to Line In */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ value = (codec_read (devc, 0x6A) & 0x200) ? 1 : 0;
+ if (devc->mixer_ext == CMI9739_MIXER_EXT)
+ value = (codec_read (devc, 0x64) & 0x400) ? 1 : 0;
+ if (devc->mixer_ext == STAC9758_MIXER_EXT)
+ value = (codec_read (devc, 0x64) & 0x50) ? 1 : 0;
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ value = (codec_read (devc, 0x76) & (1 << 11)) ? 0 : 1;
+ break;
+
+ case CENTER2MIC: /* Center to Mic */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ value = (codec_read (devc, 0x6A) & 0x400) ? 1 : 0;
+ if (devc->mixer_ext == CMI9739_MIXER_EXT)
+ value = (codec_read (devc, 0x64) & 0x1000) ? 1 : 0;
+ if (devc->mixer_ext == STAC9758_MIXER_EXT)
+ value = (codec_read (devc, 0x64) & 0x0C) ? 1 : 0;
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ value = (codec_read (devc, 0x76) & (1 << 12)) ? 0 : 1;
+ break;
+
+ case SPREAD: /* Duplicate front on lfe/rear */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ value = (codec_read (devc, 0x6A) & 0x1) ? 1 : 0;
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ value = (codec_read (devc, 0x76) & 0x80) ? 1 : 0;
+ if (devc->mixer_ext == VIA1616_MIXER_EXT)
+ value = (codec_read (devc, 0x5a) & 0x8000) ? 1 : 0;
+ break;
+
+ case MICBOOST: /* 30db Mic boost */
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ value = (codec_read (devc, 0x76) & 0x2) ? 1 : 0;
+ if (devc->mixer_ext == CMI9739_MIXER_EXT)
+ value = (codec_read (devc, 0x64) & 0x1) ? 1 : 0;
+ break;
+
+ case DOWNMIX_LFE: /* Downmix LFE to Front */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ value = (codec_read (devc, 0x6A) & 0x4) ? 1 : 0;
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ value = (codec_read (devc, 0x76) & 0x100) ? 1 : 0;
+ if (devc->mixer_ext == VIA1616_MIXER_EXT)
+ value = (codec_read (devc, 0x5a) & 0x1000) ? 1 : 0;
+ break;
+
+ case DOWNMIX_REAR: /* Downmix Rear to Front */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ value = (codec_read (devc, 0x6A) & 0x2) ? 1 : 0;
+ if (devc->mixer_ext == VIA1616_MIXER_EXT)
+ value = (codec_read (devc, 0x5a) & 0x800) ? 1 : 0;
+ break;
+ }
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case VOL_CENTER: /* Center/LFE volume */
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ codec_write (devc, 0x66,
+ mix_scale (left, right, devc->centervol_bits));
+ devc->extmixlevels[CENTER_VOL] = value;
+ break;
+
+ case VOL_REAR: /* Rear/Surround volume */
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ codec_write (devc, 0x64,
+ mix_scale (left, right, devc->rearvol_bits));
+ devc->extmixlevels[REAR_VOL] = value;
+ break;
+
+ case VOL_SIDE: /* Side Surround volume */
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ if (devc->mixer_ext == CMI9780_MIXER_EXT)
+ codec_write (devc, 0x60,
+ mix_scale (left, right, devc->sidevol_bits));
+ devc->extmixlevels[SIDE_VOL] = value;
+ break;
+
+ case REAR2LINE: /* Surround to Line In */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | 0x200);
+ else
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) & ~0x200);
+ }
+
+ if ((devc->mixer_ext == CMI9739_MIXER_EXT)
+ || (devc->mixer_ext == CMI9780_MIXER_EXT))
+ {
+ if (value)
+ codec_write (devc, 0x64, codec_read (devc, 0x64) | 0x400);
+ else
+ codec_write (devc, 0x64, codec_read (devc, 0x64) & ~0x400);
+ }
+
+ if (devc->mixer_ext == STAC9758_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x64, codec_read (devc, 0x64) | 0x50);
+ else
+ codec_write (devc, 0x64, codec_read (devc, 0x64) & ~0x50);
+ }
+
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x76,
+ codec_read (devc, 0x76) & ~(1 << 11));
+ else
+ codec_write (devc, 0x76, codec_read (devc, 0x76) | (1 << 11));
+ }
+
+ break;
+
+ case CENTER2MIC: /* Center/LFE to Mic In */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | 0x400);
+ else
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) & ~0x400);
+ }
+
+ if ((devc->mixer_ext == CMI9739_MIXER_EXT)
+ || (devc->mixer_ext == CMI9780_MIXER_EXT))
+ {
+ if (value)
+ codec_write (devc, 0x64, codec_read (devc, 0x64) | 0x1000);
+ else
+ codec_write (devc, 0x64, codec_read (devc, 0x64) & ~0x1000);
+ }
+
+ if (devc->mixer_ext == STAC9758_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x64, codec_read (devc, 0x64) | 0xC);
+ else
+ codec_write (devc, 0x64, codec_read (devc, 0x64) & ~0xC);
+ }
+
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x76,
+ codec_read (devc, 0x76) & ~(1 << 12));
+ else
+ codec_write (devc, 0x76, codec_read (devc, 0x76) | (1 << 12));
+ }
+ break;
+
+ case SPREAD: /* 4 Speaker output - LF/RF duplicate on Rear */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ {
+ if (value)
+ {
+ /* enable Line-In jack to play Surround out */
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | 0x200);
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | 1);
+ }
+ else
+ {
+ /* disable Line-In jack to play Surround out */
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) & ~0x200);
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) & ~1);
+ }
+ }
+
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x76, codec_read (devc, 0x76) | 0x80);
+ else
+ codec_write (devc, 0x76, codec_read (devc, 0x76) & ~0x80);
+ }
+
+ if (devc->mixer_ext == VIA1616_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x5a, codec_read (devc, 0x5a) | 0x8000);
+ else
+ codec_write (devc, 0x5a, codec_read (devc, 0x5a) & ~0x8000);
+ }
+ break;
+
+ case MICBOOST:
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x76, codec_read (devc, 0x76) | 0x2);
+ else
+ codec_write (devc, 0x76, codec_read (devc, 0x76) & ~0x2);
+ }
+
+ if ((devc->mixer_ext == CMI9739_MIXER_EXT)
+ || (devc->mixer_ext == CMI9780_MIXER_EXT))
+ {
+ if (value)
+ codec_write (devc, 0x64, codec_read (devc, 0x64) | 0x1);
+ else
+ codec_write (devc, 0x64, codec_read (devc, 0x64) & ~0x1);
+ }
+ break;
+
+ case DOWNMIX_LFE: /* Downmix LFE to Front */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | 0x4);
+ else
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) & ~0x4);
+ }
+
+ if (devc->mixer_ext == AD1980_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x76, codec_read (devc, 0x76) | 0x300);
+ else
+ codec_write (devc, 0x76, codec_read (devc, 0x76) & ~0x300);
+ }
+
+ if (devc->mixer_ext == VIA1616_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x5a, codec_read (devc, 0x5a) | 0x1000);
+ else
+ codec_write (devc, 0x5a, codec_read (devc, 0x5a) & ~0x1000);
+ }
+ break;
+
+ case DOWNMIX_REAR: /* Downmix Rear to Front */
+ if (devc->mixer_ext == ALC650_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) | 0x2);
+ else
+ codec_write (devc, 0x6a, codec_read (devc, 0x6a) & ~0x2);
+ }
+
+ if (devc->mixer_ext == VIA1616_MIXER_EXT)
+ {
+ if (value)
+ codec_write (devc, 0x5a, codec_read (devc, 0x5a) | 0x800);
+ else
+ codec_write (devc, 0x5a, codec_read (devc, 0x5a) & ~0x800);
+ }
+ break;
+ }
+ }
+ return value;
+}
+
+static int
+ac97_micboost_ctl (int dev, int ctrl, unsigned int cmd, int value)
+{
+ ac97_devc *devc = mixer_devs[dev]->devc;
+ int tmp;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return !!devc->micboost;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ value = !!value;
+
+ tmp = codec_read (devc, 0x0e);
+
+ if (value)
+ devc->micboost = 0x40;
+ else
+ devc->micboost = 0x00;
+
+ codec_write (devc, 0x0e, (tmp & ~0x40) | devc->micboost);
+
+ return value;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+ac97_recselect_ctl (int dev, int ctrl, unsigned int cmd, int value)
+{
+ int tmp;
+ ac97_devc *devc = mixer_devs[dev]->devc;
+
+ if (ctrl < 0 || ctrl > 1)
+ return OSS_EINVAL;
+
+ tmp = codec_read (devc, 0x1a);
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return (tmp >> (ctrl * 8)) & 0x07;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ if (value < 0 || value > 7)
+ return OSS_EINVAL;
+
+ tmp &= ~(0x7 << (ctrl * 8));
+ tmp |= (value << (ctrl * 8));
+ codec_write (devc, 0x1a, tmp);
+ return value;
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+ac97_mixext_init (int dev)
+{
+ ac97_devc *devc = mixer_devs[dev]->devc;
+ unsigned int mixflags = 0;
+
+ int group, err, ctl;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, 0, 0,
+ ac97_micboost_ctl, MIXT_ONOFF,
+ "micboost", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+
+ if (ac97_recselect)
+ {
+ if ((group =
+ mixer_ext_create_group_flags (dev, 0, "AC97_RECSEL",
+ MIXF_FLAT)) < 0)
+ return group;
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, 1,
+ ac97_recselect_ctl, MIXT_ENUM,
+ "LEFT", 8,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl,
+ "MIC CD VIDEO AUX LINE STEREOMIX MONOMIX PHONE",
+ 0);
+
+ if ((ctl =
+ mixer_ext_create_control (dev, group, 0,
+ ac97_recselect_ctl, MIXT_ENUM,
+ "RIGHT", 8,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return ctl;
+ mixer_ext_set_strings (dev, ctl,
+ "MIC CD VIDEO AUX LINE STEREOMIX MONOMIX PHONE",
+ 0);
+ }
+
+/*
+ * Don't use flat groups with AC97 chips that have slider controls (ALC650 at this moment)
+ */
+ if (devc->mixer_ext != ALC650_MIXER_EXT)
+ mixflags = MIXF_FLAT;
+
+ if ((group =
+ mixer_ext_create_group_flags (dev, 0, "AC97_MIXEXT", mixflags)) < 0)
+ return group;
+
+ if ((devc->mixer_ext == ALC650_MIXER_EXT)
+ || (devc->mixer_ext == CMI9780_MIXER_EXT))
+ {
+ if ((err =
+ mixer_ext_create_control (dev, group, VOL_CENTER,
+ ac97_mixext_ctl, MIXT_STEREOSLIDER,
+ "CENTERVOL", 100,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ ac97_mixext_ctl (dev, VOL_CENTER, SNDCTL_MIX_WRITE, 100 | (100 << 8));
+
+ if ((err =
+ mixer_ext_create_control (dev, group, VOL_REAR, ac97_mixext_ctl,
+ MIXT_STEREOSLIDER, "REARVOL", 100,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ ac97_mixext_ctl (dev, VOL_REAR, SNDCTL_MIX_WRITE, 100 | (100 << 8));
+
+ if ((err =
+ mixer_ext_create_control (dev, group, VOL_SIDE, ac97_mixext_ctl,
+ MIXT_STEREOSLIDER, "SIDEVOL", 100,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ ac97_mixext_ctl (dev, VOL_SIDE, SNDCTL_MIX_WRITE, 100 | (100 << 8));
+ }
+
+
+ if ((devc->mixer_ext == CMI9739_MIXER_EXT)
+ || (devc->mixer_ext == CMI9780_MIXER_EXT)
+ || (devc->mixer_ext == ALC650_MIXER_EXT)
+ || (devc->mixer_ext == AD1980_MIXER_EXT)
+ || (devc->mixer_ext == STAC9758_MIXER_EXT))
+ {
+ if ((err =
+ mixer_ext_create_control (dev, group, REAR2LINE,
+ ac97_mixext_ctl, MIXT_ONOFF,
+ "REAR2LINEJACK", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+
+ if ((devc->mixer_ext == CMI9739_MIXER_EXT)
+ || (devc->mixer_ext == CMI9780_MIXER_EXT)
+ || (devc->mixer_ext == ALC650_MIXER_EXT)
+ || (devc->mixer_ext == AD1980_MIXER_EXT)
+ || (devc->mixer_ext == STAC9758_MIXER_EXT))
+ {
+
+ if ((err =
+ mixer_ext_create_control (dev, group, CENTER2MIC,
+ ac97_mixext_ctl, MIXT_ONOFF,
+ "CENTER2MICJACK", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+
+ if ((devc->mixer_ext == AD1980_MIXER_EXT)
+ || (devc->mixer_ext == VIA1616_MIXER_EXT)
+ || (devc->mixer_ext == ALC650_MIXER_EXT))
+ {
+
+ if ((err =
+ mixer_ext_create_control (dev, group, SPREAD,
+ ac97_mixext_ctl, MIXT_ENUM,
+ "SPKMODE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+
+ if ((devc->mixer_ext == AD1980_MIXER_EXT)
+ || (devc->mixer_ext == VIA1616_MIXER_EXT)
+ || (devc->mixer_ext == ALC650_MIXER_EXT))
+ {
+ if ((err =
+ mixer_ext_create_control (dev, group, DOWNMIX_LFE,
+ ac97_mixext_ctl, MIXT_ONOFF,
+ "MIX-LFE2FRONT", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+
+ if ((devc->mixer_ext == VIA1616_MIXER_EXT)
+ || (devc->mixer_ext == ALC650_MIXER_EXT))
+ {
+ if ((err =
+ mixer_ext_create_control (dev, group, DOWNMIX_REAR,
+ ac97_mixext_ctl, MIXT_ONOFF,
+ "MIX-REAR2FRONT", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+
+ if ((devc->mixer_ext == AD1980_MIXER_EXT)
+ || (devc->mixer_ext == CMI9739_MIXER_EXT)
+ || (devc->mixer_ext == CMI9780_MIXER_EXT))
+ {
+ if ((err =
+ mixer_ext_create_control (dev, group, MICBOOST,
+ ac97_mixext_ctl, MIXT_ONOFF,
+ "MICBOOST", 1,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+ }
+ return 0;
+}
+
+/********************END of Mixer Extensions **************/
+
+/* AC97 Mixer Extensions */
+
+static int
+ac97mixer_ext_init (int dev)
+{
+ ac97_devc *devc = mixer_devs[dev]->devc;
+ int err;
+
+ if (devc->client_mixer_init != NULL)
+ if ((err = devc->client_mixer_init (dev)) < 0)
+ return err;
+
+ if ((devc->mixer_ext > 0) || ac97_recselect)
+ if ((err = ac97_mixext_init (dev)) < 0)
+ return err;
+
+ if (devc->spdifout_support)
+ if ((err = spdifout_ext_init (dev)) < 0)
+ return err;
+
+ if (devc->spdifin_support)
+ if ((err = spdifin_ext_init (dev)) < 0)
+ return err;
+ return 0;
+}
+
+void
+ac97_spdif_setup (int dev, int speed, int bits)
+{
+ int val;
+
+ val = ac97_spdifout_ctl (dev, SPDIFOUT_RATE, SNDCTL_MIX_READ, 0);
+
+ mixer_devs[dev]->modify_counter++;
+
+ switch (speed)
+ {
+ case 48000:
+ if (val != 0)
+ ac97_spdifout_ctl (dev, SPDIFOUT_RATE, SNDCTL_MIX_WRITE, 0);
+ break;
+
+ case 44100:
+ if (val != 1)
+ ac97_spdifout_ctl (dev, SPDIFOUT_RATE, SNDCTL_MIX_WRITE, 1);
+ break;
+
+ case 32000:
+ if (val != 2)
+ ac97_spdifout_ctl (dev, SPDIFOUT_RATE, SNDCTL_MIX_WRITE, 2);
+ break;
+
+ default:
+ break;
+ }
+
+ if (bits == AFMT_AC3)
+ ac97_spdifout_ctl (dev, SPDIFOUT_AUDIO, SNDCTL_MIX_WRITE, 1);
+ else
+ ac97_spdifout_ctl (dev, SPDIFOUT_AUDIO, SNDCTL_MIX_WRITE, 0);
+}
diff --git a/kernel/framework/ac97/oss_ac97.c b/kernel/framework/ac97/oss_ac97.c
new file mode 100644
index 0000000..8cab4e0
--- /dev/null
+++ b/kernel/framework/ac97/oss_ac97.c
@@ -0,0 +1,1228 @@
+/*
+ * Purpose: AC97 codec support library
+ *
+ * This source file contains common AC97 codec/mixer related code that is
+ * used by all drivers for AC97 based devices.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+
+#include "ac97.h"
+
+extern int ac97_amplifier; /* From oss_core_options.c */
+extern int ac97_recselect; /* From oss_core_options.c */
+
+/*
+ * LINE1 == AUX
+ */
+
+#define MIXER_DEVS (SOUND_MASK_LINE1 | SOUND_MASK_VIDEO | \
+ SOUND_MASK_MIC | SOUND_MASK_VOLUME | \
+ SOUND_MASK_LINE | SOUND_MASK_SPEAKER | \
+ SOUND_MASK_CD | SOUND_MASK_LINE | \
+ SOUND_MASK_PHONE | SOUND_MASK_MONO | \
+ SOUND_MASK_PCM | SOUND_MASK_IGAIN)
+
+#define EXTRA_DEVS (SOUND_MASK_REARVOL | SOUND_MASK_CENTERVOL | \
+ SOUND_MASK_SIDEVOL)
+
+#define REC_DEVS (SOUND_MASK_LINE1 | SOUND_MASK_MIC | \
+ SOUND_MASK_PHONE | SOUND_MASK_CD | \
+ SOUND_MASK_LINE | SOUND_MASK_VOLUME | \
+ SOUND_MASK_MONO | SOUND_MASK_VIDEO )
+
+#define STEREO_DEVS ((MIXER_DEVS|EXTRA_DEVS) & ~(SOUND_MASK_MIC| \
+ SOUND_MASK_SPEAKER|SOUND_MASK_BASS| \
+ SOUND_MASK_TREBLE | SOUND_MASK_MONO))
+
+
+static int default_mixer_levels[32] = {
+ 0x4b4b, /* Master Volume */
+ 0x3232, /* Bass */
+ 0x3232, /* Treble */
+ 0x4b4b, /* FM */
+ 0x4b4b, /* PCM */
+ 0x8000, /* PC Speaker */
+ 0x2020, /* Ext Line */
+ 0x0000, /* 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) */
+ 0x0101, /* Digital1 */
+ 0x0000, /* Digital2 */
+ 0x0000, /* Digital3 */
+ 0x0000, /* Phone In */
+ 0x4b4b, /* Mono/Phone out */
+ 0x0000, /* Video */
+ 0x0000, /* Radio */
+ 0x0000, /* Depth */
+ 0x4b4b, /* Rear */
+ 0x4b4b, /* Center */
+ 0x4b4b /* Surround */
+};
+
+static int nr_ac97 = 0;
+extern int ac97_amplifier, ac97_recselect;
+
+static unsigned short
+codec_read (ac97_devc * devc, int reg)
+{
+ return devc->read (devc->host_parms, reg) & 0xffff;
+}
+
+static int
+codec_write (ac97_devc * devc, int reg, unsigned short data)
+{
+ return devc->write (devc->host_parms, reg, data);
+}
+
+
+static int
+ac97_set_recmask (ac97_devc * devc, int pmask)
+{
+ int mask = pmask & devc->recmask;
+ int sel = 0;
+
+ mask = mask & (mask ^ devc->recdevs); /* Find out the changed bits */
+
+ if (!mask) /* No change */
+ return devc->recdevs;
+
+ devc->recdevs = mask;
+
+ switch (mask)
+ {
+ case SOUND_MASK_MIC:
+ sel = 0;
+ break;
+ case SOUND_MASK_CD:
+ sel = 1;
+ break;
+ case SOUND_MASK_VIDEO:
+ sel = 2;
+ break;
+ case SOUND_MASK_LINE1:
+ sel = 3;
+ break; /* AUX */
+ case SOUND_MASK_LINE:
+ sel = 4;
+ break;
+ case SOUND_MASK_VOLUME:
+ sel = 5;
+ break;
+ case SOUND_MASK_MONO:
+ sel = 6;
+ break;
+ case SOUND_MASK_PHONE:
+ sel = 7;
+ break;
+ default: /* Unknown choise. Default to mic */
+ devc->recdevs = SOUND_MASK_MIC;
+ sel = 0;
+ }
+ codec_write (devc, 0x1a, sel | (sel << 8));
+
+ return devc->levels[31] = devc->recdevs;
+}
+
+static int
+ac97_mixer_get (ac97_devc * devc, int dev)
+{
+ if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES)
+ return OSS_EINVAL;
+ if (!((1 << dev) & devc->devmask))
+ return OSS_EINVAL;
+ return devc->levels[dev];
+}
+
+static unsigned int
+mix_scale (int left, int right, int bits)
+{
+ int reverse = 0, mute = 0;
+
+ if (bits < 0)
+ {
+ bits = -bits;
+ reverse = 1;
+ }
+
+ if ((left | right) == 0) /* Mute */
+ mute = 0x8000;
+
+ if (reverse)
+ {
+ left = 100 - left;
+ right = 100 - right;
+ }
+
+ left = 100 - mix_cvt[left];
+ right = 100 - mix_cvt[right];
+
+ return mute | ((left * ((1 << bits) - 1) / 100) << 8) | (right *
+ ((1 << bits) -
+ 1) / 100);
+}
+
+int
+ac97_mixer_set (ac97_devc * devc, int dev, int value)
+{
+ int left, right, lvl;
+
+ if (dev < 0 || dev >= SOUND_MIXER_NRDEVICES)
+ return OSS_EINVAL;
+ if (!((1 << dev) & devc->devmask))
+ return OSS_EINVAL;
+
+ if (!((1 << dev) & STEREO_DEVS))
+ {
+ lvl = value & 0xff;
+ if (lvl > 100)
+ lvl = 100;
+ left = right = lvl;
+ value = lvl | (lvl << 8);
+ }
+ else
+ {
+ left = value & 0xff;
+ right = (value >> 8) & 0xff;
+ if (left > 100)
+ left = 100;
+ if (right > 100)
+ right = 100;
+ value = left | (right << 8);
+ }
+
+ switch (dev)
+ {
+ case SOUND_MIXER_VOLUME:
+ if (!(devc->devmask & SOUND_MASK_ALTPCM))
+ codec_write (devc, 0x04,
+ mix_scale (left, right, devc->mastervol_bits));
+ codec_write (devc, 0x02, mix_scale (left, right, devc->mastervol_bits));
+ break;
+
+ case SOUND_MIXER_TREBLE:
+ codec_write (devc, 0x08,
+ mix_scale (left, devc->levels[SOUND_MIXER_TREBLE] & 0xff,
+ 4));
+ break;
+
+ case SOUND_MIXER_BASS:
+ codec_write (devc, 0x08,
+ mix_scale (devc->levels[SOUND_MIXER_BASS] & 0xff, left,
+ 4));
+ break;
+
+ case SOUND_MIXER_DEPTH:
+ codec_write (devc, 0x22,
+ (mix_cvt[left] * ((1 << devc->enh_bits) - 1)) / 100);
+ break;
+
+ case SOUND_MIXER_SPEAKER:
+ codec_write (devc, 0x0a, mix_scale (0, left, 5) & 0x801F);
+ break;
+
+ case SOUND_MIXER_PHONE:
+ codec_write (devc, 0x0c, mix_scale (0, left, devc->mastervol_bits));
+ break;
+
+ case SOUND_MIXER_MONO:
+ codec_write (devc, 0x06, mix_scale (0, left, devc->mastervol_bits));
+ break;
+
+ case SOUND_MIXER_MIC:
+ codec_write (devc, 0x0e, (mix_scale (0, left, devc->mastervol_bits)
+ & ~0x40) | devc->micboost);
+ break;
+
+ case SOUND_MIXER_LINE:
+ codec_write (devc, 0x10, mix_scale (left, right, 5));
+ break;
+
+ case SOUND_MIXER_CD:
+ codec_write (devc, 0x12, mix_scale (left, right, 5));
+ break;
+
+ case SOUND_MIXER_VIDEO:
+ codec_write (devc, 0x14, mix_scale (left, right, 5));
+ break;
+
+ case SOUND_MIXER_LINE1:
+ codec_write (devc, 0x16, mix_scale (left, right, 5));
+ break;
+
+ case SOUND_MIXER_PCM:
+ codec_write (devc, 0x18, mix_scale (left, right, devc->pcmvol_bits));
+ break;
+
+ case SOUND_MIXER_IGAIN:
+ codec_write (devc, 0x1c, mix_scale (left, right, -4));
+ break;
+
+ case SOUND_MIXER_ALTPCM:
+ codec_write (devc, 0x04, mix_scale (left, right, devc->mastervol_bits));
+#if 0
+ codec_write (devc, 0x36, mix_scale (left, right, devc->mastervol_bits));
+ codec_write (devc, 0x38, mix_scale (left, right, devc->mastervol_bits));
+#endif
+ break;
+
+ case SOUND_MIXER_REARVOL:
+ codec_write (devc, 0x38, mix_scale (left, right, devc->rearvol_bits));
+ break;
+
+ case SOUND_MIXER_CENTERVOL:
+ codec_write (devc, 0x36, mix_scale (left, right, devc->centervol_bits));
+ break;
+
+#if 1 /* AC97 2.4 specified mid-surround channel */
+ case SOUND_MIXER_SIDEVOL:
+ codec_write (devc, 0x1c, mix_scale (left, right, devc->sidevol_bits));
+ break;
+#endif
+ default:
+ return OSS_EINVAL;
+ }
+
+ return devc->levels[dev] = value;
+}
+
+#include "ac97_ext.inc"
+
+static void
+ac97_mixer_reset (ac97_devc * devc)
+{
+ int i;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if ((1 << i) & devc->devmask)
+ ac97_mixer_set (devc, i, devc->levels[i]);
+
+ devc->recmask = REC_DEVS & devc->devmask;
+ if (devc->levels[31] == 0)
+ devc->levels[31] = SOUND_MASK_LINE;
+ ac97_set_recmask (devc, devc->levels[31]);
+}
+
+/*
+ * Remove a set of unused controls (mask) from the list of supported
+ * controls.
+ */
+void
+ac97_remove_control (ac97_devc * devc, int mask, int level)
+{
+ int i;
+
+ if (!devc->is_ok)
+ return;
+
+ devc->devmask &= ~(mask);
+ devc->recmask = REC_DEVS & devc->devmask;
+ devc->recdevs &= devc->recmask;
+ if (devc->recmask == 0)
+ {
+ ac97_set_recmask (devc, SOUND_MASK_LINE);
+ }
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if (mask & (1 << i))
+ ac97_mixer_set (devc, i, level);
+}
+
+/*
+ * Override a volume control with application defined handler. Before that
+ * set the AC97 volume to the given level.
+ */
+void
+ac97_override_control (ac97_devc * devc, int ctrl, ac97_ext_ioctl func,
+ int level)
+{
+ int dev = devc->mixer_dev;
+ int oldlevel;
+
+ if (!devc->is_ok)
+ return;
+
+ if (ctrl < 0 || ctrl >= SOUND_MIXER_NRDEVICES)
+ {
+ cmn_err (CE_WARN, "ac97: Invalid override for %d\n", ctrl);
+ return;
+ }
+ oldlevel = ac97_mixer_get (devc, ctrl);
+ ac97_mixer_set (devc, ctrl, level);
+
+ devc->overrides[ctrl] = func;
+
+ mixer_devs[dev]->ignore_mask |= (1 << ctrl);
+ func (devc->mixer_dev, -1, MIXER_WRITE (ctrl), oldlevel);
+}
+
+/*ARGSUSED*/
+static int
+find_current_recsrc (ac97_devc * devc)
+{
+ return SOUND_MIXER_IGAIN;
+}
+
+static int
+find_current_monsrc (ac97_devc * devc)
+{
+ int i;
+
+ for (i = 0; i < 32; i++)
+ {
+ if (devc->recdevs & (1 << i))
+ return i;
+ }
+
+ return SOUND_MIXER_MIC;
+}
+
+static int
+call_override_func (ac97_devc * devc, int audiodev, unsigned int cmd, int val)
+{
+ int ret, ctrl;
+
+ if (!devc->is_ok)
+ return OSS_EIO;
+
+ ctrl = cmd & 0xff;
+
+ if (ctrl < 0 || ctrl >= SOUND_MIXER_NRDEVICES
+ || devc->overrides[ctrl] == NULL)
+ return OSS_EINVAL;
+
+ ret = devc->overrides[ctrl] (devc->mixer_dev, audiodev, cmd, val);
+ if (ret < 0)
+ return ret;
+
+ return devc->levels[ctrl] = ret;
+}
+
+static int
+ac97_mixer_ioctl (int dev, int audiodev, unsigned int cmd, ioctl_arg arg)
+{
+ ac97_devc *devc = mixer_devs[dev]->devc;
+ int ctrl;
+
+/*
+ * Handle some special cases first
+ */
+
+ switch (cmd)
+ {
+ case SOUND_MIXER_WRITE_RECGAIN:
+ {
+ int chn, val;
+ chn = find_current_recsrc (devc);
+ val = *arg;
+ return *arg = (ac97_mixer_set (devc, chn, val));
+ }
+ break;
+
+ case SOUND_MIXER_READ_RECGAIN:
+ {
+ int chn;
+ chn = find_current_recsrc (devc);
+ return *arg = (ac97_mixer_get (devc, chn));
+ }
+ break;
+
+ case SOUND_MIXER_WRITE_MONGAIN:
+ {
+ int chn, val;
+ chn = find_current_monsrc (devc);
+ val = *arg;
+ return *arg = (ac97_mixer_set (devc, chn, val));
+ }
+ break;
+
+ case SOUND_MIXER_READ_MONGAIN:
+ {
+ int chn;
+ chn = find_current_monsrc (devc);
+ return *arg = (ac97_mixer_get (devc, chn));
+ }
+ break;
+
+ /* enable/disable 20db Mic Boost */
+ case SOUND_MIXER_PRIVATE1:
+ {
+ int value, tmp;
+
+ value = *arg;
+ if (value != 0 && value != 1)
+ return OSS_EINVAL;
+
+ tmp = codec_read (devc, 0x0e);
+
+ if (value)
+ devc->micboost = 0x40;
+ else
+ devc->micboost = 0x00;
+
+ codec_write (devc, 0x0e, (tmp & ~0x40) | devc->micboost);
+ return *arg = (value);
+ }
+ break;
+ }
+
+ if (((cmd >> 8) & 0xff) == 'M') /* Set control */
+ {
+ int val;
+
+ if (IOC_IS_OUTPUT (cmd))
+ switch (cmd & 0xff)
+ {
+ case SOUND_MIXER_RECSRC:
+ if (ac97_recselect)
+ return *arg = (SOUND_MASK_MIC);
+ val = *arg;
+ return *arg = (ac97_set_recmask (devc, val));
+ break;
+
+ default:
+ if ((cmd & 0xff) > SOUND_MIXER_NRDEVICES)
+ return OSS_EINVAL;
+ val = *arg;
+ ctrl = cmd & 0xff;
+ if (ctrl >= 0 && ctrl < SOUND_MIXER_NRDEVICES)
+ if (devc->overrides[ctrl] != NULL)
+ return *arg = call_override_func (devc, audiodev, cmd, val);
+
+ return *arg = (ac97_mixer_set (devc, cmd & 0xff, val));
+ }
+ else
+ switch (cmd & 0xff) /*
+ * Return parameters
+ */
+ {
+
+ case SOUND_MIXER_RECSRC:
+ if (ac97_recselect)
+ return *arg = (SOUND_MASK_MIC);
+ return *arg = (devc->recdevs);
+ break;
+
+ case SOUND_MIXER_DEVMASK:
+ return *arg = (devc->devmask);
+ break;
+
+ case SOUND_MIXER_STEREODEVS:
+ return *arg = (STEREO_DEVS);
+ break;
+
+ case SOUND_MIXER_RECMASK:
+ if (ac97_recselect)
+ return *arg = (0);
+
+ return *arg = (devc->recmask);
+ break;
+
+ case SOUND_MIXER_CAPS:
+ return *arg = (SOUND_CAP_EXCL_INPUT);
+ break;
+
+ default:
+ ctrl = cmd & 0xff;
+ if (ctrl >= 0 && ctrl < SOUND_MIXER_NRDEVICES)
+ if (devc->overrides[cmd & 0xff] != NULL)
+ return *arg = call_override_func (devc, audiodev, cmd, 0);
+ return *arg = (ac97_mixer_get (devc, cmd & 0xff));
+ }
+ }
+ else
+ {
+ return OSS_EINVAL;
+ }
+}
+
+static mixer_driver_t ac97_mixer_driver = {
+ ac97_mixer_ioctl
+};
+
+int
+ac97_install (ac97_devc * devc, char *host_name, ac97_readfunc_t readfn,
+ ac97_writefunc_t writefn, void *hostparms, oss_device_t * osdev)
+{
+ return
+ ac97_install_full (devc, host_name, readfn, writefn, hostparms, osdev, 0);
+}
+
+int
+ac97_install_full (ac97_devc * devc, char *host_name, ac97_readfunc_t readfn,
+ ac97_writefunc_t writefn, void *hostparms,
+ oss_device_t * osdev, int flags)
+{
+ int my_mixer;
+ int tmp, tmp2;
+ unsigned int id, mask;
+ char tmp_name[100];
+
+ memset (devc, 0, sizeof (ac97_devc));
+ devc->osdev = osdev;
+ devc->host_parms = hostparms;
+ devc->read = readfn;
+ devc->is_ok = 0;
+ devc->write = writefn;
+ strcpy (devc->name, "AC97");
+ if (codec_write (devc, 0x00, 0x00) < 0) /* reset */
+ return OSS_EIO;
+ codec_write (devc, 0x26, 0x00); /* Power up */
+ oss_udelay (1000);
+ if (ac97_amplifier != -1) tmp = ac97_amplifier;
+ else tmp = !(flags & AC97_INVERTED);
+
+ if (tmp)
+ codec_write (devc, 0x26, codec_read (devc, 0x26) & ~0x8000); /* Power up (external amplifier powered up) */
+ else
+ codec_write (devc, 0x26, codec_read (devc, 0x26) | 0x8000); /* Power up (external amplifier powered down) */
+ codec_write (devc, 0x20, 0x00); /* General Purpose */
+
+ tmp = codec_read (devc, 0x7c);
+ if (tmp >= 0xffff)
+ {
+ cmn_err (CE_WARN, "AC97 Codec/mixer chip doesn't seem to be alive.\n");
+ return OSS_EIO;
+ }
+
+ tmp2 = codec_read (devc, 0x7e);
+ id = ((tmp & 0xffff) << 16) | (tmp2 & 0xffff);
+
+ DDB (cmn_err (CE_CONT, "AC97 codec ID=0x%08x ('%c%c%c%x')\n",
+ id,
+ (tmp >> 8) & 0xff,
+ tmp & 0xff, (tmp2 >> 8) & 0xff, tmp2 & 0xff));
+ devc->ac97_id = codec_read (devc, 0x00);
+ devc->enh_3d = (devc->ac97_id >> 10) & 0x1f;
+
+ devc->devmask = MIXER_DEVS;
+ devc->fixed_rate = 0;
+ devc->var_rate_support = (codec_read (devc, 0x28) & 0x1) ? 1 : 0;
+ devc->spdifout_support = (codec_read (devc, 0x28) & 0x4) ? 1 : 0;
+ devc->mixer_ext = 0;
+ devc->playrate_support = PLAY_2CHAN;
+
+ if (codec_read (devc, 0x28) & 0x1C0)
+ devc->playrate_support = PLAY_6CHAN;
+ else if (codec_read (devc, 0x28) & 0x80)
+ devc->playrate_support = PLAY_4CHAN;
+
+ devc->enh_bits = 4;
+ devc->micboost = 0x40;
+ devc->pcmvol_bits = 5;
+ devc->rearvol_bits = 5;
+ devc->sidevol_bits = 5;
+ devc->centervol_bits = 5;
+ devc->auxvol_bits = 5;
+ devc->extmixlevels[CENTER_VOL] = 0x0404;
+ devc->extmixlevels[REAR_VOL] = 0x0404;
+ devc->extmixlevels[SIDE_VOL] = 0x0404;
+
+ /* need to detect all the Cirrus Logic variations! */
+ if ((id & 0xffff0000) == 0x43520000)
+ mask = 0xFFFFFFF0;
+ else
+ mask = 0xFFFFFFFF;
+
+ switch (id & mask)
+ {
+ case 0:
+ strcpy (devc->name, "Unknown");
+ break;
+
+ case 0x414b4d00:
+ strcpy (devc->name, "AK4540");
+ break;
+
+ case 0x83847600:
+ strcpy (devc->name, "STAC9700");
+ break;
+
+ case 0xc250c250:
+ case 0x83847601:
+ strcpy (devc->name, "STAC9701");
+ break;
+
+ case 0x83847609:
+ strcpy (devc->name, "STAC9721");
+ break;
+
+ case 0x83847604:
+ strcpy (devc->name, "STAC9704");
+ break;
+
+ case 0x83847605:
+ strcpy (devc->name, "STAC9705");
+ break;
+
+ case 0x83847608:
+ strcpy (devc->name, "STAC9708");
+ devc->devmask |= SOUND_MASK_ALTPCM;
+ codec_write (devc, 0x6E, 8); /* codec_read (devc, 0x6E) & ~0x8); non-inverted pphase */
+ devc->enh_bits = 2;
+ break;
+
+ case 0x83847644:
+ strcpy (devc->name, "STAC9744");
+ break;
+
+ case 0x83847650:
+ strcpy (devc->name, "STAC9750");
+ devc->spdifout_support = STAC_SPDIFOUT; /* SPDIF output on ACR */
+ devc->enh_bits = 3;
+ break;
+
+ case 0x83847652:
+ strcpy (devc->name, "STAC9752");
+ devc->spdifout_support = STAC_SPDIFOUT; /* SPDIF output on ACR */
+ devc->enh_bits = 3;
+ break;
+
+ case 0x83847656:
+ strcpy (devc->name, "STAC9756");
+ devc->spdifout_support = STAC_SPDIFOUT; /* SPDIF output on ACR */
+ devc->enh_bits = 3;
+ break;
+
+ case 0x83847666:
+ strcpy (devc->name, "STAC9766");
+ devc->enh_bits = 3;
+ devc->spdifout_support = STAC_SPDIFOUT; /* SPDIF output on ACR */
+ break;
+
+ case 0x83847658:
+ strcpy (devc->name, "STAC9758");
+ devc->enh_bits = 3;
+ devc->spdifout_support = STAC_SPDIFOUT; /* SPDIF output on ACR */
+ devc->mixer_ext = STAC9758_MIXER_EXT;
+ break;
+
+ case 0x54524108:
+ case 0x54524128:
+ strcpy (devc->name, "TR28028");
+ devc->devmask |= SOUND_MASK_ALTPCM;
+ break;
+
+ case 0x54524103:
+ case 0x54524123:
+ strcpy (devc->name, "TR28023");
+ break;
+
+ case 0x454d4328:
+ strcpy (devc->name, "EM28028");
+ codec_write (devc, 0x2a, (codec_read (devc, 0x2a) & ~3800) | 0xE0);
+ devc->devmask |= SOUND_MASK_ALTPCM;
+ break;
+
+ case 0x43585428:
+ case 0x43585429:
+ strcpy (devc->name, "CX20468");
+ devc->spdifout_support = CX_SPDIFOUT;
+ break;
+
+ case 0x43525900:
+ strcpy (devc->name, "CS4297");
+ break;
+
+ case 0x43525910:
+ strcpy (devc->name, "CS4297A");
+ devc->spdifout_support = CS_SPDIFOUT;
+ break;
+
+ case 0x43525920:
+ strcpy (devc->name, "CS4294");
+ break;
+
+ case 0x43525930:
+ strcpy (devc->name, "CS4299");
+ devc->spdifout_support = CS_SPDIFOUT;
+ break;
+
+ case 0x43525970:
+ strcpy (devc->name, "CS4202");
+ devc->spdifout_support = CS_SPDIFOUT;
+ break;
+
+ case 0x43525950:
+ strcpy (devc->name, "CS4205");
+ devc->spdifout_support = CS_SPDIFOUT;
+ break;
+
+ case 0x4144303: /* ADS3 */
+ strcpy (devc->name, "AD1819B");
+ break;
+
+ case 0x41445340: /* ADS40 */
+ strcpy (devc->name, "AD1881");
+ break;
+
+ case 0x41445348: /* ADS48 */
+ strcpy (devc->name, "AD1881A");
+ break;
+
+ case 0x41445360: /* ADS60 */
+ strcpy (devc->name, "AD1885");
+ break;
+
+ case 0x41445361: /* ADS61 */
+ strcpy (devc->name, "AD1886");
+ /* Jack sense */
+ codec_write (devc, 0x72, (codec_read (devc, 0x72) & (~0xEF)) | 0x10);
+ devc->spdifout_support = AD_SPDIFOUT;
+ break;
+
+ case 0x41445362: /* ADS62 */
+ strcpy (devc->name, "AD1887");
+ break;
+
+ case 0x41445368: /* ADS62 */
+ strcpy (devc->name, "AD1888");
+ devc->spdifout_support = AD_SPDIFOUT;
+ devc->mixer_ext = AD1980_MIXER_EXT;
+ codec_write (devc, 0x76, 0xC420);
+ devc->centervol_bits = 6;
+ devc->rearvol_bits = 6;
+ codec_write (devc, 0x04, 0x0808);
+ break;
+
+ case 0x41445370: /* ADS70 */
+ strcpy (devc->name, "AD1980");
+ devc->spdifout_support = AD_SPDIFOUT;
+ devc->mixer_ext = AD1980_MIXER_EXT;
+ codec_write (devc, 0x76, 0xC420);
+ break;
+
+ case 0x41445372: /* ADS72 */
+ strcpy (devc->name, "AD1981");
+ devc->spdifout_support = AD_SPDIFOUT;
+ /* set jacksense to mute line if headphone is plugged */
+ if (flags & AC97_FORCE_SENSE)
+ /* XXX */
+ codec_write (devc, 0x72, (codec_read (devc, 0x72) & (~0xe00)) | 0x400);
+ break;
+
+ case 0x41445374: /* ADS74 */
+ strcpy (devc->name, "AD1981B");
+ devc->spdifout_support = AD_SPDIFOUT;
+ /* set jacksense to mute line if headphone is plugged */
+ if (flags & AC97_FORCE_SENSE)
+ codec_write (devc, 0x72, (codec_read (devc, 0x72) | 0x0800));
+ break;
+
+ case 0x41445375: /* ADS74 */
+ strcpy (devc->name, "AD1985");
+ devc->spdifout_support = AD_SPDIFOUT;
+ devc->mixer_ext = AD1980_MIXER_EXT;
+ if (flags & AC97_FORCE_SENSE)
+ /* XXX */
+ codec_write (devc, 0x72, (codec_read (devc, 0x72) & (~0xe00)) | 0x400);
+ codec_write (devc, 0x76, 0xC420);
+ break;
+
+ case 0x574d4c00:
+ strcpy (devc->name, "WM9701A"); /* www.wolfson.co.uk */
+ break;
+
+ case 0x574d4c03:
+ strcpy (devc->name, "WM9703");
+ break;
+
+ case 0x574d4c04:
+ strcpy (devc->name, "WM9704");
+ devc->mixer_ext = WM9704_MIXER_EXT;
+ codec_write (devc, 0x5A, codec_read (devc, 0x5A) | 0x80); /*enable I2S */
+ break;
+
+ case 0x45838308:
+ strcpy (devc->name, "ES19XX");
+ break;
+
+ case 0x49434511: /* IcEnsemble ICE1232 (VIA1611A) */
+ strcpy (devc->name, "ICE1232/VT1611A");
+ break;
+
+ case 0x56494161: /* VIA1612A */
+ case 0x56494170: /* VIA1612A */
+ strcpy (devc->name, "VT1612A");
+ if (codec_read (devc, 0x28) & 0x04)
+ devc->spdifout_support = VIA_SPDIFOUT;
+ devc->mixer_ext = VIA1616_MIXER_EXT;
+ codec_write (devc, 0x2a, codec_read (devc, 0x2a) & ~0x3800);
+ codec_write (devc, 0x5a, 0x0230);
+ break;
+
+ case 0x49434551: /* IcEnsemble ICE1232 (VIA1616) */
+ strcpy (devc->name, "VT1616");
+ /* Enable S/PDIF mixer extensions only if S/PDIF is physically present */
+ if (codec_read (devc, 0x28) & 0x04)
+ devc->spdifout_support = VIA_SPDIFOUT;
+ devc->mixer_ext = VIA1616_MIXER_EXT;
+ devc->mixer_ext = VIA1616_MIXER_EXT;
+ codec_write (devc, 0x2a, codec_read (devc, 0x2a) & ~0x3800);
+ codec_write (devc, 0x5a, 0x0230);
+ break;
+
+ case 0x49434552: /* IcEnsemble ICE1232 (VIA1616A) */
+ strcpy (devc->name, "VT1616A");
+ devc->spdifout_support = VIA_SPDIFOUT;
+ devc->mixer_ext = VIA1616_MIXER_EXT;
+ break;
+
+ case 0x56494182: /* VIA1618 */
+ strcpy (devc->name, "VT1618");
+ devc->spdifout_support = VIA_SPDIFOUT;
+ devc->mixer_ext = VIA1616_MIXER_EXT;
+ break;
+
+ case 0x414c4326:
+ strcpy (devc->name, "ALC100");
+ devc->enh_bits = 2;
+ break;
+
+ case 0x414c4710:
+ strcpy (devc->name, "ALC200P");
+ devc->enh_bits = 2;
+ break;
+
+ case 0x414c4740:
+ strcpy (devc->name, "ALC202"); /* www.realtek.com.tw */
+ devc->spdifout_support = ALC_SPDIFOUT;
+ devc->enh_bits = 2;
+ break;
+
+ case 0x414c4770:
+ strcpy (devc->name, "ALC203"); /* www.realtek.com.tw */
+ devc->spdifout_support = ALC_SPDIFOUT;
+ devc->enh_bits = 2;
+ break;
+
+ case 0x000f8384:
+ strcpy (devc->name, "EV1938"); /* Creative/Ectiva */
+ break;
+
+ case 0x414c4750:
+ case 0x414c4752:
+ strcpy (devc->name, "ALC250"); /* www.realtek.com.tw */
+ devc->spdifout_support = ALC_SPDIFOUT;
+ devc->spdifin_support = ALC_SPDIFIN;
+ devc->enh_bits = 2;
+ break;
+
+ case 0x414c4720:
+ strcpy (devc->name, "ALC650"); /* www.realtek.com.tw */
+ devc->spdifout_support = ALC_SPDIFOUT;
+/* devc->spdifin_support = ALC_SPDIFIN; */
+ devc->mixer_ext = ALC650_MIXER_EXT;
+ devc->enh_bits = 2;
+ break;
+
+ case 0x414c4760:
+ case 0x414c4761:
+ strcpy (devc->name, "ALC655"); /* www.realtek.com.tw */
+ devc->spdifout_support = ALC_SPDIFOUT;
+ devc->spdifin_support = ALC_SPDIFIN;
+ devc->mixer_ext = ALC650_MIXER_EXT;
+ devc->enh_bits = 2;
+ break;
+
+ case 0x414c4780:
+ strcpy (devc->name, "ALC658"); /* www.realtek.com.tw */
+ devc->spdifout_support = ALC_SPDIFOUT;
+ devc->spdifin_support = ALC_SPDIFIN;
+ devc->mixer_ext = ALC650_MIXER_EXT;
+ devc->enh_bits = 2;
+ break;
+
+ case 0x414c4790:
+ strcpy (devc->name, "ALC850"); /* www.realtek.com.tw */
+ devc->spdifout_support = ALC_SPDIFOUT;
+ devc->spdifin_support = ALC_SPDIFIN;
+ devc->mixer_ext = ALC650_MIXER_EXT;
+ devc->enh_bits = 2;
+ break;
+
+ case 0x434d4941:
+ strcpy (devc->name, "CMI9738");
+ devc->devmask |= SOUND_MASK_ALTPCM;
+ break;
+
+ case 0x434d4961:
+ strcpy (devc->name, "CMI9739");
+ devc->spdifout_support = CMI_SPDIFOUT;
+ devc->spdifin_support = CMI_SPDIFIN;
+ devc->mixer_ext = CMI9739_MIXER_EXT;
+ break;
+
+ case 0x434d4983:
+ strcpy (devc->name, "CMI9761A");
+ devc->spdifout_support = CMI_SPDIFOUT;
+ devc->spdifin_support = CMI_SPDIFIN;
+ devc->mixer_ext = CMI9739_MIXER_EXT;
+ break;
+
+ case 0x434d4969:
+ strcpy (devc->name, "CMI9780");
+#if 0
+ devc->spdifout_support = CMI_SPDIFOUT;
+ devc->spdifin_support = CMI_SPDIFIN;
+ devc->mixer_ext = CMI9780_MIXER_EXT;
+ devc->playrate_support == PLAY_8CHAN;
+#endif
+ break;
+
+ case 0x594d4800:
+ strcpy (devc->name, "YMF743");
+ break;
+
+
+ case 0x594d4803:
+ strcpy (devc->name, "YMF753");
+ devc->spdifout_support = YMF_SPDIFOUT;
+ codec_write (devc, 0x66, codec_read (devc, 0x66) | 0x9); /* set TX8 + 3AWE */
+ break;
+
+ default:
+ sprintf (devc->name, "0x%04x%04x", tmp, tmp2);
+ }
+
+ DDB (cmn_err (CE_CONT, "Detected AC97 codec: %s\n", devc->name));
+ DDB (cmn_err (CE_CONT, "AC97 codec capabilities %x\n", devc->ac97_id));
+ DDB (cmn_err
+ (CE_CONT, "Dedicated Mic PCM in channel %d\n",
+ !!(devc->ac97_id & 0x0001)));
+ DDB (cmn_err
+ (CE_CONT, "Modem Line Codec support %d\n",
+ !!(devc->ac97_id & 0x0002)));
+ DDB (cmn_err
+ (CE_CONT, "Bass&Treble control %d\n", !!(devc->ac97_id & 0x0004)));
+ DDB (cmn_err
+ (CE_CONT, "Simulated stereo %d\n", !!(devc->ac97_id & 0x0008)));
+ DDB (cmn_err
+ (CE_CONT, "Headphone out support %d\n", !!(devc->ac97_id & 0x0010)));
+ DDB (cmn_err
+ (CE_CONT, "Loudness support %d\n", !!(devc->ac97_id & 0x0020)));
+ DDB (cmn_err
+ (CE_CONT, "18bit DAC resolution %d\n", !!(devc->ac97_id & 0x0040)));
+ DDB (cmn_err
+ (CE_CONT, "20bit DAC resolution %d\n", !!(devc->ac97_id & 0x0080)));
+ DDB (cmn_err
+ (CE_CONT, "18bit ADC resolution %d\n", !!(devc->ac97_id & 0x0100)));
+ DDB (cmn_err
+ (CE_CONT, "20bit ADC resolution %d\n", !!(devc->ac97_id & 0x0200)));
+ DDB (cmn_err (CE_CONT, "3D enhancement technique: %x\n", devc->enh_3d));
+#if 1
+ {
+ int ext_status = codec_read (devc, 0x28);
+ DDB (cmn_err
+ (CE_CONT, "AC97 v2.1 multi slot support %d\n",
+ !!(ext_status & 0x0200)));
+ DDB (cmn_err
+ (CE_CONT, "AC97 v2.1 surround DAC support 0x%x\n",
+ (ext_status >> 6) & 0x07));
+ }
+#endif
+
+ if (devc->fixed_rate)
+ {
+ int tmp3;
+
+ /* Turn off variable samling rate support */
+ tmp3 = codec_read (devc, 0x2a) & ~0x0001;
+ codec_write (devc, 0x2a, tmp3);
+ }
+
+ if (devc->ac97_id & 0x0004)
+ devc->devmask |= SOUND_MASK_BASS | SOUND_MASK_TREBLE;
+
+ if (devc->enh_3d != 0)
+ {
+ devc->devmask |= SOUND_MASK_DEPTH;
+ codec_write (devc, 0x20, codec_read (devc, 0x20) | 0x2000); /* Turn on 3D */
+ }
+
+
+/*
+ * Detect if the codec supports 5 or 6 bits in the master control register.
+ */
+
+ codec_write (devc, 0x02, 0x20);
+ if ((codec_read (devc, 0x02) & 0x1f) == 0x1f)
+ devc->mastervol_bits = 5;
+ else
+ devc->mastervol_bits = 6;
+
+#if 0
+ codec_write (devc, 0x18, 0x20);
+ if ((codec_read (devc, 0x18) & 0x1f) == 0x1f)
+ devc->pcmvol_bits = 5;
+ else
+ devc->pcmvol_bits = 6;
+#endif
+
+ if (devc->playrate_support == PLAY_8CHAN)
+ devc->devmask |=
+ SOUND_MASK_REARVOL | SOUND_MASK_CENTERVOL | SOUND_MASK_SIDEVOL;
+
+ if (devc->playrate_support == PLAY_6CHAN)
+ devc->devmask |= SOUND_MASK_REARVOL | SOUND_MASK_CENTERVOL;
+
+ if (devc->playrate_support == PLAY_4CHAN)
+ devc->devmask |= SOUND_MASK_REARVOL;
+
+ sprintf (tmp_name, "%s (%s)", host_name, devc->name);
+
+ if ((my_mixer = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+ osdev,
+ osdev,
+ tmp_name,
+ &ac97_mixer_driver,
+ sizeof (mixer_driver_t), devc)) >= 0)
+ {
+ mixer_devs[my_mixer]->hw_devc = hostparms;
+ mixer_devs[my_mixer]->priority = 2; /* Possible default mixer candidate */
+ devc->recdevs = 0;
+ devc->mixer_dev = my_mixer;
+ devc->is_ok = 1;
+ sprintf (tmp_name, "%s_%d", devc->name, nr_ac97++);
+
+ devc->levels = load_mixer_volumes (tmp_name, default_mixer_levels, 1);
+
+ ac97_mixer_reset (devc);
+ /* AD1888 seems to keep muting the headphone out */
+ if ((id & mask) == 0x41445368)
+ {
+ codec_write (devc, 0x04, codec_read (devc, 0x04) & ~0x8000);
+ codec_write (devc, 0x1c, codec_read (devc, 0x1c) & ~0x8000);
+ }
+ /* set PC speaker to mute causes humming on STAC97xx AC97s */
+ codec_write (devc, 0x0a, 0x8000);
+ }
+
+ if ((devc->mixer_ext) || (devc->spdifout_support)
+ || (devc->spdifin_support) || ac97_recselect)
+ {
+ mixer_ext_set_init_fn (devc->mixer_dev, ac97mixer_ext_init, 60);
+ }
+ return my_mixer;
+}
+
+int
+ac97_init_ext (int dev, ac97_devc * devc, mixer_create_controls_t func,
+ int nextra)
+{
+ if (dev < 0)
+ return OSS_EIO;
+ if ((devc->mixer_ext) || (devc->spdifout_support)
+ || (devc->spdifin_support) || ac97_recselect)
+ nextra += 50;
+ devc->client_mixer_init = func;
+ return mixer_ext_set_init_fn (dev, ac97mixer_ext_init, nextra);
+}
+
+int
+ac97_varrate (ac97_devc * devc)
+{
+ int ext_status;
+
+ if ((devc->fixed_rate) || !devc->is_ok)
+ return 0;
+
+ ext_status = codec_read (devc, 0x28);
+ if (ext_status & 0x0001)
+ {
+ devc->var_rate_support = 1;
+ }
+ return devc->var_rate_support;
+}
+
+int
+ac97_playrate (ac97_devc * devc, int srate)
+{
+ if (!devc->is_ok)
+ return 0;
+
+ if ((codec_read (devc, 0x7c) == 0x4144)
+ && (codec_read (devc, 0x7e) == 0x5303))
+ { /* AD 18191B */
+ codec_write (devc, 0x74, 0x1901);
+ codec_write (devc, 0x76, 0x0404);
+ codec_write (devc, 0x7A, srate); /*use sr1 for play */
+ return 1;
+ }
+
+ if ((codec_read (devc, 0x7c) == 0x4144)
+ && ((codec_read (devc, 0x7e) == 0x5348) ||
+ (codec_read (devc, 0x7e) == 0x5360) ||
+ (codec_read (devc, 0x7e) == 0x5361) ||
+ (codec_read (devc, 0x7e) == 0x5362)))
+
+ { /* AD1881/AD1886/AD1887/AD1891 */
+ codec_write (devc, 0x76, 0x0404);
+ codec_write (devc, 0x2a, codec_read (devc, 0x2a) | 0x01);
+ codec_write (devc, 0x2c, srate); /* use sr1 for play */
+ return 1;
+ }
+
+ if (devc->playrate_support == PLAY_6CHAN) /* set front/rear/lfe/c/s rate */
+ {
+ codec_write (devc, 0x2c, srate);
+ codec_write (devc, 0x2e, srate);
+ codec_write (devc, 0x30, srate);
+ codec_write (devc, 0x2a, codec_read (devc, 0x2a) | 0x01);
+ return 1;
+ }
+
+ codec_write (devc, 0x2c, srate);
+ codec_write (devc, 0x2a, codec_read (devc, 0x2a) | 0x01);
+ return 1;
+}
+
+int
+ac97_recrate (ac97_devc * devc, int srate)
+{
+ if (!devc->is_ok)
+ return 0;
+
+ if ((codec_read (devc, 0x7c) == 0x4144)
+ && (codec_read (devc, 0x7e) == 0x5303))
+ { /* AD 1819B */
+ codec_write (devc, 0x74, 0x1901);
+ codec_write (devc, 0x76, 0x0404);
+ codec_write (devc, 0x78, srate); /*use sr0 for rec */
+ return 1;
+ }
+
+ if ((codec_read (devc, 0x7c) == 0x4144)
+ && ((codec_read (devc, 0x7e) == 0x5348) ||
+ (codec_read (devc, 0x7e) == 0x5360) ||
+ (codec_read (devc, 0x7e) == 0x5361) ||
+ (codec_read (devc, 0x7e) == 0x5362)))
+ { /* AD1881/AD886/AD1887/AD1891 */
+ codec_write (devc, 0x76, 0x0404);
+ codec_write (devc, 0x2a, codec_read (devc, 0x2a) | 0x01);
+ codec_write (devc, 0x32, srate); /* use sr0 for rec */
+ return 1;
+ }
+
+ codec_write (devc, 0x32, srate);
+ codec_write (devc, 0x2a, codec_read (devc, 0x2a) | 0x01);
+ return 1;
+}
diff --git a/kernel/framework/audio/.config b/kernel/framework/audio/.config
new file mode 100644
index 0000000..e44f78f
--- /dev/null
+++ b/kernel/framework/audio/.config
@@ -0,0 +1 @@
+targetcpu=any
diff --git a/kernel/framework/audio/audiocnv.inc b/kernel/framework/audio/audiocnv.inc
new file mode 100644
index 0000000..27ac147
--- /dev/null
+++ b/kernel/framework/audio/audiocnv.inc
@@ -0,0 +1,160 @@
+/*
+ * Purpose: Helper functions used by audiofmt.c
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*ARGSUSED*/
+static int
+cnv_F8bits_T16bits (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl,
+ unsigned char **tgtp, sample_parms * source, sample_parms * target)
+{
+ unsigned char *p1 = *srcp;
+ short *p2 = (short*)*tgtp;
+ int len = *srcl;
+ int i, l;
+
+ VMEM_CHECK (p1, len);
+ VMEM_CHECK (p2, len * 2 / 1);
+
+ l = len / 1;
+ for (i = 0; i < l; i++)
+ p2[i] = ((int) p1[i] - 128) << 8;
+
+ *srcl = len * 2 / 1;
+ *srcp = (unsigned char*)p2;
+ *tgtp = p1;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+cnv_F8bits_T32bits (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl,
+ unsigned char **tgtp, sample_parms * source, sample_parms * target)
+{
+ unsigned char *p1 = *srcp;
+ int *p2 = (int *)*tgtp;
+ int len = *srcl;
+ int i, l;
+
+ VMEM_CHECK (p1, len);
+ VMEM_CHECK (p2, len * 4 / 1);
+
+ l = len / 1;
+ for (i = 0; i < l; i++)
+ p2[i] = ((int) p1[i] - 128) << 24;
+
+ *srcl = len * 4 / 1;
+ *srcp = (unsigned char *)p2;
+ *tgtp = p1;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+cnv_F16bits_T8bits (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl,
+ unsigned char **tgtp, sample_parms * source, sample_parms * target)
+{
+ short *p1 = (short*)*srcp;
+ unsigned char *p2 = *tgtp;
+ int len = *srcl;
+ int i, l;
+
+ VMEM_CHECK (p1, len);
+ VMEM_CHECK (p2, len * 1 / 2);
+
+ l = len / 2;
+ for (i = 0; i < l; i++)
+ p2[i] = (((int) p1[i]) >> 8) + 128;
+
+ *srcl = len * 1 / 2;
+ *srcp = (unsigned char *)p2;
+ *tgtp = (unsigned char *)p1;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+cnv_F16bits_T32bits (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl,
+ unsigned char **tgtp, sample_parms * source,
+ sample_parms * target)
+{
+ short *p1 = (short *)*srcp;
+ int *p2 = (int *)*tgtp;
+ int len = *srcl;
+ int i, l;
+
+ VMEM_CHECK (p1, len);
+ VMEM_CHECK (p2, len * 4 / 2);
+
+ l = len / 2;
+ for (i = 0; i < l; i++)
+ p2[i] = ((int) p1[i]) << 16;
+
+ *srcl = len * 4 / 2;
+ *srcp = (unsigned char *)p2;
+ *tgtp = (unsigned char *)p1;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+cnv_F32bits_T8bits (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl,
+ unsigned char **tgtp, sample_parms * source, sample_parms * target)
+{
+ int *p1 = (int*)*srcp;
+ unsigned char *p2 = *tgtp;
+ int len = *srcl;
+ int i, l;
+
+ VMEM_CHECK (p1, len);
+ VMEM_CHECK (p2, len * 1 / 4);
+
+ l = len / 4;
+ for (i = 0; i < l; i++)
+ p2[i] = (((int) p1[i]) >> 24) + 128;
+
+ *srcl = len * 1 / 4;
+ *srcp = p2;
+ *tgtp = (unsigned char *)p1;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+cnv_F32bits_T16bits (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl,
+ unsigned char **tgtp, sample_parms * source,
+ sample_parms * target)
+{
+ int *p1 = (int *)*srcp;
+ short *p2 = (short *)*tgtp;
+ int len = *srcl;
+ int i, l;
+
+ VMEM_CHECK (p1, len);
+ VMEM_CHECK (p2, len * 2 / 4);
+
+ l = len / 4;
+ for (i = 0; i < l; i++)
+ p2[i] = (((int) p1[i]) >> 16);
+
+ *srcl = len * 2 / 4;
+ *srcp = (unsigned char *)p2;
+ *tgtp = (unsigned char *)p1;
+
+ return 0;
+}
diff --git a/kernel/framework/audio/fltdata1_m.inc b/kernel/framework/audio/fltdata1_m.inc
new file mode 100644
index 0000000..580630e
--- /dev/null
+++ b/kernel/framework/audio/fltdata1_m.inc
@@ -0,0 +1,1284 @@
+/*
+ * Purpose: Filter coefficient tables for GRC3 sample rate converter
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+static int32_t filter_data[8193] = {
+ 0, -5008, -10058, -15150, -20285, -25462, -30682, -35945, -41250,
+ -46598, -51990, -57425, -62903, -68425, -73990, -79599, -85252, -90949,
+ -96690, -102475, -108304, -114178, -120097, -126060, -132068, -138121,
+ -144219, -150362, -156550, -162784, -169063, -175387, -181758, -188174,
+ -194636, -201145, -207699, -214300, -220947, -227641, -234381, -241168,
+ -248001, -254882, -261810, -268785, -275807, -282876, -289993, -297157,
+ -304369, -311629, -318937, -326293, -333697, -341149, -348649, -356197,
+ -363794, -371440, -379134, -386877, -394669, -402510, -410400, -418339,
+ -426328, -434365, -442452, -450589, -458775, -467011, -475297, -483632,
+ -492018, -500453, -508939, -517475, -526061, -534698, -543385, -552122,
+ -560911, -569750, -578639, -587580, -596572, -605615, -614708, -623853,
+ -633050, -642297, -651597, -660947, -670349, -679803, -689309, -698866,
+ -708475, -718136, -727849, -737615, -747432, -757301, -767223, -777197,
+ -787224, -797303, -807434, -817618, -827855, -838144, -848486, -858881,
+ -869329, -879830, -890384, -900990, -911650, -922363, -933129, -943949,
+ -954822, -965748, -976727, -987760, -998846, -1009986, -1021179,
+ -1032426, -1043727, -1055082, -1066490, -1077952, -1089467, -1101037,
+ -1112660, -1124337, -1136069, -1147854, -1159693, -1171587, -1183534,
+ -1195535, -1207591, -1219701, -1231865, -1244083, -1256355, -1268682,
+ -1281063, -1293498, -1305988, -1318532, -1331130, -1343783, -1356490,
+ -1369251, -1382067, -1394937, -1407862, -1420841, -1433874, -1446962,
+ -1460105, -1473302, -1486553, -1499859, -1513219, -1526634, -1540103,
+ -1553627, -1567205, -1580838, -1594525, -1608267, -1622063, -1635913,
+ -1649818, -1663778, -1677791, -1691859, -1705982, -1720159, -1734390,
+ -1748676, -1763015, -1777410, -1791858, -1806361, -1820917, -1835528,
+ -1850194, -1864913, -1879686, -1894514, -1909395, -1924331, -1939320,
+ -1954364, -1969461, -1984612, -1999817, -2015076, -2030388, -2045755,
+ -2061174, -2076648, -2092175, -2107755, -2123389, -2139076, -2154817,
+ -2170611, -2186458, -2202358, -2218312, -2234318, -2250378, -2266490,
+ -2282656, -2298874, -2315144, -2331468, -2347844, -2364273, -2380754,
+ -2397287, -2413873, -2430511, -2447201, -2463943, -2480737, -2497583,
+ -2514481, -2531431, -2548432, -2565485, -2582589, -2599745, -2616951,
+ -2634210, -2651519, -2668879, -2686290, -2703752, -2721265, -2738828,
+ -2756441, -2774105, -2791820, -2809584, -2827399, -2845263, -2863178,
+ -2881142, -2899155, -2917218, -2935331, -2953492, -2971703, -2989963,
+ -3008272, -3026629, -3045035, -3063490, -3081993, -3100544, -3119143,
+ -3137790, -3156485, -3175227, -3194017, -3212855, -3231739, -3250671,
+ -3269650, -3288675, -3307747, -3326866, -3346031, -3365242, -3384499,
+ -3403802, -3423151, -3442545, -3461985, -3481469, -3500999, -3520574,
+ -3540193, -3559857, -3579565, -3599318, -3619114, -3638955, -3658838,
+ -3678766, -3698736, -3718750, -3738807, -3758906, -3779048, -3799232,
+ -3819458, -3839727, -3860037, -3880388, -3900781, -3921215, -3941690,
+ -3962206, -3982762, -4003359, -4023995, -4044672, -4065388, -4086144,
+ -4106939, -4127772, -4148645, -4169557, -4190506, -4211494, -4232520,
+ -4253583, -4274684, -4295822, -4316997, -4338209, -4359457, -4380741,
+ -4402062, -4423418, -4444810, -4466237, -4487699, -4509196, -4530728,
+ -4552293, -4573893, -4595526, -4617193, -4638894, -4660627, -4682393,
+ -4704191, -4726021, -4747884, -4769778, -4791703, -4813660, -4835647,
+ -4857665, -4879713, -4901791, -4923898, -4946036, -4968202, -4990397,
+ -5012620, -5034872, -5057152, -5079459, -5101793, -5124155, -5146544,
+ -5168958, -5191399, -5213866, -5236358, -5258876, -5281418, -5303985,
+ -5326576, -5349191, -5371830, -5394492, -5417177, -5439884, -5462614,
+ -5485366, -5508139, -5530934, -5553750, -5576586, -5599443, -5622320,
+ -5645216, -5668131, -5691066, -5714019, -5736990, -5759979, -5782986,
+ -5806010, -5829050, -5852108, -5875181, -5898270, -5921374, -5944493,
+ -5967627, -5990775, -6013937, -6037113, -6060301, -6083503, -6106717,
+ -6129942, -6153180, -6176428, -6199688, -6222958, -6246238, -6269528,
+ -6292827, -6316134, -6339451, -6362775, -6386107, -6409447, -6432793,
+ -6456146, -6479504, -6502869, -6526239, -6549613, -6572992, -6596375,
+ -6619762, -6643151, -6666544, -6689938, -6713335, -6736733, -6760132,
+ -6783532, -6806931, -6830331, -6853730, -6877127, -6900523, -6923917,
+ -6947309, -6970697, -6994083, -7017464, -7040841, -7064213, -7087580,
+ -7110942, -7134297, -7157646, -7180988, -7204322, -7227648, -7250966,
+ -7274275, -7297575, -7320865, -7344144, -7367413, -7390670, -7413916,
+ -7437149, -7460370, -7483577, -7506771, -7529951, -7553115, -7576265,
+ -7599399, -7622517, -7645618, -7668702, -7691769, -7714817, -7737847,
+ -7760857, -7783848, -7806818, -7829768, -7852697, -7875604, -7898488,
+ -7921350, -7944189, -7967004, -7989794, -8012560, -8035300, -8058014,
+ -8080702, -8103363, -8125996, -8148602, -8171178, -8193726, -8216244,
+ -8238732, -8261189, -8283614, -8306008, -8328370, -8350698, -8372993,
+ -8395254, -8417481, -8439672, -8461827, -8483947, -8506029, -8528074,
+ -8550081, -8572050, -8593979, -8615869, -8637718, -8659527, -8681294,
+ -8703020, -8724702, -8746342, -8767938, -8789490, -8810996, -8832458,
+ -8853873, -8875242, -8896563, -8917837, -8939062, -8960238, -8981365,
+ -9002441, -9023467, -9044441, -9065363, -9086233, -9107050, -9127812,
+ -9148520, -9169174, -9189771, -9210312, -9230797, -9251224, -9271593,
+ -9291903, -9312154, -9332344, -9352475, -9372544, -9392551, -9412496,
+ -9432378, -9452196, -9471949, -9491638, -9511261, -9530818, -9550308,
+ -9569730, -9589084, -9608370, -9627586, -9646732, -9665807, -9684811,
+ -9703743, -9722602, -9741388, -9760100, -9778737, -9797299, -9815785,
+ -9834195, -9852527, -9870782, -9888957, -9907054, -9925071, -9943007,
+ -9960862, -9978635, -9996326, -10013933, -10031457, -10048896,
+ -10066250, -10083518, -10100699, -10117793, -10134799, -10151717,
+ -10168545, -10185284, -10201931, -10218488, -10234952, -10251324,
+ -10267603, -10283787, -10299877, -10315871, -10331769, -10347571,
+ -10363275, -10378880, -10394387, -10409794, -10425102, -10440308,
+ -10455412, -10470414, -10485313, -10500109, -10514799, -10529385,
+ -10543865, -10558238, -10572504, -10586662, -10600712, -10614652,
+ -10628482, -10642201, -10655809, -10669304, -10682687, -10695956,
+ -10709110, -10722150, -10735074, -10747881, -10760571, -10773143,
+ -10785597, -10797931, -10810145, -10822238, -10834210, -10846060,
+ -10857786, -10869389, -10880868, -10892221, -10903449, -10914550,
+ -10925524, -10936370, -10947087, -10957674, -10968131, -10978458,
+ -10988653, -10998715, -11008644, -11018440, -11028100, -11037626,
+ -11047015, -11056268, -11065383, -11074360, -11083198, -11091897,
+ -11100455, -11108871, -11117146, -11125278, -11133267, -11141112,
+ -11148811, -11156366, -11163774, -11171034, -11178147, -11185112,
+ -11191927, -11198592, -11205107, -11211469, -11217680, -11223738,
+ -11229642, -11235391, -11240985, -11246424, -11251705, -11256830,
+ -11261796, -11266603, -11271250, -11275738, -11280064, -11284228,
+ -11288229, -11292067, -11295741, -11299250, -11302594, -11305771,
+ -11308781, -11311624, -11314298, -11316802, -11319136, -11321300,
+ -11323292, -11325112, -11326759, -11328232, -11329531, -11330654,
+ -11331601, -11332372, -11332965, -11333380, -11333616, -11333673,
+ -11333549, -11333243, -11332756, -11332087, -11331233, -11330196,
+ -11328974, -11327566, -11325972, -11324191, -11322222, -11320064,
+ -11317717, -11315181, -11312453, -11309534, -11306422, -11303118,
+ -11299620, -11295928, -11292040, -11287956, -11283676, -11279199,
+ -11274523, -11269648, -11264574, -11259300, -11253825, -11248148,
+ -11242268, -11236185, -11229898, -11223407, -11216710, -11209808,
+ -11202698, -11195381, -11187855, -11180121, -11172176, -11164022,
+ -11155656, -11147078, -11138288, -11129284, -11120067, -11110634,
+ -11100987, -11091123, -11081042, -11070743, -11060227, -11049491,
+ -11038536, -11027360, -11015963, -11004344, -10992502, -10980438,
+ -10968149, -10955636, -10942897, -10929933, -10916742, -10903323,
+ -10889676, -10875800, -10861695, -10847359, -10832793, -10817995,
+ -10802964, -10787701, -10772204, -10756473, -10740507, -10724305,
+ -10707866, -10691191, -10674278, -10657126, -10639735, -10622105,
+ -10604234, -10586122, -10567768, -10549172, -10530332, -10511249,
+ -10491921, -10472349, -10452530, -10432465, -10412153, -10391593,
+ -10370785, -10349728, -10328421, -10306864, -10285055, -10262996,
+ -10240683, -10218118, -10195300, -10172227, -10148899, -10125316,
+ -10101477, -10077381, -10053027, -10028416, -10003546, -9978417,
+ -9953028, -9927378, -9901467, -9875295, -9848860, -9822162, -9795201,
+ -9767976, -9740485, -9712730, -9684708, -9656420, -9627865, -9599042,
+ -9569950, -9540590, -9510960, -9481060, -9450889, -9420447, -9389733,
+ -9358746, -9327487, -9295954, -9264146, -9232064, -9199707, -9167074,
+ -9134164, -9100978, -9067513, -9033771, -8999750, -8965450, -8930870,
+ -8896009, -8860868, -8825446, -8789741, -8753754, -8717485, -8680931,
+ -8644094, -8606972, -8569564, -8531872, -8493893, -8455627, -8417075,
+ -8378234, -8339106, -8299689, -8259982, -8219986, -8179700, -8139123,
+ -8098255, -8057095, -8015644, -7973899, -7931862, -7889531, -7846906,
+ -7803987, -7760772, -7717262, -7673457, -7629355, -7584956, -7540260,
+ -7495266, -7449974, -7404384, -7358495, -7312306, -7265817, -7219028,
+ -7171938, -7124548, -7076855, -7028861, -6980564, -6931964, -6883062,
+ -6833855, -6784345, -6734530, -6684410, -6633986, -6583255, -6532219,
+ -6480876, -6429227, -6377270, -6325007, -6272435, -6219555, -6166367,
+ -6112869, -6059063, -6004947, -5950521, -5895784, -5840737, -5785380,
+ -5729711, -5673730, -5617437, -5560832, -5503915, -5446685, -5389142,
+ -5331285, -5273114, -5214629, -5155830, -5096717, -5037288, -4977544,
+ -4917485, -4857110, -4796419, -4735412, -4674088, -4612447, -4550490,
+ -4488215, -4425622, -4362712, -4299484, -4235937, -4172072, -4107888,
+ -4043386, -3978564, -3913423, -3847962, -3782181, -3716081, -3649660,
+ -3582919, -3515858, -3448476, -3380773, -3312749, -3244403, -3175736,
+ -3106748, -3037438, -2967806, -2897852, -2827576, -2756978, -2686057,
+ -2614814, -2543248, -2471359, -2399147, -2326612, -2253755, -2180573,
+ -2107069, -2033241, -1959090, -1884615, -1809816, -1734694, -1659247,
+ -1583477, -1507383, -1430965, -1354223, -1277157, -1199766, -1122052,
+ -1044013, -965650, -886963, -807951, -728615, -648955, -568970,
+ -488662, -408029, -327071, -245790, -164184, -82254, 0, 82578, 165480,
+ 248707, 332258, 416132, 500331, 584853, 669699, 754868, 840362, 926179,
+ 1012319, 1098782, 1185569, 1272679, 1360112, 1447867, 1535946, 1624347,
+ 1713070, 1802116, 1891484, 1981174, 2071186, 2161520, 2252175, 2343152,
+ 2434450, 2526069, 2618009, 2710269, 2802850, 2895751, 2988972, 3082513,
+ 3176374, 3270554, 3365053, 3459871, 3555008, 3650463, 3746236, 3842327,
+ 3938736, 4035462, 4132505, 4229866, 4327542, 4425535, 4523844, 4622468,
+ 4721408, 4820662, 4920232, 5020116, 5120313, 5220825, 5321649, 5422787,
+ 5524237, 5626000, 5728075, 5830461, 5933158, 6036166, 6139484, 6243112,
+ 6347050, 6451297, 6555852, 6660716, 6765888, 6871368, 6977154, 7083247,
+ 7189646, 7296351, 7403360, 7510675, 7618294, 7726217, 7834442, 7942971,
+ 8051802, 8160935, 8270369, 8380104, 8490139, 8600474, 8711108, 8822040,
+ 8933271, 9044799, 9156625, 9268746, 9381163, 9493876, 9606883, 9720185,
+ 9833780, 9947667, 10061847, 10176319, 10291082, 10406135, 10521477,
+ 10637109, 10753030, 10869238, 10985733, 11102515, 11219583, 11336935,
+ 11454572, 11572493, 11690697, 11809184, 11927952, 12047000, 12166329,
+ 12285938, 12405825, 12525990, 12646433, 12767152, 12888146, 13009416,
+ 13130960, 13252777, 13374866, 13497228, 13619860, 13742763, 13865935,
+ 13989376, 14113084, 14237059, 14361300, 14485807, 14610577, 14735612,
+ 14860908, 14986467, 15112286, 15238366, 15364704, 15491301, 15618155,
+ 15745265, 15872631, 16000251, 16128124, 16256251, 16384629, 16513258,
+ 16642136, 16771263, 16900639, 17030261, 17160128, 17290241, 17420598,
+ 17551197, 17682039, 17813121, 17944443, 18076003, 18207802, 18339837,
+ 18472107, 18604612, 18737351, 18870322, 19003525, 19136957, 19270619,
+ 19404509, 19538626, 19672969, 19807536, 19942327, 20077340, 20212575,
+ 20348030, 20483703, 20619595, 20755703, 20892027, 21028565, 21165316,
+ 21302279, 21439453, 21576836, 21714428, 21852227, 21990231, 22128440,
+ 22266852, 22405467, 22544282, 22683297, 22822510, 22961920, 23101526,
+ 23241327, 23381320, 23521506, 23661882, 23802447, 23943200, 24084139,
+ 24225264, 24366573, 24508064, 24649736, 24791588, 24933619, 25075826,
+ 25218209, 25360767, 25503497, 25646399, 25789470, 25932711, 26076118,
+ 26219691, 26363429, 26507329, 26651391, 26795613, 26939993, 27084530,
+ 27229223, 27374069, 27519068, 27664219, 27809518, 27954966, 28100560,
+ 28246299, 28392181, 28538206, 28684370, 28830674, 28977114, 29123690,
+ 29270400, 29417243, 29564216, 29711319, 29858549, 30005906, 30153386,
+ 30300990, 30448715, 30596559, 30744521, 30892599, 31040792, 31189098,
+ 31337515, 31486042, 31634676, 31783417, 31932262, 32081209, 32230258,
+ 32379407, 32528652, 32677994, 32827430, 32976958, 33126577, 33276285,
+ 33426079, 33575960, 33725923, 33875969, 34026094, 34176298, 34326578,
+ 34476933, 34627360, 34777858, 34928426, 35079060, 35229760, 35380524,
+ 35531349, 35682234, 35833177, 35984177, 36135230, 36286336, 36437492,
+ 36588696, 36739948, 36891244, 37042582, 37193962, 37345380, 37496836,
+ 37648326, 37799849, 37951404, 38102987, 38254598, 38406234, 38557893,
+ 38709574, 38861273, 39012990, 39164722, 39316467, 39468223, 39619988,
+ 39771761, 39923538, 40075319, 40227100, 40378880, 40530657, 40682429,
+ 40834193, 40985948, 41137691, 41289421, 41441135, 41592831, 41744507,
+ 41896161, 42047790, 42199394, 42350969, 42502513, 42654024, 42805501,
+ 42956940, 43108340, 43259699, 43411013, 43562283, 43713504, 43864674,
+ 44015793, 44166856, 44317863, 44468811, 44619697, 44770520, 44921276,
+ 45071965, 45222584, 45373130, 45523601, 45673995, 45824309, 45974542,
+ 46124691, 46274754, 46424728, 46574611, 46724402, 46874096, 47023693,
+ 47173190, 47322584, 47471874, 47621056, 47770129, 47919090, 48067936,
+ 48216667, 48365278, 48513768, 48662134, 48810374, 48958486, 49106467,
+ 49254314, 49402026, 49549600, 49697033, 49844323, 49991468, 50138465,
+ 50285312, 50432007, 50578546, 50724927, 50871148, 51017207, 51163101,
+ 51308828, 51454384, 51599768, 51744978, 51890009, 52034861, 52179531,
+ 52324015, 52468312, 52612419, 52756334, 52900054, 53043576, 53186898,
+ 53330017, 53472931, 53615638, 53758134, 53900418, 54042486, 54184336,
+ 54325965, 54467372, 54608552, 54749505, 54890226, 55030714, 55170966,
+ 55310979, 55450751, 55590279, 55729560, 55868593, 56007373, 56145899,
+ 56284168, 56422177, 56559924, 56697406, 56834620, 56971564, 57108235,
+ 57244630, 57380747, 57516584, 57652136, 57787402, 57922379, 58057064,
+ 58191455, 58325549, 58459343, 58592835, 58726021, 58858900, 58991468,
+ 59123722, 59255660, 59387280, 59518578, 59649552, 59780199, 59910516,
+ 60040500, 60170150, 60299461, 60428432, 60557059, 60685340, 60813272,
+ 60940852, 61068078, 61194946, 61321454, 61447599, 61573379, 61698790,
+ 61823830, 61948496, 62072785, 62196694, 62320221, 62443363, 62566117,
+ 62688480, 62810449, 62932022, 63053195, 63173967, 63294333, 63414292,
+ 63533840, 63652975, 63771693, 63889993, 64007870, 64125323, 64242348,
+ 64358943, 64475104, 64590829, 64706115, 64820960, 64935359, 65049311,
+ 65162813, 65275861, 65388453, 65500586, 65612257, 65723464, 65834202,
+ 65944471, 66054265, 66163584, 66272423, 66380781, 66488653, 66596037,
+ 66702931, 66809331, 66915235, 67020639, 67125541, 67229938, 67333827,
+ 67437205, 67540069, 67642416, 67744244, 67845548, 67946328, 68046579,
+ 68146299, 68245484, 68344132, 68442241, 68539806, 68636826, 68733296,
+ 68829215, 68924580, 69019387, 69113633, 69207316, 69300433, 69392980,
+ 69484956, 69576356, 69667179, 69757420, 69847078, 69936149, 70024630,
+ 70112519, 70199812, 70286506, 70372600, 70458089, 70542971, 70627242,
+ 70710901, 70793944, 70876367, 70958169, 71039346, 71119895, 71199814,
+ 71279099, 71357748, 71435757, 71513124, 71589846, 71665919, 71741341,
+ 71816110, 71890221, 71963672, 72036461, 72108584, 72180038, 72250821,
+ 72320929, 72390359, 72459110, 72527177, 72594558, 72661250, 72727250,
+ 72792555, 72857162, 72921068, 72984271, 73046767, 73108554, 73169628,
+ 73229987, 73289628, 73348548, 73406744, 73464213, 73520952, 73576958,
+ 73632229, 73686762, 73740553, 73793599, 73845899, 73897448, 73948245,
+ 73998286, 74047568, 74096088, 74143844, 74190833, 74237052, 74282497,
+ 74327167, 74371058, 74414167, 74456491, 74498028, 74538775, 74578729,
+ 74617887, 74656246, 74693804, 74730556, 74766502, 74801637, 74835960,
+ 74869466, 74902154, 74934020, 74965062, 74995277, 75024662, 75053214,
+ 75080931, 75107809, 75133846, 75159038, 75183384, 75206881, 75229525,
+ 75251313, 75272244, 75292314, 75311521, 75329861, 75347332, 75363931,
+ 75379655, 75394502, 75408469, 75421553, 75433752, 75445062, 75455481,
+ 75465006, 75473634, 75481363, 75488190, 75494112, 75499127, 75503232,
+ 75506423, 75508699, 75510057, 75510494, 75510007, 75508593, 75506251,
+ 75502977, 75498768, 75493622, 75487537, 75480509, 75472536, 75463616,
+ 75453745, 75442921, 75431142, 75418405, 75404706, 75390045, 75374417,
+ 75357820, 75340253, 75321711, 75302193, 75281696, 75260217, 75237755,
+ 75214305, 75189867, 75164436, 75138011, 75110589, 75082168, 75052745,
+ 75022317, 74990882, 74958438, 74924982, 74890511, 74855023, 74818516,
+ 74780986, 74742433, 74702852, 74662242, 74620600, 74577924, 74534211,
+ 74489459, 74443665, 74396828, 74348944, 74300011, 74250027, 74198989,
+ 74146896, 74093744, 74039531, 73984255, 73927914, 73870505, 73812026,
+ 73752475, 73691848, 73630145, 73567362, 73503498, 73438549, 73372514,
+ 73305391, 73237177, 73167870, 73097467, 73025967, 72953367, 72879664,
+ 72804858, 72728945, 72651923, 72573791, 72494545, 72414184, 72332705,
+ 72250107, 72166387, 72081544, 71995574, 71908476, 71820247, 71730886,
+ 71640391, 71548759, 71455988, 71362077, 71267022, 71170823, 71073477,
+ 70974982, 70875335, 70774536, 70672581, 70569470, 70465199, 70359767,
+ 70253173, 70145413, 70036486, 69926391, 69815124, 69702685, 69589071,
+ 69474281, 69358312, 69241163, 69122831, 69003315, 68882614, 68760724,
+ 68637645, 68513374, 68387910, 68261251, 68133395, 68004340, 67874085,
+ 67742628, 67609966, 67476099, 67341025, 67204741, 67067246, 66928539,
+ 66788617, 66647480, 66505125, 66361550, 66216755, 66070737, 65923495,
+ 65775027, 65625332, 65474407, 65322252, 65168865, 65014245, 64858389,
+ 64701296, 64542965, 64383394, 64222582, 64060527, 63897228, 63732683,
+ 63566891, 63399850, 63231560, 63062018, 62891223, 62719173, 62545869,
+ 62371307, 62195487, 62018407, 61840066, 61660463, 61479596, 61297465,
+ 61114067, 60929401, 60743467, 60556263, 60367788, 60178041, 59987020,
+ 59794724, 59601152, 59406303, 59210175, 59012769, 58814081, 58614112,
+ 58412861, 58210325, 58006505, 57801398, 57595005, 57387323, 57178353,
+ 56968092, 56756540, 56543697, 56329560, 56114129, 55897404, 55679382,
+ 55460064, 55239448, 55017534, 54794321, 54569807, 54343992, 54116875,
+ 53888456, 53658733, 53427705, 53195373, 52961735, 52726790, 52490538,
+ 52252979, 52014110, 51773932, 51532444, 51289646, 51045536, 50800114,
+ 50553379, 50305332, 50055970, 49805295, 49553305, 49299999, 49045377,
+ 48789439, 48532184, 48273612, 48013722, 47752513, 47489986, 47226140,
+ 46960975, 46694489, 46426683, 46157557, 45887110, 45615341, 45342251,
+ 45067839, 44792105, 44515048, 44236669, 43956967, 43675942, 43393594,
+ 43109922, 42824927, 42538608, 42250965, 41961998, 41671707, 41380092,
+ 41087152, 40792889, 40497301, 40200388, 39902152, 39602591, 39301705,
+ 38999496, 38695962, 38391104, 38084922, 37777416, 37468587, 37158433,
+ 36846957, 36534157, 36220034, 35904588, 35587820, 35269729, 34950316,
+ 34629581, 34307525, 33984147, 33659449, 33333430, 33006091, 32677432,
+ 32347454, 32016157, 31683541, 31349607, 31014356, 30677788, 30339903,
+ 30000701, 29660185, 29318353, 28975207, 28630747, 28284974, 27937889,
+ 27589491, 27239783, 26888763, 26536434, 26182796, 25827849, 25471595,
+ 25114034, 24755167, 24394994, 24033517, 23670736, 23306653, 22941268,
+ 22574582, 22206595, 21837310, 21466726, 21094846, 20721669, 20347197,
+ 19971430, 19594371, 19216020, 18836377, 18455445, 18073224, 17689715,
+ 17304920, 16918840, 16531475, 16142828, 15752899, 15361690, 14969201,
+ 14575435, 14180392, 13784074, 13386483, 12987618, 12587483, 12186078,
+ 11783404, 11379464, 10974259, 10567789, 10160057, 9751064, 9340812,
+ 8929302, 8516536, 8102515, 7687241, 7270716, 6852941, 6433918, 6013649,
+ 5592135, 5169378, 4745379, 4320142, 3893666, 3465955, 3037010, 2606833,
+ 2175425, 1742789, 1308927, 873840, 437530, 0, -438749, -878714,
+ -1319895, -1762288, -2205891, -2650704, -3096722, -3543945, -3992370,
+ -4441994, -4892817, -5344835, -5798047, -6252449, -6708041, -7164819,
+ -7622781, -8081925, -8542249, -9003750, -9466426, -9930274, -10395292,
+ -10861478, -11328829, -11797343, -12267017, -12737848, -13209835,
+ -13682974, -14157263, -14632699, -15109280, -15587003, -16065865,
+ -16545864, -17026997, -17509261, -17992654, -18477173, -18962814,
+ -19449576, -19937455, -20426448, -20916554, -21407767, -21900087,
+ -22393509, -22888032, -23383651, -23880364, -24378168, -24877061,
+ -25377038, -25878096, -26380234, -26883447, -27387732, -27893087,
+ -28399507, -28906991, -29415534, -29925134, -30435787, -30947490,
+ -31460239, -31974032, -32488864, -33004733, -33521636, -34039568,
+ -34558526, -35078507, -35599508, -36121524, -36644553, -37168591,
+ -37693634, -38219679, -38746722, -39274760, -39803789, -40333804,
+ -40864804, -41396783, -41929739, -42463667, -42998563, -43534425,
+ -44071247, -44609027, -45147760, -45687443, -46228072, -46769642,
+ -47312150, -47855592, -48399964, -48945262, -49491481, -50038619,
+ -50586671, -51135632, -51685499, -52236267, -52787933, -53340493,
+ -53893941, -54448274, -55003488, -55559578, -56116541, -56674371,
+ -57233065, -57792619, -58353027, -58914286, -59476391, -60039338,
+ -60603122, -61167739, -61733184, -62299454, -62866543, -63434446,
+ -64003160, -64572680, -65143001, -65714119, -66286029, -66858726,
+ -67432205, -68006463, -68581493, -69157292, -69733855, -70311177,
+ -70889253, -71468078, -72047648, -72627957, -73209001, -73790775,
+ -74373274, -74956492, -75540426, -76125070, -76710418, -77296467,
+ -77883210, -78470644, -79058762, -79647560, -80237032, -80827174,
+ -81417980, -82009445, -82601564, -83194331, -83787742, -84381790,
+ -84976472, -85571781, -86167712, -86764260, -87361419, -87959184,
+ -88557550, -89156511, -89756062, -90356197, -90956910, -91558197,
+ -92160052, -92762468, -93365441, -93968965, -94573035, -95177644,
+ -95782787, -96388459, -96994653, -97601364, -98208587, -98816315,
+ -99424542, -100033264, -100642473, -101252165, -101862333, -102472972,
+ -103084075, -103695637, -104307652, -104920114, -105533016, -106146354,
+ -106760120, -107374309, -107988915, -108603931, -109219352, -109835171,
+ -110451383, -111067981, -111684959, -112302311, -112920031, -113538112,
+ -114156548, -114775333, -115394461, -116013925, -116633719, -117253837,
+ -117874272, -118495017, -119116068, -119737416, -120359056, -120980982,
+ -121603186, -122225662, -122848404, -123471405, -124094659, -124718159,
+ -125341898, -125965871, -126590069, -127214487, -127839118, -128463956,
+ -129088992, -129714222, -130339638, -130965233, -131591001, -132216934,
+ -132843027, -133469271, -134095661, -134722189, -135348849, -135975634,
+ -136602536, -137229549, -137856666, -138483880, -139111183, -139738570,
+ -140366032, -140993563, -141621156, -142248804, -142876499, -143504234,
+ -144132003, -144759798, -145387612, -146015437, -146643268, -147271095,
+ -147898913, -148526714, -149154490, -149782234, -150409940, -151037599,
+ -151665205, -152292749, -152920226, -153547626, -154174943, -154802170,
+ -155429298, -156056321, -156683231, -157310021, -157936682, -158563208,
+ -159189591, -159815823, -160441897, -161067806, -161693540, -162319094,
+ -162944459, -163569628, -164194593, -164819346, -165443880, -166068186,
+ -166692258, -167316087, -167939666, -168562986, -169186041, -169808822,
+ -170431321, -171053531, -171675443, -172297050, -172918344, -173539318,
+ -174159962, -174780269, -175400231, -176019841, -176639090, -177257970,
+ -177876473, -178494592, -179112317, -179729642, -180346558, -180963056,
+ -181579129, -182194769, -182809968, -183424717, -184039008, -184652833,
+ -185266184, -185879053, -186491431, -187103311, -187714683, -188325540,
+ -188935874, -189545675, -190154937, -190763650, -191371806, -191979397,
+ -192586415, -193192850, -193798696, -194403942, -195008582, -195612606,
+ -196216006, -196818774, -197420901, -198022379, -198623199, -199223352,
+ -199822831, -200421626, -201019730, -201617132, -202213826, -202809803,
+ -203405053, -203999568, -204593340, -205186360, -205778619, -206370109,
+ -206960821, -207550746, -208139876, -208728202, -209315715, -209902407,
+ -210488268, -211073290, -211657465, -212240783, -212823236, -213404815,
+ -213985511, -214565315, -215144219, -215722214, -216299290, -216875439,
+ -217450653, -218024921, -218598236, -219170588, -219741969, -220312370,
+ -220881781, -221450194, -222017599, -222583989, -223149353, -223713683,
+ -224276970, -224839205, -225400379, -225960482, -226519507, -227077443,
+ -227634282, -228190015, -228744632, -229298125, -229850484, -230401700,
+ -230951765, -231500669, -232048403, -232594958, -233140324, -233684493,
+ -234227456, -234769203, -235309725, -235849013, -236387058, -236923850,
+ -237459380, -237993640, -238526620, -239058310, -239588702, -240117786,
+ -240645553, -241171993, -241697098, -242220859, -242743265, -243264307,
+ -243783977, -244302265, -244819162, -245334658, -245848744, -246361411,
+ -246872650, -247382450, -247890803, -248397700, -248903130, -249407085,
+ -249909556, -250410532, -250910005, -251407964, -251904402, -252399308,
+ -252892673, -253384487, -253874742, -254363427, -254850533, -255336052,
+ -255819972, -256302286, -256782983, -257262054, -257739490, -258215281,
+ -258689417, -259161890, -259632689, -260101806, -260569231, -261034953,
+ -261498965, -261961256, -262421817, -262880637, -263337709, -263793022,
+ -264246567, -264698334, -265148314, -265596497, -266042874, -266487435,
+ -266930171, -267371072, -267810128, -268247331, -268682670, -269116136,
+ -269547720, -269977411, -270405201, -270831079, -271255037, -271677064,
+ -272097152, -272515290, -272931469, -273345680, -273757913, -274168157,
+ -274576405, -274982646, -275386871, -275789069, -276189232, -276587351,
+ -276983414, -277377413, -277769339, -278159181, -278546930, -278932577,
+ -279316112, -279697526, -280076808, -280453949, -280828940, -281201771,
+ -281572433, -281940916, -282307210, -282671306, -283033194, -283392865,
+ -283750310, -284105518, -284458480, -284809186, -285157627, -285503794,
+ -285847677, -286189266, -286528551, -286865524, -287200175, -287532494,
+ -287862471, -288190097, -288515363, -288838259, -289158775, -289476902,
+ -289792630, -290105951, -290416853, -290725329, -291031368, -291334961,
+ -291636098, -291934769, -292230967, -292524680, -292815899, -293104615,
+ -293390819, -293674500, -293955650, -294234259, -294510318, -294783816,
+ -295054745, -295323096, -295588858, -295852022, -296112579, -296370519,
+ -296625834, -296878513, -297128547, -297375927, -297620644, -297862687,
+ -298102048, -298338717, -298572685, -298803942, -299032480, -299258288,
+ -299481358, -299701680, -299919244, -300134042, -300346064, -300555300,
+ -300761742, -300965381, -301166206, -301364208, -301559379, -301751709,
+ -301941189, -302127809, -302311561, -302492435, -302670421, -302845511,
+ -303017695, -303186965, -303353310, -303516723, -303677192, -303834711,
+ -303989268, -304140856, -304289465, -304435086, -304577709, -304717326,
+ -304853928, -304987505, -305118048, -305245549, -305369998, -305491386,
+ -305609704, -305724944, -305837095, -305946150, -306052098, -306154932,
+ -306254642, -306351219, -306444655, -306534939, -306622064, -306706020,
+ -306786799, -306864392, -306938789, -307009982, -307077962, -307142720,
+ -307204248, -307262536, -307317575, -307369358, -307417875, -307463117,
+ -307505075, -307543742, -307579107, -307611163, -307639901, -307665312,
+ -307687386, -307706117, -307721495, -307733510, -307742156, -307747423,
+ -307749302, -307747785, -307742864, -307734529, -307722773, -307707586,
+ -307688961, -307666888, -307641360, -307612367, -307579902, -307543956,
+ -307504521, -307461587, -307415147, -307365193, -307311715, -307254707,
+ -307194158, -307130062, -307062410, -306991193, -306916403, -306838032,
+ -306756072, -306670514, -306581351, -306488574, -306392175, -306292147,
+ -306188479, -306081166, -305970198, -305855568, -305737267, -305615288,
+ -305489622, -305360261, -305227198, -305090425, -304949933, -304805715,
+ -304657762, -304506068, -304350623, -304191420, -304028452, -303861711,
+ -303691188, -303516876, -303338767, -303156854, -302971128, -302781583,
+ -302588210, -302391001, -302189950, -301985049, -301776289, -301563664,
+ -301347165, -301126786, -300902518, -300674355, -300442288, -300206311,
+ -299966416, -299722595, -299474842, -299223148, -298967507, -298707910,
+ -298444352, -298176824, -297905320, -297629831, -297350352, -297066874,
+ -296779390, -296487894, -296192379, -295892836, -295589260, -295281642,
+ -294969977, -294654256, -294334474, -294010623, -293682695, -293350685,
+ -293014586, -292674389, -292330090, -291981680, -291629153, -291272503,
+ -290911722, -290546803, -290177741, -289804529, -289427159, -289045625,
+ -288659921, -288270039, -287875974, -287477719, -287075268, -286668613,
+ -286257749, -285842669, -285423367, -284999835, -284572069, -284140062,
+ -283703807, -283263297, -282818528, -282369493, -281916184, -281458597,
+ -280996726, -280530563, -280060103, -279585340, -279106268, -278622881,
+ -278135172, -277643137, -277146768, -276646061, -276141009, -275631606,
+ -275117847, -274599726, -274077237, -273550374, -273019132, -272483504,
+ -271943486, -271399072, -270850256, -270297032, -269739396, -269177341,
+ -268610862, -268039954, -267464611, -266884827, -266300599, -265711919,
+ -265118783, -264521186, -263919122, -263312586, -262701573, -262086078,
+ -261466096, -260841621, -260212648, -259579173, -258941191, -258298696,
+ -257651684, -257000149, -256344088, -255683494, -255018363, -254348691,
+ -253674472, -252995702, -252312376, -251624490, -250932038, -250235017,
+ -249533421, -248827247, -248116489, -247401144, -246681206, -245956672,
+ -245227536, -244493795, -243755445, -243012480, -242264897, -241512692,
+ -240755860, -239994397, -239228300, -238457563, -237682183, -236902156,
+ -236117479, -235328146, -234534154, -233735499, -232932177, -232124185,
+ -231311519, -230494175, -229672148, -228845437, -228014036, -227177942,
+ -226337152, -225491662, -224641469, -223786568, -222926958, -222062633,
+ -221193591, -220319829, -219441343, -218558130, -217670186, -216777509,
+ -215880095, -214977941, -214071044, -213159401, -212243009, -211321865,
+ -210395966, -209465308, -208529890, -207589708, -206644759, -205695041,
+ -204740551, -203781286, -202817243, -201848420, -200874814, -199896423,
+ -198913244, -197925275, -196932512, -195934954, -194932599, -193925443,
+ -192913485, -191896723, -190875153, -189848774, -188817584, -187781580,
+ -186740761, -185695124, -184644668, -183589390, -182529288, -181464360,
+ -180394606, -179320022, -178240607, -177156359, -176067277, -174973358,
+ -173874601, -172771005, -171662568, -170549288, -169431164, -168308195,
+ -167180378, -166047713, -164910199, -163767833, -162620615, -161468543,
+ -160311616, -159149834, -157983194, -156811696, -155635339, -154454122,
+ -153268044, -152077104, -150881300, -149680633, -148475101, -147264703,
+ -146049440, -144829310, -143604312, -142374446, -141139711, -139900107,
+ -138655633, -137406289, -136152075, -134892989, -133629032, -132360204,
+ -131086504, -129807931, -128524486, -127236169, -125942979, -124644917,
+ -123341982, -122034174, -120721494, -119403941, -118081516, -116754219,
+ -115422050, -114085009, -112743097, -111396314, -110044660, -108688136,
+ -107326742, -105960479, -104589347, -103213348, -101832480, -100446746,
+ -99056145, -97660680, -96260349, -94855155, -93445098, -92030179,
+ -90610398, -89185758, -87756259, -86321901, -84882687, -83438617,
+ -81989693, -80535915, -79077286, -77613805, -76145476, -74672298,
+ -73194275, -71711406, -70223693, -68731139, -67233745, -65731512,
+ -64224442, -62712537, -61195798, -59674228, -58147828, -56616601,
+ -55080547, -53539670, -51993970, -50443451, -48888115, -47327963,
+ -45762997, -44193220, -42618635, -41039243, -39455047, -37866049,
+ -36272253, -34673659, -33070271, -31462091, -29849123, -28231368,
+ -26608829, -24981509, -23349412, -21712538, -20070893, -18424478,
+ -16773296, -15117351, -13456645, -11791182, -10120965, -8445996,
+ -6766279, -5081818, -3392616, -1698675, 0, 1703406, 3411540, 5124399,
+ 6841978, 8564275, 10291285, 12023005, 13759430, 15500559, 17246385,
+ 18996906, 20752118, 22512017, 24276599, 26045859, 27819794, 29598400,
+ 31381673, 33169607, 34962200, 36759446, 38561342, 40367883, 42179065,
+ 43994882, 45815332, 47640409, 49470108, 51304425, 53143356, 54986895,
+ 56835038, 58687780, 60545117, 62407042, 64273553, 66144642, 68020306,
+ 69900540, 71785337, 73674694, 75568605, 77467064, 79370067, 81277609,
+ 83189683, 85106284, 87027407, 88953047, 90883198, 92817854, 94757010,
+ 96700660, 98648799, 100601420, 102558519, 104520088, 106486122,
+ 108456616, 110431564, 112410958, 114394794, 116383065, 118375765,
+ 120372889, 122374429, 124380379, 126390734, 128405486, 130424630,
+ 132448159, 134476066, 136508346, 138544991, 140585995, 142631351,
+ 144681053, 146735094, 148793467, 150856165, 152923182, 154994510,
+ 157070143, 159150073, 161234294, 163322799, 165415580, 167512631,
+ 169613943, 171719511, 173829326, 175943381, 178061669, 180184183,
+ 182310915, 184441857, 186577003, 188716344, 190859873, 193007582,
+ 195159464, 197315510, 199475714, 201640066, 203808560, 205981188,
+ 208157941, 210338811, 212523791, 214712872, 216906046, 219103306,
+ 221304642, 223510047, 225719513, 227933030, 230150591, 232372188,
+ 234597811, 236827453, 239061104, 241298757, 243540402, 245786031,
+ 248035636, 250289207, 252546735, 254808213, 257073630, 259342979,
+ 261616250, 263893434, 266174523, 268459506, 270748376, 273041122,
+ 275337736, 277638209, 279942530, 282250692, 284562684, 286878497,
+ 289198122, 291521549, 293848768, 296179771, 298514547, 300853087,
+ 303195382, 305541421, 307891194, 310244693, 312601907, 314962825,
+ 317327440, 319695739, 322067714, 324443354, 326822650, 329205590,
+ 331592166, 333982366, 336376181, 338773600, 341174613, 343579210,
+ 345987380, 348399112, 350814397, 353233224, 355655582, 358081460,
+ 360510849, 362943737, 365380114, 367819968, 370263290, 372710068,
+ 375160291, 377613949, 380071030, 382531525, 384995420, 387462707,
+ 389933372, 392407406, 394884798, 397365535, 399849607, 402337002,
+ 404827710, 407321718, 409819016, 412319591, 414823433, 417330530,
+ 419840871, 422354443, 424871236, 427391237, 429914435, 432440818,
+ 434970374, 437503092, 440038960, 442577966, 445120097, 447665343,
+ 450213690, 452765128, 455319643, 457877224, 460437859, 463001536,
+ 465568241, 468137964, 470710692, 473286412, 475865112, 478446779,
+ 481031403, 483618969, 486209465, 488802879, 491399199, 493998411,
+ 496600503, 499205463, 501813277, 504423933, 507037418, 509653720,
+ 512272825, 514894721, 517519395, 520146833, 522777023, 525409952,
+ 528045606, 530683974, 533325040, 535968794, 538615220, 541264306,
+ 543916039, 546570406, 549227393, 551886986, 554549173, 557213939,
+ 559881273, 562551159, 565223585, 567898537, 570576001, 573255964,
+ 575938412, 578623331, 581310708, 584000529, 586692781, 589387448,
+ 592084519, 594783978, 597485811, 600190006, 602896547, 605605421,
+ 608316615, 611030112, 613745901, 616463966, 619184293, 621906869,
+ 624631679, 627358708, 630087943, 632819369, 635552972, 638288737,
+ 641026651, 643766698, 646508864, 649253135, 651999496, 654747932,
+ 657498430, 660250974, 663005549, 665762142, 668520737, 671281320,
+ 674043876, 676808390, 679574848, 682343233, 685113533, 687885731,
+ 690659813, 693435764, 696213569, 698993212, 701774680, 704557956,
+ 707343026, 710129874, 712918486, 715708846, 718500939, 721294750,
+ 724090264, 726887464, 729686337, 732486866, 735289037, 738092833,
+ 740898240, 743705242, 746513823, 749323968, 752135662, 754948889,
+ 757763634, 760579880, 763397612, 766216815, 769037473, 771859570,
+ 774683090, 777508018, 780334339, 783162035, 785991092, 788821493,
+ 791653222, 794486265, 797320604, 800156225, 802993110, 805831244,
+ 808670611, 811511195, 814352979, 817195949, 820040087, 822885378,
+ 825731805, 828579352, 831428004, 834277743, 837128554, 839980420,
+ 842833325, 845687253, 848542187, 851398111, 854255009, 857112865,
+ 859971661, 862831382, 865692011, 868553531, 871415927, 874279181,
+ 877143277, 880008198, 882873929, 885740451, 888607750, 891475807,
+ 894344607, 897214133, 900084367, 902955294, 905826897, 908699158,
+ 911572062, 914445591, 917319728, 920194457, 923069761, 925945623,
+ 928822026, 931698954, 934576388, 937454313, 940332712, 943211567,
+ 946090861, 948970578, 951850700, 954731211, 957612093, 960493330,
+ 963374903, 966256797, 969138994, 972021477, 974904229, 977787232,
+ 980670470, 983553925, 986437580, 989321418, 992205421, 995089573,
+ 997973855, 1000858252, 1003742745, 1006627317, 1009511951, 1012396630,
+ 1015281336, 1018166051, 1021050759, 1023935442, 1026820083, 1029704664,
+ 1032589168, 1035473577, 1038357874, 1041242041, 1044126061, 1047009917,
+ 1049893591, 1052777065, 1055660322, 1058543344, 1061426114, 1064308615,
+ 1067190828, 1070072736, 1072954322, 1075835567, 1078716455, 1081596968,
+ 1084477087, 1087356796, 1090236076, 1093114911, 1095993281, 1098871171,
+ 1101748561, 1104625435, 1107501774, 1110377561, 1113252778, 1116127408,
+ 1119001432, 1121874833, 1124747593, 1127619694, 1130491119, 1133361849,
+ 1136231867, 1139101156, 1141969696, 1144837472, 1147704463, 1150570654,
+ 1153436026, 1156300560, 1159164240, 1162027048, 1164888964, 1167749973,
+ 1170610055, 1173469194, 1176327370, 1179184566, 1182040765, 1184895947,
+ 1187750097, 1190603194, 1193455223, 1196306164, 1199155999, 1202004711,
+ 1204852283, 1207698695, 1210543930, 1213387970, 1216230797, 1219072393,
+ 1221912740, 1224751821, 1227589616, 1230426109, 1233261281, 1236095115,
+ 1238927592, 1241758694, 1244588403, 1247416702, 1250243573, 1253068996,
+ 1255892955, 1258715432, 1261536408, 1264355866, 1267173787, 1269990154,
+ 1272804948, 1275618151, 1278429747, 1281239715, 1284048040, 1286854702,
+ 1289659683, 1292462966, 1295264533, 1298064366, 1300862446, 1303658756,
+ 1306453277, 1309245992, 1312036883, 1314825932, 1317613121, 1320398431,
+ 1323181846, 1325963346, 1328742914, 1331520532, 1334296182, 1337069847,
+ 1339841507, 1342611145, 1345378744, 1348144285, 1350907751, 1353669123,
+ 1356428383, 1359185514, 1361940498, 1364693317, 1367443952, 1370192386,
+ 1372938602, 1375682580, 1378424304, 1381163756, 1383900917, 1386635769,
+ 1389368295, 1392098478, 1394826298, 1397551739, 1400274782, 1402995410,
+ 1405713605, 1408429348, 1411142623, 1413853411, 1416561695, 1419267457,
+ 1421970678, 1424671342, 1427369431, 1430064926, 1432757810, 1435448066,
+ 1438135675, 1440820620, 1443502883, 1446182447, 1448859293, 1451533405,
+ 1454204764, 1456873353, 1459539154, 1462202150, 1464862322, 1467519654,
+ 1470174128, 1472825725, 1475474430, 1478120223, 1480763087, 1483403006,
+ 1486039961, 1488673934, 1491304909, 1493932868, 1496557793, 1499179667,
+ 1501798473, 1504414192, 1507026808, 1509636304, 1512242661, 1514845862,
+ 1517445890, 1520042728, 1522636358, 1525226763, 1527813926, 1530397829,
+ 1532978455, 1535555786, 1538129807, 1540700498, 1543267843, 1545831826,
+ 1548392428, 1550949632, 1553503421, 1556053779, 1558600688, 1561144130,
+ 1563684089, 1566220548, 1568753490, 1571282897, 1573808752, 1576331039,
+ 1578849741, 1581364840, 1583876320, 1586384163, 1588888353, 1591388873,
+ 1593885705, 1596378834, 1598868242, 1601353912, 1603835828, 1606313972,
+ 1608788328, 1611258880, 1613725610, 1616188502, 1618647538, 1621102703,
+ 1623553980, 1626001352, 1628444803, 1630884315, 1633319872, 1635751459,
+ 1638179057, 1640602651, 1643022225, 1645437761, 1647849243, 1650256655,
+ 1652659981, 1655059203, 1657454307, 1659845275, 1662232091, 1664614738,
+ 1666993202, 1669367464, 1671737510, 1674103322, 1676464885, 1678822182,
+ 1681175198, 1683523917, 1685868321, 1688208396, 1690544125, 1692875492,
+ 1695202481, 1697525076, 1699843261, 1702157021, 1704466340, 1706771201,
+ 1709071589, 1711367487, 1713658881, 1715945755, 1718228092, 1720505877,
+ 1722779095, 1725047729, 1727311765, 1729571186, 1731825977, 1734076122,
+ 1736321606, 1738562414, 1740798529, 1743029938, 1745256623, 1747478570,
+ 1749695763, 1751908188, 1754115828, 1756318669, 1758516695, 1760709892,
+ 1762898243, 1765081734, 1767260350, 1769434075, 1771602895, 1773766795,
+ 1775925759, 1778079773, 1780228821, 1782372889, 1784511962, 1786646024,
+ 1788775063, 1790899061, 1793018005, 1795131880, 1797240672, 1799344365,
+ 1801442945, 1803536397, 1805624707, 1807707860, 1809785843, 1811858639,
+ 1813926236, 1815988618, 1818045771, 1820097680, 1822144333, 1824185713,
+ 1826221808, 1828252602, 1830278082, 1832298233, 1834313041, 1836322493,
+ 1838326575, 1840325271, 1842318569, 1844306454, 1846288912, 1848265930,
+ 1850237494, 1852203589, 1854164203, 1856119322, 1858068931, 1860013017,
+ 1861951567, 1863884566, 1865812002, 1867733861, 1869650129, 1871560793,
+ 1873465840, 1875365256, 1877259027, 1879147141, 1881029585, 1882906344,
+ 1884777407, 1886642759, 1888502388, 1890356280, 1892204422, 1894046803,
+ 1895883407, 1897714224, 1899539239, 1901358440, 1903171814, 1904979348,
+ 1906781030, 1908576847, 1910366786, 1912150835, 1913928980, 1915701210,
+ 1917467513, 1919227874, 1920982283, 1922730727, 1924473193, 1926209669,
+ 1927940142, 1929664602, 1931383035, 1933095429, 1934801772, 1936502052,
+ 1938196258, 1939884376, 1941566396, 1943242305, 1944912092, 1946575744,
+ 1948233249, 1949884597, 1951529776, 1953168773, 1954801577, 1956428177,
+ 1958048560, 1959662717, 1961270634, 1962872301, 1964467707, 1966056839,
+ 1967639687, 1969216240, 1970786486, 1972350414, 1973908014, 1975459273,
+ 1977004182, 1978542728, 1980074901, 1981600691, 1983120086, 1984633076,
+ 1986139649, 1987639796, 1989133505, 1990620766, 1992101568, 1993575901,
+ 1995043754, 1996505116, 1997959979, 1999408330, 2000850159, 2002285457,
+ 2003714214, 2005136418, 2006552060, 2007961130, 2009363618, 2010759513,
+ 2012148807, 2013531488, 2014907547, 2016276974, 2017639760, 2018995894,
+ 2020345368, 2021688171, 2023024294, 2024353727, 2025676460, 2026992485,
+ 2028301792, 2029604372, 2030900215, 2032189312, 2033471653, 2034747231,
+ 2036016034, 2037278056, 2038533285, 2039781714, 2041023334, 2042258135,
+ 2043486109, 2044707247, 2045921540, 2047128980, 2048329558, 2049523265,
+ 2050710093, 2051890033, 2053063077, 2054229216, 2055388443, 2056540748,
+ 2057686124, 2058824562, 2059956054, 2061080592, 2062198169, 2063308775,
+ 2064412403, 2065509045, 2066598694, 2067681340, 2068756978, 2069825598,
+ 2070887194, 2071941757, 2072989280, 2074029756, 2075063177, 2076089536,
+ 2077108824, 2078121036, 2079126164, 2080124199, 2081115137, 2082098968,
+ 2083075686, 2084045285, 2085007757, 2085963094, 2086911292, 2087852341,
+ 2088786237, 2089712971, 2090632538, 2091544930, 2092450142, 2093348167,
+ 2094238997, 2095122628, 2095999052, 2096868263, 2097730255, 2098585021,
+ 2099432556, 2100272854, 2101105908, 2101931712, 2102750261, 2103561548,
+ 2104365568, 2105162315, 2105951783, 2106733967, 2107508860, 2108276458,
+ 2109036754, 2109789744, 2110535421, 2111273781, 2112004818, 2112728527,
+ 2113444903, 2114153940, 2114855633, 2115549978, 2116236969, 2116916601,
+ 2117588870, 2118253770, 2118911297, 2119561447, 2120204213, 2120839593,
+ 2121467580, 2122088171, 2122701361, 2123307146, 2123905522, 2124496483,
+ 2125080026, 2125656147, 2126224841, 2126786104, 2127339932, 2127886322,
+ 2128425269, 2128956770, 2129480819, 2129997415, 2130506553, 2131008229,
+ 2131502440, 2131989182, 2132468452, 2132940246, 2133404560, 2133861392,
+ 2134310739, 2134752596, 2135186961, 2135613830, 2136033201, 2136445070,
+ 2136849435, 2137246292, 2137635639, 2138017473, 2138391791, 2138758590,
+ 2139117868, 2139469622, 2139813850, 2140150549, 2140479716, 2140801350,
+ 2141115448, 2141422007, 2141721026, 2142012503, 2142296434, 2142572819,
+ 2142841655, 2143102940, 2143356672, 2143602850, 2143841472, 2144072535,
+ 2144296039, 2144511982, 2144720361, 2144921177, 2145114426, 2145300109,
+ 2145478223, 2145648767, 2145811739, 2145967140, 2146114967, 2146255220,
+ 2146387897, 2146512998, 2146630522, 2146740467, 2146842833, 2146937620,
+ 2147024826, 2147104451, 2147176495, 2147240956, 2147297835, 2147347131,
+ 2147388843, 2147422972, 2147449517, 2147468478, 2147479854, 2147483646,
+ 2147479854, 2147468478, 2147449517, 2147422972, 2147388843, 2147347131,
+ 2147297835, 2147240956, 2147176495, 2147104451, 2147024826, 2146937620,
+ 2146842833, 2146740467, 2146630522, 2146512998, 2146387897, 2146255220,
+ 2146114967, 2145967140, 2145811739, 2145648767, 2145478223, 2145300109,
+ 2145114426, 2144921177, 2144720361, 2144511982, 2144296039, 2144072535,
+ 2143841472, 2143602850, 2143356672, 2143102940, 2142841655, 2142572819,
+ 2142296434, 2142012503, 2141721026, 2141422007, 2141115448, 2140801350,
+ 2140479716, 2140150549, 2139813850, 2139469622, 2139117868, 2138758590,
+ 2138391791, 2138017473, 2137635639, 2137246292, 2136849435, 2136445070,
+ 2136033201, 2135613830, 2135186961, 2134752596, 2134310739, 2133861392,
+ 2133404560, 2132940246, 2132468452, 2131989182, 2131502440, 2131008229,
+ 2130506553, 2129997415, 2129480819, 2128956770, 2128425269, 2127886322,
+ 2127339932, 2126786104, 2126224841, 2125656147, 2125080026, 2124496483,
+ 2123905522, 2123307146, 2122701361, 2122088171, 2121467580, 2120839593,
+ 2120204213, 2119561447, 2118911297, 2118253770, 2117588870, 2116916601,
+ 2116236969, 2115549978, 2114855633, 2114153940, 2113444903, 2112728527,
+ 2112004818, 2111273781, 2110535421, 2109789744, 2109036754, 2108276458,
+ 2107508860, 2106733967, 2105951783, 2105162315, 2104365568, 2103561548,
+ 2102750261, 2101931712, 2101105908, 2100272854, 2099432556, 2098585021,
+ 2097730255, 2096868263, 2095999052, 2095122628, 2094238997, 2093348167,
+ 2092450142, 2091544930, 2090632538, 2089712971, 2088786237, 2087852341,
+ 2086911292, 2085963094, 2085007757, 2084045285, 2083075686, 2082098968,
+ 2081115137, 2080124199, 2079126164, 2078121036, 2077108824, 2076089536,
+ 2075063177, 2074029756, 2072989280, 2071941757, 2070887194, 2069825598,
+ 2068756978, 2067681340, 2066598694, 2065509045, 2064412403, 2063308775,
+ 2062198169, 2061080592, 2059956054, 2058824562, 2057686124, 2056540748,
+ 2055388443, 2054229216, 2053063077, 2051890033, 2050710093, 2049523265,
+ 2048329558, 2047128980, 2045921540, 2044707247, 2043486109, 2042258135,
+ 2041023334, 2039781714, 2038533285, 2037278056, 2036016034, 2034747231,
+ 2033471653, 2032189312, 2030900215, 2029604372, 2028301792, 2026992485,
+ 2025676460, 2024353727, 2023024294, 2021688171, 2020345368, 2018995894,
+ 2017639760, 2016276974, 2014907547, 2013531488, 2012148807, 2010759513,
+ 2009363618, 2007961130, 2006552060, 2005136418, 2003714214, 2002285457,
+ 2000850159, 1999408330, 1997959979, 1996505116, 1995043754, 1993575901,
+ 1992101568, 1990620766, 1989133505, 1987639796, 1986139649, 1984633076,
+ 1983120086, 1981600691, 1980074901, 1978542728, 1977004182, 1975459273,
+ 1973908014, 1972350414, 1970786486, 1969216240, 1967639687, 1966056839,
+ 1964467707, 1962872301, 1961270634, 1959662717, 1958048560, 1956428177,
+ 1954801577, 1953168773, 1951529776, 1949884597, 1948233249, 1946575744,
+ 1944912092, 1943242305, 1941566396, 1939884376, 1938196258, 1936502052,
+ 1934801772, 1933095429, 1931383035, 1929664602, 1927940142, 1926209669,
+ 1924473193, 1922730727, 1920982283, 1919227874, 1917467513, 1915701210,
+ 1913928980, 1912150835, 1910366786, 1908576847, 1906781030, 1904979348,
+ 1903171814, 1901358440, 1899539239, 1897714224, 1895883407, 1894046803,
+ 1892204422, 1890356280, 1888502388, 1886642759, 1884777407, 1882906344,
+ 1881029585, 1879147141, 1877259027, 1875365256, 1873465840, 1871560793,
+ 1869650129, 1867733861, 1865812002, 1863884566, 1861951567, 1860013017,
+ 1858068931, 1856119322, 1854164203, 1852203589, 1850237494, 1848265930,
+ 1846288912, 1844306454, 1842318569, 1840325271, 1838326575, 1836322493,
+ 1834313041, 1832298233, 1830278082, 1828252602, 1826221808, 1824185713,
+ 1822144333, 1820097680, 1818045771, 1815988618, 1813926236, 1811858639,
+ 1809785843, 1807707860, 1805624707, 1803536397, 1801442945, 1799344365,
+ 1797240672, 1795131880, 1793018005, 1790899061, 1788775063, 1786646024,
+ 1784511962, 1782372889, 1780228821, 1778079773, 1775925759, 1773766795,
+ 1771602895, 1769434075, 1767260350, 1765081734, 1762898243, 1760709892,
+ 1758516695, 1756318669, 1754115828, 1751908188, 1749695763, 1747478570,
+ 1745256623, 1743029938, 1740798529, 1738562414, 1736321606, 1734076122,
+ 1731825977, 1729571186, 1727311765, 1725047729, 1722779095, 1720505877,
+ 1718228092, 1715945755, 1713658881, 1711367487, 1709071589, 1706771201,
+ 1704466340, 1702157021, 1699843261, 1697525076, 1695202481, 1692875492,
+ 1690544125, 1688208396, 1685868321, 1683523917, 1681175198, 1678822182,
+ 1676464885, 1674103322, 1671737510, 1669367464, 1666993202, 1664614738,
+ 1662232091, 1659845275, 1657454307, 1655059203, 1652659981, 1650256655,
+ 1647849243, 1645437761, 1643022225, 1640602651, 1638179057, 1635751459,
+ 1633319872, 1630884315, 1628444803, 1626001352, 1623553980, 1621102703,
+ 1618647538, 1616188502, 1613725610, 1611258880, 1608788328, 1606313972,
+ 1603835828, 1601353912, 1598868242, 1596378834, 1593885705, 1591388873,
+ 1588888353, 1586384163, 1583876320, 1581364840, 1578849741, 1576331039,
+ 1573808752, 1571282897, 1568753490, 1566220548, 1563684089, 1561144130,
+ 1558600688, 1556053779, 1553503421, 1550949632, 1548392428, 1545831826,
+ 1543267843, 1540700498, 1538129807, 1535555786, 1532978455, 1530397829,
+ 1527813926, 1525226763, 1522636358, 1520042728, 1517445890, 1514845862,
+ 1512242661, 1509636304, 1507026808, 1504414192, 1501798473, 1499179667,
+ 1496557793, 1493932868, 1491304909, 1488673934, 1486039961, 1483403006,
+ 1480763087, 1478120223, 1475474430, 1472825725, 1470174128, 1467519654,
+ 1464862322, 1462202150, 1459539154, 1456873353, 1454204764, 1451533405,
+ 1448859293, 1446182447, 1443502883, 1440820620, 1438135675, 1435448066,
+ 1432757810, 1430064926, 1427369431, 1424671342, 1421970678, 1419267457,
+ 1416561695, 1413853411, 1411142623, 1408429348, 1405713605, 1402995410,
+ 1400274782, 1397551739, 1394826298, 1392098478, 1389368295, 1386635769,
+ 1383900917, 1381163756, 1378424304, 1375682580, 1372938602, 1370192386,
+ 1367443952, 1364693317, 1361940498, 1359185514, 1356428383, 1353669123,
+ 1350907751, 1348144285, 1345378744, 1342611145, 1339841507, 1337069847,
+ 1334296182, 1331520532, 1328742914, 1325963346, 1323181846, 1320398431,
+ 1317613121, 1314825932, 1312036883, 1309245992, 1306453277, 1303658756,
+ 1300862446, 1298064366, 1295264533, 1292462966, 1289659683, 1286854702,
+ 1284048040, 1281239715, 1278429747, 1275618151, 1272804948, 1269990154,
+ 1267173787, 1264355866, 1261536408, 1258715432, 1255892955, 1253068996,
+ 1250243573, 1247416702, 1244588403, 1241758694, 1238927592, 1236095115,
+ 1233261281, 1230426109, 1227589616, 1224751821, 1221912740, 1219072393,
+ 1216230797, 1213387970, 1210543930, 1207698695, 1204852283, 1202004711,
+ 1199155999, 1196306164, 1193455223, 1190603194, 1187750097, 1184895947,
+ 1182040765, 1179184566, 1176327370, 1173469194, 1170610055, 1167749973,
+ 1164888964, 1162027048, 1159164240, 1156300560, 1153436026, 1150570654,
+ 1147704463, 1144837472, 1141969696, 1139101156, 1136231867, 1133361849,
+ 1130491119, 1127619694, 1124747593, 1121874833, 1119001432, 1116127408,
+ 1113252778, 1110377561, 1107501774, 1104625435, 1101748561, 1098871171,
+ 1095993281, 1093114911, 1090236076, 1087356796, 1084477087, 1081596968,
+ 1078716455, 1075835567, 1072954322, 1070072736, 1067190828, 1064308615,
+ 1061426114, 1058543344, 1055660322, 1052777065, 1049893591, 1047009917,
+ 1044126061, 1041242041, 1038357874, 1035473577, 1032589168, 1029704664,
+ 1026820083, 1023935442, 1021050759, 1018166051, 1015281336, 1012396630,
+ 1009511951, 1006627317, 1003742745, 1000858252, 997973855, 995089573,
+ 992205421, 989321418, 986437580, 983553925, 980670470, 977787232,
+ 974904229, 972021477, 969138994, 966256797, 963374903, 960493330,
+ 957612093, 954731211, 951850700, 948970578, 946090861, 943211567,
+ 940332712, 937454313, 934576388, 931698954, 928822026, 925945623,
+ 923069761, 920194457, 917319728, 914445591, 911572062, 908699158,
+ 905826897, 902955294, 900084367, 897214133, 894344607, 891475807,
+ 888607750, 885740451, 882873929, 880008198, 877143277, 874279181,
+ 871415927, 868553531, 865692011, 862831382, 859971661, 857112865,
+ 854255009, 851398111, 848542187, 845687253, 842833325, 839980420,
+ 837128554, 834277743, 831428004, 828579352, 825731805, 822885378,
+ 820040087, 817195949, 814352979, 811511195, 808670611, 805831244,
+ 802993110, 800156225, 797320604, 794486265, 791653222, 788821493,
+ 785991092, 783162035, 780334339, 777508018, 774683090, 771859570,
+ 769037473, 766216815, 763397612, 760579880, 757763634, 754948889,
+ 752135662, 749323968, 746513823, 743705242, 740898240, 738092833,
+ 735289037, 732486866, 729686337, 726887464, 724090264, 721294750,
+ 718500939, 715708846, 712918486, 710129874, 707343026, 704557956,
+ 701774680, 698993212, 696213569, 693435764, 690659813, 687885731,
+ 685113533, 682343233, 679574848, 676808390, 674043876, 671281320,
+ 668520737, 665762142, 663005549, 660250974, 657498430, 654747932,
+ 651999496, 649253135, 646508864, 643766698, 641026651, 638288737,
+ 635552972, 632819369, 630087943, 627358708, 624631679, 621906869,
+ 619184293, 616463966, 613745901, 611030112, 608316615, 605605421,
+ 602896547, 600190006, 597485811, 594783978, 592084519, 589387448,
+ 586692781, 584000529, 581310708, 578623331, 575938412, 573255964,
+ 570576001, 567898537, 565223585, 562551159, 559881273, 557213939,
+ 554549173, 551886986, 549227393, 546570406, 543916039, 541264306,
+ 538615220, 535968794, 533325040, 530683974, 528045606, 525409952,
+ 522777023, 520146833, 517519395, 514894721, 512272825, 509653720,
+ 507037418, 504423933, 501813277, 499205463, 496600503, 493998411,
+ 491399199, 488802879, 486209465, 483618969, 481031403, 478446779,
+ 475865112, 473286412, 470710692, 468137964, 465568241, 463001536,
+ 460437859, 457877224, 455319643, 452765128, 450213690, 447665343,
+ 445120097, 442577966, 440038960, 437503092, 434970374, 432440818,
+ 429914435, 427391237, 424871236, 422354443, 419840871, 417330530,
+ 414823433, 412319591, 409819016, 407321718, 404827710, 402337002,
+ 399849607, 397365535, 394884798, 392407406, 389933372, 387462707,
+ 384995420, 382531525, 380071030, 377613949, 375160291, 372710068,
+ 370263290, 367819968, 365380114, 362943737, 360510849, 358081460,
+ 355655582, 353233224, 350814397, 348399112, 345987380, 343579210,
+ 341174613, 338773600, 336376181, 333982366, 331592166, 329205590,
+ 326822650, 324443354, 322067714, 319695739, 317327440, 314962825,
+ 312601907, 310244693, 307891194, 305541421, 303195382, 300853087,
+ 298514547, 296179771, 293848768, 291521549, 289198122, 286878497,
+ 284562684, 282250692, 279942530, 277638209, 275337736, 273041122,
+ 270748376, 268459506, 266174523, 263893434, 261616250, 259342979,
+ 257073630, 254808213, 252546735, 250289207, 248035636, 245786031,
+ 243540402, 241298757, 239061104, 236827453, 234597811, 232372188,
+ 230150591, 227933030, 225719513, 223510047, 221304642, 219103306,
+ 216906046, 214712872, 212523791, 210338811, 208157941, 205981188,
+ 203808560, 201640066, 199475714, 197315510, 195159464, 193007582,
+ 190859873, 188716344, 186577003, 184441857, 182310915, 180184183,
+ 178061669, 175943381, 173829326, 171719511, 169613943, 167512631,
+ 165415580, 163322799, 161234294, 159150073, 157070143, 154994510,
+ 152923182, 150856165, 148793467, 146735094, 144681053, 142631351,
+ 140585995, 138544991, 136508346, 134476066, 132448159, 130424630,
+ 128405486, 126390734, 124380379, 122374429, 120372889, 118375765,
+ 116383065, 114394794, 112410958, 110431564, 108456616, 106486122,
+ 104520088, 102558519, 100601420, 98648799, 96700660, 94757010,
+ 92817854, 90883198, 88953047, 87027407, 85106284, 83189683, 81277609,
+ 79370067, 77467064, 75568605, 73674694, 71785337, 69900540, 68020306,
+ 66144642, 64273553, 62407042, 60545117, 58687780, 56835038, 54986895,
+ 53143356, 51304425, 49470108, 47640409, 45815332, 43994882, 42179065,
+ 40367883, 38561342, 36759446, 34962200, 33169607, 31381673, 29598400,
+ 27819794, 26045859, 24276599, 22512017, 20752118, 18996906, 17246385,
+ 15500559, 13759430, 12023005, 10291285, 8564275, 6841978, 5124399,
+ 3411540, 1703406, 0, -1698675, -3392616, -5081818, -6766279, -8445996,
+ -10120965, -11791182, -13456645, -15117351, -16773296, -18424478,
+ -20070893, -21712538, -23349412, -24981509, -26608829, -28231368,
+ -29849123, -31462091, -33070271, -34673659, -36272253, -37866049,
+ -39455047, -41039243, -42618635, -44193220, -45762997, -47327963,
+ -48888115, -50443451, -51993970, -53539670, -55080547, -56616601,
+ -58147828, -59674228, -61195798, -62712537, -64224442, -65731512,
+ -67233745, -68731139, -70223693, -71711406, -73194275, -74672298,
+ -76145476, -77613805, -79077286, -80535915, -81989693, -83438617,
+ -84882687, -86321901, -87756259, -89185758, -90610398, -92030179,
+ -93445098, -94855155, -96260349, -97660680, -99056145, -100446746,
+ -101832480, -103213348, -104589347, -105960479, -107326742, -108688136,
+ -110044660, -111396314, -112743097, -114085009, -115422050, -116754219,
+ -118081516, -119403941, -120721494, -122034174, -123341982, -124644917,
+ -125942979, -127236169, -128524486, -129807931, -131086504, -132360204,
+ -133629032, -134892989, -136152075, -137406289, -138655633, -139900107,
+ -141139711, -142374446, -143604312, -144829310, -146049440, -147264703,
+ -148475101, -149680633, -150881300, -152077104, -153268044, -154454122,
+ -155635339, -156811696, -157983194, -159149834, -160311616, -161468543,
+ -162620615, -163767833, -164910199, -166047713, -167180378, -168308195,
+ -169431164, -170549288, -171662568, -172771005, -173874601, -174973358,
+ -176067277, -177156359, -178240607, -179320022, -180394606, -181464360,
+ -182529288, -183589390, -184644668, -185695124, -186740761, -187781580,
+ -188817584, -189848774, -190875153, -191896723, -192913485, -193925443,
+ -194932599, -195934954, -196932512, -197925275, -198913244, -199896423,
+ -200874814, -201848420, -202817243, -203781286, -204740551, -205695041,
+ -206644759, -207589708, -208529890, -209465308, -210395966, -211321865,
+ -212243009, -213159401, -214071044, -214977941, -215880095, -216777509,
+ -217670186, -218558130, -219441343, -220319829, -221193591, -222062633,
+ -222926958, -223786568, -224641469, -225491662, -226337152, -227177942,
+ -228014036, -228845437, -229672148, -230494175, -231311519, -232124185,
+ -232932177, -233735499, -234534154, -235328146, -236117479, -236902156,
+ -237682183, -238457563, -239228300, -239994397, -240755860, -241512692,
+ -242264897, -243012480, -243755445, -244493795, -245227536, -245956672,
+ -246681206, -247401144, -248116489, -248827247, -249533421, -250235017,
+ -250932038, -251624490, -252312376, -252995702, -253674472, -254348691,
+ -255018363, -255683494, -256344088, -257000149, -257651684, -258298696,
+ -258941191, -259579173, -260212648, -260841621, -261466096, -262086078,
+ -262701573, -263312586, -263919122, -264521186, -265118783, -265711919,
+ -266300599, -266884827, -267464611, -268039954, -268610862, -269177341,
+ -269739396, -270297032, -270850256, -271399072, -271943486, -272483504,
+ -273019132, -273550374, -274077237, -274599726, -275117847, -275631606,
+ -276141009, -276646061, -277146768, -277643137, -278135172, -278622881,
+ -279106268, -279585340, -280060103, -280530563, -280996726, -281458597,
+ -281916184, -282369493, -282818528, -283263297, -283703807, -284140062,
+ -284572069, -284999835, -285423367, -285842669, -286257749, -286668613,
+ -287075268, -287477719, -287875974, -288270039, -288659921, -289045625,
+ -289427159, -289804529, -290177741, -290546803, -290911722, -291272503,
+ -291629153, -291981680, -292330090, -292674389, -293014586, -293350685,
+ -293682695, -294010623, -294334474, -294654256, -294969977, -295281642,
+ -295589260, -295892836, -296192379, -296487894, -296779390, -297066874,
+ -297350352, -297629831, -297905320, -298176824, -298444352, -298707910,
+ -298967507, -299223148, -299474842, -299722595, -299966416, -300206311,
+ -300442288, -300674355, -300902518, -301126786, -301347165, -301563664,
+ -301776289, -301985049, -302189950, -302391001, -302588210, -302781583,
+ -302971128, -303156854, -303338767, -303516876, -303691188, -303861711,
+ -304028452, -304191420, -304350623, -304506068, -304657762, -304805715,
+ -304949933, -305090425, -305227198, -305360261, -305489622, -305615288,
+ -305737267, -305855568, -305970198, -306081166, -306188479, -306292147,
+ -306392175, -306488574, -306581351, -306670514, -306756072, -306838032,
+ -306916403, -306991193, -307062410, -307130062, -307194158, -307254707,
+ -307311715, -307365193, -307415147, -307461587, -307504521, -307543956,
+ -307579902, -307612367, -307641360, -307666888, -307688961, -307707586,
+ -307722773, -307734529, -307742864, -307747785, -307749302, -307747423,
+ -307742156, -307733510, -307721495, -307706117, -307687386, -307665312,
+ -307639901, -307611163, -307579107, -307543742, -307505075, -307463117,
+ -307417875, -307369358, -307317575, -307262536, -307204248, -307142720,
+ -307077962, -307009982, -306938789, -306864392, -306786799, -306706020,
+ -306622064, -306534939, -306444655, -306351219, -306254642, -306154932,
+ -306052098, -305946150, -305837095, -305724944, -305609704, -305491386,
+ -305369998, -305245549, -305118048, -304987505, -304853928, -304717326,
+ -304577709, -304435086, -304289465, -304140856, -303989268, -303834711,
+ -303677192, -303516723, -303353310, -303186965, -303017695, -302845511,
+ -302670421, -302492435, -302311561, -302127809, -301941189, -301751709,
+ -301559379, -301364208, -301166206, -300965381, -300761742, -300555300,
+ -300346064, -300134042, -299919244, -299701680, -299481358, -299258288,
+ -299032480, -298803942, -298572685, -298338717, -298102048, -297862687,
+ -297620644, -297375927, -297128547, -296878513, -296625834, -296370519,
+ -296112579, -295852022, -295588858, -295323096, -295054745, -294783816,
+ -294510318, -294234259, -293955650, -293674500, -293390819, -293104615,
+ -292815899, -292524680, -292230967, -291934769, -291636098, -291334961,
+ -291031368, -290725329, -290416853, -290105951, -289792630, -289476902,
+ -289158775, -288838259, -288515363, -288190097, -287862471, -287532494,
+ -287200175, -286865524, -286528551, -286189266, -285847677, -285503794,
+ -285157627, -284809186, -284458480, -284105518, -283750310, -283392865,
+ -283033194, -282671306, -282307210, -281940916, -281572433, -281201771,
+ -280828940, -280453949, -280076808, -279697526, -279316112, -278932577,
+ -278546930, -278159181, -277769339, -277377413, -276983414, -276587351,
+ -276189232, -275789069, -275386871, -274982646, -274576405, -274168157,
+ -273757913, -273345680, -272931469, -272515290, -272097152, -271677064,
+ -271255037, -270831079, -270405201, -269977411, -269547720, -269116136,
+ -268682670, -268247331, -267810128, -267371072, -266930171, -266487435,
+ -266042874, -265596497, -265148314, -264698334, -264246567, -263793022,
+ -263337709, -262880637, -262421817, -261961256, -261498965, -261034953,
+ -260569231, -260101806, -259632689, -259161890, -258689417, -258215281,
+ -257739490, -257262054, -256782983, -256302286, -255819972, -255336052,
+ -254850533, -254363427, -253874742, -253384487, -252892673, -252399308,
+ -251904402, -251407964, -250910005, -250410532, -249909556, -249407085,
+ -248903130, -248397700, -247890803, -247382450, -246872650, -246361411,
+ -245848744, -245334658, -244819162, -244302265, -243783977, -243264307,
+ -242743265, -242220859, -241697098, -241171993, -240645553, -240117786,
+ -239588702, -239058310, -238526620, -237993640, -237459380, -236923850,
+ -236387058, -235849013, -235309725, -234769203, -234227456, -233684493,
+ -233140324, -232594958, -232048403, -231500669, -230951765, -230401700,
+ -229850484, -229298125, -228744632, -228190015, -227634282, -227077443,
+ -226519507, -225960482, -225400379, -224839205, -224276970, -223713683,
+ -223149353, -222583989, -222017599, -221450194, -220881781, -220312370,
+ -219741969, -219170588, -218598236, -218024921, -217450653, -216875439,
+ -216299290, -215722214, -215144219, -214565315, -213985511, -213404815,
+ -212823236, -212240783, -211657465, -211073290, -210488268, -209902407,
+ -209315715, -208728202, -208139876, -207550746, -206960821, -206370109,
+ -205778619, -205186360, -204593340, -203999568, -203405053, -202809803,
+ -202213826, -201617132, -201019730, -200421626, -199822831, -199223352,
+ -198623199, -198022379, -197420901, -196818774, -196216006, -195612606,
+ -195008582, -194403942, -193798696, -193192850, -192586415, -191979397,
+ -191371806, -190763650, -190154937, -189545675, -188935874, -188325540,
+ -187714683, -187103311, -186491431, -185879053, -185266184, -184652833,
+ -184039008, -183424717, -182809968, -182194769, -181579129, -180963056,
+ -180346558, -179729642, -179112317, -178494592, -177876473, -177257970,
+ -176639090, -176019841, -175400231, -174780269, -174159962, -173539318,
+ -172918344, -172297050, -171675443, -171053531, -170431321, -169808822,
+ -169186041, -168562986, -167939666, -167316087, -166692258, -166068186,
+ -165443880, -164819346, -164194593, -163569628, -162944459, -162319094,
+ -161693540, -161067806, -160441897, -159815823, -159189591, -158563208,
+ -157936682, -157310021, -156683231, -156056321, -155429298, -154802170,
+ -154174943, -153547626, -152920226, -152292749, -151665205, -151037599,
+ -150409940, -149782234, -149154490, -148526714, -147898913, -147271095,
+ -146643268, -146015437, -145387612, -144759798, -144132003, -143504234,
+ -142876499, -142248804, -141621156, -140993563, -140366032, -139738570,
+ -139111183, -138483880, -137856666, -137229549, -136602536, -135975634,
+ -135348849, -134722189, -134095661, -133469271, -132843027, -132216934,
+ -131591001, -130965233, -130339638, -129714222, -129088992, -128463956,
+ -127839118, -127214487, -126590069, -125965871, -125341898, -124718159,
+ -124094659, -123471405, -122848404, -122225662, -121603186, -120980982,
+ -120359056, -119737416, -119116068, -118495017, -117874272, -117253837,
+ -116633719, -116013925, -115394461, -114775333, -114156548, -113538112,
+ -112920031, -112302311, -111684959, -111067981, -110451383, -109835171,
+ -109219352, -108603931, -107988915, -107374309, -106760120, -106146354,
+ -105533016, -104920114, -104307652, -103695637, -103084075, -102472972,
+ -101862333, -101252165, -100642473, -100033264, -99424542, -98816315,
+ -98208587, -97601364, -96994653, -96388459, -95782787, -95177644,
+ -94573035, -93968965, -93365441, -92762468, -92160052, -91558197,
+ -90956910, -90356197, -89756062, -89156511, -88557550, -87959184,
+ -87361419, -86764260, -86167712, -85571781, -84976472, -84381790,
+ -83787742, -83194331, -82601564, -82009445, -81417980, -80827174,
+ -80237032, -79647560, -79058762, -78470644, -77883210, -77296467,
+ -76710418, -76125070, -75540426, -74956492, -74373274, -73790775,
+ -73209001, -72627957, -72047648, -71468078, -70889253, -70311177,
+ -69733855, -69157292, -68581493, -68006463, -67432205, -66858726,
+ -66286029, -65714119, -65143001, -64572680, -64003160, -63434446,
+ -62866543, -62299454, -61733184, -61167739, -60603122, -60039338,
+ -59476391, -58914286, -58353027, -57792619, -57233065, -56674371,
+ -56116541, -55559578, -55003488, -54448274, -53893941, -53340493,
+ -52787933, -52236267, -51685499, -51135632, -50586671, -50038619,
+ -49491481, -48945262, -48399964, -47855592, -47312150, -46769642,
+ -46228072, -45687443, -45147760, -44609027, -44071247, -43534425,
+ -42998563, -42463667, -41929739, -41396783, -40864804, -40333804,
+ -39803789, -39274760, -38746722, -38219679, -37693634, -37168591,
+ -36644553, -36121524, -35599508, -35078507, -34558526, -34039568,
+ -33521636, -33004733, -32488864, -31974032, -31460239, -30947490,
+ -30435787, -29925134, -29415534, -28906991, -28399507, -27893087,
+ -27387732, -26883447, -26380234, -25878096, -25377038, -24877061,
+ -24378168, -23880364, -23383651, -22888032, -22393509, -21900087,
+ -21407767, -20916554, -20426448, -19937455, -19449576, -18962814,
+ -18477173, -17992654, -17509261, -17026997, -16545864, -16065865,
+ -15587003, -15109280, -14632699, -14157263, -13682974, -13209835,
+ -12737848, -12267017, -11797343, -11328829, -10861478, -10395292,
+ -9930274, -9466426, -9003750, -8542249, -8081925, -7622781, -7164819,
+ -6708041, -6252449, -5798047, -5344835, -4892817, -4441994, -3992370,
+ -3543945, -3096722, -2650704, -2205891, -1762288, -1319895, -878714,
+ -438749, 0, 437530, 873840, 1308927, 1742789, 2175425, 2606833,
+ 3037010, 3465955, 3893666, 4320142, 4745379, 5169378, 5592135, 6013649,
+ 6433918, 6852941, 7270716, 7687241, 8102515, 8516536, 8929302, 9340812,
+ 9751064, 10160057, 10567789, 10974259, 11379464, 11783404, 12186078,
+ 12587483, 12987618, 13386483, 13784074, 14180392, 14575435, 14969201,
+ 15361690, 15752899, 16142828, 16531475, 16918840, 17304920, 17689715,
+ 18073224, 18455445, 18836377, 19216020, 19594371, 19971430, 20347197,
+ 20721669, 21094846, 21466726, 21837310, 22206595, 22574582, 22941268,
+ 23306653, 23670736, 24033517, 24394994, 24755167, 25114034, 25471595,
+ 25827849, 26182796, 26536434, 26888763, 27239783, 27589491, 27937889,
+ 28284974, 28630747, 28975207, 29318353, 29660185, 30000701, 30339903,
+ 30677788, 31014356, 31349607, 31683541, 32016157, 32347454, 32677432,
+ 33006091, 33333430, 33659449, 33984147, 34307525, 34629581, 34950316,
+ 35269729, 35587820, 35904588, 36220034, 36534157, 36846957, 37158433,
+ 37468587, 37777416, 38084922, 38391104, 38695962, 38999496, 39301705,
+ 39602591, 39902152, 40200388, 40497301, 40792889, 41087152, 41380092,
+ 41671707, 41961998, 42250965, 42538608, 42824927, 43109922, 43393594,
+ 43675942, 43956967, 44236669, 44515048, 44792105, 45067839, 45342251,
+ 45615341, 45887110, 46157557, 46426683, 46694489, 46960975, 47226140,
+ 47489986, 47752513, 48013722, 48273612, 48532184, 48789439, 49045377,
+ 49299999, 49553305, 49805295, 50055970, 50305332, 50553379, 50800114,
+ 51045536, 51289646, 51532444, 51773932, 52014110, 52252979, 52490538,
+ 52726790, 52961735, 53195373, 53427705, 53658733, 53888456, 54116875,
+ 54343992, 54569807, 54794321, 55017534, 55239448, 55460064, 55679382,
+ 55897404, 56114129, 56329560, 56543697, 56756540, 56968092, 57178353,
+ 57387323, 57595005, 57801398, 58006505, 58210325, 58412861, 58614112,
+ 58814081, 59012769, 59210175, 59406303, 59601152, 59794724, 59987020,
+ 60178041, 60367788, 60556263, 60743467, 60929401, 61114067, 61297465,
+ 61479596, 61660463, 61840066, 62018407, 62195487, 62371307, 62545869,
+ 62719173, 62891223, 63062018, 63231560, 63399850, 63566891, 63732683,
+ 63897228, 64060527, 64222582, 64383394, 64542965, 64701296, 64858389,
+ 65014245, 65168865, 65322252, 65474407, 65625332, 65775027, 65923495,
+ 66070737, 66216755, 66361550, 66505125, 66647480, 66788617, 66928539,
+ 67067246, 67204741, 67341025, 67476099, 67609966, 67742628, 67874085,
+ 68004340, 68133395, 68261251, 68387910, 68513374, 68637645, 68760724,
+ 68882614, 69003315, 69122831, 69241163, 69358312, 69474281, 69589071,
+ 69702685, 69815124, 69926391, 70036486, 70145413, 70253173, 70359767,
+ 70465199, 70569470, 70672581, 70774536, 70875335, 70974982, 71073477,
+ 71170823, 71267022, 71362077, 71455988, 71548759, 71640391, 71730886,
+ 71820247, 71908476, 71995574, 72081544, 72166387, 72250107, 72332705,
+ 72414184, 72494545, 72573791, 72651923, 72728945, 72804858, 72879664,
+ 72953367, 73025967, 73097467, 73167870, 73237177, 73305391, 73372514,
+ 73438549, 73503498, 73567362, 73630145, 73691848, 73752475, 73812026,
+ 73870505, 73927914, 73984255, 74039531, 74093744, 74146896, 74198989,
+ 74250027, 74300011, 74348944, 74396828, 74443665, 74489459, 74534211,
+ 74577924, 74620600, 74662242, 74702852, 74742433, 74780986, 74818516,
+ 74855023, 74890511, 74924982, 74958438, 74990882, 75022317, 75052745,
+ 75082168, 75110589, 75138011, 75164436, 75189867, 75214305, 75237755,
+ 75260217, 75281696, 75302193, 75321711, 75340253, 75357820, 75374417,
+ 75390045, 75404706, 75418405, 75431142, 75442921, 75453745, 75463616,
+ 75472536, 75480509, 75487537, 75493622, 75498768, 75502977, 75506251,
+ 75508593, 75510007, 75510494, 75510057, 75508699, 75506423, 75503232,
+ 75499127, 75494112, 75488190, 75481363, 75473634, 75465006, 75455481,
+ 75445062, 75433752, 75421553, 75408469, 75394502, 75379655, 75363931,
+ 75347332, 75329861, 75311521, 75292314, 75272244, 75251313, 75229525,
+ 75206881, 75183384, 75159038, 75133846, 75107809, 75080931, 75053214,
+ 75024662, 74995277, 74965062, 74934020, 74902154, 74869466, 74835960,
+ 74801637, 74766502, 74730556, 74693804, 74656246, 74617887, 74578729,
+ 74538775, 74498028, 74456491, 74414167, 74371058, 74327167, 74282497,
+ 74237052, 74190833, 74143844, 74096088, 74047568, 73998286, 73948245,
+ 73897448, 73845899, 73793599, 73740553, 73686762, 73632229, 73576958,
+ 73520952, 73464213, 73406744, 73348548, 73289628, 73229987, 73169628,
+ 73108554, 73046767, 72984271, 72921068, 72857162, 72792555, 72727250,
+ 72661250, 72594558, 72527177, 72459110, 72390359, 72320929, 72250821,
+ 72180038, 72108584, 72036461, 71963672, 71890221, 71816110, 71741341,
+ 71665919, 71589846, 71513124, 71435757, 71357748, 71279099, 71199814,
+ 71119895, 71039346, 70958169, 70876367, 70793944, 70710901, 70627242,
+ 70542971, 70458089, 70372600, 70286506, 70199812, 70112519, 70024630,
+ 69936149, 69847078, 69757420, 69667179, 69576356, 69484956, 69392980,
+ 69300433, 69207316, 69113633, 69019387, 68924580, 68829215, 68733296,
+ 68636826, 68539806, 68442241, 68344132, 68245484, 68146299, 68046579,
+ 67946328, 67845548, 67744244, 67642416, 67540069, 67437205, 67333827,
+ 67229938, 67125541, 67020639, 66915235, 66809331, 66702931, 66596037,
+ 66488653, 66380781, 66272423, 66163584, 66054265, 65944471, 65834202,
+ 65723464, 65612257, 65500586, 65388453, 65275861, 65162813, 65049311,
+ 64935359, 64820960, 64706115, 64590829, 64475104, 64358943, 64242348,
+ 64125323, 64007870, 63889993, 63771693, 63652975, 63533840, 63414292,
+ 63294333, 63173967, 63053195, 62932022, 62810449, 62688480, 62566117,
+ 62443363, 62320221, 62196694, 62072785, 61948496, 61823830, 61698790,
+ 61573379, 61447599, 61321454, 61194946, 61068078, 60940852, 60813272,
+ 60685340, 60557059, 60428432, 60299461, 60170150, 60040500, 59910516,
+ 59780199, 59649552, 59518578, 59387280, 59255660, 59123722, 58991468,
+ 58858900, 58726021, 58592835, 58459343, 58325549, 58191455, 58057064,
+ 57922379, 57787402, 57652136, 57516584, 57380747, 57244630, 57108235,
+ 56971564, 56834620, 56697406, 56559924, 56422177, 56284168, 56145899,
+ 56007373, 55868593, 55729560, 55590279, 55450751, 55310979, 55170966,
+ 55030714, 54890226, 54749505, 54608552, 54467372, 54325965, 54184336,
+ 54042486, 53900418, 53758134, 53615638, 53472931, 53330017, 53186898,
+ 53043576, 52900054, 52756334, 52612419, 52468312, 52324015, 52179531,
+ 52034861, 51890009, 51744978, 51599768, 51454384, 51308828, 51163101,
+ 51017207, 50871148, 50724927, 50578546, 50432007, 50285312, 50138465,
+ 49991468, 49844323, 49697033, 49549600, 49402026, 49254314, 49106467,
+ 48958486, 48810374, 48662134, 48513768, 48365278, 48216667, 48067936,
+ 47919090, 47770129, 47621056, 47471874, 47322584, 47173190, 47023693,
+ 46874096, 46724402, 46574611, 46424728, 46274754, 46124691, 45974542,
+ 45824309, 45673995, 45523601, 45373130, 45222584, 45071965, 44921276,
+ 44770520, 44619697, 44468811, 44317863, 44166856, 44015793, 43864674,
+ 43713504, 43562283, 43411013, 43259699, 43108340, 42956940, 42805501,
+ 42654024, 42502513, 42350969, 42199394, 42047790, 41896161, 41744507,
+ 41592831, 41441135, 41289421, 41137691, 40985948, 40834193, 40682429,
+ 40530657, 40378880, 40227100, 40075319, 39923538, 39771761, 39619988,
+ 39468223, 39316467, 39164722, 39012990, 38861273, 38709574, 38557893,
+ 38406234, 38254598, 38102987, 37951404, 37799849, 37648326, 37496836,
+ 37345380, 37193962, 37042582, 36891244, 36739948, 36588696, 36437492,
+ 36286336, 36135230, 35984177, 35833177, 35682234, 35531349, 35380524,
+ 35229760, 35079060, 34928426, 34777858, 34627360, 34476933, 34326578,
+ 34176298, 34026094, 33875969, 33725923, 33575960, 33426079, 33276285,
+ 33126577, 32976958, 32827430, 32677994, 32528652, 32379407, 32230258,
+ 32081209, 31932262, 31783417, 31634676, 31486042, 31337515, 31189098,
+ 31040792, 30892599, 30744521, 30596559, 30448715, 30300990, 30153386,
+ 30005906, 29858549, 29711319, 29564216, 29417243, 29270400, 29123690,
+ 28977114, 28830674, 28684370, 28538206, 28392181, 28246299, 28100560,
+ 27954966, 27809518, 27664219, 27519068, 27374069, 27229223, 27084530,
+ 26939993, 26795613, 26651391, 26507329, 26363429, 26219691, 26076118,
+ 25932711, 25789470, 25646399, 25503497, 25360767, 25218209, 25075826,
+ 24933619, 24791588, 24649736, 24508064, 24366573, 24225264, 24084139,
+ 23943200, 23802447, 23661882, 23521506, 23381320, 23241327, 23101526,
+ 22961920, 22822510, 22683297, 22544282, 22405467, 22266852, 22128440,
+ 21990231, 21852227, 21714428, 21576836, 21439453, 21302279, 21165316,
+ 21028565, 20892027, 20755703, 20619595, 20483703, 20348030, 20212575,
+ 20077340, 19942327, 19807536, 19672969, 19538626, 19404509, 19270619,
+ 19136957, 19003525, 18870322, 18737351, 18604612, 18472107, 18339837,
+ 18207802, 18076003, 17944443, 17813121, 17682039, 17551197, 17420598,
+ 17290241, 17160128, 17030261, 16900639, 16771263, 16642136, 16513258,
+ 16384629, 16256251, 16128124, 16000251, 15872631, 15745265, 15618155,
+ 15491301, 15364704, 15238366, 15112286, 14986467, 14860908, 14735612,
+ 14610577, 14485807, 14361300, 14237059, 14113084, 13989376, 13865935,
+ 13742763, 13619860, 13497228, 13374866, 13252777, 13130960, 13009416,
+ 12888146, 12767152, 12646433, 12525990, 12405825, 12285938, 12166329,
+ 12047000, 11927952, 11809184, 11690697, 11572493, 11454572, 11336935,
+ 11219583, 11102515, 10985733, 10869238, 10753030, 10637109, 10521477,
+ 10406135, 10291082, 10176319, 10061847, 9947667, 9833780, 9720185,
+ 9606883, 9493876, 9381163, 9268746, 9156625, 9044799, 8933271, 8822040,
+ 8711108, 8600474, 8490139, 8380104, 8270369, 8160935, 8051802, 7942971,
+ 7834442, 7726217, 7618294, 7510675, 7403360, 7296351, 7189646, 7083247,
+ 6977154, 6871368, 6765888, 6660716, 6555852, 6451297, 6347050, 6243112,
+ 6139484, 6036166, 5933158, 5830461, 5728075, 5626000, 5524237, 5422787,
+ 5321649, 5220825, 5120313, 5020116, 4920232, 4820662, 4721408, 4622468,
+ 4523844, 4425535, 4327542, 4229866, 4132505, 4035462, 3938736, 3842327,
+ 3746236, 3650463, 3555008, 3459871, 3365053, 3270554, 3176374, 3082513,
+ 2988972, 2895751, 2802850, 2710269, 2618009, 2526069, 2434450, 2343152,
+ 2252175, 2161520, 2071186, 1981174, 1891484, 1802116, 1713070, 1624347,
+ 1535946, 1447867, 1360112, 1272679, 1185569, 1098782, 1012319, 926179,
+ 840362, 754868, 669699, 584853, 500331, 416132, 332258, 248707, 165480,
+ 82578, 0, -82254, -164184, -245790, -327071, -408029, -488662, -568970,
+ -648955, -728615, -807951, -886963, -965650, -1044013, -1122052,
+ -1199766, -1277157, -1354223, -1430965, -1507383, -1583477, -1659247,
+ -1734694, -1809816, -1884615, -1959090, -2033241, -2107069, -2180573,
+ -2253755, -2326612, -2399147, -2471359, -2543248, -2614814, -2686057,
+ -2756978, -2827576, -2897852, -2967806, -3037438, -3106748, -3175736,
+ -3244403, -3312749, -3380773, -3448476, -3515858, -3582919, -3649660,
+ -3716081, -3782181, -3847962, -3913423, -3978564, -4043386, -4107888,
+ -4172072, -4235937, -4299484, -4362712, -4425622, -4488215, -4550490,
+ -4612447, -4674088, -4735412, -4796419, -4857110, -4917485, -4977544,
+ -5037288, -5096717, -5155830, -5214629, -5273114, -5331285, -5389142,
+ -5446685, -5503915, -5560832, -5617437, -5673730, -5729711, -5785380,
+ -5840737, -5895784, -5950521, -6004947, -6059063, -6112869, -6166367,
+ -6219555, -6272435, -6325007, -6377270, -6429227, -6480876, -6532219,
+ -6583255, -6633986, -6684410, -6734530, -6784345, -6833855, -6883062,
+ -6931964, -6980564, -7028861, -7076855, -7124548, -7171938, -7219028,
+ -7265817, -7312306, -7358495, -7404384, -7449974, -7495266, -7540260,
+ -7584956, -7629355, -7673457, -7717262, -7760772, -7803987, -7846906,
+ -7889531, -7931862, -7973899, -8015644, -8057095, -8098255, -8139123,
+ -8179700, -8219986, -8259982, -8299689, -8339106, -8378234, -8417075,
+ -8455627, -8493893, -8531872, -8569564, -8606972, -8644094, -8680931,
+ -8717485, -8753754, -8789741, -8825446, -8860868, -8896009, -8930870,
+ -8965450, -8999750, -9033771, -9067513, -9100978, -9134164, -9167074,
+ -9199707, -9232064, -9264146, -9295954, -9327487, -9358746, -9389733,
+ -9420447, -9450889, -9481060, -9510960, -9540590, -9569950, -9599042,
+ -9627865, -9656420, -9684708, -9712730, -9740485, -9767976, -9795201,
+ -9822162, -9848860, -9875295, -9901467, -9927378, -9953028, -9978417,
+ -10003546, -10028416, -10053027, -10077381, -10101477, -10125316,
+ -10148899, -10172227, -10195300, -10218118, -10240683, -10262996,
+ -10285055, -10306864, -10328421, -10349728, -10370785, -10391593,
+ -10412153, -10432465, -10452530, -10472349, -10491921, -10511249,
+ -10530332, -10549172, -10567768, -10586122, -10604234, -10622105,
+ -10639735, -10657126, -10674278, -10691191, -10707866, -10724305,
+ -10740507, -10756473, -10772204, -10787701, -10802964, -10817995,
+ -10832793, -10847359, -10861695, -10875800, -10889676, -10903323,
+ -10916742, -10929933, -10942897, -10955636, -10968149, -10980438,
+ -10992502, -11004344, -11015963, -11027360, -11038536, -11049491,
+ -11060227, -11070743, -11081042, -11091123, -11100987, -11110634,
+ -11120067, -11129284, -11138288, -11147078, -11155656, -11164022,
+ -11172176, -11180121, -11187855, -11195381, -11202698, -11209808,
+ -11216710, -11223407, -11229898, -11236185, -11242268, -11248148,
+ -11253825, -11259300, -11264574, -11269648, -11274523, -11279199,
+ -11283676, -11287956, -11292040, -11295928, -11299620, -11303118,
+ -11306422, -11309534, -11312453, -11315181, -11317717, -11320064,
+ -11322222, -11324191, -11325972, -11327566, -11328974, -11330196,
+ -11331233, -11332087, -11332756, -11333243, -11333549, -11333673,
+ -11333616, -11333380, -11332965, -11332372, -11331601, -11330654,
+ -11329531, -11328232, -11326759, -11325112, -11323292, -11321300,
+ -11319136, -11316802, -11314298, -11311624, -11308781, -11305771,
+ -11302594, -11299250, -11295741, -11292067, -11288229, -11284228,
+ -11280064, -11275738, -11271250, -11266603, -11261796, -11256830,
+ -11251705, -11246424, -11240985, -11235391, -11229642, -11223738,
+ -11217680, -11211469, -11205107, -11198592, -11191927, -11185112,
+ -11178147, -11171034, -11163774, -11156366, -11148811, -11141112,
+ -11133267, -11125278, -11117146, -11108871, -11100455, -11091897,
+ -11083198, -11074360, -11065383, -11056268, -11047015, -11037626,
+ -11028100, -11018440, -11008644, -10998715, -10988653, -10978458,
+ -10968131, -10957674, -10947087, -10936370, -10925524, -10914550,
+ -10903449, -10892221, -10880868, -10869389, -10857786, -10846060,
+ -10834210, -10822238, -10810145, -10797931, -10785597, -10773143,
+ -10760571, -10747881, -10735074, -10722150, -10709110, -10695956,
+ -10682687, -10669304, -10655809, -10642201, -10628482, -10614652,
+ -10600712, -10586662, -10572504, -10558238, -10543865, -10529385,
+ -10514799, -10500109, -10485313, -10470414, -10455412, -10440308,
+ -10425102, -10409794, -10394387, -10378880, -10363275, -10347571,
+ -10331769, -10315871, -10299877, -10283787, -10267603, -10251324,
+ -10234952, -10218488, -10201931, -10185284, -10168545, -10151717,
+ -10134799, -10117793, -10100699, -10083518, -10066250, -10048896,
+ -10031457, -10013933, -9996326, -9978635, -9960862, -9943007, -9925071,
+ -9907054, -9888957, -9870782, -9852527, -9834195, -9815785, -9797299,
+ -9778737, -9760100, -9741388, -9722602, -9703743, -9684811, -9665807,
+ -9646732, -9627586, -9608370, -9589084, -9569730, -9550308, -9530818,
+ -9511261, -9491638, -9471949, -9452196, -9432378, -9412496, -9392551,
+ -9372544, -9352475, -9332344, -9312154, -9291903, -9271593, -9251224,
+ -9230797, -9210312, -9189771, -9169174, -9148520, -9127812, -9107050,
+ -9086233, -9065363, -9044441, -9023467, -9002441, -8981365, -8960238,
+ -8939062, -8917837, -8896563, -8875242, -8853873, -8832458, -8810996,
+ -8789490, -8767938, -8746342, -8724702, -8703020, -8681294, -8659527,
+ -8637718, -8615869, -8593979, -8572050, -8550081, -8528074, -8506029,
+ -8483947, -8461827, -8439672, -8417481, -8395254, -8372993, -8350698,
+ -8328370, -8306008, -8283614, -8261189, -8238732, -8216244, -8193726,
+ -8171178, -8148602, -8125996, -8103363, -8080702, -8058014, -8035300,
+ -8012560, -7989794, -7967004, -7944189, -7921350, -7898488, -7875604,
+ -7852697, -7829768, -7806818, -7783848, -7760857, -7737847, -7714817,
+ -7691769, -7668702, -7645618, -7622517, -7599399, -7576265, -7553115,
+ -7529951, -7506771, -7483577, -7460370, -7437149, -7413916, -7390670,
+ -7367413, -7344144, -7320865, -7297575, -7274275, -7250966, -7227648,
+ -7204322, -7180988, -7157646, -7134297, -7110942, -7087580, -7064213,
+ -7040841, -7017464, -6994083, -6970697, -6947309, -6923917, -6900523,
+ -6877127, -6853730, -6830331, -6806931, -6783532, -6760132, -6736733,
+ -6713335, -6689938, -6666544, -6643151, -6619762, -6596375, -6572992,
+ -6549613, -6526239, -6502869, -6479504, -6456146, -6432793, -6409447,
+ -6386107, -6362775, -6339451, -6316134, -6292827, -6269528, -6246238,
+ -6222958, -6199688, -6176428, -6153180, -6129942, -6106717, -6083503,
+ -6060301, -6037113, -6013937, -5990775, -5967627, -5944493, -5921374,
+ -5898270, -5875181, -5852108, -5829050, -5806010, -5782986, -5759979,
+ -5736990, -5714019, -5691066, -5668131, -5645216, -5622320, -5599443,
+ -5576586, -5553750, -5530934, -5508139, -5485366, -5462614, -5439884,
+ -5417177, -5394492, -5371830, -5349191, -5326576, -5303985, -5281418,
+ -5258876, -5236358, -5213866, -5191399, -5168958, -5146544, -5124155,
+ -5101793, -5079459, -5057152, -5034872, -5012620, -4990397, -4968202,
+ -4946036, -4923898, -4901791, -4879713, -4857665, -4835647, -4813660,
+ -4791703, -4769778, -4747884, -4726021, -4704191, -4682393, -4660627,
+ -4638894, -4617193, -4595526, -4573893, -4552293, -4530728, -4509196,
+ -4487699, -4466237, -4444810, -4423418, -4402062, -4380741, -4359457,
+ -4338209, -4316997, -4295822, -4274684, -4253583, -4232520, -4211494,
+ -4190506, -4169557, -4148645, -4127772, -4106939, -4086144, -4065388,
+ -4044672, -4023995, -4003359, -3982762, -3962206, -3941690, -3921215,
+ -3900781, -3880388, -3860037, -3839727, -3819458, -3799232, -3779048,
+ -3758906, -3738807, -3718750, -3698736, -3678766, -3658838, -3638955,
+ -3619114, -3599318, -3579565, -3559857, -3540193, -3520574, -3500999,
+ -3481469, -3461985, -3442545, -3423151, -3403802, -3384499, -3365242,
+ -3346031, -3326866, -3307747, -3288675, -3269650, -3250671, -3231739,
+ -3212855, -3194017, -3175227, -3156485, -3137790, -3119143, -3100544,
+ -3081993, -3063490, -3045035, -3026629, -3008272, -2989963, -2971703,
+ -2953492, -2935331, -2917218, -2899155, -2881142, -2863178, -2845263,
+ -2827399, -2809584, -2791820, -2774105, -2756441, -2738828, -2721265,
+ -2703752, -2686290, -2668879, -2651519, -2634210, -2616951, -2599745,
+ -2582589, -2565485, -2548432, -2531431, -2514481, -2497583, -2480737,
+ -2463943, -2447201, -2430511, -2413873, -2397287, -2380754, -2364273,
+ -2347844, -2331468, -2315144, -2298874, -2282656, -2266490, -2250378,
+ -2234318, -2218312, -2202358, -2186458, -2170611, -2154817, -2139076,
+ -2123389, -2107755, -2092175, -2076648, -2061174, -2045755, -2030388,
+ -2015076, -1999817, -1984612, -1969461, -1954364, -1939320, -1924331,
+ -1909395, -1894514, -1879686, -1864913, -1850194, -1835528, -1820917,
+ -1806361, -1791858, -1777410, -1763015, -1748676, -1734390, -1720159,
+ -1705982, -1691859, -1677791, -1663778, -1649818, -1635913, -1622063,
+ -1608267, -1594525, -1580838, -1567205, -1553627, -1540103, -1526634,
+ -1513219, -1499859, -1486553, -1473302, -1460105, -1446962, -1433874,
+ -1420841, -1407862, -1394937, -1382067, -1369251, -1356490, -1343783,
+ -1331130, -1318532, -1305988, -1293498, -1281063, -1268682, -1256355,
+ -1244083, -1231865, -1219701, -1207591, -1195535, -1183534, -1171587,
+ -1159693, -1147854, -1136069, -1124337, -1112660, -1101037, -1089467,
+ -1077952, -1066490, -1055082, -1043727, -1032426, -1021179, -1009986,
+ -998846, -987760, -976727, -965748, -954822, -943949, -933129, -922363,
+ -911650, -900990, -890384, -879830, -869329, -858881, -848486, -838144,
+ -827855, -817618, -807434, -797303, -787224, -777197, -767223, -757301,
+ -747432, -737615, -727849, -718136, -708475, -698866, -689309, -679803,
+ -670349, -660947, -651597, -642297, -633050, -623853, -614708, -605615,
+ -596572, -587580, -578639, -569750, -560911, -552122, -543385, -534698,
+ -526061, -517475, -508939, -500453, -492018, -483632, -475297, -467011,
+ -458775, -450589, -442452, -434365, -426328, -418339, -410400, -402510,
+ -394669, -386877, -379134, -371440, -363794, -356197, -348649, -341149,
+ -333697, -326293, -318937, -311629, -304369, -297157, -289993, -282876,
+ -275807, -268785, -261810, -254882, -248001, -241168, -234381, -227641,
+ -220947, -214300, -207699, -201145, -194636, -188174, -181758, -175387,
+ -169063, -162784, -156550, -150362, -144219, -138121, -132068, -126060,
+ -120097, -114178, -108304, -102475, -96690, -90949, -85252, -79599,
+ -73990, -68425, -62903, -57425, -51990, -46598, -41250, -35945, -30682,
+ -25462, -20285, -15150, -10058, -5008, 0
+};
diff --git a/kernel/framework/audio/fltdata2_h.inc b/kernel/framework/audio/fltdata2_h.inc
new file mode 100644
index 0000000..2f3cf33
--- /dev/null
+++ b/kernel/framework/audio/fltdata2_h.inc
@@ -0,0 +1,2503 @@
+/*
+ * Purpose: Filter coefficient tables for GRC3
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+static int32_t filter_data[16385] = {
+ 0, -2498, -5007, -7527, -10057, -12598, -15149, -17711, -20283, -22866,
+ -25459, -28063, -30677, -33301, -35936, -38582, -41238, -43904, -46581,
+ -49268, -51966, -54674, -57392, -60121, -62860, -65610, -68370, -71141,
+ -73922, -76713, -79515, -82327, -85149, -87982, -90825, -93678, -96542,
+ -99416, -102301, -105195, -108100, -111016, -113941, -116877, -119823,
+ -122779, -125746, -128723, -131710, -134707, -137714, -140732, -143760,
+ -146798, -149846, -152904, -155972, -159051, -162139, -165238, -168347,
+ -171466, -174594, -177733, -180882, -184041, -187210, -190389, -193578,
+ -196777, -199986, -203205, -206433, -209672, -212920, -216179, -219447,
+ -222725, -226013, -229310, -232618, -235935, -239262, -242599, -245945,
+ -249301, -252667, -256042, -259427, -262822, -266227, -269641, -273064,
+ -276497, -279940, -283392, -286854, -290325, -293805, -297295, -300795,
+ -304304, -307822, -311350, -314886, -318433, -321988, -325553, -329127,
+ -332710, -336303, -339904, -343515, -347135, -350764, -354402, -358050,
+ -361706, -365371, -369045, -372728, -376421, -380122, -383832, -387550,
+ -391278, -395014, -398760, -402514, -406276, -410048, -413828, -417617,
+ -421414, -425220, -429035, -432858, -436690, -440530, -444378, -448235,
+ -452101, -455974, -459857, -463747, -467646, -471553, -475468, -479391,
+ -483323, -487262, -491210, -495166, -499130, -503102, -507082, -511069,
+ -515065, -519069, -523080, -527099, -531126, -535161, -539203, -543253,
+ -547311, -551376, -555449, -559530, -563618, -567713, -571816, -575926,
+ -580044, -584169, -588301, -592440, -596587, -600741, -604902, -609070,
+ -613245, -617427, -621616, -625812, -630015, -634225, -638442, -642665,
+ -646895, -651132, -655376, -659626, -663883, -668146, -672416, -676693,
+ -680975, -685265, -689560, -693862, -698170, -702484, -706805, -711132,
+ -715464, -719803, -724148, -728499, -732855, -737218, -741586, -745961,
+ -750341, -754726, -759117, -763514, -767917, -772325, -776738, -781157,
+ -785581, -790011, -794446, -798886, -803331, -807782, -812237, -816698,
+ -821164, -825634, -830110, -834590, -839075, -843565, -848060, -852559,
+ -857063, -861571, -866084, -870602, -875123, -879650, -884180, -888715,
+ -893254, -897797, -902344, -906895, -911451, -916010, -920573, -925140,
+ -929711, -934285, -938863, -943445, -948031, -952620, -957212, -961808,
+ -966407, -971009, -975615, -980224, -984836, -989451, -994069, -998690,
+ -1003314, -1007941, -1012571, -1017203, -1021838, -1026476, -1031116,
+ -1035759, -1040404, -1045052, -1049702, -1054354, -1059009, -1063665,
+ -1068324, -1072985, -1077648, -1082313, -1086979, -1091648, -1096318,
+ -1100990, -1105663, -1110338, -1115015, -1119693, -1124372, -1129053,
+ -1133735, -1138418, -1143102, -1147787, -1152474, -1157161, -1161849,
+ -1166538, -1171228, -1175918, -1180609, -1185301, -1189993, -1194686,
+ -1199379, -1204072, -1208765, -1213459, -1218153, -1222847, -1227540,
+ -1232234, -1236928, -1241621, -1246314, -1251007, -1255699, -1260391,
+ -1265082, -1269773, -1274463, -1279152, -1283840, -1288528, -1293214,
+ -1297900, -1302584, -1307267, -1311950, -1316630, -1321310, -1325987,
+ -1330664, -1335339, -1340012, -1344683, -1349353, -1354021, -1358687,
+ -1363350, -1368012, -1372672, -1377329, -1381984, -1386637, -1391288,
+ -1395935, -1400581, -1405223, -1409863, -1414500, -1419135, -1423766,
+ -1428394, -1433019, -1437641, -1442260, -1446876, -1451488, -1456097,
+ -1460702, -1465303, -1469901, -1474495, -1479086, -1483672, -1488255,
+ -1492833, -1497407, -1501977, -1506543, -1511105, -1515662, -1520214,
+ -1524762, -1529305, -1533844, -1538377, -1542906, -1547430, -1551949,
+ -1556463, -1560971, -1565474, -1569972, -1574465, -1578952, -1583433,
+ -1587909, -1592378, -1596843, -1601301, -1605753, -1610199, -1614639,
+ -1619073, -1623500, -1627921, -1632336, -1636744, -1641146, -1645540,
+ -1649929, -1654310, -1658684, -1663051, -1667411, -1671764, -1676110,
+ -1680448, -1684779, -1689102, -1693418, -1697726, -1702027, -1706319,
+ -1710604, -1714880, -1719149, -1723409, -1727662, -1731905, -1736141,
+ -1740368, -1744586, -1748796, -1752997, -1757189, -1761372, -1765546,
+ -1769711, -1773867, -1778014, -1782152, -1786280, -1790398, -1794507,
+ -1798606, -1802696, -1806776, -1810845, -1814905, -1818955, -1822995,
+ -1827024, -1831043, -1835051, -1839050, -1843037, -1847014, -1850980,
+ -1854935, -1858879, -1862812, -1866734, -1870645, -1874545, -1878433,
+ -1882310, -1886175, -1890029, -1893871, -1897701, -1901520, -1905326,
+ -1909120, -1912902, -1916672, -1920430, -1924175, -1927908, -1931628,
+ -1935336, -1939030, -1942712, -1946381, -1950037, -1953680, -1957310,
+ -1960926, -1964529, -1968119, -1971695, -1975258, -1978806, -1982341,
+ -1985863, -1989370, -1992863, -1996342, -1999806, -2003257, -2006693,
+ -2010114, -2013521, -2016913, -2020291, -2023654, -2027001, -2030334,
+ -2033651, -2036954, -2040241, -2043513, -2046769, -2050009, -2053234,
+ -2056444, -2059637, -2062815, -2065976, -2069122, -2072251, -2075364,
+ -2078461, -2081541, -2084605, -2087652, -2090682, -2093696, -2096693,
+ -2099672, -2102635, -2105581, -2108509, -2111420, -2114313, -2117189,
+ -2120048, -2122889, -2125712, -2128517, -2131304, -2134073, -2136824,
+ -2139557, -2142272, -2144968, -2147646, -2150305, -2152945, -2155567,
+ -2158170, -2160754, -2163319, -2165865, -2168391, -2170899, -2173387,
+ -2175855, -2178304, -2180734, -2183144, -2185533, -2187904, -2190254,
+ -2192584, -2194893, -2197183, -2199452, -2201701, -2203929, -2206137,
+ -2208324, -2210490, -2212636, -2214760, -2216864, -2218946, -2221007,
+ -2223047, -2225066, -2227063, -2229038, -2230992, -2232924, -2234834,
+ -2236722, -2238589, -2240433, -2242255, -2244055, -2245832, -2247587,
+ -2249320, -2251030, -2252717, -2254382, -2256023, -2257642, -2259238,
+ -2260810, -2262360, -2263886, -2265388, -2266868, -2268323, -2269755,
+ -2271164, -2272548, -2273909, -2275246, -2276558, -2277847, -2279111,
+ -2280351, -2281567, -2282758, -2283924, -2285066, -2286183, -2287276,
+ -2288343, -2289386, -2290403, -2291395, -2292362, -2293304, -2294220,
+ -2295111, -2295976, -2296816, -2297630, -2298418, -2299180, -2299916,
+ -2300626, -2301310, -2301968, -2302600, -2303205, -2303783, -2304335,
+ -2304861, -2305359, -2305831, -2306276, -2306694, -2307086, -2307449,
+ -2307786, -2308096, -2308378, -2308633, -2308860, -2309059, -2309231,
+ -2309375, -2309492, -2309580, -2309640, -2309673, -2309677, -2309653,
+ -2309601, -2309520, -2309411, -2309273, -2309107, -2308912, -2308688,
+ -2308436, -2308154, -2307844, -2307504, -2307135, -2306738, -2306310,
+ -2305854, -2305368, -2304852, -2304307, -2303732, -2303128, -2302493,
+ -2301829, -2301135, -2300410, -2299656, -2298871, -2298057, -2297211,
+ -2296336, -2295430, -2294493, -2293526, -2292528, -2291499, -2290440,
+ -2289350, -2288228, -2287076, -2285892, -2284677, -2283431, -2282154,
+ -2280845, -2279505, -2278133, -2276730, -2275295, -2273828, -2272330,
+ -2270800, -2269237, -2267643, -2266016, -2264358, -2262667, -2260944,
+ -2259189, -2257401, -2255581, -2253728, -2251842, -2249924, -2247974,
+ -2245990, -2243974, -2241924, -2239842, -2237727, -2235578, -2233396,
+ -2231181, -2228933, -2226652, -2224337, -2221988, -2219606, -2217191,
+ -2214741, -2212258, -2209742, -2207191, -2204607, -2201988, -2199336,
+ -2196649, -2193929, -2191174, -2188385, -2185561, -2182703, -2179811,
+ -2176885, -2173923, -2170928, -2167897, -2164832, -2161732, -2158598,
+ -2155428, -2152224, -2148984, -2145710, -2142400, -2139056, -2135676,
+ -2132261, -2128811, -2125325, -2121804, -2118248, -2114656, -2111029,
+ -2107366, -2103667, -2099933, -2096163, -2092357, -2088516, -2084638,
+ -2080725, -2076776, -2072790, -2068769, -2064712, -2060618, -2056488,
+ -2052322, -2048120, -2043881, -2039607, -2035295, -2030947, -2026563,
+ -2022142, -2017685, -2013191, -2008660, -2004093, -1999489, -1994848,
+ -1990171, -1985456, -1980705, -1975916, -1971091, -1966229, -1961329,
+ -1956393, -1951420, -1946409, -1941361, -1936276, -1931154, -1925994,
+ -1920797, -1915563, -1910291, -1904982, -1899636, -1894252, -1888830,
+ -1883371, -1877874, -1872340, -1866768, -1861159, -1855511, -1849826,
+ -1844104, -1838343, -1832545, -1826709, -1820835, -1814923, -1808973,
+ -1802985, -1796959, -1790896, -1784794, -1778654, -1772476, -1766261,
+ -1760007, -1753714, -1747384, -1741016, -1734609, -1728164, -1721681,
+ -1715160, -1708600, -1702002, -1695366, -1688692, -1681979, -1675228,
+ -1668438, -1661610, -1654744, -1647839, -1640896, -1633914, -1626894,
+ -1619836, -1612739, -1605603, -1598429, -1591217, -1583966, -1576676,
+ -1569348, -1561981, -1554576, -1547132, -1539650, -1532129, -1524569,
+ -1516971, -1509334, -1501659, -1493945, -1486192, -1478401, -1470571,
+ -1462702, -1454795, -1446849, -1438865, -1430842, -1422780, -1414680,
+ -1406540, -1398363, -1390147, -1381892, -1373598, -1365266, -1356895,
+ -1348486, -1340038, -1331551, -1323026, -1314462, -1305859, -1297218,
+ -1288538, -1279820, -1271063, -1262268, -1253434, -1244562, -1235651,
+ -1226701, -1217713, -1208687, -1199622, -1190518, -1181376, -1172196,
+ -1162977, -1153720, -1144425, -1135091, -1125718, -1116308, -1106859,
+ -1097371, -1087846, -1078282, -1068680, -1059039, -1049361, -1039644,
+ -1029889, -1020096, -1010265, -1000396, -990488, -980543, -970560,
+ -960538, -950479, -940381, -930246, -920073, -909862, -899613, -889326,
+ -879002, -868640, -858240, -847802, -837327, -826814, -816264, -805676,
+ -795050, -784387, -773687, -762949, -752174, -741362, -730512, -719625,
+ -708700, -697739, -686740, -675704, -664632, -653522, -642375, -631191,
+ -619971, -608713, -597419, -586088, -574720, -563316, -551875, -540397,
+ -528883, -517333, -505746, -494122, -482463, -470767, -459035, -447266,
+ -435462, -423621, -411745, -399832, -387884, -375899, -363879, -351823,
+ -339732, -327605, -315442, -303244, -291010, -278741, -266437, -254097,
+ -241723, -229313, -216868, -204388, -191873, -179323, -166738, -154119,
+ -141465, -128776, -116053, -103295, -90503, -77676, -64815, -51920,
+ -38991, -26028, -13031, 0, 13064, 26163, 39296, 52462, 65661, 78894,
+ 92161, 105461, 118794, 132160, 145559, 158991, 172457, 185955, 199485,
+ 213049, 226645, 240274, 253934, 267628, 281353, 295111, 308901, 322723,
+ 336576, 350462, 364379, 378328, 392308, 406320, 420364, 434438, 448544,
+ 462681, 476848, 491047, 505277, 519537, 533828, 548149, 562501, 576883,
+ 591295, 605737, 620210, 634712, 649244, 663806, 678398, 693019, 707669,
+ 722349, 737058, 751796, 766563, 781359, 796184, 811037, 825919, 840830,
+ 855768, 870735, 885731, 900754, 915805, 930884, 945990, 961124, 976286,
+ 991475, 1006691, 1021934, 1037204, 1052501, 1067825, 1083175, 1098552,
+ 1113956, 1129385, 1144841, 1160323, 1175831, 1191364, 1206923, 1222508,
+ 1238118, 1253754, 1269414, 1285100, 1300811, 1316546, 1332306, 1348091,
+ 1363899, 1379733, 1395590, 1411471, 1427377, 1443306, 1459258, 1475234,
+ 1491234, 1507257, 1523302, 1539371, 1555462, 1571577, 1587713, 1603872,
+ 1620054, 1636257, 1652483, 1668730, 1684999, 1701289, 1717601, 1733935,
+ 1750289, 1766664, 1783060, 1799477, 1815915, 1832373, 1848851, 1865349,
+ 1881867, 1898405, 1914963, 1931540, 1948136, 1964752, 1981387, 1998040,
+ 2014713, 2031404, 2048113, 2064841, 2081587, 2098351, 2115133, 2131932,
+ 2148749, 2165583, 2182435, 2199303, 2216189, 2233091, 2250010, 2266945,
+ 2283896, 2300864, 2317847, 2334846, 2351861, 2368891, 2385936, 2402997,
+ 2420072, 2437162, 2454267, 2471386, 2488520, 2505667, 2522829, 2540004,
+ 2557193, 2574395, 2591610, 2608839, 2626080, 2643334, 2660601, 2677880,
+ 2695171, 2712474, 2729790, 2747116, 2764455, 2781804, 2799165, 2816537,
+ 2833919, 2851312, 2868716, 2886129, 2903553, 2920987, 2938430, 2955883,
+ 2973345, 2990816, 3008297, 3025786, 3043283, 3060790, 3078304, 3095826,
+ 3113356, 3130894, 3148439, 3165992, 3183552, 3201118, 3218692, 3236271,
+ 3253858, 3271450, 3289048, 3306652, 3324261, 3341876, 3359496, 3377121,
+ 3394751, 3412386, 3430024, 3447667, 3465314, 3482965, 3500619, 3518277,
+ 3535938, 3553602, 3571269, 3588938, 3606610, 3624284, 3641960, 3659637,
+ 3677317, 3694997, 3712679, 3730362, 3748046, 3765730, 3783414, 3801099,
+ 3818784, 3836468, 3854152, 3871835, 3889517, 3907199, 3924879, 3942557,
+ 3960234, 3977909, 3995581, 4013251, 4030919, 4048584, 4066246, 4083905,
+ 4101560, 4119212, 4136859, 4154503, 4172143, 4189778, 4207408, 4225033,
+ 4242653, 4260268, 4277877, 4295481, 4313078, 4330669, 4348254, 4365832,
+ 4383403, 4400967, 4418524, 4436073, 4453614, 4471148, 4488673, 4506189,
+ 4523697, 4541196, 4558686, 4576167, 4593638, 4611099, 4628550, 4645991,
+ 4663421, 4680841, 4698250, 4715648, 4733034, 4750409, 4767771, 4785122,
+ 4802460, 4819786, 4837099, 4854400, 4871687, 4888960, 4906220, 4923466,
+ 4940697, 4957915, 4975117, 4992305, 5009478, 5026635, 5043777, 5060903,
+ 5078013, 5095107, 5112184, 5129245, 5146289, 5163315, 5180324, 5197315,
+ 5214289, 5231244, 5248181, 5265099, 5281999, 5298879, 5315740, 5332581,
+ 5349403, 5366204, 5382986, 5399746, 5416486, 5433205, 5449903, 5466579,
+ 5483233, 5499865, 5516476, 5533063, 5549628, 5566170, 5582689, 5599184,
+ 5615656, 5632104, 5648527, 5664927, 5681301, 5697651, 5713975, 5730274,
+ 5746548, 5762795, 5779016, 5795211, 5811380, 5827521, 5843636, 5859722,
+ 5875782, 5891813, 5907817, 5923792, 5939738, 5955656, 5971544, 5987403,
+ 6003233, 6019032, 6034802, 6050541, 6066250, 6081927, 6097574, 6113189,
+ 6128773, 6144325, 6159845, 6175332, 6190787, 6206209, 6221598, 6236953,
+ 6252275, 6267563, 6282817, 6298036, 6313221, 6328371, 6343486, 6358566,
+ 6373610, 6388618, 6403590, 6418526, 6433425, 6448287, 6463112, 6477899,
+ 6492649, 6507361, 6522035, 6536671, 6551267, 6565825, 6580344, 6594823,
+ 6609263, 6623663, 6638022, 6652341, 6666620, 6680857, 6695054, 6709208,
+ 6723322, 6737393, 6751422, 6765408, 6779352, 6793253, 6807110, 6820924,
+ 6834695, 6848421, 6862103, 6875741, 6889334, 6902882, 6916384, 6929841,
+ 6943253, 6956618, 6969937, 6983209, 6996435, 7009613, 7022745, 7035829,
+ 7048864, 7061852, 7074792, 7087683, 7100525, 7113318, 7126062, 7138756,
+ 7151400, 7163994, 7176538, 7189031, 7201474, 7213865, 7226205, 7238493,
+ 7250730, 7262914, 7275046, 7287125, 7299151, 7311125, 7323044, 7334911,
+ 7346723, 7358481, 7370185, 7381834, 7393428, 7404967, 7416451, 7427878,
+ 7439250, 7450566, 7461826, 7473028, 7484174, 7495263, 7506294, 7517268,
+ 7528183, 7539041, 7549840, 7560580, 7571261, 7581884, 7592446, 7602949,
+ 7613393, 7623776, 7634098, 7644360, 7654561, 7664701, 7674779, 7684796,
+ 7694751, 7704643, 7714473, 7724241, 7733946, 7743587, 7753165, 7762680,
+ 7772130, 7781517, 7790839, 7800096, 7809289, 7818416, 7827478, 7836475,
+ 7845406, 7854270, 7863068, 7871800, 7880465, 7889063, 7897593, 7906056,
+ 7914451, 7922778, 7931037, 7939227, 7947349, 7955401, 7963385, 7971299,
+ 7979143, 7986917, 7994621, 8002254, 8009817, 8017309, 8024730, 8032080,
+ 8039358, 8046564, 8053698, 8060759, 8067748, 8074665, 8081508, 8088278,
+ 8094974, 8101597, 8108146, 8114620, 8121021, 8127346, 8133597, 8139772,
+ 8145873, 8151897, 8157846, 8163719, 8169515, 8175235, 8180879, 8186445,
+ 8191934, 8197346, 8202680, 8207936, 8213115, 8218215, 8223236, 8228179,
+ 8233042, 8237827, 8242532, 8247157, 8251703, 8256168, 8260553, 8264858,
+ 8269082, 8273225, 8277286, 8281267, 8285165, 8288982, 8292717, 8296369,
+ 8299939, 8303427, 8306831, 8310152, 8313390, 8316545, 8319615, 8322602,
+ 8325504, 8328322, 8331056, 8333704, 8336268, 8338746, 8341139, 8343446,
+ 8345668, 8347803, 8349852, 8351814, 8353690, 8355479, 8357181, 8358796,
+ 8360323, 8361762, 8363113, 8364377, 8365552, 8366638, 8367636, 8368545,
+ 8369365, 8370096, 8370737, 8371288, 8371750, 8372121, 8372403, 8372593,
+ 8372693, 8372703, 8372621, 8372448, 8372184, 8371828, 8371380, 8370840,
+ 8370208, 8369484, 8368667, 8367758, 8366756, 8365660, 8364471, 8363189,
+ 8361814, 8360344, 8358780, 8357123, 8355371, 8353524, 8351583, 8349547,
+ 8347416, 8345189, 8342867, 8340450, 8337937, 8335328, 8332623, 8329822,
+ 8326924, 8323929, 8320838, 8317650, 8314365, 8310983, 8307503, 8303926,
+ 8300251, 8296478, 8292607, 8288637, 8284570, 8280404, 8276139, 8271775,
+ 8267312, 8262750, 8258089, 8253328, 8248468, 8243508, 8238448, 8233288,
+ 8228027, 8222666, 8217205, 8211643, 8205980, 8200217, 8194352, 8188386,
+ 8182318, 8176149, 8169878, 8163506, 8157031, 8150455, 8143776, 8136995,
+ 8130111, 8123125, 8116036, 8108844, 8101549, 8094151, 8086649, 8079044,
+ 8071336, 8063524, 8055608, 8047588, 8039464, 8031236, 8022904, 8014467,
+ 8005926, 7997280, 7988529, 7979673, 7970713, 7961647, 7952476, 7943200,
+ 7933818, 7924330, 7914737, 7905038, 7895234, 7885323, 7875306, 7865183,
+ 7854953, 7844618, 7834175, 7823626, 7812970, 7802208, 7791338, 7780362,
+ 7769278, 7758087, 7746789, 7735383, 7723870, 7712250, 7700521, 7688685,
+ 7676741, 7664689, 7652529, 7640261, 7627885, 7615401, 7602808, 7590106,
+ 7577297, 7564378, 7551351, 7538215, 7524971, 7511617, 7498154, 7484583,
+ 7470902, 7457112, 7443213, 7429205, 7415087, 7400860, 7386523, 7372077,
+ 7357521, 7342855, 7328080, 7313195, 7298200, 7283095, 7267880, 7252555,
+ 7237120, 7221575, 7205919, 7190154, 7174278, 7158292, 7142195, 7125988,
+ 7109671, 7093243, 7076704, 7060055, 7043296, 7026426, 7009445, 6992353,
+ 6975150, 6957837, 6940413, 6922878, 6905233, 6887476, 6869608, 6851630,
+ 6833540, 6815340, 6797028, 6778606, 6760072, 6741428, 6722672, 6703805,
+ 6684827, 6665738, 6646538, 6627226, 6607804, 6588270, 6568625, 6548869,
+ 6529002, 6509023, 6488934, 6468733, 6448421, 6427998, 6407463, 6386818,
+ 6366061, 6345193, 6324214, 6303124, 6281923, 6260610, 6239187, 6217652,
+ 6196007, 6174250, 6152382, 6130404, 6108314, 6086113, 6063802, 6041379,
+ 6018846, 5996201, 5973446, 5950581, 5927604, 5904517, 5881318, 5858010,
+ 5834590, 5811061, 5787420, 5763669, 5739808, 5715836, 5691754, 5667561,
+ 5643258, 5618845, 5594322, 5569689, 5544946, 5520092, 5495129, 5470056,
+ 5444873, 5419580, 5394178, 5368666, 5343044, 5317313, 5291472, 5265522,
+ 5239463, 5213294, 5187016, 5160630, 5134134, 5107529, 5080815, 5053993,
+ 5027062, 5000022, 4972874, 4945618, 4918253, 4890779, 4863198, 4835508,
+ 4807711, 4779805, 4751792, 4723671, 4695443, 4667107, 4638663, 4610113,
+ 4581455, 4552690, 4523818, 4494839, 4465753, 4436561, 4407262, 4377857,
+ 4348345, 4318727, 4289003, 4259173, 4229238, 4199196, 4169049, 4138797,
+ 4108439, 4077976, 4047408, 4016735, 3985957, 3955074, 3924087, 3892996,
+ 3861800, 3830500, 3799096, 3767588, 3735976, 3704261, 3672443, 3640521,
+ 3608496, 3576368, 3544137, 3511804, 3479368, 3446830, 3414190, 3381447,
+ 3348603, 3315657, 3282609, 3249460, 3216210, 3182859, 3149407, 3115854,
+ 3082201, 3048447, 3014593, 2980639, 2946586, 2912432, 2878180, 2843828,
+ 2809377, 2774827, 2740178, 2705431, 2670585, 2635641, 2600600, 2565460,
+ 2530223, 2494889, 2459457, 2423929, 2388303, 2352582, 2316763, 2280849,
+ 2244839, 2208733, 2172532, 2136235, 2099843, 2063356, 2026775, 1990099,
+ 1953329, 1916465, 1879507, 1842456, 1805311, 1768073, 1730743, 1693320,
+ 1655804, 1618196, 1580496, 1542705, 1504822, 1466848, 1428783, 1390627,
+ 1352381, 1314044, 1275617, 1237101, 1198495, 1159800, 1121016, 1082143,
+ 1043182, 1004132, 964995, 925770, 886457, 847057, 807570, 767997,
+ 728337, 688591, 648759, 608842, 568839, 528751, 488579, 448322, 407980,
+ 367555, 327046, 286454, 245779, 205021, 164181, 123258, 82253, 41167,
+ 0, -41248, -82577, -123987, -165477, -207047, -248696, -290425,
+ -332232, -374118, -416083, -458125, -500245, -542443, -584718, -627069,
+ -669497, -712001, -754580, -797235, -839966, -882771, -925651, -968604,
+ -1011632, -1054733, -1097908, -1141155, -1184475, -1227867, -1271331,
+ -1314866, -1358472, -1402150, -1445898, -1489716, -1533603, -1577560,
+ -1621587, -1665682, -1709845, -1754077, -1798376, -1842743, -1887176,
+ -1931676, -1976243, -2020875, -2065573, -2110336, -2155164, -2200056,
+ -2245013, -2290033, -2335116, -2380263, -2425472, -2470743, -2516076,
+ -2561470, -2606926, -2652442, -2698019, -2743656, -2789352, -2835107,
+ -2880921, -2926794, -2972724, -3018712, -3064757, -3110860, -3157018,
+ -3203233, -3249503, -3295828, -3342209, -3388643, -3435132, -3481675,
+ -3528270, -3574919, -3621619, -3668372, -3715177, -3762032, -3808938,
+ -3855895, -3902902, -3949958, -3997063, -4044217, -4091419, -4138668,
+ -4185966, -4233310, -4280701, -4328137, -4375620, -4423148, -4470720,
+ -4518337, -4565998, -4613702, -4661450, -4709240, -4757072, -4804946,
+ -4852862, -4900818, -4948815, -4996851, -5044927, -5093042, -5141196,
+ -5189388, -5237618, -5285885, -5334189, -5382529, -5430905, -5479316,
+ -5527763, -5576244, -5624759, -5673308, -5721889, -5770504, -5819150,
+ -5867829, -5916538, -5965279, -6014049, -6062850, -6111680, -6160538,
+ -6209425, -6258341, -6307283, -6356253, -6405249, -6454271, -6503318,
+ -6552391, -6601488, -6650609, -6699754, -6748922, -6798112, -6847324,
+ -6896559, -6945814, -6995090, -7044386, -7093701, -7143036, -7192389,
+ -7241761, -7291150, -7340556, -7389979, -7439418, -7488872, -7538342,
+ -7587826, -7637325, -7686836, -7736361, -7785899, -7835448, -7885009,
+ -7934581, -7984164, -8033756, -8083358, -8132969, -8182588, -8232215,
+ -8281850, -8331491, -8381139, -8430792, -8480451, -8530114, -8579781,
+ -8629453, -8679127, -8728804, -8778483, -8828163, -8877845, -8927527,
+ -8977209, -9026890, -9076570, -9126249, -9175925, -9225598, -9275268,
+ -9324935, -9374596, -9424253, -9473905, -9523550, -9573189, -9622820,
+ -9672444, -9722060, -9771667, -9821264, -9870852, -9920429, -9969995,
+ -10019549, -10069092, -10118622, -10168138, -10217641, -10267129,
+ -10316602, -10366060, -10415502, -10464927, -10514335, -10563726,
+ -10613097, -10662451, -10711784, -10761098, -10810391, -10859663,
+ -10908913, -10958141, -11007346, -11056527, -11105685, -11154818,
+ -11203925, -11253007, -11302063, -11351092, -11400093, -11449066,
+ -11498011, -11546926, -11595811, -11644667, -11693491, -11742283,
+ -11791044, -11839772, -11888466, -11937127, -11985753, -12034344,
+ -12082899, -12131418, -12179901, -12228345, -12276752, -12325120,
+ -12373450, -12421739, -12469988, -12518196, -12566362, -12614486,
+ -12662567, -12710605, -12758599, -12806549, -12854453, -12902312,
+ -12950124, -12997890, -13045607, -13093277, -13140898, -13188469,
+ -13235991, -13283462, -13330882, -13378250, -13425566, -13472828,
+ -13520038, -13567193, -13614293, -13661338, -13708327, -13755259,
+ -13802134, -13848951, -13895710, -13942409, -13989049, -14035629,
+ -14082148, -14128606, -14175001, -14221334, -14267603, -14313808,
+ -14359949, -14406025, -14452035, -14497979, -14543855, -14589664,
+ -14635405, -14681077, -14726679, -14772212, -14817673, -14863064,
+ -14908382, -14953628, -14998801, -15043900, -15088925, -15133874,
+ -15178748, -15223546, -15268267, -15312910, -15357476, -15401962,
+ -15446370, -15490697, -15534944, -15579109, -15623193, -15667194,
+ -15711113, -15754947, -15798698, -15842363, -15885943, -15929436,
+ -15972843, -16016163, -16059394, -16102537, -16145591, -16188554,
+ -16231427, -16274209, -16316900, -16359498, -16402002, -16444414,
+ -16486731, -16528953, -16571079, -16613110, -16655044, -16696880,
+ -16738619, -16780258, -16821799, -16863240, -16904580, -16945819,
+ -16986957, -17027992, -17068924, -17109753, -17150477, -17191096,
+ -17231611, -17272019, -17312320, -17352514, -17392600, -17432577,
+ -17472446, -17512204, -17551852, -17591389, -17630815, -17670128,
+ -17709328, -17748414, -17787387, -17826245, -17864987, -17903613,
+ -17942123, -17980515, -18018790, -18056946, -18094983, -18132900,
+ -18170697, -18208373, -18245927, -18283359, -18320668, -18357854,
+ -18394916, -18431853, -18468665, -18505351, -18541911, -18578343,
+ -18614648, -18650824, -18686871, -18722789, -18758576, -18794233,
+ -18829758, -18865152, -18900412, -18935539, -18970533, -19005392,
+ -19040116, -19074704, -19109156, -19143471, -19177648, -19211688,
+ -19245588, -19279349, -19312971, -19346451, -19379791, -19412989,
+ -19446044, -19478957, -19511725, -19544350, -19576830, -19609165,
+ -19641353, -19673395, -19705290, -19737037, -19768635, -19800085,
+ -19831385, -19862535, -19893534, -19924381, -19955077, -19985620,
+ -20016010, -20046246, -20076328, -20106255, -20136027, -20165642,
+ -20195101, -20224402, -20253546, -20282531, -20311356, -20340023,
+ -20368529, -20396874, -20425058, -20453080, -20480939, -20508636,
+ -20536168, -20563536, -20590740, -20617777, -20644649, -20671354,
+ -20697892, -20724263, -20750465, -20776498, -20802361, -20828055,
+ -20853578, -20878929, -20904109, -20929117, -20953951, -20978613,
+ -21003100, -21027412, -21051550, -21075512, -21099297, -21122906,
+ -21146337, -21169590, -21192665, -21215561, -21238277, -21260813,
+ -21283168, -21305342, -21327334, -21349144, -21370770, -21392214,
+ -21413473, -21434548, -21455437, -21476141, -21496659, -21516990,
+ -21537133, -21557089, -21576857, -21596435, -21615825, -21635024,
+ -21654032, -21672850, -21691476, -21709910, -21728152, -21746200,
+ -21764054, -21781715, -21799180, -21816451, -21833525, -21850404,
+ -21867085, -21883569, -21899856, -21915944, -21931833, -21947523,
+ -21963013, -21978302, -21993391, -22008278, -22022963, -22037446,
+ -22051726, -22065802, -22079675, -22093343, -22106806, -22120064,
+ -22133115, -22145961, -22158599, -22171030, -22183254, -22195269,
+ -22207075, -22218671, -22230058, -22241235, -22252201, -22262955,
+ -22273498, -22283828, -22293946, -22303851, -22313542, -22323019,
+ -22332281, -22341329, -22350161, -22358777, -22367176, -22375359,
+ -22383324, -22391072, -22398601, -22405911, -22413003, -22419874,
+ -22426526, -22432957, -22439167, -22445156, -22450923, -22456468,
+ -22461790, -22466889, -22471764, -22476415, -22480842, -22485044,
+ -22489020, -22492771, -22496295, -22499594, -22502665, -22505508,
+ -22508124, -22510511, -22512670, -22514600, -22516300, -22517770,
+ -22519010, -22520019, -22520797, -22521344, -22521659, -22521741,
+ -22521590, -22521207, -22520590, -22519739, -22518653, -22517333,
+ -22515778, -22513988, -22511962, -22509699, -22507200, -22504464,
+ -22501490, -22498279, -22494830, -22491142, -22487216, -22483050,
+ -22478645, -22474000, -22469115, -22463989, -22458622, -22453014,
+ -22447164, -22441072, -22434738, -22428161, -22421341, -22414277,
+ -22406970, -22399419, -22391624, -22383584, -22375298, -22366768,
+ -22357991, -22348969, -22339700, -22330185, -22320423, -22310413,
+ -22300156, -22289651, -22278897, -22267896, -22256645, -22245145,
+ -22233396, -22221397, -22209148, -22196649, -22183899, -22170898,
+ -22157646, -22144143, -22130388, -22116381, -22102121, -22087610,
+ -22072845, -22057827, -22042556, -22027031, -22011252, -21995219,
+ -21978932, -21962390, -21945593, -21928541, -21911233, -21893670,
+ -21875851, -21857776, -21839444, -21820856, -21802011, -21782909,
+ -21763549, -21743932, -21724057, -21703925, -21683533, -21662884,
+ -21641976, -21620809, -21599383, -21577697, -21555753, -21533548,
+ -21511084, -21488359, -21465374, -21442129, -21418623, -21394856,
+ -21370829, -21346540, -21321989, -21297177, -21272103, -21246768,
+ -21221170, -21195310, -21169187, -21142802, -21116155, -21089244,
+ -21062070, -21034633, -21006933, -20978969, -20950741, -20922250,
+ -20893495, -20864476, -20835192, -20805644, -20775832, -20745755,
+ -20715413, -20684807, -20653936, -20622799, -20591397, -20559731,
+ -20527798, -20495600, -20463137, -20430408, -20397413, -20364152,
+ -20330625, -20296832, -20262773, -20228448, -20193856, -20158998,
+ -20123874, -20088483, -20052825, -20016901, -19980710, -19944252,
+ -19907527, -19870535, -19833277, -19795751, -19757958, -19719898,
+ -19681571, -19642977, -19604116, -19564987, -19525591, -19485928,
+ -19445997, -19405799, -19365334, -19324601, -19283601, -19242333,
+ -19200798, -19158996, -19116926, -19074588, -19031984, -18989111,
+ -18945972, -18902565, -18858890, -18814948, -18770739, -18726263,
+ -18681519, -18636508, -18591230, -18545684, -18499872, -18453792,
+ -18407445, -18360832, -18313951, -18266803, -18219389, -18171707,
+ -18123759, -18075545, -18027063, -17978315, -17929301, -17880020,
+ -17830473, -17780660, -17730581, -17680235, -17629624, -17578747,
+ -17527604, -17476195, -17424521, -17372581, -17320376, -17267906,
+ -17215171, -17162171, -17108906, -17055376, -17001582, -16947523,
+ -16893200, -16838612, -16783761, -16728645, -16673266, -16617623,
+ -16561717, -16505548, -16449115, -16392419, -16335461, -16278240,
+ -16220756, -16163010, -16105002, -16046732, -15988200, -15929407,
+ -15870352, -15811036, -15751460, -15691622, -15631524, -15571165,
+ -15510546, -15449667, -15388529, -15327131, -15265473, -15203557,
+ -15141381, -15078948, -15016255, -14953305, -14890096, -14826630,
+ -14762907, -14698926, -14634688, -14570194, -14505443, -14440436,
+ -14375174, -14309655, -14243882, -14177853, -14111569, -14045031,
+ -13978239, -13911193, -13843893, -13776340, -13708534, -13640475,
+ -13572163, -13503600, -13434784, -13365717, -13296399, -13226830,
+ -13157011, -13086941, -13016621, -12946052, -12875233, -12804166,
+ -12732850, -12661286, -12589474, -12517414, -12445108, -12372554,
+ -12299754, -12226708, -12153417, -12079880, -12006098, -11932071,
+ -11857800, -11783286, -11708527, -11633526, -11558283, -11482797,
+ -11407069, -11331100, -11254889, -11178438, -11101747, -11024816,
+ -10947646, -10870236, -10792588, -10714702, -10636579, -10558218,
+ -10479620, -10400786, -10321716, -10242410, -10162870, -10083095,
+ -10003086, -9922843, -9842367, -9761658, -9680717, -9599544, -9518140,
+ -9436505, -9354640, -9272545, -9190221, -9107667, -9024886, -8941876,
+ -8858639, -8775176, -8691485, -8607570, -8523428, -8439062, -8354472,
+ -8269658, -8184620, -8099360, -8013878, -7928174, -7842250, -7756104,
+ -7669739, -7583154, -7496350, -7409328, -7322088, -7234631, -7146957,
+ -7059068, -6970962, -6882642, -6794108, -6705359, -6616398, -6527224,
+ -6437838, -6348241, -6258432, -6168414, -6078186, -5987749, -5897104,
+ -5806251, -5715190, -5623924, -5532451, -5440773, -5348891, -5256804,
+ -5164514, -5072022, -4979327, -4886431, -4793334, -4700037, -4606541,
+ -4512845, -4418952, -4324861, -4230573, -4136089, -4041410, -3946536,
+ -3851467, -3756206, -3660751, -3565105, -3469267, -3373238, -3277020,
+ -3180612, -3084016, -2987232, -2890260, -2793102, -2695759, -2598231,
+ -2500518, -2402622, -2304543, -2206282, -2107839, -2009216, -1910414,
+ -1811432, -1712271, -1612933, -1513419, -1413728, -1313862, -1213821,
+ -1113607, -1013219, -912659, -811928, -711026, -609954, -508713,
+ -407304, -305727, -203984, -102074, 0, 102239, 204641, 307206, 409934,
+ 512822, 615871, 719079, 822446, 925970, 1029652, 1133489, 1237482,
+ 1341630, 1445931, 1550385, 1654991, 1759748, 1864655, 1969711, 2074917,
+ 2180269, 2285769, 2391414, 2497205, 2603140, 2709218, 2815438, 2921800,
+ 3028303, 3134945, 3241726, 3348645, 3455702, 3562894, 3670222, 3777684,
+ 3885280, 3993008, 4100868, 4208859, 4316979, 4425228, 4533606, 4642110,
+ 4750740, 4859496, 4968376, 5077379, 5186504, 5295751, 5405118, 5514605,
+ 5624211, 5733934, 5843773, 5953729, 6063799, 6173982, 6284279, 6394687,
+ 6505207, 6615836, 6726574, 6837420, 6948373, 7059432, 7170595, 7281863,
+ 7393234, 7504706, 7616280, 7727953, 7839726, 7951596, 8063564, 8175627,
+ 8287785, 8400037, 8512382, 8624819, 8737346, 8849964, 8962670, 9075463,
+ 9188344, 9301310, 9414361, 9527495, 9640712, 9754010, 9867389, 9980847,
+ 10094383, 10207997, 10321687, 10435452, 10549291, 10663203, 10777187,
+ 10891241, 11005366, 11119559, 11233820, 11348147, 11462540, 11576997,
+ 11691518, 11806100, 11920744, 12035448, 12150210, 12265030, 12379907,
+ 12494840, 12609827, 12724868, 12839960, 12955104, 13070298, 13185541,
+ 13300831, 13416168, 13531551, 13646978, 13762448, 13877961, 13993514,
+ 14109108, 14224740, 14340410, 14456116, 14571857, 14687633, 14803441,
+ 14919282, 15035153, 15151054, 15266983, 15382939, 15498922, 15614929,
+ 15730960, 15847014, 15963089, 16079184, 16195298, 16311430, 16427579,
+ 16543743, 16659922, 16776114, 16892318, 17008533, 17124757, 17240989,
+ 17357229, 17473475, 17589726, 17705980, 17822237, 17938495, 18054753,
+ 18171009, 18287264, 18403515, 18519761, 18636000, 18752233, 18868457,
+ 18984672, 19100875, 19217067, 19333245, 19449409, 19565556, 19681687,
+ 19797800, 19913893, 20029965, 20146015, 20262042, 20378045, 20494022,
+ 20609972, 20725894, 20841787, 20957648, 21073478, 21189275, 21305038,
+ 21420764, 21536454, 21652106, 21767718, 21883290, 21998820, 22114306,
+ 22229748, 22345145, 22460494, 22575795, 22691046, 22806247, 22921396,
+ 23036491, 23151532, 23266517, 23381444, 23496314, 23611123, 23725872,
+ 23840558, 23955181, 24069739, 24184230, 24298654, 24413010, 24527296,
+ 24641510, 24755652, 24869719, 24983712, 25097628, 25211467, 25325226,
+ 25438905, 25552502, 25666017, 25779447, 25892792, 26006049, 26119219,
+ 26232299, 26345288, 26458186, 26570990, 26683699, 26796312, 26908828,
+ 27021245, 27133562, 27245778, 27357891, 27469901, 27581805, 27693603,
+ 27805293, 27916874, 28028344, 28139702, 28250948, 28362078, 28473094,
+ 28583992, 28694771, 28805431, 28915970, 29026386, 29136678, 29246846,
+ 29356887, 29466800, 29576585, 29686239, 29795761, 29905150, 30014405,
+ 30123524, 30232506, 30341350, 30450054, 30558617, 30667037, 30775314,
+ 30883446, 30991431, 31099269, 31206957, 31314496, 31421882, 31529115,
+ 31636194, 31743117, 31849883, 31956491, 32062939, 32169225, 32275349,
+ 32381310, 32487105, 32592733, 32698194, 32803486, 32908607, 33013556,
+ 33118332, 33222934, 33327359, 33431607, 33535677, 33639567, 33743275,
+ 33846801, 33950143, 34053300, 34156270, 34259051, 34361644, 34464046,
+ 34566256, 34668272, 34770094, 34871719, 34973148, 35074377, 35175406,
+ 35276234, 35376859, 35477280, 35577496, 35677504, 35777305, 35876896,
+ 35976276, 36075444, 36174398, 36273137, 36371661, 36469966, 36568053,
+ 36665920, 36763565, 36860987, 36958184, 37055156, 37151902, 37248418,
+ 37344706, 37440762, 37536586, 37632176, 37727532, 37822651, 37917532,
+ 38012175, 38106577, 38200737, 38294655, 38388328, 38481755, 38574936,
+ 38667868, 38760551, 38852982, 38945162, 39037087, 39128758, 39220173,
+ 39311330, 39402228, 39492865, 39583241, 39673354, 39763203, 39852787,
+ 39942103, 40031152, 40119931, 40208439, 40296675, 40384637, 40472325,
+ 40559736, 40646871, 40733726, 40820302, 40906596, 40992607, 41078335,
+ 41163777, 41248933, 41333801, 41418379, 41502668, 41586664, 41670367,
+ 41753777, 41836890, 41919706, 42002224, 42084443, 42166361, 42247976,
+ 42329288, 42410296, 42490997, 42571391, 42651477, 42731253, 42810717,
+ 42889869, 42968708, 43047231, 43125438, 43203328, 43280899, 43358150,
+ 43435079, 43511686, 43587969, 43663926, 43739558, 43814861, 43889836,
+ 43964480, 44038793, 44112774, 44186420, 44259731, 44332706, 44405342,
+ 44477640, 44549598, 44621214, 44692487, 44763417, 44834001, 44904239,
+ 44974129, 45043671, 45112862, 45181701, 45250189, 45318322, 45386100,
+ 45453522, 45520587, 45587293, 45653639, 45719623, 45785246, 45850505,
+ 45915399, 45979927, 46044088, 46107880, 46171303, 46234355, 46297036,
+ 46359343, 46421275, 46482832, 46544013, 46604815, 46665238, 46725281,
+ 46784943, 46844222, 46903117, 46961627, 47019751, 47077487, 47134835,
+ 47191794, 47248361, 47304537, 47360319, 47415707, 47470700, 47525296,
+ 47579495, 47633294, 47686694, 47739692, 47792288, 47844481, 47896269,
+ 47947652, 47998628, 48049195, 48099354, 48149103, 48198440, 48247365,
+ 48295876, 48343973, 48391654, 48438919, 48485765, 48532193, 48578200,
+ 48623786, 48668950, 48713691, 48758007, 48801897, 48845361, 48888398,
+ 48931006, 48973183, 49014930, 49056246, 49097128, 49137576, 49177589,
+ 49217166, 49256306, 49295007, 49333269, 49371091, 49408472, 49445410,
+ 49481905, 49517956, 49553561, 49588720, 49623431, 49657694, 49691507,
+ 49724870, 49757781, 49790240, 49822245, 49853796, 49884891, 49915530,
+ 49945712, 49975435, 50004699, 50033502, 50061844, 50089724, 50117141,
+ 50144093, 50170580, 50196602, 50222156, 50247242, 50271859, 50296006,
+ 50319683, 50342887, 50365619, 50387878, 50409662, 50430970, 50451803,
+ 50472158, 50492034, 50511432, 50530350, 50548787, 50566742, 50584215,
+ 50601204, 50617709, 50633729, 50649262, 50664309, 50678867, 50692937,
+ 50706517, 50719607, 50732206, 50744313, 50755926, 50767046, 50777671,
+ 50787801, 50797435, 50806571, 50815210, 50823350, 50830990, 50838130,
+ 50844769, 50850906, 50856540, 50861671, 50866297, 50870419, 50874034,
+ 50877143, 50879745, 50881838, 50883423, 50884498, 50885062, 50885116,
+ 50884657, 50883686, 50882201, 50880203, 50877689, 50874660, 50871115,
+ 50867053, 50862473, 50857375, 50851758, 50845621, 50838963, 50831785,
+ 50824084, 50815861, 50807115, 50797845, 50788051, 50777731, 50766886,
+ 50755514, 50743615, 50731188, 50718233, 50704749, 50690735, 50676191,
+ 50661116, 50645510, 50629372, 50612700, 50595496, 50577758, 50559485,
+ 50540677, 50521333, 50501454, 50481037, 50460083, 50438591, 50416561,
+ 50393992, 50370883, 50347234, 50323044, 50298313, 50273041, 50247226,
+ 50220868, 50193968, 50166523, 50138534, 50110001, 50080922, 50051297,
+ 50021126, 49990409, 49959144, 49927332, 49894971, 49862062, 49828604,
+ 49794597, 49760039, 49724931, 49689273, 49653063, 49616301, 49578988,
+ 49541122, 49502703, 49463731, 49424205, 49384126, 49343491, 49302302,
+ 49260558, 49218258, 49175402, 49131990, 49088021, 49043496, 48998413,
+ 48952772, 48906573, 48859816, 48812500, 48764625, 48716191, 48667198,
+ 48617644, 48567530, 48516856, 48465621, 48413825, 48361467, 48308548,
+ 48255067, 48201024, 48146419, 48091251, 48035520, 47979226, 47922369,
+ 47864948, 47806963, 47748414, 47689301, 47629624, 47569382, 47508575,
+ 47447204, 47385267, 47322765, 47259697, 47196064, 47131864, 47067099,
+ 47001768, 46935870, 46869406, 46802376, 46734778, 46666614, 46597884,
+ 46528586, 46458721, 46388288, 46317289, 46245722, 46173588, 46100886,
+ 46027616, 45953779, 45879374, 45804402, 45728861, 45652753, 45576077,
+ 45498833, 45421021, 45342641, 45263693, 45184177, 45104093, 45023442,
+ 44942222, 44860434, 44778079, 44695155, 44611664, 44527605, 44442979,
+ 44357784, 44272022, 44185693, 44098796, 44011332, 43923300, 43834701,
+ 43745535, 43655802, 43565502, 43474636, 43383202, 43291203, 43198636,
+ 43105504, 43011805, 42917541, 42822710, 42727314, 42631353, 42534826,
+ 42437734, 42340077, 42241855, 42143069, 42043719, 41943804, 41843326,
+ 41742283, 41640678, 41538509, 41435777, 41332483, 41228626, 41124206,
+ 41019225, 40913682, 40807578, 40700913, 40593687, 40485900, 40377554,
+ 40268647, 40159181, 40049155, 39938571, 39827428, 39715727, 39603468,
+ 39490651, 39377277, 39263347, 39148860, 39033817, 38918218, 38802064,
+ 38685355, 38568091, 38450274, 38331903, 38212978, 38093501, 37973472,
+ 37852890, 37731757, 37610073, 37487839, 37365054, 37241720, 37117837,
+ 36993405, 36868425, 36742897, 36616822, 36490200, 36363033, 36235319,
+ 36107061, 35978258, 35848911, 35719021, 35588588, 35457612, 35326095,
+ 35194037, 35061438, 34928299, 34794620, 34660403, 34525647, 34390354,
+ 34254524, 34118158, 33981256, 33843819, 33705847, 33567342, 33428303,
+ 33288732, 33148630, 33007996, 32866832, 32725138, 32582915, 32440163,
+ 32296884, 32153079, 32008746, 31863889, 31718507, 31572601, 31426171,
+ 31279219, 31131746, 30983751, 30835236, 30686202, 30536649, 30386579,
+ 30235991, 30084887, 29933268, 29781134, 29628487, 29475326, 29321654,
+ 29167470, 29012776, 28857572, 28701859, 28545639, 28388912, 28231679,
+ 28073940, 27915698, 27756952, 27597703, 27437953, 27277702, 27116952,
+ 26955703, 26793956, 26631712, 26468973, 26305738, 26142009, 25977788,
+ 25813074, 25647869, 25482174, 25315990, 25149319, 24982160, 24814514,
+ 24646384, 24477770, 24308673, 24139094, 23969035, 23798495, 23627477,
+ 23455981, 23284008, 23111560, 22938638, 22765242, 22591374, 22417034,
+ 22242225, 22066947, 21891201, 21714989, 21538310, 21361168, 21183562,
+ 21005495, 20826966, 20647978, 20468531, 20288627, 20108266, 19927451,
+ 19746182, 19564460, 19382287, 19199664, 19016592, 18833072, 18649105,
+ 18464694, 18279839, 18094540, 17908801, 17722621, 17536003, 17348947,
+ 17161454, 16973527, 16785165, 16596372, 16407147, 16217493, 16027410,
+ 15836900, 15645964, 15454604, 15262821, 15070616, 14877990, 14684946,
+ 14491484, 14297606, 14103313, 13908606, 13713488, 13517958, 13322020,
+ 13125674, 12928921, 12731764, 12534202, 12336239, 12137875, 11939112,
+ 11739952, 11540395, 11340443, 11140098, 10939361, 10738234, 10536718,
+ 10334815, 10132526, 9929852, 9726796, 9523359, 9319542, 9115346,
+ 8910774, 8705827, 8500507, 8294814, 8088752, 7882320, 7675521, 7468356,
+ 7260828, 7052937, 6844685, 6636074, 6427105, 6217780, 6008101, 5798069,
+ 5587686, 5376954, 5165874, 4954447, 4742676, 4530563, 4318108, 4105313,
+ 3892181, 3678713, 3464911, 3250775, 3036309, 2821514, 2606391, 2390942,
+ 2175169, 1959073, 1742658, 1525923, 1308871, 1091504, 873823, 655830,
+ 437528, 218917, 0, -219222, -438746, -658572, -878698, -1099120,
+ -1319839, -1540851, -1762155, -1983749, -2205631, -2427800, -2650254,
+ -2872990, -3096007, -3319303, -3542877, -3766725, -3990847, -4215240,
+ -4439903, -4664834, -4890030, -5115490, -5341212, -5567194, -5793434,
+ -6019931, -6246681, -6473684, -6700937, -6928439, -7156187, -7384179,
+ -7612414, -7840889, -8069603, -8298553, -8527738, -8757156, -8986804,
+ -9216680, -9446783, -9677111, -9907661, -10138432, -10369421,
+ -10600626, -10832046, -11063678, -11295521, -11527572, -11759828,
+ -11992289, -12224952, -12457815, -12690876, -12924133, -13157583,
+ -13391225, -13625056, -13859075, -14093279, -14327667, -14562235,
+ -14796983, -15031907, -15267006, -15502277, -15737719, -15973330,
+ -16209106, -16445046, -16681148, -16917410, -17153829, -17390404,
+ -17627132, -17864010, -18101038, -18338212, -18575530, -18812991,
+ -19050592, -19288330, -19526204, -19764211, -20002350, -20240617,
+ -20479011, -20717530, -20956171, -21194931, -21433810, -21672804,
+ -21911911, -22151129, -22390455, -22629889, -22869426, -23109065,
+ -23348804, -23588640, -23828571, -24068595, -24308710, -24548912,
+ -24789200, -25029572, -25270025, -25510557, -25751166, -25991849,
+ -26232604, -26473428, -26714320, -26955277, -27196296, -27437375,
+ -27678513, -27919706, -28160952, -28402249, -28643594, -28884986,
+ -29126421, -29367898, -29609413, -29850966, -30092552, -30334170,
+ -30575818, -30817493, -31059192, -31300913, -31542655, -31784414,
+ -32026187, -32267974, -32509770, -32751575, -32993384, -33235197,
+ -33477009, -33718820, -33960627, -34202426, -34444217, -34685995,
+ -34927760, -35169507, -35411236, -35652943, -35894625, -36136282,
+ -36377909, -36619505, -36861067, -37102592, -37344079, -37585524,
+ -37826925, -38068280, -38309586, -38550841, -38792042, -39033186,
+ -39274272, -39515296, -39756256, -39997150, -40237975, -40478728,
+ -40719408, -40960011, -41200535, -41440978, -41681336, -41921608,
+ -42161791, -42401882, -42641878, -42881778, -43121579, -43361278,
+ -43600873, -43840360, -44079738, -44319004, -44558155, -44797189,
+ -45036104, -45274895, -45513563, -45752102, -45990512, -46228789,
+ -46466930, -46704934, -46942798, -47180519, -47418094, -47655521,
+ -47892797, -48129920, -48366888, -48603696, -48840344, -49076828,
+ -49313146, -49549294, -49785272, -50021075, -50256702, -50492149,
+ -50727414, -50962495, -51197389, -51432093, -51666605, -51900921,
+ -52135040, -52368959, -52602675, -52836186, -53069488, -53302580,
+ -53535458, -53768121, -54000564, -54232787, -54464786, -54696558,
+ -54928101, -55159412, -55390489, -55621329, -55851929, -56082287,
+ -56312400, -56542265, -56771880, -57001242, -57230349, -57459197,
+ -57687785, -57916109, -58144166, -58371956, -58599473, -58826717,
+ -59053684, -59280371, -59506777, -59732897, -59958731, -60184274,
+ -60409525, -60634480, -60859138, -61083494, -61307548, -61531295,
+ -61754734, -61977862, -62200676, -62423173, -62645351, -62867207,
+ -63088738, -63309942, -63530817, -63751359, -63971565, -64191434,
+ -64410962, -64630147, -64848986, -65067477, -65285616, -65503402,
+ -65720831, -65937901, -66154610, -66370953, -66586930, -66802537,
+ -67017771, -67232630, -67447112, -67661213, -67874931, -68088263,
+ -68301207, -68513759, -68725918, -68937681, -69149045, -69360007,
+ -69570564, -69780715, -69990456, -70199784, -70408698, -70617194,
+ -70825270, -71032923, -71240150, -71446949, -71653318, -71859252,
+ -72064751, -72269811, -72474430, -72678604, -72882332, -73085610,
+ -73288436, -73490808, -73692723, -73894177, -74095169, -74295696,
+ -74495755, -74695344, -74894459, -75093099, -75291261, -75488941,
+ -75686138, -75882849, -76079071, -76274802, -76470039, -76664779,
+ -76859019, -77052758, -77245992, -77438719, -77630937, -77822642,
+ -78013832, -78204505, -78394657, -78584287, -78773391, -78961968,
+ -79150014, -79337527, -79524504, -79710943, -79896841, -80082195,
+ -80267004, -80451264, -80634973, -80818128, -81000726, -81182766,
+ -81364244, -81545158, -81725506, -81905284, -82084491, -82263124,
+ -82441179, -82618655, -82795550, -82971860, -83147582, -83322716,
+ -83497257, -83671203, -83844553, -84017302, -84189450, -84360992,
+ -84531928, -84702253, -84871967, -85041065, -85209546, -85377408,
+ -85544647, -85711261, -85877247, -86042604, -86207329, -86371419,
+ -86534872, -86697684, -86859855, -87021381, -87182259, -87342488,
+ -87502065, -87660987, -87819252, -87976858, -88133801, -88290081,
+ -88445693, -88600636, -88754907, -88908505, -89061425, -89213667,
+ -89365227, -89516103, -89666293, -89815794, -89964604, -90112720,
+ -90260141, -90406863, -90552885, -90698203, -90842816, -90986721,
+ -91129916, -91272399, -91414166, -91555216, -91695546, -91835154,
+ -91974038, -92112195, -92249623, -92386320, -92522282, -92657509,
+ -92791997, -92925745, -93058749, -93191008, -93322519, -93453280,
+ -93583289, -93712544, -93841041, -93968780, -94095757, -94221970,
+ -94347417, -94472096, -94596004, -94719140, -94841501, -94963084,
+ -95083888, -95203910, -95323148, -95441600, -95559263, -95676136,
+ -95792216, -95907501, -96021989, -96135677, -96248563, -96360646,
+ -96471923, -96582391, -96692049, -96800895, -96908925, -97016139,
+ -97122534, -97228108, -97332859, -97436784, -97539882, -97642150,
+ -97743586, -97844188, -97943954, -98042883, -98140971, -98238217,
+ -98334618, -98430173, -98524880, -98618736, -98711739, -98803888,
+ -98895180, -98985613, -99075186, -99163896, -99251741, -99338719,
+ -99424828, -99510066, -99594432, -99677922, -99760536, -99842271,
+ -99923126, -100003097, -100082184, -100160384, -100237696, -100314117,
+ -100389645, -100464279, -100538017, -100610856, -100682796, -100753833,
+ -100823966, -100893194, -100961514, -101028924, -101095423, -101161008,
+ -101225679, -101289432, -101352266, -101414180, -101475171, -101535238,
+ -101594379, -101652591, -101709874, -101766226, -101821644, -101876127,
+ -101929673, -101982280, -102033947, -102084672, -102134453, -102183288,
+ -102231176, -102278115, -102324103, -102369138, -102413220, -102456345,
+ -102498513, -102539721, -102579969, -102619254, -102657575, -102694930,
+ -102731317, -102766736, -102801183, -102834658, -102867159, -102898685,
+ -102929233, -102958803, -102987392, -103014999, -103041623, -103067261,
+ -103091913, -103115577, -103138252, -103159935, -103180625, -103200322,
+ -103219022, -103236725, -103253430, -103269135, -103283838, -103297538,
+ -103310233, -103321922, -103332604, -103342278, -103350941, -103358592,
+ -103365230, -103370854, -103375462, -103379053, -103381625, -103383178,
+ -103383709, -103383217, -103381702, -103379161, -103375594, -103370999,
+ -103365375, -103358720, -103351034, -103342314, -103332561, -103321771,
+ -103309945, -103297081, -103283178, -103268234, -103252249, -103235220,
+ -103217148, -103198030, -103177866, -103156655, -103134394, -103111084,
+ -103086723, -103061309, -103034842, -103007321, -102978745, -102949111,
+ -102918420, -102886671, -102853861, -102819991, -102785059, -102749064,
+ -102712004, -102673880, -102634690, -102594433, -102553108, -102510713,
+ -102467249, -102422714, -102377107, -102330428, -102282674, -102233846,
+ -102183942, -102132962, -102080904, -102027769, -101973554, -101918259,
+ -101861883, -101804425, -101745885, -101686261, -101625553, -101563761,
+ -101500882, -101436917, -101371864, -101305724, -101238494, -101170175,
+ -101100765, -101030264, -100958672, -100885986, -100812208, -100737336,
+ -100661369, -100584306, -100506148, -100426893, -100346541, -100265091,
+ -100182543, -100098895, -100014148, -99928301, -99841352, -99753303,
+ -99664151, -99573897, -99482539, -99390079, -99296514, -99201844,
+ -99106069, -99009189, -98911203, -98812110, -98711910, -98610603,
+ -98508188, -98404664, -98300032, -98194291, -98087441, -97979480,
+ -97870410, -97760228, -97648936, -97536533, -97423018, -97308391,
+ -97192651, -97075800, -96957835, -96838758, -96718567, -96597262,
+ -96474844, -96351312, -96226665, -96100904, -95974028, -95846038,
+ -95716932, -95586711, -95455375, -95322924, -95189356, -95054673,
+ -94918874, -94781960, -94643929, -94504782, -94364518, -94223139,
+ -94080643, -93937031, -93792303, -93646458, -93499497, -93351420,
+ -93202226, -93051916, -92900490, -92747947, -92594289, -92439514,
+ -92283624, -92126618, -91968496, -91809258, -91648905, -91487436,
+ -91324853, -91161154, -90996341, -90830413, -90663370, -90495214,
+ -90325943, -90155559, -89984061, -89811450, -89637726, -89462889,
+ -89286940, -89109879, -88931706, -88752422, -88572026, -88390520,
+ -88207904, -88024177, -87839341, -87653396, -87466341, -87278179,
+ -87088908, -86898530, -86707045, -86514454, -86320756, -86125952,
+ -85930044, -85733031, -85534914, -85335693, -85135369, -84933943,
+ -84731415, -84527786, -84323056, -84117226, -83910296, -83702268,
+ -83493141, -83282917, -83071597, -82859180, -82645667, -82431060,
+ -82215358, -81998564, -81780676, -81561697, -81341627, -81120466,
+ -80898216, -80674877, -80450450, -80224936, -79998335, -79770649,
+ -79541879, -79312025, -79081088, -78849069, -78615969, -78381788,
+ -78146529, -77910191, -77672776, -77434285, -77194718, -76954077,
+ -76712362, -76469575, -76225716, -75980787, -75734789, -75487723,
+ -75239589, -74990390, -74740125, -74488796, -74236405, -73982952,
+ -73728439, -73472866, -73216235, -72958546, -72699802, -72440004,
+ -72179152, -71917248, -71654292, -71390288, -71125234, -70859134,
+ -70591987, -70323796, -70054562, -69784286, -69512969, -69240613,
+ -68967219, -68692788, -68417323, -68140823, -67863291, -67584728,
+ -67305136, -67024515, -66742868, -66460196, -66176500, -65891781,
+ -65606042, -65319284, -65031508, -64742716, -64452910, -64162090,
+ -63870259, -63577418, -63283569, -62988714, -62692853, -62395989,
+ -62098123, -61799256, -61499392, -61198531, -60896674, -60593825,
+ -60289984, -59985152, -59679333, -59372527, -59064737, -58755964,
+ -58446210, -58135476, -57823765, -57511078, -57197418, -56882786,
+ -56567183, -56250612, -55933075, -55614574, -55295110, -54974686,
+ -54653302, -54330962, -54007668, -53683420, -53358222, -53032075,
+ -52704981, -52376942, -52047961, -51718039, -51387178, -51055380,
+ -50722648, -50388984, -50054389, -49718866, -49382417, -49045043,
+ -48706748, -48367534, -48027402, -47686354, -47344393, -47001522,
+ -46657742, -46313055, -45967464, -45620971, -45273579, -44925288,
+ -44576103, -44226025, -43875057, -43523200, -43170457, -42816831,
+ -42462324, -42106938, -41750675, -41393538, -41035530, -40676653,
+ -40316909, -39956300, -39594830, -39232500, -38869313, -38505272,
+ -38140379, -37774637, -37408047, -37040613, -36672338, -36303223,
+ -35933271, -35562485, -35190868, -34818422, -34445149, -34071053,
+ -33696135, -33320400, -32943848, -32566483, -32188308, -31809326,
+ -31429538, -31048948, -30667558, -30285372, -29902391, -29518619,
+ -29134059, -28748713, -28362584, -27975675, -27587988, -27199527,
+ -26810294, -26420293, -26029525, -25637995, -25245704, -24852656,
+ -24458854, -24064300, -23668998, -23272950, -22876159, -22478629,
+ -22080362, -21681361, -21281630, -20881171, -20479987, -20078081,
+ -19675457, -19272118, -18868066, -18463304, -18057836, -17651665,
+ -17244793, -16837225, -16428962, -16020009, -15610369, -15200043,
+ -14789037, -14377352, -13964992, -13551961, -13138261, -12723896,
+ -12308869, -11893183, -11476842, -11059848, -10642205, -10223916,
+ -9804985, -9385415, -8965209, -8544371, -8122903, -7700810, -7278094,
+ -6854759, -6430809, -6006246, -5581074, -5155297, -4728918, -4301940,
+ -3874367, -3446202, -3017449, -2588111, -2158192, -1727695, -1296624,
+ -864982, -432773, 0, 433333, 867223, 1301666, 1736658, 2172197,
+ 2608278, 3044897, 3482052, 3919738, 4357952, 4796690, 5235949, 5675725,
+ 6116014, 6556813, 6998117, 7439924, 7882229, 8325029, 8768320, 9212098,
+ 9656360, 10101101, 10546319, 10992008, 11438166, 11884789, 12331873,
+ 12779414, 13227408, 13675851, 14124740, 14574070, 15023839, 15474041,
+ 15924674, 16375732, 16827213, 17279113, 17731426, 18184151, 18637282,
+ 19090816, 19544748, 19999075, 20453793, 20908898, 21364386, 21820253,
+ 22276494, 22733107, 23190086, 23647428, 24105128, 24563184, 25021590,
+ 25480343, 25939438, 26398872, 26858640, 27318738, 27779162, 28239909,
+ 28700973, 29162352, 29624039, 30086033, 30548327, 31010919, 31473804,
+ 31936978, 32400437, 32864175, 33328190, 33792478, 34257033, 34721851,
+ 35186929, 35652262, 36117846, 36583677, 37049749, 37516060, 37982605,
+ 38449379, 38916379, 39383599, 39851036, 40318685, 40786542, 41254603,
+ 41722862, 42191317, 42659963, 43128794, 43597807, 44066998, 44536362,
+ 45005894, 45475591, 45945448, 46415460, 46885623, 47355932, 47826384,
+ 48296973, 48767696, 49238547, 49709523, 50180619, 50651830, 51123152,
+ 51594580, 52066110, 52537738, 53009458, 53481267, 53953160, 54425132,
+ 54897178, 55369295, 55841478, 56313722, 56786022, 57258375, 57730775,
+ 58203217, 58675698, 59148213, 59620757, 60093325, 60565913, 61038516,
+ 61511130, 61983750, 62456371, 62928989, 63401599, 63874196, 64346776,
+ 64819334, 65291866, 65764366, 66236830, 66709254, 67181632, 67653961,
+ 68126234, 68598449, 69070599, 69542680, 70014688, 70486617, 70958463,
+ 71430222, 71901887, 72373456, 72844923, 73316282, 73787531, 74258662,
+ 74729673, 75200558, 75671312, 76141931, 76612410, 77082743, 77552927,
+ 78022956, 78492825, 78962530, 79432066, 79901428, 80370612, 80839611,
+ 81308423, 81777041, 82245461, 82713678, 83181687, 83649483, 84117062,
+ 84584419, 85051548, 85518445, 85985105, 86451523, 86917694, 87383613,
+ 87849276, 88314678, 88779813, 89244677, 89709264, 90173571, 90637591,
+ 91101321, 91564754, 92027887, 92490714, 92953230, 93415431, 93877312,
+ 94338866, 94800091, 95260980, 95721529, 96181732, 96641586, 97101084,
+ 97560222, 98018995, 98477398, 98935426, 99393074, 99850336, 100307209,
+ 100763687, 101219766, 101675439, 102130702, 102585551, 103039979,
+ 103493983, 103947557, 104400696, 104853395, 105305650, 105757454,
+ 106208804, 106659694, 107110119, 107560074, 108009554, 108458555,
+ 108907070, 109355096, 109802626, 110249657, 110696183, 111142198,
+ 111587699, 112032679, 112477135, 112921060, 113364450, 113807300,
+ 114249605, 114691360, 115132559, 115573198, 116013272, 116452775,
+ 116891703, 117330051, 117767813, 118204984, 118641560, 119077535,
+ 119512905, 119947664, 120381807, 120815330, 121248226, 121680492,
+ 122112122, 122543111, 122973454, 123403146, 123832183, 124260557,
+ 124688266, 125115304, 125541665, 125967345, 126392339, 126816642,
+ 127240248, 127663152, 128085351, 128506837, 128927607, 129347656,
+ 129766978, 130185568, 130603422, 131020534, 131436899, 131852512,
+ 132267369, 132681463, 133094791, 133507347, 133919126, 134330123,
+ 134740333, 135149751, 135558372, 135966191, 136373202, 136779402,
+ 137184785, 137589345, 137993078, 138395980, 138798044, 139199265,
+ 139599640, 139999162, 140397828, 140795631, 141192567, 141588630,
+ 141983817, 142378121, 142771538, 143164064, 143555691, 143946417,
+ 144336236, 144725143, 145113132, 145500200, 145886341, 146271550,
+ 146655821, 147039151, 147421535, 147802966, 148183440, 148562953,
+ 148941500, 149319074, 149695673, 150071290, 150445920, 150819559,
+ 151192202, 151563844, 151934479, 152304104, 152672713, 153040300,
+ 153406863, 153772394, 154136890, 154500346, 154862756, 155224116,
+ 155584421, 155943667, 156301847, 156658958, 157014994, 157369950,
+ 157723823, 158076606, 158428295, 158778886, 159128373, 159476751,
+ 159824016, 160170163, 160515187, 160859083, 161201847, 161543473,
+ 161883957, 162223294, 162561479, 162898508, 163234375, 163569077,
+ 163902607, 164234962, 164566136, 164896125, 165224925, 165552529,
+ 165878934, 166204135, 166528128, 166850906, 167172467, 167492804,
+ 167811914, 168129791, 168446432, 168761830, 169075982, 169388883,
+ 169700528, 170010913, 170320033, 170627882, 170934458, 171239755,
+ 171543767, 171846492, 172147924, 172448058, 172746890, 173044416,
+ 173340630, 173635528, 173929106, 174221359, 174512282, 174801872,
+ 175090122, 175377030, 175662589, 175946797, 176229648, 176511137,
+ 176791261, 177070014, 177347393, 177623392, 177898008, 178171236,
+ 178443070, 178713508, 178982545, 179250175, 179516395, 179781200,
+ 180044586, 180306549, 180567083, 180826185, 181083851, 181340075,
+ 181594854, 181848183, 182100057, 182350473, 182599427, 182846913,
+ 183092928, 183337467, 183580526, 183822101, 184062187, 184300780,
+ 184537876, 184773471, 185007560, 185240140, 185471205, 185700752,
+ 185928777, 186155275, 186380242, 186603674, 186825567, 187045916,
+ 187264719, 187481969, 187697664, 187911799, 188124371, 188335374,
+ 188544805, 188752660, 188958934, 189163625, 189366727, 189568236,
+ 189768149, 189966462, 190163171, 190358271, 190551758, 190743629,
+ 190933880, 191122507, 191309505, 191494871, 191678602, 191860692,
+ 192041138, 192219937, 192397084, 192572575, 192746407, 192918576,
+ 193089078, 193257909, 193425065, 193590543, 193754338, 193916448,
+ 194076868, 194235594, 194392623, 194547951, 194701574, 194853489,
+ 195003692, 195152179, 195298946, 195443991, 195587308, 195728895,
+ 195868748, 196006864, 196143238, 196277867, 196410748, 196541877,
+ 196671250, 196798864, 196924716, 197048802, 197171118, 197291661,
+ 197410427, 197527413, 197642616, 197756032, 197867657, 197977489,
+ 198085524, 198191758, 198296188, 198398811, 198499623, 198598621,
+ 198695802, 198791163, 198884699, 198976408, 199066287, 199154333,
+ 199240541, 199324909, 199407434, 199488112, 199566940, 199643916,
+ 199719035, 199792295, 199863693, 199933225, 200000889, 200066681,
+ 200130598, 200192637, 200252796, 200311071, 200367458, 200421956,
+ 200474561, 200525270, 200574080, 200620988, 200665991, 200709087,
+ 200750272, 200789544, 200826899, 200862335, 200895849, 200927438,
+ 200957100, 200984831, 201010629, 201034490, 201056413, 201076394,
+ 201094431, 201110521, 201124661, 201136849, 201147082, 201155357,
+ 201161671, 201166023, 201168409, 201168827, 201167274, 201163748,
+ 201158246, 201150766, 201141305, 201129860, 201116430, 201101011,
+ 201083601, 201064198, 201042800, 201019404, 200994007, 200966607,
+ 200937202, 200905790, 200872368, 200836934, 200799485, 200760020,
+ 200718535, 200675030, 200629501, 200581947, 200532365, 200480753,
+ 200427108, 200371430, 200313715, 200253961, 200192167, 200128331,
+ 200062449, 199994521, 199924544, 199852516, 199778436, 199702301,
+ 199624109, 199543858, 199461547, 199377173, 199290735, 199202231,
+ 199111658, 199019016, 198924302, 198827514, 198728651, 198627711,
+ 198524692, 198419593, 198312411, 198203145, 198091794, 197978355,
+ 197862827, 197745209, 197625498, 197503694, 197379794, 197253798,
+ 197125703, 196995507, 196863211, 196728811, 196592308, 196453698,
+ 196312981, 196170155, 196025219, 195878172, 195729012, 195577737,
+ 195424347, 195268841, 195111216, 194951472, 194789608, 194625621,
+ 194459512, 194291278, 194120919, 193948434, 193773821, 193597079,
+ 193418207, 193237205, 193054070, 192868803, 192681401, 192491864,
+ 192300191, 192106382, 191910434, 191712347, 191512121, 191309754,
+ 191105245, 190898594, 190689800, 190478862, 190265779, 190050551,
+ 189833176, 189613654, 189391984, 189168166, 188942199, 188714081,
+ 188483814, 188251395, 188016825, 187780102, 187541227, 187300198,
+ 187057016, 186811679, 186564187, 186314540, 186062737, 185808779,
+ 185552663, 185294391, 185033961, 184771374, 184506629, 184239725,
+ 183970664, 183699443, 183426063, 183150524, 182872826, 182592967,
+ 182310950, 182026772, 181740434, 181451936, 181161278, 180868459,
+ 180573480, 180276341, 179977042, 179675582, 179371962, 179066182,
+ 178758241, 178448141, 178135880, 177821460, 177504881, 177186142,
+ 176865243, 176542186, 176216970, 175889596, 175560063, 175228373,
+ 174894525, 174558520, 174220358, 173880040, 173537566, 173192936,
+ 172846152, 172497212, 172146119, 171792872, 171437471, 171079919,
+ 170720214, 170358358, 169994352, 169628195, 169259889, 168889435,
+ 168516832, 168142082, 167765186, 167386144, 167004956, 166621625,
+ 166236151, 165848534, 165458776, 165066876, 164672838, 164276660,
+ 163878345, 163477892, 163075304, 162670581, 162263724, 161854735,
+ 161443614, 161030363, 160614982, 160197473, 159777837, 159356075,
+ 158932188, 158506178, 158078046, 157647793, 157215421, 156780930,
+ 156344323, 155905600, 155464763, 155021814, 154576753, 154129582,
+ 153680303, 153228918, 152775427, 152319832, 151862135, 151402338,
+ 150940441, 150476448, 150010358, 149542175, 149071899, 148599533,
+ 148125078, 147648535, 147169908, 146689197, 146206404, 145721531,
+ 145234581, 144745554, 144254454, 143761281, 143266037, 142768726,
+ 142269348, 141767906, 141264402, 140758837, 140251215, 139741537,
+ 139229805, 138716021, 138200188, 137682307, 137162382, 136640413,
+ 136116404, 135590357, 135062274, 134532157, 134000009, 133465833,
+ 132929629, 132391402, 131851153, 131308885, 130764600, 130218301,
+ 129669990, 129119671, 128567345, 128013014, 127456683, 126898353,
+ 126338027, 125775708, 125211398, 124645100, 124076817, 123506552,
+ 122934307, 122360086, 121783890, 121205724, 120625589, 120043489,
+ 119459427, 118873406, 118285428, 117695497, 117103615, 116509786,
+ 115914013, 115316298, 114716645, 114115058, 113511539, 112906090,
+ 112298717, 111689421, 111078206, 110465076, 109850033, 109233081,
+ 108614223, 107993462, 107370803, 106746248, 106119800, 105491463,
+ 104861241, 104229138, 103595155, 102959298, 102321569, 101681973,
+ 101040512, 100397191, 99752013, 99104981, 98456100, 97805373, 97152804,
+ 96498396, 95842153, 95184080, 94524179, 93862456, 93198912, 92533554,
+ 91866383, 91197405, 90526623, 89854041, 89179663, 88503494, 87825537,
+ 87145795, 86464275, 85780978, 85095911, 84409075, 83720477, 83030120,
+ 82338007, 81644145, 80948536, 80251184, 79552096, 78851273, 78148722,
+ 77444445, 76738449, 76030736, 75321312, 74610181, 73897346, 73182814,
+ 72466588, 71748673, 71029074, 70307794, 69584839, 68860213, 68133921,
+ 67405967, 66676357, 65945094, 65212184, 64477631, 63741440, 63003617,
+ 62264164, 61523089, 60780395, 60036086, 59290169, 58542648, 57793528,
+ 57042814, 56290511, 55536624, 54781158, 54024117, 53265508, 52505334,
+ 51743602, 50980317, 50215482, 49449105, 48681189, 47911740, 47140764,
+ 46368265, 45594249, 44818721, 44041686, 43263150, 42483118, 41701596,
+ 40918588, 40134101, 39348140, 38560710, 37771816, 36981465, 36189661,
+ 35396411, 34601719, 33805592, 33008035, 32209053, 31408653, 30606839,
+ 29803618, 28998996, 28192978, 27385569, 26576776, 25766604, 24955060,
+ 24142148, 23327876, 22512248, 21695271, 20876950, 20057292, 19236302,
+ 18413986, 17590351, 16765402, 15939146, 15111588, 14282735, 13452592,
+ 12621166, 11788463, 10954488, 10119249, 9282752, 8445002, 7606006,
+ 6765770, 5924300, 5081603, 4237684, 3392552, 2546210, 1698667, 849928,
+ 0, -851111, -1703398, -2556855, -3411476, -4267254, -5124182, -5982254,
+ -6841463, -7701803, -8563267, -9425848, -10289541, -11154337,
+ -12020232, -12887217, -13755286, -14624432, -15494649, -16365930,
+ -17238268, -18111657, -18986089, -19861557, -20738055, -21615576,
+ -22494114, -23373660, -24254208, -25135751, -26018283, -26901796,
+ -27786283, -28671737, -29558151, -30445519, -31333832, -32223084,
+ -33113268, -34004377, -34896403, -35789340, -36683179, -37577914,
+ -38473539, -39370044, -40267424, -41165670, -42064777, -42964735,
+ -43865538, -44767179, -45669651, -46572945, -47477054, -48381972,
+ -49287690, -50194201, -51101498, -52009574, -52918420, -53828029,
+ -54738393, -55649506, -56561359, -57473945, -58387257, -59301286,
+ -60216025, -61131467, -62047603, -62964426, -63881929, -64800103,
+ -65718941, -66638435, -67558578, -68479361, -69400776, -70322817,
+ -71245475, -72168742, -73092610, -74017072, -74942119, -75867744,
+ -76793939, -77720695, -78648005, -79575861, -80504255, -81433179,
+ -82362624, -83292584, -84223048, -85154011, -86085463, -87017396,
+ -87949803, -88882675, -89816004, -90749782, -91684000, -92618651,
+ -93553726, -94489218, -95425117, -96361415, -97298105, -98235178,
+ -99172625, -100110439, -101048611, -101987132, -102925995, -103865191,
+ -104804712, -105744548, -106684693, -107625137, -108565871, -109506888,
+ -110448179, -111389736, -112331549, -113273611, -114215913, -115158447,
+ -116101203, -117044174, -117987350, -118930723, -119874285, -120818027,
+ -121761940, -122706015, -123650245, -124594619, -125539131, -126483770,
+ -127428528, -128373397, -129318368, -130263431, -131208579, -132153802,
+ -133099091, -134044439, -134989835, -135935272, -136880740, -137826230,
+ -138771734, -139717243, -140662748, -141608239, -142553709, -143499147,
+ -144444546, -145389896, -146335189, -147280414, -148225564, -149170629,
+ -150115601, -151060470, -152005227, -152949863, -153894370, -154838737,
+ -155782957, -156727019, -157670916, -158614637, -159558173, -160501517,
+ -161444657, -162387586, -163330294, -164272771, -165215010, -166156999,
+ -167098731, -168040197, -168981386, -169922289, -170862898, -171803203,
+ -172743195, -173682864, -174622202, -175561199, -176499845, -177438132,
+ -178376050, -179313590, -180250742, -181187497, -182123845, -183059778,
+ -183995286, -184930359, -185864989, -186799165, -187732879, -188666120,
+ -189598880, -190531149, -191462917, -192394176, -193324915, -194255125,
+ -195184797, -196113922, -197042488, -197970489, -198897912, -199824750,
+ -200750993, -201676630, -202601653, -203526052, -204449817, -205372939,
+ -206295409, -207217216, -208138351, -209058805, -209978567, -210897629,
+ -211815980, -212733611, -213650513, -214566675, -215482088, -216396743,
+ -217310630, -218223738, -219136059, -220047583, -220958299, -221868199,
+ -222777273, -223685510, -224592902, -225499438, -226405109, -227309904,
+ -228213815, -229116832, -230018944, -230920143, -231820417, -232719759,
+ -233618157, -234515601, -235412083, -236307593, -237202120, -238095654,
+ -238988187, -239879708, -240770207, -241659675, -242548102, -243435477,
+ -244321791, -245207035, -246091198, -246974271, -247856243, -248737106,
+ -249616848, -250495460, -251372933, -252249256, -253124420, -253998414,
+ -254871229, -255742855, -256613282, -257482501, -258350500, -259217271,
+ -260082803, -260947087, -261810112, -262671870, -263532349, -264391540,
+ -265249433, -266106018, -266961285, -267815225, -268667826, -269519081,
+ -270368977, -271217507, -272064659, -272910423, -273754791, -274597751,
+ -275439294, -276279410, -277118089, -277955321, -278791096, -279625404,
+ -280458235, -281289580, -282119428, -282947769, -283774594, -284599892,
+ -285423654, -286245869, -287066528, -287885620, -288703136, -289519066,
+ -290333400, -291146127, -291957238, -292766724, -293574573, -294380776,
+ -295185323, -295988204, -296789409, -297588928, -298386752, -299182870,
+ -299977272, -300769949, -301560889, -302350085, -303137524, -303923199,
+ -304707098, -305489211, -306269530, -307048043, -307824741, -308599613,
+ -309372651, -310143844, -310913182, -311680655, -312446253, -313209966,
+ -313971785, -314731699, -315489699, -316245774, -316999915, -317752112,
+ -318502355, -319250633, -319996938, -320741258, -321483585, -322223908,
+ -322962218, -323698504, -324432757, -325164967, -325895123, -326623217,
+ -327349238, -328073176, -328795021, -329514764, -330232395, -330947903,
+ -331661280, -332372514, -333081597, -333788518, -334493268, -335195837,
+ -335896215, -336594392, -337290358, -337984104, -338675620, -339364895,
+ -340051921, -340736687, -341419183, -342099400, -342777329, -343452958,
+ -344126280, -344797282, -345465957, -346132294, -346796284, -347457916,
+ -348117182, -348774071, -349428573, -350080679, -350730380, -351377665,
+ -352022525, -352664950, -353304930, -353942456, -354577519, -355210108,
+ -355840214, -356467827, -357092937, -357715536, -358335613, -358953158,
+ -359568163, -360180618, -360790512, -361397837, -362002582, -362604739,
+ -363204297, -363801248, -364395581, -364987287, -365576357, -366162781,
+ -366746550, -367327653, -367906083, -368481828, -369054880, -369625229,
+ -370192866, -370757781, -371319965, -371879408, -372436102, -372990036,
+ -373541201, -374089588, -374635188, -375177990, -375717987, -376255168,
+ -376789524, -377321045, -377849723, -378375549, -378898512, -379418604,
+ -379935815, -380450136, -380961558, -381470071, -381975667, -382478336,
+ -382978069, -383474856, -383968689, -384459559, -384947455, -385432370,
+ -385914294, -386393217, -386869131, -387342027, -387811895, -388278727,
+ -388742512, -389203244, -389660911, -390115506, -390567019, -391015441,
+ -391460763, -391902977, -392342073, -392778042, -393210876, -393640565,
+ -394067100, -394490474, -394910676, -395327698, -395741531, -396152166,
+ -396559594, -396963807, -397364796, -397762552, -398157066, -398548329,
+ -398936333, -399321069, -399702528, -400080701, -400455581, -400827157,
+ -401195422, -401560367, -401921983, -402280261, -402635194, -402986771,
+ -403334986, -403679829, -404021291, -404359365, -404694041, -405025311,
+ -405353167, -405677601, -405998603, -406316165, -406630279, -406940937,
+ -407248130, -407551850, -407852088, -408148836, -408442085, -408731829,
+ -409018057, -409300762, -409579936, -409855570, -410127656, -410396186,
+ -410661152, -410922546, -411180359, -411434583, -411685211, -411932233,
+ -412175643, -412415431, -412651590, -412884112, -413112989, -413338213,
+ -413559775, -413777669, -413991885, -414202417, -414409255, -414612393,
+ -414811822, -415007535, -415199523, -415387779, -415572295, -415753064,
+ -415930077, -416103326, -416272805, -416438506, -416600420, -416758540,
+ -416912858, -417063367, -417210059, -417352927, -417491963, -417627159,
+ -417758509, -417886003, -418009636, -418129399, -418245286, -418357287,
+ -418465397, -418569608, -418669913, -418766303, -418858772, -418947313,
+ -419031918, -419112580, -419189292, -419262046, -419330835, -419395653,
+ -419456491, -419513344, -419566203, -419615061, -419659912, -419700749,
+ -419737564, -419770351, -419799102, -419823811, -419844470, -419861073,
+ -419873612, -419882082, -419886474, -419886783, -419883001, -419875121,
+ -419863138, -419847044, -419826832, -419802495, -419774028, -419741423,
+ -419704674, -419663774, -419618716, -419569494, -419516102, -419458533,
+ -419396780, -419330837, -419260698, -419186356, -419107804, -419025037,
+ -418938048, -418846831, -418751379, -418651686, -418547746, -418439552,
+ -418327099, -418210380, -418089389, -417964121, -417834568, -417700724,
+ -417562585, -417420143, -417273392, -417122328, -416966943, -416807232,
+ -416643188, -416474807, -416302082, -416125007, -415943576, -415757784,
+ -415567625, -415373093, -415174183, -414970888, -414763204, -414551124,
+ -414334643, -414113755, -413888455, -413658738, -413424597, -413186027,
+ -412943023, -412695579, -412443691, -412187351, -411926557, -411661301,
+ -411391578, -411117384, -410838714, -410555561, -410267921, -409975788,
+ -409679158, -409378025, -409072384, -408762231, -408447559, -408128365,
+ -407804643, -407476389, -407143596, -406806261, -406464379, -406117944,
+ -405766953, -405411399, -405051279, -404686587, -404317320, -403943472,
+ -403565038, -403182015, -402794397, -402402180, -402005359, -401603930,
+ -401197889, -400787230, -400371950, -399952044, -399527508, -399098338,
+ -398664529, -398226076, -397782976, -397335225, -396882818, -396425751,
+ -395964020, -395497621, -395026549, -394550802, -394070374, -393585262,
+ -393095461, -392600969, -392101780, -391597892, -391089299, -390576000,
+ -390057988, -389535262, -389007817, -388475650, -387938756, -387397133,
+ -386850776, -386299683, -385743848, -385183270, -384617945, -384047868,
+ -383473037, -382893449, -382309099, -381719985, -381126103, -380527450,
+ -379924023, -379315818, -378702833, -378085064, -377462509, -376835163,
+ -376203024, -375566089, -374924355, -374277819, -373626479, -372970330,
+ -372309371, -371643598, -370973009, -370297600, -369617370, -368932315,
+ -368242433, -367547721, -366848177, -366143797, -365434580, -364720522,
+ -364001622, -363277877, -362549284, -361815841, -361077546, -360334396,
+ -359586389, -358833523, -358075795, -357313204, -356545746, -355773421,
+ -354996225, -354214158, -353427216, -352635397, -351838701, -351037124,
+ -350230665, -349419322, -348603093, -347781977, -346955971, -346125073,
+ -345289283, -344448598, -343603017, -342752538, -341897159, -341036879,
+ -340171697, -339301610, -338426618, -337546719, -336661911, -335772194,
+ -334877565, -333978025, -333073570, -332164201, -331249915, -330330712,
+ -329406591, -328477550, -327543589, -326604706, -325660900, -324712171,
+ -323758517, -322799938, -321836433, -320868001, -319894640, -318916351,
+ -317933133, -316944985, -315951905, -314953895, -313950952, -312943077,
+ -311930269, -310912527, -309889851, -308862241, -307829696, -306792215,
+ -305749799, -304702448, -303650160, -302592936, -301530775, -300463677,
+ -299391643, -298314672, -297232764, -296145919, -295054137, -293957418,
+ -292855762, -291749170, -290637641, -289521175, -288399774, -287273436,
+ -286142163, -285005955, -283864811, -282718733, -281567721, -280411776,
+ -279250897, -278085085, -276914342, -275738667, -274558061, -273372525,
+ -272182059, -270986665, -269786343, -268581093, -267370917, -266155816,
+ -264935790, -263710841, -262480969, -261246175, -260006461, -258761828,
+ -257512275, -256257806, -254998421, -253734121, -252464907, -251190781,
+ -249911745, -248627798, -247338944, -246045183, -244746516, -243442946,
+ -242134474, -240821100, -239502828, -238179659, -236851593, -235518634,
+ -234180783, -232838041, -231490410, -230137892, -228780490, -227418205,
+ -226051038, -224678993, -223302070, -221920273, -220533602, -219142061,
+ -217745652, -216344376, -214938236, -213527234, -212111372, -210690654,
+ -209265080, -207834654, -206399379, -204959256, -203514288, -202064477,
+ -200609827, -199150340, -197686018, -196216864, -194742882, -193264073,
+ -191780440, -190291987, -188798717, -187300631, -185797733, -184290027,
+ -182777515, -181260199, -179738085, -178211173, -176679468, -175142972,
+ -173601690, -172055624, -170504777, -168949153, -167388755, -165823587,
+ -164253652, -162678954, -161099495, -159515280, -157926313, -156332596,
+ -154734133, -153130929, -151522986, -149910309, -148292902, -146670768,
+ -145043910, -143412334, -141776043, -140135041, -138489331, -136838919,
+ -135183807, -133524001, -131859504, -130190320, -128516454, -126837910,
+ -125154692, -123466805, -121774253, -120077040, -118375170, -116668649,
+ -114957481, -113241670, -111521220, -109796137, -108066425, -106332089,
+ -104593133, -102849562, -101101382, -99348596, -97591209, -95829227,
+ -94062655, -92291497, -90515758, -88735444, -86950559, -85161109,
+ -83367098, -81568532, -79765416, -77957756, -76145556, -74328822,
+ -72507559, -70681773, -68851468, -67016651, -65177327, -63333502,
+ -61485180, -59632368, -57775071, -55913295, -54047045, -52176328,
+ -50301149, -48421513, -46537427, -44648897, -42755927, -40858526,
+ -38956697, -37050448, -35139784, -33224711, -31305236, -29381364,
+ -27453102, -25520456, -23583433, -21642037, -19696277, -17746158,
+ -15791686, -13832868, -11869711, -9902220, -7930403, -5954266,
+ -3973815, -1989057, 0, 1993351, 3990989, 5992908, 7999099, 10009557,
+ 12024275, 14043245, 16066462, 18093917, 20125604, 22161515, 24201645,
+ 26245985, 28294529, 30347269, 32404199, 34465310, 36530596, 38600050,
+ 40673664, 42751430, 44833342, 46919392, 49009572, 51103875, 53202294,
+ 55304821, 57411447, 59522167, 61636972, 63755854, 65878805, 68005819,
+ 70136886, 72272000, 74411152, 76554335, 78701540, 80852759, 83007986,
+ 85167211, 87330427, 89497625, 91668797, 93843936, 96023032, 98206079,
+ 100393067, 102583988, 104778834, 106977597, 109180268, 111386839,
+ 113597301, 115811647, 118029866, 120251952, 122477895, 124707686,
+ 126941318, 129178781, 131420066, 133665166, 135914071, 138166772,
+ 140423261, 142683529, 144947566, 147215364, 149486915, 151762208,
+ 154041235, 156323988, 158610456, 160900631, 163194503, 165492064,
+ 167793304, 170098214, 172406785, 174719008, 177034872, 179354369,
+ 181677490, 184004225, 186334564, 188668498, 191006017, 193347113,
+ 195691775, 198039994, 200391760, 202747064, 205105895, 207468245,
+ 209834102, 212203459, 214576304, 216952628, 219332421, 221715674,
+ 224102375, 226492516, 228886086, 231283075, 233683473, 236087271,
+ 238494457, 240905023, 243318957, 245736249, 248156890, 250580868,
+ 253008175, 255438798, 257872729, 260309957, 262750470, 265194260,
+ 267641315, 270091624, 272545178, 275001966, 277461978, 279925201,
+ 282391627, 284861244, 287334042, 289810010, 292289136, 294771412,
+ 297256824, 299745364, 302237020, 304731780, 307229635, 309730572,
+ 312234582, 314741654, 317251775, 319764936, 322281124, 324800329,
+ 327322541, 329847747, 332375936, 334907097, 337441220, 339978292,
+ 342518303, 345061240, 347607094, 350155852, 352707502, 355262035,
+ 357819437, 360379698, 362942806, 365508749, 368077516, 370649096,
+ 373223477, 375800646, 378380593, 380963306, 383548773, 386136982,
+ 388727921, 391321579, 393917945, 396517005, 399118748, 401723162,
+ 404330236, 406939958, 409552314, 412167294, 414784886, 417405076,
+ 420027854, 422653207, 425281123, 427911590, 430544596, 433180128,
+ 435818174, 438458723, 441101761, 443747277, 446395257, 449045691,
+ 451698565, 454353867, 457011584, 459671705, 462334217, 464999106,
+ 467666362, 470335970, 473007919, 475682196, 478358789, 481037684,
+ 483718870, 486402333, 489088061, 491776040, 494466260, 497158705,
+ 499853365, 502550225, 505249274, 507950497, 510653883, 513359419,
+ 516067091, 518776887, 521488793, 524202797, 526918886, 529637047,
+ 532357266, 535079530, 537803827, 540530143, 543258465, 545988781,
+ 548721076, 551455337, 554191552, 556929708, 559669790, 562411785,
+ 565155681, 567901464, 570649121, 573398637, 576150001, 578903198,
+ 581658215, 584415039, 587173656, 589934052, 592696215, 595460130,
+ 598225784, 600993163, 603762255, 606533045, 609305519, 612079664,
+ 614855467, 617632914, 620411990, 623192683, 625974978, 628758862,
+ 631544321, 634331341, 637119908, 639910009, 642701630, 645494757,
+ 648289375, 651085472, 653883033, 656682043, 659482491, 662284360,
+ 665087638, 667892309, 670698362, 673505780, 676314550, 679124659,
+ 681936091, 684748834, 687562872, 690378191, 693194778, 696012619,
+ 698831698, 701652002, 704473517, 707296228, 710120121, 712945183,
+ 715771397, 718598751, 721427230, 724256820, 727087505, 729919273,
+ 732752108, 735585996, 738420923, 741256874, 744093835, 746931791,
+ 749770728, 752610632, 755451487, 758293280, 761135996, 763979620,
+ 766824137, 769669534, 772515796, 775362907, 778210854, 781059622,
+ 783909195, 786759561, 789610703, 792462607, 795315258, 798168642,
+ 801022745, 803877550, 806733044, 809589212, 812446038, 815303509,
+ 818161610, 821020325, 823879639, 826739539, 829600009, 832461034,
+ 835322599, 838184690, 841047292, 843910389, 846773967, 849638011,
+ 852502506, 855367437, 858232788, 861098546, 863964696, 866831221,
+ 869698107, 872565339, 875432903, 878300782, 881168963, 884037429,
+ 886906166, 889775160, 892644394, 895513853, 898383523, 901253389,
+ 904123434, 906993645, 909864006, 912734502, 915605118, 918475838,
+ 921346648, 924217532, 927088475, 929959462, 932830478, 935701506,
+ 938572534, 941443544, 944314522, 947185452, 950056319, 952927109,
+ 955797805, 958668393, 961538857, 964409182, 967279352, 970149352,
+ 973019168, 975888783, 978758182, 981627351, 984496273, 987364933,
+ 990233316, 993101407, 995969190, 998836650, 1001703771, 1004570539,
+ 1007436937, 1010302950, 1013168564, 1016033762, 1018898529, 1021762849,
+ 1024626709, 1027490091, 1030352980, 1033215361, 1036077219, 1038938538,
+ 1041799303, 1044659498, 1047519108, 1050378117, 1053236511, 1056094272,
+ 1058951387, 1061807839, 1064663612, 1067518693, 1070373065, 1073226712,
+ 1076079619, 1078931771, 1081783151, 1084633746, 1087483539, 1090332514,
+ 1093180656, 1096027950, 1098874380, 1101719930, 1104564586, 1107408331,
+ 1110251150, 1113093028, 1115933949, 1118773897, 1121612857, 1124450814,
+ 1127287751, 1130123654, 1132958507, 1135792294, 1138625000, 1141456610,
+ 1144287107, 1147116476, 1149944702, 1152771769, 1155597662, 1158422365,
+ 1161245863, 1164068139, 1166889179, 1169708968, 1172527488, 1175344726,
+ 1178160665, 1180975290, 1183788586, 1186600536, 1189411126, 1192220340,
+ 1195028162, 1197834577, 1200639569, 1203443123, 1206245223, 1209045854,
+ 1211845000, 1214642646, 1217438776, 1220233375, 1223026428, 1225817918,
+ 1228607830, 1231396150, 1234182860, 1236967947, 1239751393, 1242533185,
+ 1245313306, 1248091742, 1250868475, 1253643492, 1256416776, 1259188313,
+ 1261958086, 1264726080, 1267492280, 1270256671, 1273019236, 1275779961,
+ 1278538831, 1281295828, 1284050940, 1286804149, 1289555440, 1292304799,
+ 1295052209, 1297797656, 1300541123, 1303282596, 1306022060, 1308759498,
+ 1311494895, 1314228237, 1316959508, 1319688692, 1322415774, 1325140739,
+ 1327863572, 1330584256, 1333302778, 1336019121, 1338733271, 1341445211,
+ 1344154928, 1346862404, 1349567627, 1352270579, 1354971246, 1357669612,
+ 1360365663, 1363059382, 1365750756, 1368439768, 1371126404, 1373810648,
+ 1376492485, 1379171901, 1381848879, 1384523404, 1387195462, 1389865038,
+ 1392532116, 1395196681, 1397858718, 1400518212, 1403175148, 1405829511,
+ 1408481285, 1411130456, 1413777009, 1416420929, 1419062200, 1421700808,
+ 1424336737, 1426969973, 1429600501, 1432228305, 1434853371, 1437475684,
+ 1440095228, 1442711990, 1445325953, 1447937104, 1450545427, 1453150907,
+ 1455753530, 1458353281, 1460950144, 1463544105, 1466135149, 1468723262,
+ 1471308429, 1473890634, 1476469863, 1479046101, 1481619334, 1484189547,
+ 1486756725, 1489320854, 1491881918, 1494439903, 1496994794, 1499546578,
+ 1502095238, 1504640761, 1507183132, 1509722336, 1512258360, 1514791187,
+ 1517320804, 1519847196, 1522370348, 1524890247, 1527406877, 1529920225,
+ 1532430275, 1534937014, 1537440426, 1539940498, 1542437215, 1544930562,
+ 1547420526, 1549907092, 1552390245, 1554869972, 1557346257, 1559819088,
+ 1562288449, 1564754326, 1567216705, 1569675572, 1572130912, 1574582712,
+ 1577030957, 1579475633, 1581916726, 1584354222, 1586788106, 1589218366,
+ 1591644985, 1594067952, 1596487251, 1598902868, 1601314790, 1603723003,
+ 1606127492, 1608528243, 1610925244, 1613318479, 1615707936, 1618093599,
+ 1620475456, 1622853492, 1625227694, 1627598048, 1629964539, 1632327156,
+ 1634685882, 1637040706, 1639391613, 1641738589, 1644081622, 1646420696,
+ 1648755800, 1651086918, 1653414038, 1655737146, 1658056228, 1660371271,
+ 1662682262, 1664989187, 1667292032, 1669590784, 1671885430, 1674175956,
+ 1676462350, 1678744597, 1681022684, 1683296598, 1685566326, 1687831854,
+ 1690093170, 1692350260, 1694603110, 1696851709, 1699096042, 1701336096,
+ 1703571858, 1705803316, 1708030456, 1710253265, 1712471731, 1714685839,
+ 1716895578, 1719100934, 1721301894, 1723498446, 1725690576, 1727878272,
+ 1730061521, 1732240310, 1734414627, 1736584458, 1738749790, 1740910612,
+ 1743066911, 1745218673, 1747365887, 1749508539, 1751646617, 1753780108,
+ 1755909000, 1758033281, 1760152938, 1762267958, 1764378329, 1766484039,
+ 1768585075, 1770681424, 1772773076, 1774860016, 1776942233, 1779019715,
+ 1781092450, 1783160425, 1785223627, 1787282046, 1789335668, 1791384482,
+ 1793428476, 1795467637, 1797501954, 1799531414, 1801556006, 1803575717,
+ 1805590536, 1807600451, 1809605450, 1811605521, 1813600652, 1815590832,
+ 1817576048, 1819556289, 1821531544, 1823501800, 1825467047, 1827427272,
+ 1829382463, 1831332610, 1833277700, 1835217723, 1837152667, 1839082519,
+ 1841007270, 1842926907, 1844841419, 1846750795, 1848655023, 1850554092,
+ 1852447992, 1854336710, 1856220236, 1858098558, 1859971665, 1861839546,
+ 1863702190, 1865559587, 1867411724, 1869258591, 1871100178, 1872936472,
+ 1874767464, 1876593142, 1878413495, 1880228513, 1882038186, 1883842501,
+ 1885641449, 1887435018, 1889223199, 1891005980, 1892783351, 1894555301,
+ 1896321820, 1898082898, 1899838523, 1901588686, 1903333375, 1905072582,
+ 1906806294, 1908534502, 1910257196, 1911974366, 1913686000, 1915392090,
+ 1917092624, 1918787593, 1920476987, 1922160795, 1923839008, 1925511615,
+ 1927178607, 1928839973, 1930495704, 1932145790, 1933790221, 1935428987,
+ 1937062078, 1938689486, 1940311199, 1941927208, 1943537504, 1945142077,
+ 1946740917, 1948334016, 1949921363, 1951502948, 1953078764, 1954648799,
+ 1956213045, 1957771492, 1959324131, 1960870953, 1962411949, 1963947109,
+ 1965476424, 1966999885, 1968517483, 1970029209, 1971535053, 1973035008,
+ 1974529063, 1976017210, 1977499440, 1978975744, 1980446113, 1981910538,
+ 1983369012, 1984821524, 1986268067, 1987708631, 1989143208, 1990571790,
+ 1991994367, 1993410932, 1994821475, 1996225989, 1997624465, 1999016895,
+ 2000403269, 2001783581, 2003157821, 2004525982, 2005888055, 2007244032,
+ 2008593904, 2009937665, 2011275306, 2012606818, 2013932194, 2015251425,
+ 2016564505, 2017871425, 2019172176, 2020466752, 2021755145, 2023037347,
+ 2024313349, 2025583145, 2026846727, 2028104088, 2029355219, 2030600113,
+ 2031838763, 2033071161, 2034297301, 2035517173, 2036730772, 2037938090,
+ 2039139119, 2040333853, 2041522284, 2042704405, 2043880210, 2045049690,
+ 2046212839, 2047369650, 2048520115, 2049664229, 2050801984, 2051933373,
+ 2053058390, 2054177028, 2055289279, 2056395138, 2057494597, 2058587651,
+ 2059674291, 2060754513, 2061828309, 2062895673, 2063956599, 2065011080,
+ 2066059109, 2067100681, 2068135789, 2069164427, 2070186589, 2071202268,
+ 2072211459, 2073214155, 2074210351, 2075200040, 2076183216, 2077159874,
+ 2078130008, 2079093611, 2080050678, 2081001203, 2081945181, 2082882605,
+ 2083813470, 2084737771, 2085655502, 2086566657, 2087471231, 2088369219,
+ 2089260614, 2090145412, 2091023607, 2091895195, 2092760169, 2093618524,
+ 2094470256, 2095315359, 2096153828, 2096985658, 2097810844, 2098629381,
+ 2099441264, 2100246488, 2101045049, 2101836941, 2102622160, 2103400701,
+ 2104172559, 2104937730, 2105696208, 2106447991, 2107193072, 2107931447,
+ 2108663112, 2109388063, 2110106295, 2110817803, 2111522584, 2112220634,
+ 2112911947, 2113596520, 2114274349, 2114945429, 2115609757, 2116267329,
+ 2116918140, 2117562186, 2118199465, 2118829971, 2119453701, 2120070652,
+ 2120680819, 2121284199, 2121880788, 2122470582, 2123053579, 2123629775,
+ 2124199165, 2124761747, 2125317517, 2125866472, 2126408608, 2126943923,
+ 2127472413, 2127994074, 2128508904, 2129016900, 2129518058, 2130012376,
+ 2130499850, 2130980477, 2131454255, 2131921181, 2132381251, 2132834464,
+ 2133280816, 2133720305, 2134152928, 2134578682, 2134997565, 2135409574,
+ 2135814707, 2136212961, 2136604334, 2136988824, 2137366428, 2137737144,
+ 2138100969, 2138457902, 2138807941, 2139151082, 2139487325, 2139816667,
+ 2140139106, 2140454640, 2140763267, 2141064986, 2141359794, 2141647690,
+ 2141928672, 2142202738, 2142469887, 2142730117, 2142983427, 2143229814,
+ 2143469278, 2143701817, 2143927429, 2144146114, 2144357869, 2144562694,
+ 2144760588, 2144951548, 2145135575, 2145312666, 2145482822, 2145646040,
+ 2145802320, 2145951661, 2146094061, 2146229521, 2146358039, 2146479615,
+ 2146594247, 2146701936, 2146802680, 2146896478, 2146983331, 2147063238,
+ 2147136198, 2147202210, 2147261275, 2147313392, 2147358561, 2147396781,
+ 2147428052, 2147452375, 2147469748, 2147480172, 2147483647, 2147480172,
+ 2147469748, 2147452375, 2147428052, 2147396781, 2147358561, 2147313392,
+ 2147261275, 2147202210, 2147136198, 2147063238, 2146983331, 2146896478,
+ 2146802680, 2146701936, 2146594247, 2146479615, 2146358039, 2146229521,
+ 2146094061, 2145951661, 2145802320, 2145646040, 2145482822, 2145312666,
+ 2145135575, 2144951548, 2144760588, 2144562694, 2144357869, 2144146114,
+ 2143927429, 2143701817, 2143469278, 2143229814, 2142983427, 2142730117,
+ 2142469887, 2142202738, 2141928672, 2141647690, 2141359794, 2141064986,
+ 2140763267, 2140454640, 2140139106, 2139816667, 2139487325, 2139151082,
+ 2138807941, 2138457902, 2138100969, 2137737144, 2137366428, 2136988824,
+ 2136604334, 2136212961, 2135814707, 2135409574, 2134997565, 2134578682,
+ 2134152928, 2133720305, 2133280816, 2132834464, 2132381251, 2131921181,
+ 2131454255, 2130980477, 2130499850, 2130012376, 2129518058, 2129016900,
+ 2128508904, 2127994074, 2127472413, 2126943923, 2126408608, 2125866472,
+ 2125317517, 2124761747, 2124199165, 2123629775, 2123053579, 2122470582,
+ 2121880788, 2121284199, 2120680819, 2120070652, 2119453701, 2118829971,
+ 2118199465, 2117562186, 2116918140, 2116267329, 2115609757, 2114945429,
+ 2114274349, 2113596520, 2112911947, 2112220634, 2111522584, 2110817803,
+ 2110106295, 2109388063, 2108663112, 2107931447, 2107193072, 2106447991,
+ 2105696208, 2104937730, 2104172559, 2103400701, 2102622160, 2101836941,
+ 2101045049, 2100246488, 2099441264, 2098629381, 2097810844, 2096985658,
+ 2096153828, 2095315359, 2094470256, 2093618524, 2092760169, 2091895195,
+ 2091023607, 2090145412, 2089260614, 2088369219, 2087471231, 2086566657,
+ 2085655502, 2084737771, 2083813470, 2082882605, 2081945181, 2081001203,
+ 2080050678, 2079093611, 2078130008, 2077159874, 2076183216, 2075200040,
+ 2074210351, 2073214155, 2072211459, 2071202268, 2070186589, 2069164427,
+ 2068135789, 2067100681, 2066059109, 2065011080, 2063956599, 2062895673,
+ 2061828309, 2060754513, 2059674291, 2058587651, 2057494597, 2056395138,
+ 2055289279, 2054177028, 2053058390, 2051933373, 2050801984, 2049664229,
+ 2048520115, 2047369650, 2046212839, 2045049690, 2043880210, 2042704405,
+ 2041522284, 2040333853, 2039139119, 2037938090, 2036730772, 2035517173,
+ 2034297301, 2033071161, 2031838763, 2030600113, 2029355219, 2028104088,
+ 2026846727, 2025583145, 2024313349, 2023037347, 2021755145, 2020466752,
+ 2019172176, 2017871425, 2016564505, 2015251425, 2013932194, 2012606818,
+ 2011275306, 2009937665, 2008593904, 2007244032, 2005888055, 2004525982,
+ 2003157821, 2001783581, 2000403269, 1999016895, 1997624465, 1996225989,
+ 1994821475, 1993410932, 1991994367, 1990571790, 1989143208, 1987708631,
+ 1986268067, 1984821524, 1983369012, 1981910538, 1980446113, 1978975744,
+ 1977499440, 1976017210, 1974529063, 1973035008, 1971535053, 1970029209,
+ 1968517483, 1966999885, 1965476424, 1963947109, 1962411949, 1960870953,
+ 1959324131, 1957771492, 1956213045, 1954648799, 1953078764, 1951502948,
+ 1949921363, 1948334016, 1946740917, 1945142077, 1943537504, 1941927208,
+ 1940311199, 1938689486, 1937062078, 1935428987, 1933790221, 1932145790,
+ 1930495704, 1928839973, 1927178607, 1925511615, 1923839008, 1922160795,
+ 1920476987, 1918787593, 1917092624, 1915392090, 1913686000, 1911974366,
+ 1910257196, 1908534502, 1906806294, 1905072582, 1903333375, 1901588686,
+ 1899838523, 1898082898, 1896321820, 1894555301, 1892783351, 1891005980,
+ 1889223199, 1887435018, 1885641449, 1883842501, 1882038186, 1880228513,
+ 1878413495, 1876593142, 1874767464, 1872936472, 1871100178, 1869258591,
+ 1867411724, 1865559587, 1863702190, 1861839546, 1859971665, 1858098558,
+ 1856220236, 1854336710, 1852447992, 1850554092, 1848655023, 1846750795,
+ 1844841419, 1842926907, 1841007270, 1839082519, 1837152667, 1835217723,
+ 1833277700, 1831332610, 1829382463, 1827427272, 1825467047, 1823501800,
+ 1821531544, 1819556289, 1817576048, 1815590832, 1813600652, 1811605521,
+ 1809605450, 1807600451, 1805590536, 1803575717, 1801556006, 1799531414,
+ 1797501954, 1795467637, 1793428476, 1791384482, 1789335668, 1787282046,
+ 1785223627, 1783160425, 1781092450, 1779019715, 1776942233, 1774860016,
+ 1772773076, 1770681424, 1768585075, 1766484039, 1764378329, 1762267958,
+ 1760152938, 1758033281, 1755909000, 1753780108, 1751646617, 1749508539,
+ 1747365887, 1745218673, 1743066911, 1740910612, 1738749790, 1736584458,
+ 1734414627, 1732240310, 1730061521, 1727878272, 1725690576, 1723498446,
+ 1721301894, 1719100934, 1716895578, 1714685839, 1712471731, 1710253265,
+ 1708030456, 1705803316, 1703571858, 1701336096, 1699096042, 1696851709,
+ 1694603110, 1692350260, 1690093170, 1687831854, 1685566326, 1683296598,
+ 1681022684, 1678744597, 1676462350, 1674175956, 1671885430, 1669590784,
+ 1667292032, 1664989187, 1662682262, 1660371271, 1658056228, 1655737146,
+ 1653414038, 1651086918, 1648755800, 1646420696, 1644081622, 1641738589,
+ 1639391613, 1637040706, 1634685882, 1632327156, 1629964539, 1627598048,
+ 1625227694, 1622853492, 1620475456, 1618093599, 1615707936, 1613318479,
+ 1610925244, 1608528243, 1606127492, 1603723003, 1601314790, 1598902868,
+ 1596487251, 1594067952, 1591644985, 1589218366, 1586788106, 1584354222,
+ 1581916726, 1579475633, 1577030957, 1574582712, 1572130912, 1569675572,
+ 1567216705, 1564754326, 1562288449, 1559819088, 1557346257, 1554869972,
+ 1552390245, 1549907092, 1547420526, 1544930562, 1542437215, 1539940498,
+ 1537440426, 1534937014, 1532430275, 1529920225, 1527406877, 1524890247,
+ 1522370348, 1519847196, 1517320804, 1514791187, 1512258360, 1509722336,
+ 1507183132, 1504640761, 1502095238, 1499546578, 1496994794, 1494439903,
+ 1491881918, 1489320854, 1486756725, 1484189547, 1481619334, 1479046101,
+ 1476469863, 1473890634, 1471308429, 1468723262, 1466135149, 1463544105,
+ 1460950144, 1458353281, 1455753530, 1453150907, 1450545427, 1447937104,
+ 1445325953, 1442711990, 1440095228, 1437475684, 1434853371, 1432228305,
+ 1429600501, 1426969973, 1424336737, 1421700808, 1419062200, 1416420929,
+ 1413777009, 1411130456, 1408481285, 1405829511, 1403175148, 1400518212,
+ 1397858718, 1395196681, 1392532116, 1389865038, 1387195462, 1384523404,
+ 1381848879, 1379171901, 1376492485, 1373810648, 1371126404, 1368439768,
+ 1365750756, 1363059382, 1360365663, 1357669612, 1354971246, 1352270579,
+ 1349567627, 1346862404, 1344154928, 1341445211, 1338733271, 1336019121,
+ 1333302778, 1330584256, 1327863572, 1325140739, 1322415774, 1319688692,
+ 1316959508, 1314228237, 1311494895, 1308759498, 1306022060, 1303282596,
+ 1300541123, 1297797656, 1295052209, 1292304799, 1289555440, 1286804149,
+ 1284050940, 1281295828, 1278538831, 1275779961, 1273019236, 1270256671,
+ 1267492280, 1264726080, 1261958086, 1259188313, 1256416776, 1253643492,
+ 1250868475, 1248091742, 1245313306, 1242533185, 1239751393, 1236967947,
+ 1234182860, 1231396150, 1228607830, 1225817918, 1223026428, 1220233375,
+ 1217438776, 1214642646, 1211845000, 1209045854, 1206245223, 1203443123,
+ 1200639569, 1197834577, 1195028162, 1192220340, 1189411126, 1186600536,
+ 1183788586, 1180975290, 1178160665, 1175344726, 1172527488, 1169708968,
+ 1166889179, 1164068139, 1161245863, 1158422365, 1155597662, 1152771769,
+ 1149944702, 1147116476, 1144287107, 1141456610, 1138625000, 1135792294,
+ 1132958507, 1130123654, 1127287751, 1124450814, 1121612857, 1118773897,
+ 1115933949, 1113093028, 1110251150, 1107408331, 1104564586, 1101719930,
+ 1098874380, 1096027950, 1093180656, 1090332514, 1087483539, 1084633746,
+ 1081783151, 1078931771, 1076079619, 1073226712, 1070373065, 1067518693,
+ 1064663612, 1061807839, 1058951387, 1056094272, 1053236511, 1050378117,
+ 1047519108, 1044659498, 1041799303, 1038938538, 1036077219, 1033215361,
+ 1030352980, 1027490091, 1024626709, 1021762849, 1018898529, 1016033762,
+ 1013168564, 1010302950, 1007436937, 1004570539, 1001703771, 998836650,
+ 995969190, 993101407, 990233316, 987364933, 984496273, 981627351,
+ 978758182, 975888783, 973019168, 970149352, 967279352, 964409182,
+ 961538857, 958668393, 955797805, 952927109, 950056319, 947185452,
+ 944314522, 941443544, 938572534, 935701506, 932830478, 929959462,
+ 927088475, 924217532, 921346648, 918475838, 915605118, 912734502,
+ 909864006, 906993645, 904123434, 901253389, 898383523, 895513853,
+ 892644394, 889775160, 886906166, 884037429, 881168963, 878300782,
+ 875432903, 872565339, 869698107, 866831221, 863964696, 861098546,
+ 858232788, 855367437, 852502506, 849638011, 846773967, 843910389,
+ 841047292, 838184690, 835322599, 832461034, 829600009, 826739539,
+ 823879639, 821020325, 818161610, 815303509, 812446038, 809589212,
+ 806733044, 803877550, 801022745, 798168642, 795315258, 792462607,
+ 789610703, 786759561, 783909195, 781059622, 778210854, 775362907,
+ 772515796, 769669534, 766824137, 763979620, 761135996, 758293280,
+ 755451487, 752610632, 749770728, 746931791, 744093835, 741256874,
+ 738420923, 735585996, 732752108, 729919273, 727087505, 724256820,
+ 721427230, 718598751, 715771397, 712945183, 710120121, 707296228,
+ 704473517, 701652002, 698831698, 696012619, 693194778, 690378191,
+ 687562872, 684748834, 681936091, 679124659, 676314550, 673505780,
+ 670698362, 667892309, 665087638, 662284360, 659482491, 656682043,
+ 653883033, 651085472, 648289375, 645494757, 642701630, 639910009,
+ 637119908, 634331341, 631544321, 628758862, 625974978, 623192683,
+ 620411990, 617632914, 614855467, 612079664, 609305519, 606533045,
+ 603762255, 600993163, 598225784, 595460130, 592696215, 589934052,
+ 587173656, 584415039, 581658215, 578903198, 576150001, 573398637,
+ 570649121, 567901464, 565155681, 562411785, 559669790, 556929708,
+ 554191552, 551455337, 548721076, 545988781, 543258465, 540530143,
+ 537803827, 535079530, 532357266, 529637047, 526918886, 524202797,
+ 521488793, 518776887, 516067091, 513359419, 510653883, 507950497,
+ 505249274, 502550225, 499853365, 497158705, 494466260, 491776040,
+ 489088061, 486402333, 483718870, 481037684, 478358789, 475682196,
+ 473007919, 470335970, 467666362, 464999106, 462334217, 459671705,
+ 457011584, 454353867, 451698565, 449045691, 446395257, 443747277,
+ 441101761, 438458723, 435818174, 433180128, 430544596, 427911590,
+ 425281123, 422653207, 420027854, 417405076, 414784886, 412167294,
+ 409552314, 406939958, 404330236, 401723162, 399118748, 396517005,
+ 393917945, 391321579, 388727921, 386136982, 383548773, 380963306,
+ 378380593, 375800646, 373223477, 370649096, 368077516, 365508749,
+ 362942806, 360379698, 357819437, 355262035, 352707502, 350155852,
+ 347607094, 345061240, 342518303, 339978292, 337441220, 334907097,
+ 332375936, 329847747, 327322541, 324800329, 322281124, 319764936,
+ 317251775, 314741654, 312234582, 309730572, 307229635, 304731780,
+ 302237020, 299745364, 297256824, 294771412, 292289136, 289810010,
+ 287334042, 284861244, 282391627, 279925201, 277461978, 275001966,
+ 272545178, 270091624, 267641315, 265194260, 262750470, 260309957,
+ 257872729, 255438798, 253008175, 250580868, 248156890, 245736249,
+ 243318957, 240905023, 238494457, 236087271, 233683473, 231283075,
+ 228886086, 226492516, 224102375, 221715674, 219332421, 216952628,
+ 214576304, 212203459, 209834102, 207468245, 205105895, 202747064,
+ 200391760, 198039994, 195691775, 193347113, 191006017, 188668498,
+ 186334564, 184004225, 181677490, 179354369, 177034872, 174719008,
+ 172406785, 170098214, 167793304, 165492064, 163194503, 160900631,
+ 158610456, 156323988, 154041235, 151762208, 149486915, 147215364,
+ 144947566, 142683529, 140423261, 138166772, 135914071, 133665166,
+ 131420066, 129178781, 126941318, 124707686, 122477895, 120251952,
+ 118029866, 115811647, 113597301, 111386839, 109180268, 106977597,
+ 104778834, 102583988, 100393067, 98206079, 96023032, 93843936,
+ 91668797, 89497625, 87330427, 85167211, 83007986, 80852759, 78701540,
+ 76554335, 74411152, 72272000, 70136886, 68005819, 65878805, 63755854,
+ 61636972, 59522167, 57411447, 55304821, 53202294, 51103875, 49009572,
+ 46919392, 44833342, 42751430, 40673664, 38600050, 36530596, 34465310,
+ 32404199, 30347269, 28294529, 26245985, 24201645, 22161515, 20125604,
+ 18093917, 16066462, 14043245, 12024275, 10009557, 7999099, 5992908,
+ 3990989, 1993351, 0, -1989057, -3973815, -5954266, -7930403, -9902220,
+ -11869711, -13832868, -15791686, -17746158, -19696277, -21642037,
+ -23583433, -25520456, -27453102, -29381364, -31305236, -33224711,
+ -35139784, -37050448, -38956697, -40858526, -42755927, -44648897,
+ -46537427, -48421513, -50301149, -52176328, -54047045, -55913295,
+ -57775071, -59632368, -61485180, -63333502, -65177327, -67016651,
+ -68851468, -70681773, -72507559, -74328822, -76145556, -77957756,
+ -79765416, -81568532, -83367098, -85161109, -86950559, -88735444,
+ -90515758, -92291497, -94062655, -95829227, -97591209, -99348596,
+ -101101382, -102849562, -104593133, -106332089, -108066425, -109796137,
+ -111521220, -113241670, -114957481, -116668649, -118375170, -120077040,
+ -121774253, -123466805, -125154692, -126837910, -128516454, -130190320,
+ -131859504, -133524001, -135183807, -136838919, -138489331, -140135041,
+ -141776043, -143412334, -145043910, -146670768, -148292902, -149910309,
+ -151522986, -153130929, -154734133, -156332596, -157926313, -159515280,
+ -161099495, -162678954, -164253652, -165823587, -167388755, -168949153,
+ -170504777, -172055624, -173601690, -175142972, -176679468, -178211173,
+ -179738085, -181260199, -182777515, -184290027, -185797733, -187300631,
+ -188798717, -190291987, -191780440, -193264073, -194742882, -196216864,
+ -197686018, -199150340, -200609827, -202064477, -203514288, -204959256,
+ -206399379, -207834654, -209265080, -210690654, -212111372, -213527234,
+ -214938236, -216344376, -217745652, -219142061, -220533602, -221920273,
+ -223302070, -224678993, -226051038, -227418205, -228780490, -230137892,
+ -231490410, -232838041, -234180783, -235518634, -236851593, -238179659,
+ -239502828, -240821100, -242134474, -243442946, -244746516, -246045183,
+ -247338944, -248627798, -249911745, -251190781, -252464907, -253734121,
+ -254998421, -256257806, -257512275, -258761828, -260006461, -261246175,
+ -262480969, -263710841, -264935790, -266155816, -267370917, -268581093,
+ -269786343, -270986665, -272182059, -273372525, -274558061, -275738667,
+ -276914342, -278085085, -279250897, -280411776, -281567721, -282718733,
+ -283864811, -285005955, -286142163, -287273436, -288399774, -289521175,
+ -290637641, -291749170, -292855762, -293957418, -295054137, -296145919,
+ -297232764, -298314672, -299391643, -300463677, -301530775, -302592936,
+ -303650160, -304702448, -305749799, -306792215, -307829696, -308862241,
+ -309889851, -310912527, -311930269, -312943077, -313950952, -314953895,
+ -315951905, -316944985, -317933133, -318916351, -319894640, -320868001,
+ -321836433, -322799938, -323758517, -324712171, -325660900, -326604706,
+ -327543589, -328477550, -329406591, -330330712, -331249915, -332164201,
+ -333073570, -333978025, -334877565, -335772194, -336661911, -337546719,
+ -338426618, -339301610, -340171697, -341036879, -341897159, -342752538,
+ -343603017, -344448598, -345289283, -346125073, -346955971, -347781977,
+ -348603093, -349419322, -350230665, -351037124, -351838701, -352635397,
+ -353427216, -354214158, -354996225, -355773421, -356545746, -357313204,
+ -358075795, -358833523, -359586389, -360334396, -361077546, -361815841,
+ -362549284, -363277877, -364001622, -364720522, -365434580, -366143797,
+ -366848177, -367547721, -368242433, -368932315, -369617370, -370297600,
+ -370973009, -371643598, -372309371, -372970330, -373626479, -374277819,
+ -374924355, -375566089, -376203024, -376835163, -377462509, -378085064,
+ -378702833, -379315818, -379924023, -380527450, -381126103, -381719985,
+ -382309099, -382893449, -383473037, -384047868, -384617945, -385183270,
+ -385743848, -386299683, -386850776, -387397133, -387938756, -388475650,
+ -389007817, -389535262, -390057988, -390576000, -391089299, -391597892,
+ -392101780, -392600969, -393095461, -393585262, -394070374, -394550802,
+ -395026549, -395497621, -395964020, -396425751, -396882818, -397335225,
+ -397782976, -398226076, -398664529, -399098338, -399527508, -399952044,
+ -400371950, -400787230, -401197889, -401603930, -402005359, -402402180,
+ -402794397, -403182015, -403565038, -403943472, -404317320, -404686587,
+ -405051279, -405411399, -405766953, -406117944, -406464379, -406806261,
+ -407143596, -407476389, -407804643, -408128365, -408447559, -408762231,
+ -409072384, -409378025, -409679158, -409975788, -410267921, -410555561,
+ -410838714, -411117384, -411391578, -411661301, -411926557, -412187351,
+ -412443691, -412695579, -412943023, -413186027, -413424597, -413658738,
+ -413888455, -414113755, -414334643, -414551124, -414763204, -414970888,
+ -415174183, -415373093, -415567625, -415757784, -415943576, -416125007,
+ -416302082, -416474807, -416643188, -416807232, -416966943, -417122328,
+ -417273392, -417420143, -417562585, -417700724, -417834568, -417964121,
+ -418089389, -418210380, -418327099, -418439552, -418547746, -418651686,
+ -418751379, -418846831, -418938048, -419025037, -419107804, -419186356,
+ -419260698, -419330837, -419396780, -419458533, -419516102, -419569494,
+ -419618716, -419663774, -419704674, -419741423, -419774028, -419802495,
+ -419826832, -419847044, -419863138, -419875121, -419883001, -419886783,
+ -419886474, -419882082, -419873612, -419861073, -419844470, -419823811,
+ -419799102, -419770351, -419737564, -419700749, -419659912, -419615061,
+ -419566203, -419513344, -419456491, -419395653, -419330835, -419262046,
+ -419189292, -419112580, -419031918, -418947313, -418858772, -418766303,
+ -418669913, -418569608, -418465397, -418357287, -418245286, -418129399,
+ -418009636, -417886003, -417758509, -417627159, -417491963, -417352927,
+ -417210059, -417063367, -416912858, -416758540, -416600420, -416438506,
+ -416272805, -416103326, -415930077, -415753064, -415572295, -415387779,
+ -415199523, -415007535, -414811822, -414612393, -414409255, -414202417,
+ -413991885, -413777669, -413559775, -413338213, -413112989, -412884112,
+ -412651590, -412415431, -412175643, -411932233, -411685211, -411434583,
+ -411180359, -410922546, -410661152, -410396186, -410127656, -409855570,
+ -409579936, -409300762, -409018057, -408731829, -408442085, -408148836,
+ -407852088, -407551850, -407248130, -406940937, -406630279, -406316165,
+ -405998603, -405677601, -405353167, -405025311, -404694041, -404359365,
+ -404021291, -403679829, -403334986, -402986771, -402635194, -402280261,
+ -401921983, -401560367, -401195422, -400827157, -400455581, -400080701,
+ -399702528, -399321069, -398936333, -398548329, -398157066, -397762552,
+ -397364796, -396963807, -396559594, -396152166, -395741531, -395327698,
+ -394910676, -394490474, -394067100, -393640565, -393210876, -392778042,
+ -392342073, -391902977, -391460763, -391015441, -390567019, -390115506,
+ -389660911, -389203244, -388742512, -388278727, -387811895, -387342027,
+ -386869131, -386393217, -385914294, -385432370, -384947455, -384459559,
+ -383968689, -383474856, -382978069, -382478336, -381975667, -381470071,
+ -380961558, -380450136, -379935815, -379418604, -378898512, -378375549,
+ -377849723, -377321045, -376789524, -376255168, -375717987, -375177990,
+ -374635188, -374089588, -373541201, -372990036, -372436102, -371879408,
+ -371319965, -370757781, -370192866, -369625229, -369054880, -368481828,
+ -367906083, -367327653, -366746550, -366162781, -365576357, -364987287,
+ -364395581, -363801248, -363204297, -362604739, -362002582, -361397837,
+ -360790512, -360180618, -359568163, -358953158, -358335613, -357715536,
+ -357092937, -356467827, -355840214, -355210108, -354577519, -353942456,
+ -353304930, -352664950, -352022525, -351377665, -350730380, -350080679,
+ -349428573, -348774071, -348117182, -347457916, -346796284, -346132294,
+ -345465957, -344797282, -344126280, -343452958, -342777329, -342099400,
+ -341419183, -340736687, -340051921, -339364895, -338675620, -337984104,
+ -337290358, -336594392, -335896215, -335195837, -334493268, -333788518,
+ -333081597, -332372514, -331661280, -330947903, -330232395, -329514764,
+ -328795021, -328073176, -327349238, -326623217, -325895123, -325164967,
+ -324432757, -323698504, -322962218, -322223908, -321483585, -320741258,
+ -319996938, -319250633, -318502355, -317752112, -316999915, -316245774,
+ -315489699, -314731699, -313971785, -313209966, -312446253, -311680655,
+ -310913182, -310143844, -309372651, -308599613, -307824741, -307048043,
+ -306269530, -305489211, -304707098, -303923199, -303137524, -302350085,
+ -301560889, -300769949, -299977272, -299182870, -298386752, -297588928,
+ -296789409, -295988204, -295185323, -294380776, -293574573, -292766724,
+ -291957238, -291146127, -290333400, -289519066, -288703136, -287885620,
+ -287066528, -286245869, -285423654, -284599892, -283774594, -282947769,
+ -282119428, -281289580, -280458235, -279625404, -278791096, -277955321,
+ -277118089, -276279410, -275439294, -274597751, -273754791, -272910423,
+ -272064659, -271217507, -270368977, -269519081, -268667826, -267815225,
+ -266961285, -266106018, -265249433, -264391540, -263532349, -262671870,
+ -261810112, -260947087, -260082803, -259217271, -258350500, -257482501,
+ -256613282, -255742855, -254871229, -253998414, -253124420, -252249256,
+ -251372933, -250495460, -249616848, -248737106, -247856243, -246974271,
+ -246091198, -245207035, -244321791, -243435477, -242548102, -241659675,
+ -240770207, -239879708, -238988187, -238095654, -237202120, -236307593,
+ -235412083, -234515601, -233618157, -232719759, -231820417, -230920143,
+ -230018944, -229116832, -228213815, -227309904, -226405109, -225499438,
+ -224592902, -223685510, -222777273, -221868199, -220958299, -220047583,
+ -219136059, -218223738, -217310630, -216396743, -215482088, -214566675,
+ -213650513, -212733611, -211815980, -210897629, -209978567, -209058805,
+ -208138351, -207217216, -206295409, -205372939, -204449817, -203526052,
+ -202601653, -201676630, -200750993, -199824750, -198897912, -197970489,
+ -197042488, -196113922, -195184797, -194255125, -193324915, -192394176,
+ -191462917, -190531149, -189598880, -188666120, -187732879, -186799165,
+ -185864989, -184930359, -183995286, -183059778, -182123845, -181187497,
+ -180250742, -179313590, -178376050, -177438132, -176499845, -175561199,
+ -174622202, -173682864, -172743195, -171803203, -170862898, -169922289,
+ -168981386, -168040197, -167098731, -166156999, -165215010, -164272771,
+ -163330294, -162387586, -161444657, -160501517, -159558173, -158614637,
+ -157670916, -156727019, -155782957, -154838737, -153894370, -152949863,
+ -152005227, -151060470, -150115601, -149170629, -148225564, -147280414,
+ -146335189, -145389896, -144444546, -143499147, -142553709, -141608239,
+ -140662748, -139717243, -138771734, -137826230, -136880740, -135935272,
+ -134989835, -134044439, -133099091, -132153802, -131208579, -130263431,
+ -129318368, -128373397, -127428528, -126483770, -125539131, -124594619,
+ -123650245, -122706015, -121761940, -120818027, -119874285, -118930723,
+ -117987350, -117044174, -116101203, -115158447, -114215913, -113273611,
+ -112331549, -111389736, -110448179, -109506888, -108565871, -107625137,
+ -106684693, -105744548, -104804712, -103865191, -102925995, -101987132,
+ -101048611, -100110439, -99172625, -98235178, -97298105, -96361415,
+ -95425117, -94489218, -93553726, -92618651, -91684000, -90749782,
+ -89816004, -88882675, -87949803, -87017396, -86085463, -85154011,
+ -84223048, -83292584, -82362624, -81433179, -80504255, -79575861,
+ -78648005, -77720695, -76793939, -75867744, -74942119, -74017072,
+ -73092610, -72168742, -71245475, -70322817, -69400776, -68479361,
+ -67558578, -66638435, -65718941, -64800103, -63881929, -62964426,
+ -62047603, -61131467, -60216025, -59301286, -58387257, -57473945,
+ -56561359, -55649506, -54738393, -53828029, -52918420, -52009574,
+ -51101498, -50194201, -49287690, -48381972, -47477054, -46572945,
+ -45669651, -44767179, -43865538, -42964735, -42064777, -41165670,
+ -40267424, -39370044, -38473539, -37577914, -36683179, -35789340,
+ -34896403, -34004377, -33113268, -32223084, -31333832, -30445519,
+ -29558151, -28671737, -27786283, -26901796, -26018283, -25135751,
+ -24254208, -23373660, -22494114, -21615576, -20738055, -19861557,
+ -18986089, -18111657, -17238268, -16365930, -15494649, -14624432,
+ -13755286, -12887217, -12020232, -11154337, -10289541, -9425848,
+ -8563267, -7701803, -6841463, -5982254, -5124182, -4267254, -3411476,
+ -2556855, -1703398, -851111, 0, 849928, 1698667, 2546210, 3392552,
+ 4237684, 5081603, 5924300, 6765770, 7606006, 8445002, 9282752,
+ 10119249, 10954488, 11788463, 12621166, 13452592, 14282735, 15111588,
+ 15939146, 16765402, 17590351, 18413986, 19236302, 20057292, 20876950,
+ 21695271, 22512248, 23327876, 24142148, 24955060, 25766604, 26576776,
+ 27385569, 28192978, 28998996, 29803618, 30606839, 31408653, 32209053,
+ 33008035, 33805592, 34601719, 35396411, 36189661, 36981465, 37771816,
+ 38560710, 39348140, 40134101, 40918588, 41701596, 42483118, 43263150,
+ 44041686, 44818721, 45594249, 46368265, 47140764, 47911740, 48681189,
+ 49449105, 50215482, 50980317, 51743602, 52505334, 53265508, 54024117,
+ 54781158, 55536624, 56290511, 57042814, 57793528, 58542648, 59290169,
+ 60036086, 60780395, 61523089, 62264164, 63003617, 63741440, 64477631,
+ 65212184, 65945094, 66676357, 67405967, 68133921, 68860213, 69584839,
+ 70307794, 71029074, 71748673, 72466588, 73182814, 73897346, 74610181,
+ 75321312, 76030736, 76738449, 77444445, 78148722, 78851273, 79552096,
+ 80251184, 80948536, 81644145, 82338007, 83030120, 83720477, 84409075,
+ 85095911, 85780978, 86464275, 87145795, 87825537, 88503494, 89179663,
+ 89854041, 90526623, 91197405, 91866383, 92533554, 93198912, 93862456,
+ 94524179, 95184080, 95842153, 96498396, 97152804, 97805373, 98456100,
+ 99104981, 99752013, 100397191, 101040512, 101681973, 102321569,
+ 102959298, 103595155, 104229138, 104861241, 105491463, 106119800,
+ 106746248, 107370803, 107993462, 108614223, 109233081, 109850033,
+ 110465076, 111078206, 111689421, 112298717, 112906090, 113511539,
+ 114115058, 114716645, 115316298, 115914013, 116509786, 117103615,
+ 117695497, 118285428, 118873406, 119459427, 120043489, 120625589,
+ 121205724, 121783890, 122360086, 122934307, 123506552, 124076817,
+ 124645100, 125211398, 125775708, 126338027, 126898353, 127456683,
+ 128013014, 128567345, 129119671, 129669990, 130218301, 130764600,
+ 131308885, 131851153, 132391402, 132929629, 133465833, 134000009,
+ 134532157, 135062274, 135590357, 136116404, 136640413, 137162382,
+ 137682307, 138200188, 138716021, 139229805, 139741537, 140251215,
+ 140758837, 141264402, 141767906, 142269348, 142768726, 143266037,
+ 143761281, 144254454, 144745554, 145234581, 145721531, 146206404,
+ 146689197, 147169908, 147648535, 148125078, 148599533, 149071899,
+ 149542175, 150010358, 150476448, 150940441, 151402338, 151862135,
+ 152319832, 152775427, 153228918, 153680303, 154129582, 154576753,
+ 155021814, 155464763, 155905600, 156344323, 156780930, 157215421,
+ 157647793, 158078046, 158506178, 158932188, 159356075, 159777837,
+ 160197473, 160614982, 161030363, 161443614, 161854735, 162263724,
+ 162670581, 163075304, 163477892, 163878345, 164276660, 164672838,
+ 165066876, 165458776, 165848534, 166236151, 166621625, 167004956,
+ 167386144, 167765186, 168142082, 168516832, 168889435, 169259889,
+ 169628195, 169994352, 170358358, 170720214, 171079919, 171437471,
+ 171792872, 172146119, 172497212, 172846152, 173192936, 173537566,
+ 173880040, 174220358, 174558520, 174894525, 175228373, 175560063,
+ 175889596, 176216970, 176542186, 176865243, 177186142, 177504881,
+ 177821460, 178135880, 178448141, 178758241, 179066182, 179371962,
+ 179675582, 179977042, 180276341, 180573480, 180868459, 181161278,
+ 181451936, 181740434, 182026772, 182310950, 182592967, 182872826,
+ 183150524, 183426063, 183699443, 183970664, 184239725, 184506629,
+ 184771374, 185033961, 185294391, 185552663, 185808779, 186062737,
+ 186314540, 186564187, 186811679, 187057016, 187300198, 187541227,
+ 187780102, 188016825, 188251395, 188483814, 188714081, 188942199,
+ 189168166, 189391984, 189613654, 189833176, 190050551, 190265779,
+ 190478862, 190689800, 190898594, 191105245, 191309754, 191512121,
+ 191712347, 191910434, 192106382, 192300191, 192491864, 192681401,
+ 192868803, 193054070, 193237205, 193418207, 193597079, 193773821,
+ 193948434, 194120919, 194291278, 194459512, 194625621, 194789608,
+ 194951472, 195111216, 195268841, 195424347, 195577737, 195729012,
+ 195878172, 196025219, 196170155, 196312981, 196453698, 196592308,
+ 196728811, 196863211, 196995507, 197125703, 197253798, 197379794,
+ 197503694, 197625498, 197745209, 197862827, 197978355, 198091794,
+ 198203145, 198312411, 198419593, 198524692, 198627711, 198728651,
+ 198827514, 198924302, 199019016, 199111658, 199202231, 199290735,
+ 199377173, 199461547, 199543858, 199624109, 199702301, 199778436,
+ 199852516, 199924544, 199994521, 200062449, 200128331, 200192167,
+ 200253961, 200313715, 200371430, 200427108, 200480753, 200532365,
+ 200581947, 200629501, 200675030, 200718535, 200760020, 200799485,
+ 200836934, 200872368, 200905790, 200937202, 200966607, 200994007,
+ 201019404, 201042800, 201064198, 201083601, 201101011, 201116430,
+ 201129860, 201141305, 201150766, 201158246, 201163748, 201167274,
+ 201168827, 201168409, 201166023, 201161671, 201155357, 201147082,
+ 201136849, 201124661, 201110521, 201094431, 201076394, 201056413,
+ 201034490, 201010629, 200984831, 200957100, 200927438, 200895849,
+ 200862335, 200826899, 200789544, 200750272, 200709087, 200665991,
+ 200620988, 200574080, 200525270, 200474561, 200421956, 200367458,
+ 200311071, 200252796, 200192637, 200130598, 200066681, 200000889,
+ 199933225, 199863693, 199792295, 199719035, 199643916, 199566940,
+ 199488112, 199407434, 199324909, 199240541, 199154333, 199066287,
+ 198976408, 198884699, 198791163, 198695802, 198598621, 198499623,
+ 198398811, 198296188, 198191758, 198085524, 197977489, 197867657,
+ 197756032, 197642616, 197527413, 197410427, 197291661, 197171118,
+ 197048802, 196924716, 196798864, 196671250, 196541877, 196410748,
+ 196277867, 196143238, 196006864, 195868748, 195728895, 195587308,
+ 195443991, 195298946, 195152179, 195003692, 194853489, 194701574,
+ 194547951, 194392623, 194235594, 194076868, 193916448, 193754338,
+ 193590543, 193425065, 193257909, 193089078, 192918576, 192746407,
+ 192572575, 192397084, 192219937, 192041138, 191860692, 191678602,
+ 191494871, 191309505, 191122507, 190933880, 190743629, 190551758,
+ 190358271, 190163171, 189966462, 189768149, 189568236, 189366727,
+ 189163625, 188958934, 188752660, 188544805, 188335374, 188124371,
+ 187911799, 187697664, 187481969, 187264719, 187045916, 186825567,
+ 186603674, 186380242, 186155275, 185928777, 185700752, 185471205,
+ 185240140, 185007560, 184773471, 184537876, 184300780, 184062187,
+ 183822101, 183580526, 183337467, 183092928, 182846913, 182599427,
+ 182350473, 182100057, 181848183, 181594854, 181340075, 181083851,
+ 180826185, 180567083, 180306549, 180044586, 179781200, 179516395,
+ 179250175, 178982545, 178713508, 178443070, 178171236, 177898008,
+ 177623392, 177347393, 177070014, 176791261, 176511137, 176229648,
+ 175946797, 175662589, 175377030, 175090122, 174801872, 174512282,
+ 174221359, 173929106, 173635528, 173340630, 173044416, 172746890,
+ 172448058, 172147924, 171846492, 171543767, 171239755, 170934458,
+ 170627882, 170320033, 170010913, 169700528, 169388883, 169075982,
+ 168761830, 168446432, 168129791, 167811914, 167492804, 167172467,
+ 166850906, 166528128, 166204135, 165878934, 165552529, 165224925,
+ 164896125, 164566136, 164234962, 163902607, 163569077, 163234375,
+ 162898508, 162561479, 162223294, 161883957, 161543473, 161201847,
+ 160859083, 160515187, 160170163, 159824016, 159476751, 159128373,
+ 158778886, 158428295, 158076606, 157723823, 157369950, 157014994,
+ 156658958, 156301847, 155943667, 155584421, 155224116, 154862756,
+ 154500346, 154136890, 153772394, 153406863, 153040300, 152672713,
+ 152304104, 151934479, 151563844, 151192202, 150819559, 150445920,
+ 150071290, 149695673, 149319074, 148941500, 148562953, 148183440,
+ 147802966, 147421535, 147039151, 146655821, 146271550, 145886341,
+ 145500200, 145113132, 144725143, 144336236, 143946417, 143555691,
+ 143164064, 142771538, 142378121, 141983817, 141588630, 141192567,
+ 140795631, 140397828, 139999162, 139599640, 139199265, 138798044,
+ 138395980, 137993078, 137589345, 137184785, 136779402, 136373202,
+ 135966191, 135558372, 135149751, 134740333, 134330123, 133919126,
+ 133507347, 133094791, 132681463, 132267369, 131852512, 131436899,
+ 131020534, 130603422, 130185568, 129766978, 129347656, 128927607,
+ 128506837, 128085351, 127663152, 127240248, 126816642, 126392339,
+ 125967345, 125541665, 125115304, 124688266, 124260557, 123832183,
+ 123403146, 122973454, 122543111, 122112122, 121680492, 121248226,
+ 120815330, 120381807, 119947664, 119512905, 119077535, 118641560,
+ 118204984, 117767813, 117330051, 116891703, 116452775, 116013272,
+ 115573198, 115132559, 114691360, 114249605, 113807300, 113364450,
+ 112921060, 112477135, 112032679, 111587699, 111142198, 110696183,
+ 110249657, 109802626, 109355096, 108907070, 108458555, 108009554,
+ 107560074, 107110119, 106659694, 106208804, 105757454, 105305650,
+ 104853395, 104400696, 103947557, 103493983, 103039979, 102585551,
+ 102130702, 101675439, 101219766, 100763687, 100307209, 99850336,
+ 99393074, 98935426, 98477398, 98018995, 97560222, 97101084, 96641586,
+ 96181732, 95721529, 95260980, 94800091, 94338866, 93877312, 93415431,
+ 92953230, 92490714, 92027887, 91564754, 91101321, 90637591, 90173571,
+ 89709264, 89244677, 88779813, 88314678, 87849276, 87383613, 86917694,
+ 86451523, 85985105, 85518445, 85051548, 84584419, 84117062, 83649483,
+ 83181687, 82713678, 82245461, 81777041, 81308423, 80839611, 80370612,
+ 79901428, 79432066, 78962530, 78492825, 78022956, 77552927, 77082743,
+ 76612410, 76141931, 75671312, 75200558, 74729673, 74258662, 73787531,
+ 73316282, 72844923, 72373456, 71901887, 71430222, 70958463, 70486617,
+ 70014688, 69542680, 69070599, 68598449, 68126234, 67653961, 67181632,
+ 66709254, 66236830, 65764366, 65291866, 64819334, 64346776, 63874196,
+ 63401599, 62928989, 62456371, 61983750, 61511130, 61038516, 60565913,
+ 60093325, 59620757, 59148213, 58675698, 58203217, 57730775, 57258375,
+ 56786022, 56313722, 55841478, 55369295, 54897178, 54425132, 53953160,
+ 53481267, 53009458, 52537738, 52066110, 51594580, 51123152, 50651830,
+ 50180619, 49709523, 49238547, 48767696, 48296973, 47826384, 47355932,
+ 46885623, 46415460, 45945448, 45475591, 45005894, 44536362, 44066998,
+ 43597807, 43128794, 42659963, 42191317, 41722862, 41254603, 40786542,
+ 40318685, 39851036, 39383599, 38916379, 38449379, 37982605, 37516060,
+ 37049749, 36583677, 36117846, 35652262, 35186929, 34721851, 34257033,
+ 33792478, 33328190, 32864175, 32400437, 31936978, 31473804, 31010919,
+ 30548327, 30086033, 29624039, 29162352, 28700973, 28239909, 27779162,
+ 27318738, 26858640, 26398872, 25939438, 25480343, 25021590, 24563184,
+ 24105128, 23647428, 23190086, 22733107, 22276494, 21820253, 21364386,
+ 20908898, 20453793, 19999075, 19544748, 19090816, 18637282, 18184151,
+ 17731426, 17279113, 16827213, 16375732, 15924674, 15474041, 15023839,
+ 14574070, 14124740, 13675851, 13227408, 12779414, 12331873, 11884789,
+ 11438166, 10992008, 10546319, 10101101, 9656360, 9212098, 8768320,
+ 8325029, 7882229, 7439924, 6998117, 6556813, 6116014, 5675725, 5235949,
+ 4796690, 4357952, 3919738, 3482052, 3044897, 2608278, 2172197, 1736658,
+ 1301666, 867223, 433333, 0, -432773, -864982, -1296624, -1727695,
+ -2158192, -2588111, -3017449, -3446202, -3874367, -4301940, -4728918,
+ -5155297, -5581074, -6006246, -6430809, -6854759, -7278094, -7700810,
+ -8122903, -8544371, -8965209, -9385415, -9804985, -10223916, -10642205,
+ -11059848, -11476842, -11893183, -12308869, -12723896, -13138261,
+ -13551961, -13964992, -14377352, -14789037, -15200043, -15610369,
+ -16020009, -16428962, -16837225, -17244793, -17651665, -18057836,
+ -18463304, -18868066, -19272118, -19675457, -20078081, -20479987,
+ -20881171, -21281630, -21681361, -22080362, -22478629, -22876159,
+ -23272950, -23668998, -24064300, -24458854, -24852656, -25245704,
+ -25637995, -26029525, -26420293, -26810294, -27199527, -27587988,
+ -27975675, -28362584, -28748713, -29134059, -29518619, -29902391,
+ -30285372, -30667558, -31048948, -31429538, -31809326, -32188308,
+ -32566483, -32943848, -33320400, -33696135, -34071053, -34445149,
+ -34818422, -35190868, -35562485, -35933271, -36303223, -36672338,
+ -37040613, -37408047, -37774637, -38140379, -38505272, -38869313,
+ -39232500, -39594830, -39956300, -40316909, -40676653, -41035530,
+ -41393538, -41750675, -42106938, -42462324, -42816831, -43170457,
+ -43523200, -43875057, -44226025, -44576103, -44925288, -45273579,
+ -45620971, -45967464, -46313055, -46657742, -47001522, -47344393,
+ -47686354, -48027402, -48367534, -48706748, -49045043, -49382417,
+ -49718866, -50054389, -50388984, -50722648, -51055380, -51387178,
+ -51718039, -52047961, -52376942, -52704981, -53032075, -53358222,
+ -53683420, -54007668, -54330962, -54653302, -54974686, -55295110,
+ -55614574, -55933075, -56250612, -56567183, -56882786, -57197418,
+ -57511078, -57823765, -58135476, -58446210, -58755964, -59064737,
+ -59372527, -59679333, -59985152, -60289984, -60593825, -60896674,
+ -61198531, -61499392, -61799256, -62098123, -62395989, -62692853,
+ -62988714, -63283569, -63577418, -63870259, -64162090, -64452910,
+ -64742716, -65031508, -65319284, -65606042, -65891781, -66176500,
+ -66460196, -66742868, -67024515, -67305136, -67584728, -67863291,
+ -68140823, -68417323, -68692788, -68967219, -69240613, -69512969,
+ -69784286, -70054562, -70323796, -70591987, -70859134, -71125234,
+ -71390288, -71654292, -71917248, -72179152, -72440004, -72699802,
+ -72958546, -73216235, -73472866, -73728439, -73982952, -74236405,
+ -74488796, -74740125, -74990390, -75239589, -75487723, -75734789,
+ -75980787, -76225716, -76469575, -76712362, -76954077, -77194718,
+ -77434285, -77672776, -77910191, -78146529, -78381788, -78615969,
+ -78849069, -79081088, -79312025, -79541879, -79770649, -79998335,
+ -80224936, -80450450, -80674877, -80898216, -81120466, -81341627,
+ -81561697, -81780676, -81998564, -82215358, -82431060, -82645667,
+ -82859180, -83071597, -83282917, -83493141, -83702268, -83910296,
+ -84117226, -84323056, -84527786, -84731415, -84933943, -85135369,
+ -85335693, -85534914, -85733031, -85930044, -86125952, -86320756,
+ -86514454, -86707045, -86898530, -87088908, -87278179, -87466341,
+ -87653396, -87839341, -88024177, -88207904, -88390520, -88572026,
+ -88752422, -88931706, -89109879, -89286940, -89462889, -89637726,
+ -89811450, -89984061, -90155559, -90325943, -90495214, -90663370,
+ -90830413, -90996341, -91161154, -91324853, -91487436, -91648905,
+ -91809258, -91968496, -92126618, -92283624, -92439514, -92594289,
+ -92747947, -92900490, -93051916, -93202226, -93351420, -93499497,
+ -93646458, -93792303, -93937031, -94080643, -94223139, -94364518,
+ -94504782, -94643929, -94781960, -94918874, -95054673, -95189356,
+ -95322924, -95455375, -95586711, -95716932, -95846038, -95974028,
+ -96100904, -96226665, -96351312, -96474844, -96597262, -96718567,
+ -96838758, -96957835, -97075800, -97192651, -97308391, -97423018,
+ -97536533, -97648936, -97760228, -97870410, -97979480, -98087441,
+ -98194291, -98300032, -98404664, -98508188, -98610603, -98711910,
+ -98812110, -98911203, -99009189, -99106069, -99201844, -99296514,
+ -99390079, -99482539, -99573897, -99664151, -99753303, -99841352,
+ -99928301, -100014148, -100098895, -100182543, -100265091, -100346541,
+ -100426893, -100506148, -100584306, -100661369, -100737336, -100812208,
+ -100885986, -100958672, -101030264, -101100765, -101170175, -101238494,
+ -101305724, -101371864, -101436917, -101500882, -101563761, -101625553,
+ -101686261, -101745885, -101804425, -101861883, -101918259, -101973554,
+ -102027769, -102080904, -102132962, -102183942, -102233846, -102282674,
+ -102330428, -102377107, -102422714, -102467249, -102510713, -102553108,
+ -102594433, -102634690, -102673880, -102712004, -102749064, -102785059,
+ -102819991, -102853861, -102886671, -102918420, -102949111, -102978745,
+ -103007321, -103034842, -103061309, -103086723, -103111084, -103134394,
+ -103156655, -103177866, -103198030, -103217148, -103235220, -103252249,
+ -103268234, -103283178, -103297081, -103309945, -103321771, -103332561,
+ -103342314, -103351034, -103358720, -103365375, -103370999, -103375594,
+ -103379161, -103381702, -103383217, -103383709, -103383178, -103381625,
+ -103379053, -103375462, -103370854, -103365230, -103358592, -103350941,
+ -103342278, -103332604, -103321922, -103310233, -103297538, -103283838,
+ -103269135, -103253430, -103236725, -103219022, -103200322, -103180625,
+ -103159935, -103138252, -103115577, -103091913, -103067261, -103041623,
+ -103014999, -102987392, -102958803, -102929233, -102898685, -102867159,
+ -102834658, -102801183, -102766736, -102731317, -102694930, -102657575,
+ -102619254, -102579969, -102539721, -102498513, -102456345, -102413220,
+ -102369138, -102324103, -102278115, -102231176, -102183288, -102134453,
+ -102084672, -102033947, -101982280, -101929673, -101876127, -101821644,
+ -101766226, -101709874, -101652591, -101594379, -101535238, -101475171,
+ -101414180, -101352266, -101289432, -101225679, -101161008, -101095423,
+ -101028924, -100961514, -100893194, -100823966, -100753833, -100682796,
+ -100610856, -100538017, -100464279, -100389645, -100314117, -100237696,
+ -100160384, -100082184, -100003097, -99923126, -99842271, -99760536,
+ -99677922, -99594432, -99510066, -99424828, -99338719, -99251741,
+ -99163896, -99075186, -98985613, -98895180, -98803888, -98711739,
+ -98618736, -98524880, -98430173, -98334618, -98238217, -98140971,
+ -98042883, -97943954, -97844188, -97743586, -97642150, -97539882,
+ -97436784, -97332859, -97228108, -97122534, -97016139, -96908925,
+ -96800895, -96692049, -96582391, -96471923, -96360646, -96248563,
+ -96135677, -96021989, -95907501, -95792216, -95676136, -95559263,
+ -95441600, -95323148, -95203910, -95083888, -94963084, -94841501,
+ -94719140, -94596004, -94472096, -94347417, -94221970, -94095757,
+ -93968780, -93841041, -93712544, -93583289, -93453280, -93322519,
+ -93191008, -93058749, -92925745, -92791997, -92657509, -92522282,
+ -92386320, -92249623, -92112195, -91974038, -91835154, -91695546,
+ -91555216, -91414166, -91272399, -91129916, -90986721, -90842816,
+ -90698203, -90552885, -90406863, -90260141, -90112720, -89964604,
+ -89815794, -89666293, -89516103, -89365227, -89213667, -89061425,
+ -88908505, -88754907, -88600636, -88445693, -88290081, -88133801,
+ -87976858, -87819252, -87660987, -87502065, -87342488, -87182259,
+ -87021381, -86859855, -86697684, -86534872, -86371419, -86207329,
+ -86042604, -85877247, -85711261, -85544647, -85377408, -85209546,
+ -85041065, -84871967, -84702253, -84531928, -84360992, -84189450,
+ -84017302, -83844553, -83671203, -83497257, -83322716, -83147582,
+ -82971860, -82795550, -82618655, -82441179, -82263124, -82084491,
+ -81905284, -81725506, -81545158, -81364244, -81182766, -81000726,
+ -80818128, -80634973, -80451264, -80267004, -80082195, -79896841,
+ -79710943, -79524504, -79337527, -79150014, -78961968, -78773391,
+ -78584287, -78394657, -78204505, -78013832, -77822642, -77630937,
+ -77438719, -77245992, -77052758, -76859019, -76664779, -76470039,
+ -76274802, -76079071, -75882849, -75686138, -75488941, -75291261,
+ -75093099, -74894459, -74695344, -74495755, -74295696, -74095169,
+ -73894177, -73692723, -73490808, -73288436, -73085610, -72882332,
+ -72678604, -72474430, -72269811, -72064751, -71859252, -71653318,
+ -71446949, -71240150, -71032923, -70825270, -70617194, -70408698,
+ -70199784, -69990456, -69780715, -69570564, -69360007, -69149045,
+ -68937681, -68725918, -68513759, -68301207, -68088263, -67874931,
+ -67661213, -67447112, -67232630, -67017771, -66802537, -66586930,
+ -66370953, -66154610, -65937901, -65720831, -65503402, -65285616,
+ -65067477, -64848986, -64630147, -64410962, -64191434, -63971565,
+ -63751359, -63530817, -63309942, -63088738, -62867207, -62645351,
+ -62423173, -62200676, -61977862, -61754734, -61531295, -61307548,
+ -61083494, -60859138, -60634480, -60409525, -60184274, -59958731,
+ -59732897, -59506777, -59280371, -59053684, -58826717, -58599473,
+ -58371956, -58144166, -57916109, -57687785, -57459197, -57230349,
+ -57001242, -56771880, -56542265, -56312400, -56082287, -55851929,
+ -55621329, -55390489, -55159412, -54928101, -54696558, -54464786,
+ -54232787, -54000564, -53768121, -53535458, -53302580, -53069488,
+ -52836186, -52602675, -52368959, -52135040, -51900921, -51666605,
+ -51432093, -51197389, -50962495, -50727414, -50492149, -50256702,
+ -50021075, -49785272, -49549294, -49313146, -49076828, -48840344,
+ -48603696, -48366888, -48129920, -47892797, -47655521, -47418094,
+ -47180519, -46942798, -46704934, -46466930, -46228789, -45990512,
+ -45752102, -45513563, -45274895, -45036104, -44797189, -44558155,
+ -44319004, -44079738, -43840360, -43600873, -43361278, -43121579,
+ -42881778, -42641878, -42401882, -42161791, -41921608, -41681336,
+ -41440978, -41200535, -40960011, -40719408, -40478728, -40237975,
+ -39997150, -39756256, -39515296, -39274272, -39033186, -38792042,
+ -38550841, -38309586, -38068280, -37826925, -37585524, -37344079,
+ -37102592, -36861067, -36619505, -36377909, -36136282, -35894625,
+ -35652943, -35411236, -35169507, -34927760, -34685995, -34444217,
+ -34202426, -33960627, -33718820, -33477009, -33235197, -32993384,
+ -32751575, -32509770, -32267974, -32026187, -31784414, -31542655,
+ -31300913, -31059192, -30817493, -30575818, -30334170, -30092552,
+ -29850966, -29609413, -29367898, -29126421, -28884986, -28643594,
+ -28402249, -28160952, -27919706, -27678513, -27437375, -27196296,
+ -26955277, -26714320, -26473428, -26232604, -25991849, -25751166,
+ -25510557, -25270025, -25029572, -24789200, -24548912, -24308710,
+ -24068595, -23828571, -23588640, -23348804, -23109065, -22869426,
+ -22629889, -22390455, -22151129, -21911911, -21672804, -21433810,
+ -21194931, -20956171, -20717530, -20479011, -20240617, -20002350,
+ -19764211, -19526204, -19288330, -19050592, -18812991, -18575530,
+ -18338212, -18101038, -17864010, -17627132, -17390404, -17153829,
+ -16917410, -16681148, -16445046, -16209106, -15973330, -15737719,
+ -15502277, -15267006, -15031907, -14796983, -14562235, -14327667,
+ -14093279, -13859075, -13625056, -13391225, -13157583, -12924133,
+ -12690876, -12457815, -12224952, -11992289, -11759828, -11527572,
+ -11295521, -11063678, -10832046, -10600626, -10369421, -10138432,
+ -9907661, -9677111, -9446783, -9216680, -8986804, -8757156, -8527738,
+ -8298553, -8069603, -7840889, -7612414, -7384179, -7156187, -6928439,
+ -6700937, -6473684, -6246681, -6019931, -5793434, -5567194, -5341212,
+ -5115490, -4890030, -4664834, -4439903, -4215240, -3990847, -3766725,
+ -3542877, -3319303, -3096007, -2872990, -2650254, -2427800, -2205631,
+ -1983749, -1762155, -1540851, -1319839, -1099120, -878698, -658572,
+ -438746, -219222, 0, 218917, 437528, 655830, 873823, 1091504, 1308871,
+ 1525923, 1742658, 1959073, 2175169, 2390942, 2606391, 2821514, 3036309,
+ 3250775, 3464911, 3678713, 3892181, 4105313, 4318108, 4530563, 4742676,
+ 4954447, 5165874, 5376954, 5587686, 5798069, 6008101, 6217780, 6427105,
+ 6636074, 6844685, 7052937, 7260828, 7468356, 7675521, 7882320, 8088752,
+ 8294814, 8500507, 8705827, 8910774, 9115346, 9319542, 9523359, 9726796,
+ 9929852, 10132526, 10334815, 10536718, 10738234, 10939361, 11140098,
+ 11340443, 11540395, 11739952, 11939112, 12137875, 12336239, 12534202,
+ 12731764, 12928921, 13125674, 13322020, 13517958, 13713488, 13908606,
+ 14103313, 14297606, 14491484, 14684946, 14877990, 15070616, 15262821,
+ 15454604, 15645964, 15836900, 16027410, 16217493, 16407147, 16596372,
+ 16785165, 16973527, 17161454, 17348947, 17536003, 17722621, 17908801,
+ 18094540, 18279839, 18464694, 18649105, 18833072, 19016592, 19199664,
+ 19382287, 19564460, 19746182, 19927451, 20108266, 20288627, 20468531,
+ 20647978, 20826966, 21005495, 21183562, 21361168, 21538310, 21714989,
+ 21891201, 22066947, 22242225, 22417034, 22591374, 22765242, 22938638,
+ 23111560, 23284008, 23455981, 23627477, 23798495, 23969035, 24139094,
+ 24308673, 24477770, 24646384, 24814514, 24982160, 25149319, 25315990,
+ 25482174, 25647869, 25813074, 25977788, 26142009, 26305738, 26468973,
+ 26631712, 26793956, 26955703, 27116952, 27277702, 27437953, 27597703,
+ 27756952, 27915698, 28073940, 28231679, 28388912, 28545639, 28701859,
+ 28857572, 29012776, 29167470, 29321654, 29475326, 29628487, 29781134,
+ 29933268, 30084887, 30235991, 30386579, 30536649, 30686202, 30835236,
+ 30983751, 31131746, 31279219, 31426171, 31572601, 31718507, 31863889,
+ 32008746, 32153079, 32296884, 32440163, 32582915, 32725138, 32866832,
+ 33007996, 33148630, 33288732, 33428303, 33567342, 33705847, 33843819,
+ 33981256, 34118158, 34254524, 34390354, 34525647, 34660403, 34794620,
+ 34928299, 35061438, 35194037, 35326095, 35457612, 35588588, 35719021,
+ 35848911, 35978258, 36107061, 36235319, 36363033, 36490200, 36616822,
+ 36742897, 36868425, 36993405, 37117837, 37241720, 37365054, 37487839,
+ 37610073, 37731757, 37852890, 37973472, 38093501, 38212978, 38331903,
+ 38450274, 38568091, 38685355, 38802064, 38918218, 39033817, 39148860,
+ 39263347, 39377277, 39490651, 39603468, 39715727, 39827428, 39938571,
+ 40049155, 40159181, 40268647, 40377554, 40485900, 40593687, 40700913,
+ 40807578, 40913682, 41019225, 41124206, 41228626, 41332483, 41435777,
+ 41538509, 41640678, 41742283, 41843326, 41943804, 42043719, 42143069,
+ 42241855, 42340077, 42437734, 42534826, 42631353, 42727314, 42822710,
+ 42917541, 43011805, 43105504, 43198636, 43291203, 43383202, 43474636,
+ 43565502, 43655802, 43745535, 43834701, 43923300, 44011332, 44098796,
+ 44185693, 44272022, 44357784, 44442979, 44527605, 44611664, 44695155,
+ 44778079, 44860434, 44942222, 45023442, 45104093, 45184177, 45263693,
+ 45342641, 45421021, 45498833, 45576077, 45652753, 45728861, 45804402,
+ 45879374, 45953779, 46027616, 46100886, 46173588, 46245722, 46317289,
+ 46388288, 46458721, 46528586, 46597884, 46666614, 46734778, 46802376,
+ 46869406, 46935870, 47001768, 47067099, 47131864, 47196064, 47259697,
+ 47322765, 47385267, 47447204, 47508575, 47569382, 47629624, 47689301,
+ 47748414, 47806963, 47864948, 47922369, 47979226, 48035520, 48091251,
+ 48146419, 48201024, 48255067, 48308548, 48361467, 48413825, 48465621,
+ 48516856, 48567530, 48617644, 48667198, 48716191, 48764625, 48812500,
+ 48859816, 48906573, 48952772, 48998413, 49043496, 49088021, 49131990,
+ 49175402, 49218258, 49260558, 49302302, 49343491, 49384126, 49424205,
+ 49463731, 49502703, 49541122, 49578988, 49616301, 49653063, 49689273,
+ 49724931, 49760039, 49794597, 49828604, 49862062, 49894971, 49927332,
+ 49959144, 49990409, 50021126, 50051297, 50080922, 50110001, 50138534,
+ 50166523, 50193968, 50220868, 50247226, 50273041, 50298313, 50323044,
+ 50347234, 50370883, 50393992, 50416561, 50438591, 50460083, 50481037,
+ 50501454, 50521333, 50540677, 50559485, 50577758, 50595496, 50612700,
+ 50629372, 50645510, 50661116, 50676191, 50690735, 50704749, 50718233,
+ 50731188, 50743615, 50755514, 50766886, 50777731, 50788051, 50797845,
+ 50807115, 50815861, 50824084, 50831785, 50838963, 50845621, 50851758,
+ 50857375, 50862473, 50867053, 50871115, 50874660, 50877689, 50880203,
+ 50882201, 50883686, 50884657, 50885116, 50885062, 50884498, 50883423,
+ 50881838, 50879745, 50877143, 50874034, 50870419, 50866297, 50861671,
+ 50856540, 50850906, 50844769, 50838130, 50830990, 50823350, 50815210,
+ 50806571, 50797435, 50787801, 50777671, 50767046, 50755926, 50744313,
+ 50732206, 50719607, 50706517, 50692937, 50678867, 50664309, 50649262,
+ 50633729, 50617709, 50601204, 50584215, 50566742, 50548787, 50530350,
+ 50511432, 50492034, 50472158, 50451803, 50430970, 50409662, 50387878,
+ 50365619, 50342887, 50319683, 50296006, 50271859, 50247242, 50222156,
+ 50196602, 50170580, 50144093, 50117141, 50089724, 50061844, 50033502,
+ 50004699, 49975435, 49945712, 49915530, 49884891, 49853796, 49822245,
+ 49790240, 49757781, 49724870, 49691507, 49657694, 49623431, 49588720,
+ 49553561, 49517956, 49481905, 49445410, 49408472, 49371091, 49333269,
+ 49295007, 49256306, 49217166, 49177589, 49137576, 49097128, 49056246,
+ 49014930, 48973183, 48931006, 48888398, 48845361, 48801897, 48758007,
+ 48713691, 48668950, 48623786, 48578200, 48532193, 48485765, 48438919,
+ 48391654, 48343973, 48295876, 48247365, 48198440, 48149103, 48099354,
+ 48049195, 47998628, 47947652, 47896269, 47844481, 47792288, 47739692,
+ 47686694, 47633294, 47579495, 47525296, 47470700, 47415707, 47360319,
+ 47304537, 47248361, 47191794, 47134835, 47077487, 47019751, 46961627,
+ 46903117, 46844222, 46784943, 46725281, 46665238, 46604815, 46544013,
+ 46482832, 46421275, 46359343, 46297036, 46234355, 46171303, 46107880,
+ 46044088, 45979927, 45915399, 45850505, 45785246, 45719623, 45653639,
+ 45587293, 45520587, 45453522, 45386100, 45318322, 45250189, 45181701,
+ 45112862, 45043671, 44974129, 44904239, 44834001, 44763417, 44692487,
+ 44621214, 44549598, 44477640, 44405342, 44332706, 44259731, 44186420,
+ 44112774, 44038793, 43964480, 43889836, 43814861, 43739558, 43663926,
+ 43587969, 43511686, 43435079, 43358150, 43280899, 43203328, 43125438,
+ 43047231, 42968708, 42889869, 42810717, 42731253, 42651477, 42571391,
+ 42490997, 42410296, 42329288, 42247976, 42166361, 42084443, 42002224,
+ 41919706, 41836890, 41753777, 41670367, 41586664, 41502668, 41418379,
+ 41333801, 41248933, 41163777, 41078335, 40992607, 40906596, 40820302,
+ 40733726, 40646871, 40559736, 40472325, 40384637, 40296675, 40208439,
+ 40119931, 40031152, 39942103, 39852787, 39763203, 39673354, 39583241,
+ 39492865, 39402228, 39311330, 39220173, 39128758, 39037087, 38945162,
+ 38852982, 38760551, 38667868, 38574936, 38481755, 38388328, 38294655,
+ 38200737, 38106577, 38012175, 37917532, 37822651, 37727532, 37632176,
+ 37536586, 37440762, 37344706, 37248418, 37151902, 37055156, 36958184,
+ 36860987, 36763565, 36665920, 36568053, 36469966, 36371661, 36273137,
+ 36174398, 36075444, 35976276, 35876896, 35777305, 35677504, 35577496,
+ 35477280, 35376859, 35276234, 35175406, 35074377, 34973148, 34871719,
+ 34770094, 34668272, 34566256, 34464046, 34361644, 34259051, 34156270,
+ 34053300, 33950143, 33846801, 33743275, 33639567, 33535677, 33431607,
+ 33327359, 33222934, 33118332, 33013556, 32908607, 32803486, 32698194,
+ 32592733, 32487105, 32381310, 32275349, 32169225, 32062939, 31956491,
+ 31849883, 31743117, 31636194, 31529115, 31421882, 31314496, 31206957,
+ 31099269, 30991431, 30883446, 30775314, 30667037, 30558617, 30450054,
+ 30341350, 30232506, 30123524, 30014405, 29905150, 29795761, 29686239,
+ 29576585, 29466800, 29356887, 29246846, 29136678, 29026386, 28915970,
+ 28805431, 28694771, 28583992, 28473094, 28362078, 28250948, 28139702,
+ 28028344, 27916874, 27805293, 27693603, 27581805, 27469901, 27357891,
+ 27245778, 27133562, 27021245, 26908828, 26796312, 26683699, 26570990,
+ 26458186, 26345288, 26232299, 26119219, 26006049, 25892792, 25779447,
+ 25666017, 25552502, 25438905, 25325226, 25211467, 25097628, 24983712,
+ 24869719, 24755652, 24641510, 24527296, 24413010, 24298654, 24184230,
+ 24069739, 23955181, 23840558, 23725872, 23611123, 23496314, 23381444,
+ 23266517, 23151532, 23036491, 22921396, 22806247, 22691046, 22575795,
+ 22460494, 22345145, 22229748, 22114306, 21998820, 21883290, 21767718,
+ 21652106, 21536454, 21420764, 21305038, 21189275, 21073478, 20957648,
+ 20841787, 20725894, 20609972, 20494022, 20378045, 20262042, 20146015,
+ 20029965, 19913893, 19797800, 19681687, 19565556, 19449409, 19333245,
+ 19217067, 19100875, 18984672, 18868457, 18752233, 18636000, 18519761,
+ 18403515, 18287264, 18171009, 18054753, 17938495, 17822237, 17705980,
+ 17589726, 17473475, 17357229, 17240989, 17124757, 17008533, 16892318,
+ 16776114, 16659922, 16543743, 16427579, 16311430, 16195298, 16079184,
+ 15963089, 15847014, 15730960, 15614929, 15498922, 15382939, 15266983,
+ 15151054, 15035153, 14919282, 14803441, 14687633, 14571857, 14456116,
+ 14340410, 14224740, 14109108, 13993514, 13877961, 13762448, 13646978,
+ 13531551, 13416168, 13300831, 13185541, 13070298, 12955104, 12839960,
+ 12724868, 12609827, 12494840, 12379907, 12265030, 12150210, 12035448,
+ 11920744, 11806100, 11691518, 11576997, 11462540, 11348147, 11233820,
+ 11119559, 11005366, 10891241, 10777187, 10663203, 10549291, 10435452,
+ 10321687, 10207997, 10094383, 9980847, 9867389, 9754010, 9640712,
+ 9527495, 9414361, 9301310, 9188344, 9075463, 8962670, 8849964, 8737346,
+ 8624819, 8512382, 8400037, 8287785, 8175627, 8063564, 7951596, 7839726,
+ 7727953, 7616280, 7504706, 7393234, 7281863, 7170595, 7059432, 6948373,
+ 6837420, 6726574, 6615836, 6505207, 6394687, 6284279, 6173982, 6063799,
+ 5953729, 5843773, 5733934, 5624211, 5514605, 5405118, 5295751, 5186504,
+ 5077379, 4968376, 4859496, 4750740, 4642110, 4533606, 4425228, 4316979,
+ 4208859, 4100868, 3993008, 3885280, 3777684, 3670222, 3562894, 3455702,
+ 3348645, 3241726, 3134945, 3028303, 2921800, 2815438, 2709218, 2603140,
+ 2497205, 2391414, 2285769, 2180269, 2074917, 1969711, 1864655, 1759748,
+ 1654991, 1550385, 1445931, 1341630, 1237482, 1133489, 1029652, 925970,
+ 822446, 719079, 615871, 512822, 409934, 307206, 204641, 102239, 0,
+ -102074, -203984, -305727, -407304, -508713, -609954, -711026, -811928,
+ -912659, -1013219, -1113607, -1213821, -1313862, -1413728, -1513419,
+ -1612933, -1712271, -1811432, -1910414, -2009216, -2107839, -2206282,
+ -2304543, -2402622, -2500518, -2598231, -2695759, -2793102, -2890260,
+ -2987232, -3084016, -3180612, -3277020, -3373238, -3469267, -3565105,
+ -3660751, -3756206, -3851467, -3946536, -4041410, -4136089, -4230573,
+ -4324861, -4418952, -4512845, -4606541, -4700037, -4793334, -4886431,
+ -4979327, -5072022, -5164514, -5256804, -5348891, -5440773, -5532451,
+ -5623924, -5715190, -5806251, -5897104, -5987749, -6078186, -6168414,
+ -6258432, -6348241, -6437838, -6527224, -6616398, -6705359, -6794108,
+ -6882642, -6970962, -7059068, -7146957, -7234631, -7322088, -7409328,
+ -7496350, -7583154, -7669739, -7756104, -7842250, -7928174, -8013878,
+ -8099360, -8184620, -8269658, -8354472, -8439062, -8523428, -8607570,
+ -8691485, -8775176, -8858639, -8941876, -9024886, -9107667, -9190221,
+ -9272545, -9354640, -9436505, -9518140, -9599544, -9680717, -9761658,
+ -9842367, -9922843, -10003086, -10083095, -10162870, -10242410,
+ -10321716, -10400786, -10479620, -10558218, -10636579, -10714702,
+ -10792588, -10870236, -10947646, -11024816, -11101747, -11178438,
+ -11254889, -11331100, -11407069, -11482797, -11558283, -11633526,
+ -11708527, -11783286, -11857800, -11932071, -12006098, -12079880,
+ -12153417, -12226708, -12299754, -12372554, -12445108, -12517414,
+ -12589474, -12661286, -12732850, -12804166, -12875233, -12946052,
+ -13016621, -13086941, -13157011, -13226830, -13296399, -13365717,
+ -13434784, -13503600, -13572163, -13640475, -13708534, -13776340,
+ -13843893, -13911193, -13978239, -14045031, -14111569, -14177853,
+ -14243882, -14309655, -14375174, -14440436, -14505443, -14570194,
+ -14634688, -14698926, -14762907, -14826630, -14890096, -14953305,
+ -15016255, -15078948, -15141381, -15203557, -15265473, -15327131,
+ -15388529, -15449667, -15510546, -15571165, -15631524, -15691622,
+ -15751460, -15811036, -15870352, -15929407, -15988200, -16046732,
+ -16105002, -16163010, -16220756, -16278240, -16335461, -16392419,
+ -16449115, -16505548, -16561717, -16617623, -16673266, -16728645,
+ -16783761, -16838612, -16893200, -16947523, -17001582, -17055376,
+ -17108906, -17162171, -17215171, -17267906, -17320376, -17372581,
+ -17424521, -17476195, -17527604, -17578747, -17629624, -17680235,
+ -17730581, -17780660, -17830473, -17880020, -17929301, -17978315,
+ -18027063, -18075545, -18123759, -18171707, -18219389, -18266803,
+ -18313951, -18360832, -18407445, -18453792, -18499872, -18545684,
+ -18591230, -18636508, -18681519, -18726263, -18770739, -18814948,
+ -18858890, -18902565, -18945972, -18989111, -19031984, -19074588,
+ -19116926, -19158996, -19200798, -19242333, -19283601, -19324601,
+ -19365334, -19405799, -19445997, -19485928, -19525591, -19564987,
+ -19604116, -19642977, -19681571, -19719898, -19757958, -19795751,
+ -19833277, -19870535, -19907527, -19944252, -19980710, -20016901,
+ -20052825, -20088483, -20123874, -20158998, -20193856, -20228448,
+ -20262773, -20296832, -20330625, -20364152, -20397413, -20430408,
+ -20463137, -20495600, -20527798, -20559731, -20591397, -20622799,
+ -20653936, -20684807, -20715413, -20745755, -20775832, -20805644,
+ -20835192, -20864476, -20893495, -20922250, -20950741, -20978969,
+ -21006933, -21034633, -21062070, -21089244, -21116155, -21142802,
+ -21169187, -21195310, -21221170, -21246768, -21272103, -21297177,
+ -21321989, -21346540, -21370829, -21394856, -21418623, -21442129,
+ -21465374, -21488359, -21511084, -21533548, -21555753, -21577697,
+ -21599383, -21620809, -21641976, -21662884, -21683533, -21703925,
+ -21724057, -21743932, -21763549, -21782909, -21802011, -21820856,
+ -21839444, -21857776, -21875851, -21893670, -21911233, -21928541,
+ -21945593, -21962390, -21978932, -21995219, -22011252, -22027031,
+ -22042556, -22057827, -22072845, -22087610, -22102121, -22116381,
+ -22130388, -22144143, -22157646, -22170898, -22183899, -22196649,
+ -22209148, -22221397, -22233396, -22245145, -22256645, -22267896,
+ -22278897, -22289651, -22300156, -22310413, -22320423, -22330185,
+ -22339700, -22348969, -22357991, -22366768, -22375298, -22383584,
+ -22391624, -22399419, -22406970, -22414277, -22421341, -22428161,
+ -22434738, -22441072, -22447164, -22453014, -22458622, -22463989,
+ -22469115, -22474000, -22478645, -22483050, -22487216, -22491142,
+ -22494830, -22498279, -22501490, -22504464, -22507200, -22509699,
+ -22511962, -22513988, -22515778, -22517333, -22518653, -22519739,
+ -22520590, -22521207, -22521590, -22521741, -22521659, -22521344,
+ -22520797, -22520019, -22519010, -22517770, -22516300, -22514600,
+ -22512670, -22510511, -22508124, -22505508, -22502665, -22499594,
+ -22496295, -22492771, -22489020, -22485044, -22480842, -22476415,
+ -22471764, -22466889, -22461790, -22456468, -22450923, -22445156,
+ -22439167, -22432957, -22426526, -22419874, -22413003, -22405911,
+ -22398601, -22391072, -22383324, -22375359, -22367176, -22358777,
+ -22350161, -22341329, -22332281, -22323019, -22313542, -22303851,
+ -22293946, -22283828, -22273498, -22262955, -22252201, -22241235,
+ -22230058, -22218671, -22207075, -22195269, -22183254, -22171030,
+ -22158599, -22145961, -22133115, -22120064, -22106806, -22093343,
+ -22079675, -22065802, -22051726, -22037446, -22022963, -22008278,
+ -21993391, -21978302, -21963013, -21947523, -21931833, -21915944,
+ -21899856, -21883569, -21867085, -21850404, -21833525, -21816451,
+ -21799180, -21781715, -21764054, -21746200, -21728152, -21709910,
+ -21691476, -21672850, -21654032, -21635024, -21615825, -21596435,
+ -21576857, -21557089, -21537133, -21516990, -21496659, -21476141,
+ -21455437, -21434548, -21413473, -21392214, -21370770, -21349144,
+ -21327334, -21305342, -21283168, -21260813, -21238277, -21215561,
+ -21192665, -21169590, -21146337, -21122906, -21099297, -21075512,
+ -21051550, -21027412, -21003100, -20978613, -20953951, -20929117,
+ -20904109, -20878929, -20853578, -20828055, -20802361, -20776498,
+ -20750465, -20724263, -20697892, -20671354, -20644649, -20617777,
+ -20590740, -20563536, -20536168, -20508636, -20480939, -20453080,
+ -20425058, -20396874, -20368529, -20340023, -20311356, -20282531,
+ -20253546, -20224402, -20195101, -20165642, -20136027, -20106255,
+ -20076328, -20046246, -20016010, -19985620, -19955077, -19924381,
+ -19893534, -19862535, -19831385, -19800085, -19768635, -19737037,
+ -19705290, -19673395, -19641353, -19609165, -19576830, -19544350,
+ -19511725, -19478957, -19446044, -19412989, -19379791, -19346451,
+ -19312971, -19279349, -19245588, -19211688, -19177648, -19143471,
+ -19109156, -19074704, -19040116, -19005392, -18970533, -18935539,
+ -18900412, -18865152, -18829758, -18794233, -18758576, -18722789,
+ -18686871, -18650824, -18614648, -18578343, -18541911, -18505351,
+ -18468665, -18431853, -18394916, -18357854, -18320668, -18283359,
+ -18245927, -18208373, -18170697, -18132900, -18094983, -18056946,
+ -18018790, -17980515, -17942123, -17903613, -17864987, -17826245,
+ -17787387, -17748414, -17709328, -17670128, -17630815, -17591389,
+ -17551852, -17512204, -17472446, -17432577, -17392600, -17352514,
+ -17312320, -17272019, -17231611, -17191096, -17150477, -17109753,
+ -17068924, -17027992, -16986957, -16945819, -16904580, -16863240,
+ -16821799, -16780258, -16738619, -16696880, -16655044, -16613110,
+ -16571079, -16528953, -16486731, -16444414, -16402002, -16359498,
+ -16316900, -16274209, -16231427, -16188554, -16145591, -16102537,
+ -16059394, -16016163, -15972843, -15929436, -15885943, -15842363,
+ -15798698, -15754947, -15711113, -15667194, -15623193, -15579109,
+ -15534944, -15490697, -15446370, -15401962, -15357476, -15312910,
+ -15268267, -15223546, -15178748, -15133874, -15088925, -15043900,
+ -14998801, -14953628, -14908382, -14863064, -14817673, -14772212,
+ -14726679, -14681077, -14635405, -14589664, -14543855, -14497979,
+ -14452035, -14406025, -14359949, -14313808, -14267603, -14221334,
+ -14175001, -14128606, -14082148, -14035629, -13989049, -13942409,
+ -13895710, -13848951, -13802134, -13755259, -13708327, -13661338,
+ -13614293, -13567193, -13520038, -13472828, -13425566, -13378250,
+ -13330882, -13283462, -13235991, -13188469, -13140898, -13093277,
+ -13045607, -12997890, -12950124, -12902312, -12854453, -12806549,
+ -12758599, -12710605, -12662567, -12614486, -12566362, -12518196,
+ -12469988, -12421739, -12373450, -12325120, -12276752, -12228345,
+ -12179901, -12131418, -12082899, -12034344, -11985753, -11937127,
+ -11888466, -11839772, -11791044, -11742283, -11693491, -11644667,
+ -11595811, -11546926, -11498011, -11449066, -11400093, -11351092,
+ -11302063, -11253007, -11203925, -11154818, -11105685, -11056527,
+ -11007346, -10958141, -10908913, -10859663, -10810391, -10761098,
+ -10711784, -10662451, -10613097, -10563726, -10514335, -10464927,
+ -10415502, -10366060, -10316602, -10267129, -10217641, -10168138,
+ -10118622, -10069092, -10019549, -9969995, -9920429, -9870852,
+ -9821264, -9771667, -9722060, -9672444, -9622820, -9573189, -9523550,
+ -9473905, -9424253, -9374596, -9324935, -9275268, -9225598, -9175925,
+ -9126249, -9076570, -9026890, -8977209, -8927527, -8877845, -8828163,
+ -8778483, -8728804, -8679127, -8629453, -8579781, -8530114, -8480451,
+ -8430792, -8381139, -8331491, -8281850, -8232215, -8182588, -8132969,
+ -8083358, -8033756, -7984164, -7934581, -7885009, -7835448, -7785899,
+ -7736361, -7686836, -7637325, -7587826, -7538342, -7488872, -7439418,
+ -7389979, -7340556, -7291150, -7241761, -7192389, -7143036, -7093701,
+ -7044386, -6995090, -6945814, -6896559, -6847324, -6798112, -6748922,
+ -6699754, -6650609, -6601488, -6552391, -6503318, -6454271, -6405249,
+ -6356253, -6307283, -6258341, -6209425, -6160538, -6111680, -6062850,
+ -6014049, -5965279, -5916538, -5867829, -5819150, -5770504, -5721889,
+ -5673308, -5624759, -5576244, -5527763, -5479316, -5430905, -5382529,
+ -5334189, -5285885, -5237618, -5189388, -5141196, -5093042, -5044927,
+ -4996851, -4948815, -4900818, -4852862, -4804946, -4757072, -4709240,
+ -4661450, -4613702, -4565998, -4518337, -4470720, -4423148, -4375620,
+ -4328137, -4280701, -4233310, -4185966, -4138668, -4091419, -4044217,
+ -3997063, -3949958, -3902902, -3855895, -3808938, -3762032, -3715177,
+ -3668372, -3621619, -3574919, -3528270, -3481675, -3435132, -3388643,
+ -3342209, -3295828, -3249503, -3203233, -3157018, -3110860, -3064757,
+ -3018712, -2972724, -2926794, -2880921, -2835107, -2789352, -2743656,
+ -2698019, -2652442, -2606926, -2561470, -2516076, -2470743, -2425472,
+ -2380263, -2335116, -2290033, -2245013, -2200056, -2155164, -2110336,
+ -2065573, -2020875, -1976243, -1931676, -1887176, -1842743, -1798376,
+ -1754077, -1709845, -1665682, -1621587, -1577560, -1533603, -1489716,
+ -1445898, -1402150, -1358472, -1314866, -1271331, -1227867, -1184475,
+ -1141155, -1097908, -1054733, -1011632, -968604, -925651, -882771,
+ -839966, -797235, -754580, -712001, -669497, -627069, -584718, -542443,
+ -500245, -458125, -416083, -374118, -332232, -290425, -248696, -207047,
+ -165477, -123987, -82577, -41248, 0, 41167, 82253, 123258, 164181,
+ 205021, 245779, 286454, 327046, 367555, 407980, 448322, 488579, 528751,
+ 568839, 608842, 648759, 688591, 728337, 767997, 807570, 847057, 886457,
+ 925770, 964995, 1004132, 1043182, 1082143, 1121016, 1159800, 1198495,
+ 1237101, 1275617, 1314044, 1352381, 1390627, 1428783, 1466848, 1504822,
+ 1542705, 1580496, 1618196, 1655804, 1693320, 1730743, 1768073, 1805311,
+ 1842456, 1879507, 1916465, 1953329, 1990099, 2026775, 2063356, 2099843,
+ 2136235, 2172532, 2208733, 2244839, 2280849, 2316763, 2352582, 2388303,
+ 2423929, 2459457, 2494889, 2530223, 2565460, 2600600, 2635641, 2670585,
+ 2705431, 2740178, 2774827, 2809377, 2843828, 2878180, 2912432, 2946586,
+ 2980639, 3014593, 3048447, 3082201, 3115854, 3149407, 3182859, 3216210,
+ 3249460, 3282609, 3315657, 3348603, 3381447, 3414190, 3446830, 3479368,
+ 3511804, 3544137, 3576368, 3608496, 3640521, 3672443, 3704261, 3735976,
+ 3767588, 3799096, 3830500, 3861800, 3892996, 3924087, 3955074, 3985957,
+ 4016735, 4047408, 4077976, 4108439, 4138797, 4169049, 4199196, 4229238,
+ 4259173, 4289003, 4318727, 4348345, 4377857, 4407262, 4436561, 4465753,
+ 4494839, 4523818, 4552690, 4581455, 4610113, 4638663, 4667107, 4695443,
+ 4723671, 4751792, 4779805, 4807711, 4835508, 4863198, 4890779, 4918253,
+ 4945618, 4972874, 5000022, 5027062, 5053993, 5080815, 5107529, 5134134,
+ 5160630, 5187016, 5213294, 5239463, 5265522, 5291472, 5317313, 5343044,
+ 5368666, 5394178, 5419580, 5444873, 5470056, 5495129, 5520092, 5544946,
+ 5569689, 5594322, 5618845, 5643258, 5667561, 5691754, 5715836, 5739808,
+ 5763669, 5787420, 5811061, 5834590, 5858010, 5881318, 5904517, 5927604,
+ 5950581, 5973446, 5996201, 6018846, 6041379, 6063802, 6086113, 6108314,
+ 6130404, 6152382, 6174250, 6196007, 6217652, 6239187, 6260610, 6281923,
+ 6303124, 6324214, 6345193, 6366061, 6386818, 6407463, 6427998, 6448421,
+ 6468733, 6488934, 6509023, 6529002, 6548869, 6568625, 6588270, 6607804,
+ 6627226, 6646538, 6665738, 6684827, 6703805, 6722672, 6741428, 6760072,
+ 6778606, 6797028, 6815340, 6833540, 6851630, 6869608, 6887476, 6905233,
+ 6922878, 6940413, 6957837, 6975150, 6992353, 7009445, 7026426, 7043296,
+ 7060055, 7076704, 7093243, 7109671, 7125988, 7142195, 7158292, 7174278,
+ 7190154, 7205919, 7221575, 7237120, 7252555, 7267880, 7283095, 7298200,
+ 7313195, 7328080, 7342855, 7357521, 7372077, 7386523, 7400860, 7415087,
+ 7429205, 7443213, 7457112, 7470902, 7484583, 7498154, 7511617, 7524971,
+ 7538215, 7551351, 7564378, 7577297, 7590106, 7602808, 7615401, 7627885,
+ 7640261, 7652529, 7664689, 7676741, 7688685, 7700521, 7712250, 7723870,
+ 7735383, 7746789, 7758087, 7769278, 7780362, 7791338, 7802208, 7812970,
+ 7823626, 7834175, 7844618, 7854953, 7865183, 7875306, 7885323, 7895234,
+ 7905038, 7914737, 7924330, 7933818, 7943200, 7952476, 7961647, 7970713,
+ 7979673, 7988529, 7997280, 8005926, 8014467, 8022904, 8031236, 8039464,
+ 8047588, 8055608, 8063524, 8071336, 8079044, 8086649, 8094151, 8101549,
+ 8108844, 8116036, 8123125, 8130111, 8136995, 8143776, 8150455, 8157031,
+ 8163506, 8169878, 8176149, 8182318, 8188386, 8194352, 8200217, 8205980,
+ 8211643, 8217205, 8222666, 8228027, 8233288, 8238448, 8243508, 8248468,
+ 8253328, 8258089, 8262750, 8267312, 8271775, 8276139, 8280404, 8284570,
+ 8288637, 8292607, 8296478, 8300251, 8303926, 8307503, 8310983, 8314365,
+ 8317650, 8320838, 8323929, 8326924, 8329822, 8332623, 8335328, 8337937,
+ 8340450, 8342867, 8345189, 8347416, 8349547, 8351583, 8353524, 8355371,
+ 8357123, 8358780, 8360344, 8361814, 8363189, 8364471, 8365660, 8366756,
+ 8367758, 8368667, 8369484, 8370208, 8370840, 8371380, 8371828, 8372184,
+ 8372448, 8372621, 8372703, 8372693, 8372593, 8372403, 8372121, 8371750,
+ 8371288, 8370737, 8370096, 8369365, 8368545, 8367636, 8366638, 8365552,
+ 8364377, 8363113, 8361762, 8360323, 8358796, 8357181, 8355479, 8353690,
+ 8351814, 8349852, 8347803, 8345668, 8343446, 8341139, 8338746, 8336268,
+ 8333704, 8331056, 8328322, 8325504, 8322602, 8319615, 8316545, 8313390,
+ 8310152, 8306831, 8303427, 8299939, 8296369, 8292717, 8288982, 8285165,
+ 8281267, 8277286, 8273225, 8269082, 8264858, 8260553, 8256168, 8251703,
+ 8247157, 8242532, 8237827, 8233042, 8228179, 8223236, 8218215, 8213115,
+ 8207936, 8202680, 8197346, 8191934, 8186445, 8180879, 8175235, 8169515,
+ 8163719, 8157846, 8151897, 8145873, 8139772, 8133597, 8127346, 8121021,
+ 8114620, 8108146, 8101597, 8094974, 8088278, 8081508, 8074665, 8067748,
+ 8060759, 8053698, 8046564, 8039358, 8032080, 8024730, 8017309, 8009817,
+ 8002254, 7994621, 7986917, 7979143, 7971299, 7963385, 7955401, 7947349,
+ 7939227, 7931037, 7922778, 7914451, 7906056, 7897593, 7889063, 7880465,
+ 7871800, 7863068, 7854270, 7845406, 7836475, 7827478, 7818416, 7809289,
+ 7800096, 7790839, 7781517, 7772130, 7762680, 7753165, 7743587, 7733946,
+ 7724241, 7714473, 7704643, 7694751, 7684796, 7674779, 7664701, 7654561,
+ 7644360, 7634098, 7623776, 7613393, 7602949, 7592446, 7581884, 7571261,
+ 7560580, 7549840, 7539041, 7528183, 7517268, 7506294, 7495263, 7484174,
+ 7473028, 7461826, 7450566, 7439250, 7427878, 7416451, 7404967, 7393428,
+ 7381834, 7370185, 7358481, 7346723, 7334911, 7323044, 7311125, 7299151,
+ 7287125, 7275046, 7262914, 7250730, 7238493, 7226205, 7213865, 7201474,
+ 7189031, 7176538, 7163994, 7151400, 7138756, 7126062, 7113318, 7100525,
+ 7087683, 7074792, 7061852, 7048864, 7035829, 7022745, 7009613, 6996435,
+ 6983209, 6969937, 6956618, 6943253, 6929841, 6916384, 6902882, 6889334,
+ 6875741, 6862103, 6848421, 6834695, 6820924, 6807110, 6793253, 6779352,
+ 6765408, 6751422, 6737393, 6723322, 6709208, 6695054, 6680857, 6666620,
+ 6652341, 6638022, 6623663, 6609263, 6594823, 6580344, 6565825, 6551267,
+ 6536671, 6522035, 6507361, 6492649, 6477899, 6463112, 6448287, 6433425,
+ 6418526, 6403590, 6388618, 6373610, 6358566, 6343486, 6328371, 6313221,
+ 6298036, 6282817, 6267563, 6252275, 6236953, 6221598, 6206209, 6190787,
+ 6175332, 6159845, 6144325, 6128773, 6113189, 6097574, 6081927, 6066250,
+ 6050541, 6034802, 6019032, 6003233, 5987403, 5971544, 5955656, 5939738,
+ 5923792, 5907817, 5891813, 5875782, 5859722, 5843636, 5827521, 5811380,
+ 5795211, 5779016, 5762795, 5746548, 5730274, 5713975, 5697651, 5681301,
+ 5664927, 5648527, 5632104, 5615656, 5599184, 5582689, 5566170, 5549628,
+ 5533063, 5516476, 5499865, 5483233, 5466579, 5449903, 5433205, 5416486,
+ 5399746, 5382986, 5366204, 5349403, 5332581, 5315740, 5298879, 5281999,
+ 5265099, 5248181, 5231244, 5214289, 5197315, 5180324, 5163315, 5146289,
+ 5129245, 5112184, 5095107, 5078013, 5060903, 5043777, 5026635, 5009478,
+ 4992305, 4975117, 4957915, 4940697, 4923466, 4906220, 4888960, 4871687,
+ 4854400, 4837099, 4819786, 4802460, 4785122, 4767771, 4750409, 4733034,
+ 4715648, 4698250, 4680841, 4663421, 4645991, 4628550, 4611099, 4593638,
+ 4576167, 4558686, 4541196, 4523697, 4506189, 4488673, 4471148, 4453614,
+ 4436073, 4418524, 4400967, 4383403, 4365832, 4348254, 4330669, 4313078,
+ 4295481, 4277877, 4260268, 4242653, 4225033, 4207408, 4189778, 4172143,
+ 4154503, 4136859, 4119212, 4101560, 4083905, 4066246, 4048584, 4030919,
+ 4013251, 3995581, 3977909, 3960234, 3942557, 3924879, 3907199, 3889517,
+ 3871835, 3854152, 3836468, 3818784, 3801099, 3783414, 3765730, 3748046,
+ 3730362, 3712679, 3694997, 3677317, 3659637, 3641960, 3624284, 3606610,
+ 3588938, 3571269, 3553602, 3535938, 3518277, 3500619, 3482965, 3465314,
+ 3447667, 3430024, 3412386, 3394751, 3377121, 3359496, 3341876, 3324261,
+ 3306652, 3289048, 3271450, 3253858, 3236271, 3218692, 3201118, 3183552,
+ 3165992, 3148439, 3130894, 3113356, 3095826, 3078304, 3060790, 3043283,
+ 3025786, 3008297, 2990816, 2973345, 2955883, 2938430, 2920987, 2903553,
+ 2886129, 2868716, 2851312, 2833919, 2816537, 2799165, 2781804, 2764455,
+ 2747116, 2729790, 2712474, 2695171, 2677880, 2660601, 2643334, 2626080,
+ 2608839, 2591610, 2574395, 2557193, 2540004, 2522829, 2505667, 2488520,
+ 2471386, 2454267, 2437162, 2420072, 2402997, 2385936, 2368891, 2351861,
+ 2334846, 2317847, 2300864, 2283896, 2266945, 2250010, 2233091, 2216189,
+ 2199303, 2182435, 2165583, 2148749, 2131932, 2115133, 2098351, 2081587,
+ 2064841, 2048113, 2031404, 2014713, 1998040, 1981387, 1964752, 1948136,
+ 1931540, 1914963, 1898405, 1881867, 1865349, 1848851, 1832373, 1815915,
+ 1799477, 1783060, 1766664, 1750289, 1733935, 1717601, 1701289, 1684999,
+ 1668730, 1652483, 1636257, 1620054, 1603872, 1587713, 1571577, 1555462,
+ 1539371, 1523302, 1507257, 1491234, 1475234, 1459258, 1443306, 1427377,
+ 1411471, 1395590, 1379733, 1363899, 1348091, 1332306, 1316546, 1300811,
+ 1285100, 1269414, 1253754, 1238118, 1222508, 1206923, 1191364, 1175831,
+ 1160323, 1144841, 1129385, 1113956, 1098552, 1083175, 1067825, 1052501,
+ 1037204, 1021934, 1006691, 991475, 976286, 961124, 945990, 930884,
+ 915805, 900754, 885731, 870735, 855768, 840830, 825919, 811037, 796184,
+ 781359, 766563, 751796, 737058, 722349, 707669, 693019, 678398, 663806,
+ 649244, 634712, 620210, 605737, 591295, 576883, 562501, 548149, 533828,
+ 519537, 505277, 491047, 476848, 462681, 448544, 434438, 420364, 406320,
+ 392308, 378328, 364379, 350462, 336576, 322723, 308901, 295111, 281353,
+ 267628, 253934, 240274, 226645, 213049, 199485, 185955, 172457, 158991,
+ 145559, 132160, 118794, 105461, 92161, 78894, 65661, 52462, 39296,
+ 26163, 13064, 0, -13031, -26028, -38991, -51920, -64815, -77676,
+ -90503, -103295, -116053, -128776, -141465, -154119, -166738, -179323,
+ -191873, -204388, -216868, -229313, -241723, -254097, -266437, -278741,
+ -291010, -303244, -315442, -327605, -339732, -351823, -363879, -375899,
+ -387884, -399832, -411745, -423621, -435462, -447266, -459035, -470767,
+ -482463, -494122, -505746, -517333, -528883, -540397, -551875, -563316,
+ -574720, -586088, -597419, -608713, -619971, -631191, -642375, -653522,
+ -664632, -675704, -686740, -697739, -708700, -719625, -730512, -741362,
+ -752174, -762949, -773687, -784387, -795050, -805676, -816264, -826814,
+ -837327, -847802, -858240, -868640, -879002, -889326, -899613, -909862,
+ -920073, -930246, -940381, -950479, -960538, -970560, -980543, -990488,
+ -1000396, -1010265, -1020096, -1029889, -1039644, -1049361, -1059039,
+ -1068680, -1078282, -1087846, -1097371, -1106859, -1116308, -1125718,
+ -1135091, -1144425, -1153720, -1162977, -1172196, -1181376, -1190518,
+ -1199622, -1208687, -1217713, -1226701, -1235651, -1244562, -1253434,
+ -1262268, -1271063, -1279820, -1288538, -1297218, -1305859, -1314462,
+ -1323026, -1331551, -1340038, -1348486, -1356895, -1365266, -1373598,
+ -1381892, -1390147, -1398363, -1406540, -1414680, -1422780, -1430842,
+ -1438865, -1446849, -1454795, -1462702, -1470571, -1478401, -1486192,
+ -1493945, -1501659, -1509334, -1516971, -1524569, -1532129, -1539650,
+ -1547132, -1554576, -1561981, -1569348, -1576676, -1583966, -1591217,
+ -1598429, -1605603, -1612739, -1619836, -1626894, -1633914, -1640896,
+ -1647839, -1654744, -1661610, -1668438, -1675228, -1681979, -1688692,
+ -1695366, -1702002, -1708600, -1715160, -1721681, -1728164, -1734609,
+ -1741016, -1747384, -1753714, -1760007, -1766261, -1772476, -1778654,
+ -1784794, -1790896, -1796959, -1802985, -1808973, -1814923, -1820835,
+ -1826709, -1832545, -1838343, -1844104, -1849826, -1855511, -1861159,
+ -1866768, -1872340, -1877874, -1883371, -1888830, -1894252, -1899636,
+ -1904982, -1910291, -1915563, -1920797, -1925994, -1931154, -1936276,
+ -1941361, -1946409, -1951420, -1956393, -1961329, -1966229, -1971091,
+ -1975916, -1980705, -1985456, -1990171, -1994848, -1999489, -2004093,
+ -2008660, -2013191, -2017685, -2022142, -2026563, -2030947, -2035295,
+ -2039607, -2043881, -2048120, -2052322, -2056488, -2060618, -2064712,
+ -2068769, -2072790, -2076776, -2080725, -2084638, -2088516, -2092357,
+ -2096163, -2099933, -2103667, -2107366, -2111029, -2114656, -2118248,
+ -2121804, -2125325, -2128811, -2132261, -2135676, -2139056, -2142400,
+ -2145710, -2148984, -2152224, -2155428, -2158598, -2161732, -2164832,
+ -2167897, -2170928, -2173923, -2176885, -2179811, -2182703, -2185561,
+ -2188385, -2191174, -2193929, -2196649, -2199336, -2201988, -2204607,
+ -2207191, -2209742, -2212258, -2214741, -2217191, -2219606, -2221988,
+ -2224337, -2226652, -2228933, -2231181, -2233396, -2235578, -2237727,
+ -2239842, -2241924, -2243974, -2245990, -2247974, -2249924, -2251842,
+ -2253728, -2255581, -2257401, -2259189, -2260944, -2262667, -2264358,
+ -2266016, -2267643, -2269237, -2270800, -2272330, -2273828, -2275295,
+ -2276730, -2278133, -2279505, -2280845, -2282154, -2283431, -2284677,
+ -2285892, -2287076, -2288228, -2289350, -2290440, -2291499, -2292528,
+ -2293526, -2294493, -2295430, -2296336, -2297211, -2298057, -2298871,
+ -2299656, -2300410, -2301135, -2301829, -2302493, -2303128, -2303732,
+ -2304307, -2304852, -2305368, -2305854, -2306310, -2306738, -2307135,
+ -2307504, -2307844, -2308154, -2308436, -2308688, -2308912, -2309107,
+ -2309273, -2309411, -2309520, -2309601, -2309653, -2309677, -2309673,
+ -2309640, -2309580, -2309492, -2309375, -2309231, -2309059, -2308860,
+ -2308633, -2308378, -2308096, -2307786, -2307449, -2307086, -2306694,
+ -2306276, -2305831, -2305359, -2304861, -2304335, -2303783, -2303205,
+ -2302600, -2301968, -2301310, -2300626, -2299916, -2299180, -2298418,
+ -2297630, -2296816, -2295976, -2295111, -2294220, -2293304, -2292362,
+ -2291395, -2290403, -2289386, -2288343, -2287276, -2286183, -2285066,
+ -2283924, -2282758, -2281567, -2280351, -2279111, -2277847, -2276558,
+ -2275246, -2273909, -2272548, -2271164, -2269755, -2268323, -2266868,
+ -2265388, -2263886, -2262360, -2260810, -2259238, -2257642, -2256023,
+ -2254382, -2252717, -2251030, -2249320, -2247587, -2245832, -2244055,
+ -2242255, -2240433, -2238589, -2236722, -2234834, -2232924, -2230992,
+ -2229038, -2227063, -2225066, -2223047, -2221007, -2218946, -2216864,
+ -2214760, -2212636, -2210490, -2208324, -2206137, -2203929, -2201701,
+ -2199452, -2197183, -2194893, -2192584, -2190254, -2187904, -2185533,
+ -2183144, -2180734, -2178304, -2175855, -2173387, -2170899, -2168391,
+ -2165865, -2163319, -2160754, -2158170, -2155567, -2152945, -2150305,
+ -2147646, -2144968, -2142272, -2139557, -2136824, -2134073, -2131304,
+ -2128517, -2125712, -2122889, -2120048, -2117189, -2114313, -2111420,
+ -2108509, -2105581, -2102635, -2099672, -2096693, -2093696, -2090682,
+ -2087652, -2084605, -2081541, -2078461, -2075364, -2072251, -2069122,
+ -2065976, -2062815, -2059637, -2056444, -2053234, -2050009, -2046769,
+ -2043513, -2040241, -2036954, -2033651, -2030334, -2027001, -2023654,
+ -2020291, -2016913, -2013521, -2010114, -2006693, -2003257, -1999806,
+ -1996342, -1992863, -1989370, -1985863, -1982341, -1978806, -1975258,
+ -1971695, -1968119, -1964529, -1960926, -1957310, -1953680, -1950037,
+ -1946381, -1942712, -1939030, -1935336, -1931628, -1927908, -1924175,
+ -1920430, -1916672, -1912902, -1909120, -1905326, -1901520, -1897701,
+ -1893871, -1890029, -1886175, -1882310, -1878433, -1874545, -1870645,
+ -1866734, -1862812, -1858879, -1854935, -1850980, -1847014, -1843037,
+ -1839050, -1835051, -1831043, -1827024, -1822995, -1818955, -1814905,
+ -1810845, -1806776, -1802696, -1798606, -1794507, -1790398, -1786280,
+ -1782152, -1778014, -1773867, -1769711, -1765546, -1761372, -1757189,
+ -1752997, -1748796, -1744586, -1740368, -1736141, -1731905, -1727662,
+ -1723409, -1719149, -1714880, -1710604, -1706319, -1702027, -1697726,
+ -1693418, -1689102, -1684779, -1680448, -1676110, -1671764, -1667411,
+ -1663051, -1658684, -1654310, -1649929, -1645540, -1641146, -1636744,
+ -1632336, -1627921, -1623500, -1619073, -1614639, -1610199, -1605753,
+ -1601301, -1596843, -1592378, -1587909, -1583433, -1578952, -1574465,
+ -1569972, -1565474, -1560971, -1556463, -1551949, -1547430, -1542906,
+ -1538377, -1533844, -1529305, -1524762, -1520214, -1515662, -1511105,
+ -1506543, -1501977, -1497407, -1492833, -1488255, -1483672, -1479086,
+ -1474495, -1469901, -1465303, -1460702, -1456097, -1451488, -1446876,
+ -1442260, -1437641, -1433019, -1428394, -1423766, -1419135, -1414500,
+ -1409863, -1405223, -1400581, -1395935, -1391288, -1386637, -1381984,
+ -1377329, -1372672, -1368012, -1363350, -1358687, -1354021, -1349353,
+ -1344683, -1340012, -1335339, -1330664, -1325987, -1321310, -1316630,
+ -1311950, -1307267, -1302584, -1297900, -1293214, -1288528, -1283840,
+ -1279152, -1274463, -1269773, -1265082, -1260391, -1255699, -1251007,
+ -1246314, -1241621, -1236928, -1232234, -1227540, -1222847, -1218153,
+ -1213459, -1208765, -1204072, -1199379, -1194686, -1189993, -1185301,
+ -1180609, -1175918, -1171228, -1166538, -1161849, -1157161, -1152474,
+ -1147787, -1143102, -1138418, -1133735, -1129053, -1124372, -1119693,
+ -1115015, -1110338, -1105663, -1100990, -1096318, -1091648, -1086979,
+ -1082313, -1077648, -1072985, -1068324, -1063665, -1059009, -1054354,
+ -1049702, -1045052, -1040404, -1035759, -1031116, -1026476, -1021838,
+ -1017203, -1012571, -1007941, -1003314, -998690, -994069, -989451,
+ -984836, -980224, -975615, -971009, -966407, -961808, -957212, -952620,
+ -948031, -943445, -938863, -934285, -929711, -925140, -920573, -916010,
+ -911451, -906895, -902344, -897797, -893254, -888715, -884180, -879650,
+ -875123, -870602, -866084, -861571, -857063, -852559, -848060, -843565,
+ -839075, -834590, -830110, -825634, -821164, -816698, -812237, -807782,
+ -803331, -798886, -794446, -790011, -785581, -781157, -776738, -772325,
+ -767917, -763514, -759117, -754726, -750341, -745961, -741586, -737218,
+ -732855, -728499, -724148, -719803, -715464, -711132, -706805, -702484,
+ -698170, -693862, -689560, -685265, -680975, -676693, -672416, -668146,
+ -663883, -659626, -655376, -651132, -646895, -642665, -638442, -634225,
+ -630015, -625812, -621616, -617427, -613245, -609070, -604902, -600741,
+ -596587, -592440, -588301, -584169, -580044, -575926, -571816, -567713,
+ -563618, -559530, -555449, -551376, -547311, -543253, -539203, -535161,
+ -531126, -527099, -523080, -519069, -515065, -511069, -507082, -503102,
+ -499130, -495166, -491210, -487262, -483323, -479391, -475468, -471553,
+ -467646, -463747, -459857, -455974, -452101, -448235, -444378, -440530,
+ -436690, -432858, -429035, -425220, -421414, -417617, -413828, -410048,
+ -406276, -402514, -398760, -395014, -391278, -387550, -383832, -380122,
+ -376421, -372728, -369045, -365371, -361706, -358050, -354402, -350764,
+ -347135, -343515, -339904, -336303, -332710, -329127, -325553, -321988,
+ -318433, -314886, -311350, -307822, -304304, -300795, -297295, -293805,
+ -290325, -286854, -283392, -279940, -276497, -273064, -269641, -266227,
+ -262822, -259427, -256042, -252667, -249301, -245945, -242599, -239262,
+ -235935, -232618, -229310, -226013, -222725, -219447, -216179, -212920,
+ -209672, -206433, -203205, -199986, -196777, -193578, -190389, -187210,
+ -184041, -180882, -177733, -174594, -171466, -168347, -165238, -162139,
+ -159051, -155972, -152904, -149846, -146798, -143760, -140732, -137714,
+ -134707, -131710, -128723, -125746, -122779, -119823, -116877, -113941,
+ -111016, -108100, -105195, -102301, -99416, -96542, -93678, -90825,
+ -87982, -85149, -82327, -79515, -76713, -73922, -71141, -68370, -65610,
+ -62860, -60121, -57392, -54674, -51966, -49268, -46581, -43904, -41238,
+ -38582, -35936, -33301, -30677, -28063, -25459, -22866, -20283, -17711,
+ -15149, -12598, -10057, -7527, -5007, -2498, 0
+};
diff --git a/kernel/framework/audio/fltdata3_l.inc b/kernel/framework/audio/fltdata3_l.inc
new file mode 100644
index 0000000..c606c74
--- /dev/null
+++ b/kernel/framework/audio/fltdata3_l.inc
@@ -0,0 +1,689 @@
+/*
+ * Purpose: Filter coefficient tables for GRC3
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+static int32_t filter_data[4097] = {
+ 0, -43570, -87593, -132073, -177009, -222405, -268261, -314581,
+ -361366, -408617, -456336, -504526, -553189, -602325, -651938, -702028,
+ -752598, -803650, -855185, -907205, -959713, -1012709, -1066196,
+ -1120176, -1174650, -1229621, -1285089, -1341058, -1397528, -1454502,
+ -1511982, -1569968, -1628464, -1687470, -1746989, -1807023, -1867572,
+ -1928640, -1990227, -2052336, -2114969, -2178126, -2241810, -2306023,
+ -2370767, -2436042, -2501851, -2568196, -2635079, -2702500, -2770463,
+ -2838968, -2908017, -2977612, -3047755, -3118448, -3189691, -3261488,
+ -3333839, -3406746, -3480211, -3554236, -3628822, -3703971, -3779685,
+ -3855965, -3932813, -4010230, -4088218, -4166780, -4245915, -4325627,
+ -4405917, -4486785, -4568235, -4650267, -4732883, -4816085, -4899874,
+ -4984252, -5069220, -5154780, -5240933, -5327682, -5415027, -5502970,
+ -5591512, -5680656, -5770402, -5860752, -5951708, -6043271, -6135443,
+ -6228224, -6321617, -6415623, -6510244, -6605480, -6701333, -6797805,
+ -6894897, -6992611, -7090947, -7189908, -7289494, -7389707, -7490549,
+ -7592020, -7694123, -7796857, -7900226, -8004230, -8108870, -8214147,
+ -8320064, -8426621, -8533819, -8641661, -8750146, -8859276, -8969053,
+ -9079478, -9190552, -9302276, -9414651, -9527679, -9641360, -9755697,
+ -9870689, -9986339, -10102647, -10219615, -10337243, -10455532,
+ -10574485, -10694101, -10814383, -10935330, -11056944, -11179227,
+ -11302178, -11425800, -11550093, -11675058, -11800696, -11927008,
+ -12053996, -12181659, -12309999, -12439017, -12568714, -12699091,
+ -12830148, -12961887, -13094307, -13227412, -13361200, -13495673,
+ -13630832, -13766677, -13903209, -14040430, -14178339, -14316938,
+ -14456228, -14596208, -14736880, -14878245, -15020302, -15163054,
+ -15306500, -15450641, -15595478, -15741012, -15887242, -16034170,
+ -16181797, -16330122, -16479146, -16628871, -16779295, -16930421,
+ -17082248, -17234777, -17388008, -17541942, -17696580, -17851921,
+ -18007966, -18164716, -18322170, -18480330, -18639196, -18798767,
+ -18959045, -19120029, -19281720, -19444119, -19607224, -19771038,
+ -19935559, -20100788, -20266726, -20433372, -20600727, -20768791,
+ -20937563, -21107045, -21277236, -21448136, -21619746, -21792065,
+ -21965093, -22138831, -22313278, -22488435, -22664301, -22840876,
+ -23018161, -23196155, -23374859, -23554271, -23734392, -23915223,
+ -24096761, -24279008, -24461964, -24645627, -24829998, -25015077,
+ -25200863, -25387356, -25574556, -25762462, -25951074, -26140392,
+ -26330415, -26521143, -26712576, -26904712, -27097553, -27291096,
+ -27485342, -27680290, -27875940, -28072291, -28269343, -28467095,
+ -28665546, -28864695, -29064543, -29265089, -29466331, -29668269,
+ -29870903, -30074231, -30278253, -30482969, -30688377, -30894476,
+ -31101266, -31308746, -31516915, -31725772, -31935317, -32145547,
+ -32356463, -32568064, -32780347, -32993313, -33206961, -33421289,
+ -33636296, -33851981, -34068343, -34285381, -34503094, -34721480,
+ -34940539, -35160268, -35380668, -35601737, -35823472, -36045874,
+ -36268941, -36492671, -36717063, -36942116, -37167828, -37394198,
+ -37621224, -37848905, -38077240, -38306227, -38535863, -38766149,
+ -38997082, -39228661, -39460883, -39693748, -39927254, -40161398,
+ -40396180, -40631598, -40867649, -41104332, -41341645, -41579587,
+ -41818156, -42057349, -42297164, -42537601, -42778656, -43020329,
+ -43262616, -43505516, -43749028, -43993148, -44237875, -44483206,
+ -44729140, -44975675, -45222807, -45470536, -45718859, -45967773,
+ -46217276, -46467367, -46718042, -46969299, -47221137, -47473552,
+ -47726542, -47980105, -48234239, -48488940, -48744207, -49000036,
+ -49256426, -49513373, -49770876, -50028931, -50287535, -50546687,
+ -50806383, -51066621, -51327398, -51588711, -51850557, -52112934,
+ -52375839, -52639268, -52903220, -53167690, -53432677, -53698176,
+ -53964186, -54230703, -54497724, -54765245, -55033265, -55301779,
+ -55570785, -55840279, -56110259, -56380720, -56651661, -56923077,
+ -57194964, -57467321, -57740143, -58013428, -58287171, -58561369,
+ -58836019, -59111118, -59386661, -59662646, -59939068, -60215925,
+ -60493212, -60770926, -61049064, -61327621, -61606594, -61885979,
+ -62165772, -62445970, -62726569, -63007564, -63288953, -63570731,
+ -63852894, -64135438, -64418360, -64701655, -64985319, -65269349,
+ -65553739, -65838487, -66123588, -66409037, -66694831, -66980965,
+ -67267436, -67554238, -67841368, -68128821, -68416593, -68704680,
+ -68993076, -69281779, -69570782, -69860083, -70149675, -70439556,
+ -70729720, -71020162, -71310878, -71601864, -71893114, -72184624,
+ -72476390, -72768406, -73060668, -73353171, -73645909, -73938880,
+ -74232076, -74525494, -74819129, -75112975, -75407028, -75701282,
+ -75995733, -76290376, -76585205, -76880215, -77175401, -77470758,
+ -77766281, -78061964, -78357803, -78653792, -78949925, -79246197,
+ -79542604, -79839139, -80135797, -80432572, -80729460, -81026455,
+ -81323551, -81620742, -81918024, -82215389, -82512834, -82810352,
+ -83107937, -83405584, -83703287, -84001040, -84298837, -84596673,
+ -84894542, -85192437, -85490354, -85788285, -86086225, -86384169,
+ -86682109, -86980041, -87277957, -87575852, -87873720, -88171554,
+ -88469349, -88767098, -89064795, -89362433, -89660007, -89957510,
+ -90254936, -90552278, -90849530, -91146685, -91443738, -91740681,
+ -92037509, -92334214, -92630790, -92927231, -93223529, -93519679,
+ -93815673, -94111506, -94407169, -94702657, -94997963, -95293079,
+ -95588000, -95882717, -96177226, -96471517, -96765585, -97059423,
+ -97353024, -97646380, -97939484, -98232330, -98524911, -98817219,
+ -99109247, -99400988, -99692436, -99983581, -100274419, -100564940,
+ -100855138, -101145006, -101434536, -101723721, -102012553, -102301026,
+ -102589131, -102876861, -103164209, -103451167, -103737727, -104023883,
+ -104309626, -104594949, -104879843, -105164303, -105448319, -105731884,
+ -106014991, -106297631, -106579796, -106861480, -107142674, -107423370,
+ -107703560, -107983236, -108262391, -108541017, -108819105, -109096647,
+ -109373636, -109650063, -109925920, -110201200, -110475893, -110749992,
+ -111023489, -111296375, -111568643, -111840283, -112111288, -112381649,
+ -112651358, -112920406, -113188786, -113456489, -113723506, -113989829,
+ -114255449, -114520359, -114784548, -115048010, -115310735, -115572715,
+ -115833940, -116094404, -116354096, -116613008, -116871131, -117128457,
+ -117384977, -117640682, -117895564, -118149613, -118402820, -118655178,
+ -118906676, -119157307, -119407060, -119655927, -119903900, -120150969,
+ -120397125, -120642359, -120886662, -121130025, -121372438, -121613894,
+ -121854382, -122093893, -122332418, -122569949, -122806475, -123041988,
+ -123276477, -123509935, -123742351, -123973717, -124204022, -124433258,
+ -124661415, -124888484, -125114455, -125339319, -125563066, -125785687,
+ -126007172, -126227512, -126446697, -126664718, -126881565, -127097228,
+ -127311698, -127524965, -127737019, -127947852, -128157452, -128365810,
+ -128572918, -128778764, -128983338, -129186633, -129388636, -129589339,
+ -129788732, -129986805, -130183547, -130378950, -130573002, -130765695,
+ -130957018, -131146961, -131335514, -131522667, -131708411, -131892735,
+ -132075628, -132257082, -132437085, -132615628, -132792701, -132968293,
+ -133142395, -133314995, -133486085, -133655653, -133823690, -133990184,
+ -134155127, -134318508, -134480316, -134640541, -134799172, -134956201,
+ -135111615, -135265405, -135417561, -135568071, -135716926, -135864115,
+ -136009628, -136153454, -136295583, -136436004, -136574707, -136711682,
+ -136846917, -136980402, -137112128, -137242082, -137370255, -137496636,
+ -137621215, -137743980, -137864922, -137984030, -138101292, -138216698,
+ -138330239, -138441902, -138551678, -138659555, -138765523, -138869571,
+ -138971689, -139071865, -139170090, -139266351, -139360639, -139452943,
+ -139543251, -139631554, -139717840, -139802098, -139884317, -139964488,
+ -140042598, -140118638, -140192595, -140264460, -140334221, -140401868,
+ -140467389, -140530774, -140592011, -140651091, -140708001, -140762732,
+ -140815271, -140865608, -140913733, -140959634, -141003299, -141044719,
+ -141083882, -141120778, -141155394, -141187721, -141217746, -141245460,
+ -141270851, -141293908, -141314620, -141332976, -141348965, -141362575,
+ -141373797, -141382618, -141389028, -141393015, -141394570, -141393679,
+ -141390333, -141384520, -141376229, -141365450, -141352170, -141336379,
+ -141318066, -141297220, -141273829, -141247883, -141219370, -141188279,
+ -141154599, -141118320, -141079429, -141037916, -140993770, -140946979,
+ -140897532, -140845419, -140790628, -140733147, -140672967, -140610075,
+ -140544461, -140476114, -140405022, -140331174, -140254559, -140175166,
+ -140092984, -140008001, -139920208, -139829591, -139736141, -139639847,
+ -139540696, -139438679, -139333783, -139225998, -139115313, -139001717,
+ -138885198, -138765745, -138643348, -138517995, -138389675, -138258377,
+ -138124090, -137986803, -137846505, -137703185, -137556831, -137407433,
+ -137254980, -137099461, -136940863, -136779178, -136614393, -136446497,
+ -136275480, -136101331, -135924037, -135743590, -135559977, -135373187,
+ -135183210, -134990034, -134793650, -134594044, -134391208, -134185129,
+ -133975798, -133763202, -133547331, -133328175, -133105722, -132879961,
+ -132650882, -132418474, -132182725, -131943626, -131701164, -131455330,
+ -131206113, -130953501, -130697485, -130438052, -130175193, -129908897,
+ -129639153, -129365950, -129089277, -128809125, -128525481, -128238336,
+ -127947679, -127653499, -127355785, -127054528, -126749716, -126441338,
+ -126129385, -125813845, -125494708, -125171963, -124845601, -124515610,
+ -124181980, -123844700, -123503761, -123159150, -122810860, -122458877,
+ -122103193, -121743798, -121380679, -121013828, -120643234, -120268886,
+ -119890775, -119508889, -119123220, -118733756, -118340487, -117943403,
+ -117542495, -117137751, -116729161, -116316716, -115900406, -115480219,
+ -115056147, -114628179, -114196305, -113760516, -113320800, -112877148,
+ -112429551, -111977998, -111522479, -111062985, -110599506, -110132031,
+ -109660551, -109185057, -108705537, -108221984, -107734386, -107242735,
+ -106747020, -106247232, -105743361, -105235398, -104723333, -104207157,
+ -103686860, -103162432, -102633863, -102101146, -101564269, -101023225,
+ -100478002, -99928593, -99374986, -98817175, -98255148, -97688897,
+ -97118412, -96543685, -95964706, -95381466, -94793956, -94202167,
+ -93606089, -93005714, -92401033, -91792036, -91178715, -90561061,
+ -89939065, -89312718, -88682011, -88046936, -87407483, -86763645,
+ -86115411, -85462774, -84805725, -84144255, -83478356, -82808019,
+ -82133236, -81453997, -80770296, -80082122, -79389469, -78692326,
+ -77990687, -77284543, -76573885, -75858706, -75138996, -74414749,
+ -73685955, -72952607, -72214696, -71472216, -70725156, -69973511,
+ -69217271, -68456429, -67690977, -66920907, -66146211, -65366882,
+ -64582911, -63794292, -63001017, -62203077, -61400466, -60593176,
+ -59781199, -58964527, -58143155, -57317073, -56486275, -55650754,
+ -54810501, -53965511, -53115775, -52261287, -51402039, -50538025,
+ -49669237, -48795669, -47917312, -47034162, -46146210, -45253449,
+ -44355874, -43453477, -42546251, -41634190, -40717287, -39795536,
+ -38868930, -37937462, -37001127, -36059917, -35113826, -34162849,
+ -33206977, -32246207, -31280530, -30309941, -29334435, -28354004,
+ -27368642, -26378345, -25383105, -24382917, -23377775, -22367673,
+ -21352606, -20332568, -19307552, -18277554, -17242567, -16202587,
+ -15157608, -14107623, -13052629, -11992619, -10927588, -9857532,
+ -8782443, -7702319, -6617153, -5526940, -4431675, -3331353, -2225970,
+ -1115521, 0, 1120597, 2246275, 3377039, 4512893, 5653843, 6799891,
+ 7951044, 9107305, 10268679, 11435170, 12606782, 13783521, 14965389,
+ 16152391, 17344532, 18541815, 19744244, 20951823, 22164556, 23382448,
+ 24605501, 25833720, 27067108, 28305668, 29549406, 30798323, 32052423,
+ 33311711, 34576189, 35845860, 37120729, 38400797, 39686069, 40976547,
+ 42272235, 43573135, 44879251, 46190585, 47507140, 48828919, 50155925,
+ 51488160, 52825627, 54168329, 55516268, 56869446, 58227867, 59591532,
+ 60960443, 62334604, 63714015, 65098680, 66488600, 67883777, 69284214,
+ 70689911, 72100872, 73517098, 74938590, 76365350, 77797380, 79234682,
+ 80677257, 82125106, 83578230, 85036632, 86500312, 87969272, 89443512,
+ 90923035, 92407840, 93897929, 95393303, 96893963, 98399909, 99911142,
+ 101427664, 102949474, 104476572, 106008961, 107546640, 109089609,
+ 110637869, 112191420, 113750263, 115314396, 116883822, 118458539,
+ 120038547, 121623847, 123214439, 124810321, 126411494, 128017958,
+ 129629712, 131246756, 132869088, 134496710, 136129619, 137767815,
+ 139411298, 141060066, 142714119, 144373456, 146038076, 147707977,
+ 149383159, 151063621, 152749360, 154440377, 156136668, 157838234,
+ 159545072, 161257181, 162974559, 164697204, 166425116, 168158291,
+ 169896728, 171640425, 173389381, 175143592, 176903057, 178667774,
+ 180437740, 182212953, 183993411, 185779111, 187570050, 189366227,
+ 191167637, 192974280, 194786151, 196603248, 198425568, 200253108,
+ 202085865, 203923836, 205767018, 207615407, 209469001, 211327795,
+ 213191786, 215060971, 216935347, 218814909, 220699654, 222589578,
+ 224484677, 226384948, 228290386, 230200988, 232116749, 234037665,
+ 235963732, 237894945, 239831301, 241772795, 243719422, 245671177,
+ 247628057, 249590056, 251557170, 253529394, 255506722, 257489151,
+ 259476675, 261469288, 263466986, 265469763, 267477615, 269490536,
+ 271508519, 273531561, 275559655, 277592796, 279630977, 281674194,
+ 283722440, 285775710, 287833997, 289897295, 291965599, 294038902,
+ 296117199, 298200481, 300288744, 302381981, 304480185, 306583350,
+ 308691469, 310804535, 312922542, 315045483, 317173351, 319306138,
+ 321443839, 323586445, 325733949, 327886345, 330043625, 332205781,
+ 334372807, 336544694, 338721435, 340903022, 343089448, 345280705,
+ 347476785, 349677680, 351883382, 354093883, 356309174, 358529248,
+ 360754097, 362983712, 365218084, 367457205, 369701067, 371949661,
+ 374202979, 376461011, 378723748, 380991183, 383263305, 385540107,
+ 387821578, 390107710, 392398493, 394693919, 396993977, 399298659,
+ 401607955, 403921855, 406240350, 408563430, 410891085, 413223306,
+ 415560082, 417901404, 420247261, 422597644, 424952542, 427311946,
+ 429675844, 432044226, 434417083, 436794402, 439176175, 441562390,
+ 443953037, 446348105, 448747582, 451151459, 453559723, 455972365,
+ 458389373, 460810735, 463236441, 465666479, 468100838, 470539507,
+ 472982473, 475429726, 477881254, 480337044, 482797086, 485261367,
+ 487729876, 490202600, 492679528, 495160647, 497645945, 500135411,
+ 502629031, 505126793, 507628686, 510134695, 512644810, 515159016,
+ 517677303, 520199656, 522726063, 525256511, 527790987, 530329478,
+ 532871971, 535418453, 537968910, 540523330, 543081699, 545644003,
+ 548210230, 550780365, 553354395, 555932307, 558514086, 561099718,
+ 563689191, 566282490, 568879600, 571480509, 574085201, 576693663,
+ 579305881, 581921839, 584541524, 587164922, 589792017, 592422796,
+ 595057243, 597695344, 600337084, 602982449, 605631423, 608283992,
+ 610940141, 613599853, 616263116, 618929912, 621600227, 624274046,
+ 626951354, 629632134, 632316371, 635004051, 637695156, 640389672,
+ 643087583, 645788873, 648493526, 651201526, 653912857, 656627504,
+ 659345449, 662066678, 664791173, 667518918, 670249898, 672984095,
+ 675721494, 678462077, 681205828, 683952731, 686702768, 689455924,
+ 692212181, 694971522, 697733931, 700499390, 703267882, 706039390,
+ 708813898, 711591388, 714371842, 717155244, 719941575, 722730819,
+ 725522958, 728317974, 731115850, 733916567, 736720110, 739526459,
+ 742335596, 745147504, 747962165, 750779561, 753599674, 756422486,
+ 759247977, 762076132, 764906930, 767740353, 770576384, 773415004,
+ 776256194, 779099935, 781946210, 784794999, 787646284, 790500045,
+ 793356265, 796214924, 799076003, 801939484, 804805347, 807673573,
+ 810544143, 813417038, 816292238, 819169725, 822049479, 824931480,
+ 827815710, 830702148, 833590775, 836481572, 839374518, 842269595,
+ 845166782, 848066059, 850967407, 853870806, 856776236, 859683677,
+ 862593109, 865504511, 868417864, 871333148, 874250341, 877169425,
+ 880090378, 883013180, 885937811, 888864250, 891792477, 894722471,
+ 897654212, 900587679, 903522851, 906459707, 909398227, 912338390,
+ 915280175, 918223561, 921168527, 924115052, 927063115, 930012694,
+ 932963770, 935916320, 938870323, 941825758, 944782604, 947740839,
+ 950700442, 953661392, 956623666, 959587244, 962552104, 965518224,
+ 968485582, 971454158, 974423928, 977394872, 980366968, 983340193,
+ 986314526, 989289944, 992266427, 995243951, 998222495, 1001202037,
+ 1004182555, 1007164025, 1010146427, 1013129738, 1016113936, 1019098998,
+ 1022084902, 1025071625, 1028059146, 1031047441, 1034036489, 1037026266,
+ 1040016750, 1043007919, 1045999750, 1048992219, 1051985306, 1054978985,
+ 1057973236, 1060968035, 1063963359, 1066959186, 1069955492, 1072952255,
+ 1075949451, 1078947057, 1081945052, 1084943410, 1087942110, 1090941128,
+ 1093940441, 1096940026, 1099939860, 1102939919, 1105940180, 1108940619,
+ 1111941215, 1114941942, 1117942777, 1120943698, 1123944681, 1126945702,
+ 1129946738, 1132947764, 1135948759, 1138949697, 1141950556, 1144951312,
+ 1147951940, 1150952419, 1153952722, 1156952828, 1159952711, 1162952349,
+ 1165951718, 1168950793, 1171949551, 1174947968, 1177946019, 1180943682,
+ 1183940932, 1186937744, 1189934096, 1192929963, 1195925320, 1198920145,
+ 1201914412, 1204908098, 1207901179, 1210893629, 1213885426, 1216876545,
+ 1219866962, 1222856652, 1225845591, 1228833755, 1231821120, 1234807662,
+ 1237793355, 1240778176, 1243762101, 1246745104, 1249727162, 1252708250,
+ 1255688343, 1258667418, 1261645450, 1264622414, 1267598286, 1270573041,
+ 1273546655, 1276519103, 1279490361, 1282460404, 1285429208, 1288396747,
+ 1291362998, 1294327936, 1297291536, 1300253773, 1303214624, 1306174062,
+ 1309132064, 1312088605, 1315043660, 1317997205, 1320949214, 1323899663,
+ 1326848528, 1329795783, 1332741404, 1335685366, 1338627645, 1341568215,
+ 1344507051, 1347444130, 1350379426, 1353312914, 1356244570, 1359174369,
+ 1362102286, 1365028296, 1367952374, 1370874496, 1373794637, 1376712771,
+ 1379628875, 1382542922, 1385454889, 1388364751, 1391272482, 1394178058,
+ 1397081453, 1399982644, 1402881606, 1405778312, 1408672739, 1411564862,
+ 1414454656, 1417342095, 1420227156, 1423109813, 1425990041, 1428867816,
+ 1431743112, 1434615906, 1437486171, 1440353883, 1443219018, 1446081551,
+ 1448941456, 1451798708, 1454653284, 1457505158, 1460354306, 1463200702,
+ 1466044321, 1468885140, 1471723133, 1474558275, 1477390542, 1480219909,
+ 1483046351, 1485869843, 1488690361, 1491507880, 1494322374, 1497133821,
+ 1499942194, 1502747469, 1505549621, 1508348626, 1511144459, 1513937095,
+ 1516726510, 1519512679, 1522295577, 1525075180, 1527851463, 1530624402,
+ 1533393972, 1536160149, 1538922907, 1541682223, 1544438072, 1547190429,
+ 1549939270, 1552684570, 1555426306, 1558164452, 1560898984, 1563629877,
+ 1566357108, 1569080652, 1571800485, 1574516582, 1577228919, 1579937471,
+ 1582642215, 1585343126, 1588040180, 1590733352, 1593422619, 1596107956,
+ 1598789339, 1601466744, 1604140146, 1606809523, 1609474849, 1612136101,
+ 1614793254, 1617446285, 1620095169, 1622739883, 1625380402, 1628016704,
+ 1630648763, 1633276556, 1635900059, 1638519248, 1641134100, 1643744591,
+ 1646350697, 1648952394, 1651549658, 1654142467, 1656730796, 1659314621,
+ 1661893920, 1664468669, 1667038843, 1669604420, 1672165376, 1674721688,
+ 1677273332, 1679820285, 1682362524, 1684900025, 1687432765, 1689960721,
+ 1692483869, 1695002186, 1697515650, 1700024237, 1702527924, 1705026688,
+ 1707520506, 1710009354, 1712493211, 1714972053, 1717445857, 1719914600,
+ 1722378260, 1724836813, 1727290238, 1729738511, 1732181610, 1734619511,
+ 1737052193, 1739479633, 1741901809, 1744318697, 1746730275, 1749136522,
+ 1751537414, 1753932930, 1756323047, 1758707742, 1761086994, 1763460781,
+ 1765829080, 1768191869, 1770549126, 1772900830, 1775246958, 1777587488,
+ 1779922398, 1782251667, 1784575273, 1786893194, 1789205409, 1791511895,
+ 1793812631, 1796107596, 1798396768, 1800680125, 1802957646, 1805229311,
+ 1807495096, 1809754982, 1812008946, 1814256968, 1816499026, 1818735100,
+ 1820965168, 1823189210, 1825407204, 1827619129, 1829824964, 1832024690,
+ 1834218284, 1836405726, 1838586996, 1840762073, 1842930937, 1845093566,
+ 1847249940, 1849400040, 1851543844, 1853681332, 1855812485, 1857937281,
+ 1860055701, 1862167724, 1864273331, 1866372501, 1868465215, 1870551452,
+ 1872631194, 1874704419, 1876771108, 1878831243, 1880884802, 1882931767,
+ 1884972117, 1887005834, 1889032899, 1891053291, 1893066991, 1895073981,
+ 1897074241, 1899067752, 1901054494, 1903034450, 1905007600, 1906973925,
+ 1908933406, 1910886025, 1912831762, 1914770600, 1916702519, 1918627502,
+ 1920545529, 1922456583, 1924360644, 1926257695, 1928147718, 1930030694,
+ 1931906605, 1933775433, 1935637160, 1937491769, 1939339241, 1941179559,
+ 1943012705, 1944838661, 1946657410, 1948468934, 1950273215, 1952070238,
+ 1953859983, 1955642434, 1957417573, 1959185384, 1960945850, 1962698952,
+ 1964444675, 1966183002, 1967913915, 1969637399, 1971353435, 1973062009,
+ 1974763103, 1976456700, 1978142785, 1979821341, 1981492351, 1983155800,
+ 1984811672, 1986459950, 1988100618, 1989733661, 1991359063, 1992976807,
+ 1994586878, 1996189261, 1997783940, 1999370900, 2000950124, 2002521598,
+ 2004085307, 2005641235, 2007189366, 2008729687, 2010262182, 2011786836,
+ 2013303634, 2014812562, 2016313604, 2017806746, 2019291974, 2020769273,
+ 2022238629, 2023700027, 2025153454, 2026598894, 2028036334, 2029465759,
+ 2030887157, 2032300512, 2033705812, 2035103042, 2036492189, 2037873238,
+ 2039246178, 2040610993, 2041967672, 2043316200, 2044656565, 2045988752,
+ 2047312750, 2048628546, 2049936125, 2051235476, 2052526587, 2053809443,
+ 2055084032, 2056350343, 2057608363, 2058858079, 2060099479, 2061332551,
+ 2062557282, 2063773662, 2064981677, 2066181316, 2067372568, 2068555420,
+ 2069729861, 2070895879, 2072053463, 2073202601, 2074343283, 2075475496,
+ 2076599231, 2077714475, 2078821218, 2079919449, 2081009157, 2082090331,
+ 2083162962, 2084227037, 2085282547, 2086329481, 2087367829, 2088397581,
+ 2089418727, 2090431256, 2091435159, 2092430425, 2093417045, 2094395009,
+ 2095364308, 2096324932, 2097276871, 2098220116, 2099154657, 2100080487,
+ 2100997594, 2101905971, 2102805608, 2103696497, 2104578628, 2105451993,
+ 2106316584, 2107172391, 2108019406, 2108857622, 2109687029, 2110507619,
+ 2111319385, 2112122318, 2112916410, 2113701654, 2114478042, 2115245566,
+ 2116004218, 2116753991, 2117494877, 2118226870, 2118949962, 2119664145,
+ 2120369413, 2121065759, 2121753176, 2122431657, 2123101195, 2123761783,
+ 2124413416, 2125056087, 2125689789, 2126314515, 2126930261, 2127537019,
+ 2128134784, 2128723550, 2129303311, 2129874061, 2130435794, 2130988506,
+ 2131532190, 2132066841, 2132592453, 2133109023, 2133616544, 2134115011,
+ 2134604419, 2135084765, 2135556042, 2136018246, 2136471373, 2136915418,
+ 2137350376, 2137776244, 2138193017, 2138600691, 2138999262, 2139388726,
+ 2139769079, 2140140317, 2140502437, 2140855436, 2141199308, 2141534052,
+ 2141859663, 2142176139, 2142483477, 2142781673, 2143070724, 2143350628,
+ 2143621381, 2143882982, 2144135427, 2144378714, 2144612841, 2144837804,
+ 2145053603, 2145260235, 2145457697, 2145645988, 2145825106, 2145995050,
+ 2146155816, 2146307405, 2146449814, 2146583042, 2146707087, 2146821949,
+ 2146927626, 2147024118, 2147111422, 2147189539, 2147258468, 2147318207,
+ 2147368757, 2147410117, 2147442286, 2147465264, 2147479051, 2147483647,
+ 2147479051, 2147465264, 2147442286, 2147410117, 2147368757, 2147318207,
+ 2147258468, 2147189539, 2147111422, 2147024118, 2146927626, 2146821949,
+ 2146707087, 2146583042, 2146449814, 2146307405, 2146155816, 2145995050,
+ 2145825106, 2145645988, 2145457697, 2145260235, 2145053603, 2144837804,
+ 2144612841, 2144378714, 2144135427, 2143882982, 2143621381, 2143350628,
+ 2143070724, 2142781673, 2142483477, 2142176139, 2141859663, 2141534052,
+ 2141199308, 2140855436, 2140502437, 2140140317, 2139769079, 2139388726,
+ 2138999262, 2138600691, 2138193017, 2137776244, 2137350376, 2136915418,
+ 2136471373, 2136018246, 2135556042, 2135084765, 2134604419, 2134115011,
+ 2133616544, 2133109023, 2132592453, 2132066841, 2131532190, 2130988506,
+ 2130435794, 2129874061, 2129303311, 2128723550, 2128134784, 2127537019,
+ 2126930261, 2126314515, 2125689789, 2125056087, 2124413416, 2123761783,
+ 2123101195, 2122431657, 2121753176, 2121065759, 2120369413, 2119664145,
+ 2118949962, 2118226870, 2117494877, 2116753991, 2116004218, 2115245566,
+ 2114478042, 2113701654, 2112916410, 2112122318, 2111319385, 2110507619,
+ 2109687029, 2108857622, 2108019406, 2107172391, 2106316584, 2105451993,
+ 2104578628, 2103696497, 2102805608, 2101905971, 2100997594, 2100080487,
+ 2099154657, 2098220116, 2097276871, 2096324932, 2095364308, 2094395009,
+ 2093417045, 2092430425, 2091435159, 2090431256, 2089418727, 2088397581,
+ 2087367829, 2086329481, 2085282547, 2084227037, 2083162962, 2082090331,
+ 2081009157, 2079919449, 2078821218, 2077714475, 2076599231, 2075475496,
+ 2074343283, 2073202601, 2072053463, 2070895879, 2069729861, 2068555420,
+ 2067372568, 2066181316, 2064981677, 2063773662, 2062557282, 2061332551,
+ 2060099479, 2058858079, 2057608363, 2056350343, 2055084032, 2053809443,
+ 2052526587, 2051235476, 2049936125, 2048628546, 2047312750, 2045988752,
+ 2044656565, 2043316200, 2041967672, 2040610993, 2039246178, 2037873238,
+ 2036492189, 2035103042, 2033705812, 2032300512, 2030887157, 2029465759,
+ 2028036334, 2026598894, 2025153454, 2023700027, 2022238629, 2020769273,
+ 2019291974, 2017806746, 2016313604, 2014812562, 2013303634, 2011786836,
+ 2010262182, 2008729687, 2007189366, 2005641235, 2004085307, 2002521598,
+ 2000950124, 1999370900, 1997783940, 1996189261, 1994586878, 1992976807,
+ 1991359063, 1989733661, 1988100618, 1986459950, 1984811672, 1983155800,
+ 1981492351, 1979821341, 1978142785, 1976456700, 1974763103, 1973062009,
+ 1971353435, 1969637399, 1967913915, 1966183002, 1964444675, 1962698952,
+ 1960945850, 1959185384, 1957417573, 1955642434, 1953859983, 1952070238,
+ 1950273215, 1948468934, 1946657410, 1944838661, 1943012705, 1941179559,
+ 1939339241, 1937491769, 1935637160, 1933775433, 1931906605, 1930030694,
+ 1928147718, 1926257695, 1924360644, 1922456583, 1920545529, 1918627502,
+ 1916702519, 1914770600, 1912831762, 1910886025, 1908933406, 1906973925,
+ 1905007600, 1903034450, 1901054494, 1899067752, 1897074241, 1895073981,
+ 1893066991, 1891053291, 1889032899, 1887005834, 1884972117, 1882931767,
+ 1880884802, 1878831243, 1876771108, 1874704419, 1872631194, 1870551452,
+ 1868465215, 1866372501, 1864273331, 1862167724, 1860055701, 1857937281,
+ 1855812485, 1853681332, 1851543844, 1849400040, 1847249940, 1845093566,
+ 1842930937, 1840762073, 1838586996, 1836405726, 1834218284, 1832024690,
+ 1829824964, 1827619129, 1825407204, 1823189210, 1820965168, 1818735100,
+ 1816499026, 1814256968, 1812008946, 1809754982, 1807495096, 1805229311,
+ 1802957646, 1800680125, 1798396768, 1796107596, 1793812631, 1791511895,
+ 1789205409, 1786893194, 1784575273, 1782251667, 1779922398, 1777587488,
+ 1775246958, 1772900830, 1770549126, 1768191869, 1765829080, 1763460781,
+ 1761086994, 1758707742, 1756323047, 1753932930, 1751537414, 1749136522,
+ 1746730275, 1744318697, 1741901809, 1739479633, 1737052193, 1734619511,
+ 1732181610, 1729738511, 1727290238, 1724836813, 1722378260, 1719914600,
+ 1717445857, 1714972053, 1712493211, 1710009354, 1707520506, 1705026688,
+ 1702527924, 1700024237, 1697515650, 1695002186, 1692483869, 1689960721,
+ 1687432765, 1684900025, 1682362524, 1679820285, 1677273332, 1674721688,
+ 1672165376, 1669604420, 1667038843, 1664468669, 1661893920, 1659314621,
+ 1656730796, 1654142467, 1651549658, 1648952394, 1646350697, 1643744591,
+ 1641134100, 1638519248, 1635900059, 1633276556, 1630648763, 1628016704,
+ 1625380402, 1622739883, 1620095169, 1617446285, 1614793254, 1612136101,
+ 1609474849, 1606809523, 1604140146, 1601466744, 1598789339, 1596107956,
+ 1593422619, 1590733352, 1588040180, 1585343126, 1582642215, 1579937471,
+ 1577228919, 1574516582, 1571800485, 1569080652, 1566357108, 1563629877,
+ 1560898984, 1558164452, 1555426306, 1552684570, 1549939270, 1547190429,
+ 1544438072, 1541682223, 1538922907, 1536160149, 1533393972, 1530624402,
+ 1527851463, 1525075180, 1522295577, 1519512679, 1516726510, 1513937095,
+ 1511144459, 1508348626, 1505549621, 1502747469, 1499942194, 1497133821,
+ 1494322374, 1491507880, 1488690361, 1485869843, 1483046351, 1480219909,
+ 1477390542, 1474558275, 1471723133, 1468885140, 1466044321, 1463200702,
+ 1460354306, 1457505158, 1454653284, 1451798708, 1448941456, 1446081551,
+ 1443219018, 1440353883, 1437486171, 1434615906, 1431743112, 1428867816,
+ 1425990041, 1423109813, 1420227156, 1417342095, 1414454656, 1411564862,
+ 1408672739, 1405778312, 1402881606, 1399982644, 1397081453, 1394178058,
+ 1391272482, 1388364751, 1385454889, 1382542922, 1379628875, 1376712771,
+ 1373794637, 1370874496, 1367952374, 1365028296, 1362102286, 1359174369,
+ 1356244570, 1353312914, 1350379426, 1347444130, 1344507051, 1341568215,
+ 1338627645, 1335685366, 1332741404, 1329795783, 1326848528, 1323899663,
+ 1320949214, 1317997205, 1315043660, 1312088605, 1309132064, 1306174062,
+ 1303214624, 1300253773, 1297291536, 1294327936, 1291362998, 1288396747,
+ 1285429208, 1282460404, 1279490361, 1276519103, 1273546655, 1270573041,
+ 1267598286, 1264622414, 1261645450, 1258667418, 1255688343, 1252708250,
+ 1249727162, 1246745104, 1243762101, 1240778176, 1237793355, 1234807662,
+ 1231821120, 1228833755, 1225845591, 1222856652, 1219866962, 1216876545,
+ 1213885426, 1210893629, 1207901179, 1204908098, 1201914412, 1198920145,
+ 1195925320, 1192929963, 1189934096, 1186937744, 1183940932, 1180943682,
+ 1177946019, 1174947968, 1171949551, 1168950793, 1165951718, 1162952349,
+ 1159952711, 1156952828, 1153952722, 1150952419, 1147951940, 1144951312,
+ 1141950556, 1138949697, 1135948759, 1132947764, 1129946738, 1126945702,
+ 1123944681, 1120943698, 1117942777, 1114941942, 1111941215, 1108940619,
+ 1105940180, 1102939919, 1099939860, 1096940026, 1093940441, 1090941128,
+ 1087942110, 1084943410, 1081945052, 1078947057, 1075949451, 1072952255,
+ 1069955492, 1066959186, 1063963359, 1060968035, 1057973236, 1054978985,
+ 1051985306, 1048992219, 1045999750, 1043007919, 1040016750, 1037026266,
+ 1034036489, 1031047441, 1028059146, 1025071625, 1022084902, 1019098998,
+ 1016113936, 1013129738, 1010146427, 1007164025, 1004182555, 1001202037,
+ 998222495, 995243951, 992266427, 989289944, 986314526, 983340193,
+ 980366968, 977394872, 974423928, 971454158, 968485582, 965518224,
+ 962552104, 959587244, 956623666, 953661392, 950700442, 947740839,
+ 944782604, 941825758, 938870323, 935916320, 932963770, 930012694,
+ 927063115, 924115052, 921168527, 918223561, 915280175, 912338390,
+ 909398227, 906459707, 903522851, 900587679, 897654212, 894722471,
+ 891792477, 888864250, 885937811, 883013180, 880090378, 877169425,
+ 874250341, 871333148, 868417864, 865504511, 862593109, 859683677,
+ 856776236, 853870806, 850967407, 848066059, 845166782, 842269595,
+ 839374518, 836481572, 833590775, 830702148, 827815710, 824931480,
+ 822049479, 819169725, 816292238, 813417038, 810544143, 807673573,
+ 804805347, 801939484, 799076003, 796214924, 793356265, 790500045,
+ 787646284, 784794999, 781946210, 779099935, 776256194, 773415004,
+ 770576384, 767740353, 764906930, 762076132, 759247977, 756422486,
+ 753599674, 750779561, 747962165, 745147504, 742335596, 739526459,
+ 736720110, 733916567, 731115850, 728317974, 725522958, 722730819,
+ 719941575, 717155244, 714371842, 711591388, 708813898, 706039390,
+ 703267882, 700499390, 697733931, 694971522, 692212181, 689455924,
+ 686702768, 683952731, 681205828, 678462077, 675721494, 672984095,
+ 670249898, 667518918, 664791173, 662066678, 659345449, 656627504,
+ 653912857, 651201526, 648493526, 645788873, 643087583, 640389672,
+ 637695156, 635004051, 632316371, 629632134, 626951354, 624274046,
+ 621600227, 618929912, 616263116, 613599853, 610940141, 608283992,
+ 605631423, 602982449, 600337084, 597695344, 595057243, 592422796,
+ 589792017, 587164922, 584541524, 581921839, 579305881, 576693663,
+ 574085201, 571480509, 568879600, 566282490, 563689191, 561099718,
+ 558514086, 555932307, 553354395, 550780365, 548210230, 545644003,
+ 543081699, 540523330, 537968910, 535418453, 532871971, 530329478,
+ 527790987, 525256511, 522726063, 520199656, 517677303, 515159016,
+ 512644810, 510134695, 507628686, 505126793, 502629031, 500135411,
+ 497645945, 495160647, 492679528, 490202600, 487729876, 485261367,
+ 482797086, 480337044, 477881254, 475429726, 472982473, 470539507,
+ 468100838, 465666479, 463236441, 460810735, 458389373, 455972365,
+ 453559723, 451151459, 448747582, 446348105, 443953037, 441562390,
+ 439176175, 436794402, 434417083, 432044226, 429675844, 427311946,
+ 424952542, 422597644, 420247261, 417901404, 415560082, 413223306,
+ 410891085, 408563430, 406240350, 403921855, 401607955, 399298659,
+ 396993977, 394693919, 392398493, 390107710, 387821578, 385540107,
+ 383263305, 380991183, 378723748, 376461011, 374202979, 371949661,
+ 369701067, 367457205, 365218084, 362983712, 360754097, 358529248,
+ 356309174, 354093883, 351883382, 349677680, 347476785, 345280705,
+ 343089448, 340903022, 338721435, 336544694, 334372807, 332205781,
+ 330043625, 327886345, 325733949, 323586445, 321443839, 319306138,
+ 317173351, 315045483, 312922542, 310804535, 308691469, 306583350,
+ 304480185, 302381981, 300288744, 298200481, 296117199, 294038902,
+ 291965599, 289897295, 287833997, 285775710, 283722440, 281674194,
+ 279630977, 277592796, 275559655, 273531561, 271508519, 269490536,
+ 267477615, 265469763, 263466986, 261469288, 259476675, 257489151,
+ 255506722, 253529394, 251557170, 249590056, 247628057, 245671177,
+ 243719422, 241772795, 239831301, 237894945, 235963732, 234037665,
+ 232116749, 230200988, 228290386, 226384948, 224484677, 222589578,
+ 220699654, 218814909, 216935347, 215060971, 213191786, 211327795,
+ 209469001, 207615407, 205767018, 203923836, 202085865, 200253108,
+ 198425568, 196603248, 194786151, 192974280, 191167637, 189366227,
+ 187570050, 185779111, 183993411, 182212953, 180437740, 178667774,
+ 176903057, 175143592, 173389381, 171640425, 169896728, 168158291,
+ 166425116, 164697204, 162974559, 161257181, 159545072, 157838234,
+ 156136668, 154440377, 152749360, 151063621, 149383159, 147707977,
+ 146038076, 144373456, 142714119, 141060066, 139411298, 137767815,
+ 136129619, 134496710, 132869088, 131246756, 129629712, 128017958,
+ 126411494, 124810321, 123214439, 121623847, 120038547, 118458539,
+ 116883822, 115314396, 113750263, 112191420, 110637869, 109089609,
+ 107546640, 106008961, 104476572, 102949474, 101427664, 99911142,
+ 98399909, 96893963, 95393303, 93897929, 92407840, 90923035, 89443512,
+ 87969272, 86500312, 85036632, 83578230, 82125106, 80677257, 79234682,
+ 77797380, 76365350, 74938590, 73517098, 72100872, 70689911, 69284214,
+ 67883777, 66488600, 65098680, 63714015, 62334604, 60960443, 59591532,
+ 58227867, 56869446, 55516268, 54168329, 52825627, 51488160, 50155925,
+ 48828919, 47507140, 46190585, 44879251, 43573135, 42272235, 40976547,
+ 39686069, 38400797, 37120729, 35845860, 34576189, 33311711, 32052423,
+ 30798323, 29549406, 28305668, 27067108, 25833720, 24605501, 23382448,
+ 22164556, 20951823, 19744244, 18541815, 17344532, 16152391, 14965389,
+ 13783521, 12606782, 11435170, 10268679, 9107305, 7951044, 6799891,
+ 5653843, 4512893, 3377039, 2246275, 1120597, 0, -1115521, -2225970,
+ -3331353, -4431675, -5526940, -6617153, -7702319, -8782443, -9857532,
+ -10927588, -11992619, -13052629, -14107623, -15157608, -16202587,
+ -17242567, -18277554, -19307552, -20332568, -21352606, -22367673,
+ -23377775, -24382917, -25383105, -26378345, -27368642, -28354004,
+ -29334435, -30309941, -31280530, -32246207, -33206977, -34162849,
+ -35113826, -36059917, -37001127, -37937462, -38868930, -39795536,
+ -40717287, -41634190, -42546251, -43453477, -44355874, -45253449,
+ -46146210, -47034162, -47917312, -48795669, -49669237, -50538025,
+ -51402039, -52261287, -53115775, -53965511, -54810501, -55650754,
+ -56486275, -57317073, -58143155, -58964527, -59781199, -60593176,
+ -61400466, -62203077, -63001017, -63794292, -64582911, -65366882,
+ -66146211, -66920907, -67690977, -68456429, -69217271, -69973511,
+ -70725156, -71472216, -72214696, -72952607, -73685955, -74414749,
+ -75138996, -75858706, -76573885, -77284543, -77990687, -78692326,
+ -79389469, -80082122, -80770296, -81453997, -82133236, -82808019,
+ -83478356, -84144255, -84805725, -85462774, -86115411, -86763645,
+ -87407483, -88046936, -88682011, -89312718, -89939065, -90561061,
+ -91178715, -91792036, -92401033, -93005714, -93606089, -94202167,
+ -94793956, -95381466, -95964706, -96543685, -97118412, -97688897,
+ -98255148, -98817175, -99374986, -99928593, -100478002, -101023225,
+ -101564269, -102101146, -102633863, -103162432, -103686860, -104207157,
+ -104723333, -105235398, -105743361, -106247232, -106747020, -107242735,
+ -107734386, -108221984, -108705537, -109185057, -109660551, -110132031,
+ -110599506, -111062985, -111522479, -111977998, -112429551, -112877148,
+ -113320800, -113760516, -114196305, -114628179, -115056147, -115480219,
+ -115900406, -116316716, -116729161, -117137751, -117542495, -117943403,
+ -118340487, -118733756, -119123220, -119508889, -119890775, -120268886,
+ -120643234, -121013828, -121380679, -121743798, -122103193, -122458877,
+ -122810860, -123159150, -123503761, -123844700, -124181980, -124515610,
+ -124845601, -125171963, -125494708, -125813845, -126129385, -126441338,
+ -126749716, -127054528, -127355785, -127653499, -127947679, -128238336,
+ -128525481, -128809125, -129089277, -129365950, -129639153, -129908897,
+ -130175193, -130438052, -130697485, -130953501, -131206113, -131455330,
+ -131701164, -131943626, -132182725, -132418474, -132650882, -132879961,
+ -133105722, -133328175, -133547331, -133763202, -133975798, -134185129,
+ -134391208, -134594044, -134793650, -134990034, -135183210, -135373187,
+ -135559977, -135743590, -135924037, -136101331, -136275480, -136446497,
+ -136614393, -136779178, -136940863, -137099461, -137254980, -137407433,
+ -137556831, -137703185, -137846505, -137986803, -138124090, -138258377,
+ -138389675, -138517995, -138643348, -138765745, -138885198, -139001717,
+ -139115313, -139225998, -139333783, -139438679, -139540696, -139639847,
+ -139736141, -139829591, -139920208, -140008001, -140092984, -140175166,
+ -140254559, -140331174, -140405022, -140476114, -140544461, -140610075,
+ -140672967, -140733147, -140790628, -140845419, -140897532, -140946979,
+ -140993770, -141037916, -141079429, -141118320, -141154599, -141188279,
+ -141219370, -141247883, -141273829, -141297220, -141318066, -141336379,
+ -141352170, -141365450, -141376229, -141384520, -141390333, -141393679,
+ -141394570, -141393015, -141389028, -141382618, -141373797, -141362575,
+ -141348965, -141332976, -141314620, -141293908, -141270851, -141245460,
+ -141217746, -141187721, -141155394, -141120778, -141083882, -141044719,
+ -141003299, -140959634, -140913733, -140865608, -140815271, -140762732,
+ -140708001, -140651091, -140592011, -140530774, -140467389, -140401868,
+ -140334221, -140264460, -140192595, -140118638, -140042598, -139964488,
+ -139884317, -139802098, -139717840, -139631554, -139543251, -139452943,
+ -139360639, -139266351, -139170090, -139071865, -138971689, -138869571,
+ -138765523, -138659555, -138551678, -138441902, -138330239, -138216698,
+ -138101292, -137984030, -137864922, -137743980, -137621215, -137496636,
+ -137370255, -137242082, -137112128, -136980402, -136846917, -136711682,
+ -136574707, -136436004, -136295583, -136153454, -136009628, -135864115,
+ -135716926, -135568071, -135417561, -135265405, -135111615, -134956201,
+ -134799172, -134640541, -134480316, -134318508, -134155127, -133990184,
+ -133823690, -133655653, -133486085, -133314995, -133142395, -132968293,
+ -132792701, -132615628, -132437085, -132257082, -132075628, -131892735,
+ -131708411, -131522667, -131335514, -131146961, -130957018, -130765695,
+ -130573002, -130378950, -130183547, -129986805, -129788732, -129589339,
+ -129388636, -129186633, -128983338, -128778764, -128572918, -128365810,
+ -128157452, -127947852, -127737019, -127524965, -127311698, -127097228,
+ -126881565, -126664718, -126446697, -126227512, -126007172, -125785687,
+ -125563066, -125339319, -125114455, -124888484, -124661415, -124433258,
+ -124204022, -123973717, -123742351, -123509935, -123276477, -123041988,
+ -122806475, -122569949, -122332418, -122093893, -121854382, -121613894,
+ -121372438, -121130025, -120886662, -120642359, -120397125, -120150969,
+ -119903900, -119655927, -119407060, -119157307, -118906676, -118655178,
+ -118402820, -118149613, -117895564, -117640682, -117384977, -117128457,
+ -116871131, -116613008, -116354096, -116094404, -115833940, -115572715,
+ -115310735, -115048010, -114784548, -114520359, -114255449, -113989829,
+ -113723506, -113456489, -113188786, -112920406, -112651358, -112381649,
+ -112111288, -111840283, -111568643, -111296375, -111023489, -110749992,
+ -110475893, -110201200, -109925920, -109650063, -109373636, -109096647,
+ -108819105, -108541017, -108262391, -107983236, -107703560, -107423370,
+ -107142674, -106861480, -106579796, -106297631, -106014991, -105731884,
+ -105448319, -105164303, -104879843, -104594949, -104309626, -104023883,
+ -103737727, -103451167, -103164209, -102876861, -102589131, -102301026,
+ -102012553, -101723721, -101434536, -101145006, -100855138, -100564940,
+ -100274419, -99983581, -99692436, -99400988, -99109247, -98817219,
+ -98524911, -98232330, -97939484, -97646380, -97353024, -97059423,
+ -96765585, -96471517, -96177226, -95882717, -95588000, -95293079,
+ -94997963, -94702657, -94407169, -94111506, -93815673, -93519679,
+ -93223529, -92927231, -92630790, -92334214, -92037509, -91740681,
+ -91443738, -91146685, -90849530, -90552278, -90254936, -89957510,
+ -89660007, -89362433, -89064795, -88767098, -88469349, -88171554,
+ -87873720, -87575852, -87277957, -86980041, -86682109, -86384169,
+ -86086225, -85788285, -85490354, -85192437, -84894542, -84596673,
+ -84298837, -84001040, -83703287, -83405584, -83107937, -82810352,
+ -82512834, -82215389, -81918024, -81620742, -81323551, -81026455,
+ -80729460, -80432572, -80135797, -79839139, -79542604, -79246197,
+ -78949925, -78653792, -78357803, -78061964, -77766281, -77470758,
+ -77175401, -76880215, -76585205, -76290376, -75995733, -75701282,
+ -75407028, -75112975, -74819129, -74525494, -74232076, -73938880,
+ -73645909, -73353171, -73060668, -72768406, -72476390, -72184624,
+ -71893114, -71601864, -71310878, -71020162, -70729720, -70439556,
+ -70149675, -69860083, -69570782, -69281779, -68993076, -68704680,
+ -68416593, -68128821, -67841368, -67554238, -67267436, -66980965,
+ -66694831, -66409037, -66123588, -65838487, -65553739, -65269349,
+ -64985319, -64701655, -64418360, -64135438, -63852894, -63570731,
+ -63288953, -63007564, -62726569, -62445970, -62165772, -61885979,
+ -61606594, -61327621, -61049064, -60770926, -60493212, -60215925,
+ -59939068, -59662646, -59386661, -59111118, -58836019, -58561369,
+ -58287171, -58013428, -57740143, -57467321, -57194964, -56923077,
+ -56651661, -56380720, -56110259, -55840279, -55570785, -55301779,
+ -55033265, -54765245, -54497724, -54230703, -53964186, -53698176,
+ -53432677, -53167690, -52903220, -52639268, -52375839, -52112934,
+ -51850557, -51588711, -51327398, -51066621, -50806383, -50546687,
+ -50287535, -50028931, -49770876, -49513373, -49256426, -49000036,
+ -48744207, -48488940, -48234239, -47980105, -47726542, -47473552,
+ -47221137, -46969299, -46718042, -46467367, -46217276, -45967773,
+ -45718859, -45470536, -45222807, -44975675, -44729140, -44483206,
+ -44237875, -43993148, -43749028, -43505516, -43262616, -43020329,
+ -42778656, -42537601, -42297164, -42057349, -41818156, -41579587,
+ -41341645, -41104332, -40867649, -40631598, -40396180, -40161398,
+ -39927254, -39693748, -39460883, -39228661, -38997082, -38766149,
+ -38535863, -38306227, -38077240, -37848905, -37621224, -37394198,
+ -37167828, -36942116, -36717063, -36492671, -36268941, -36045874,
+ -35823472, -35601737, -35380668, -35160268, -34940539, -34721480,
+ -34503094, -34285381, -34068343, -33851981, -33636296, -33421289,
+ -33206961, -32993313, -32780347, -32568064, -32356463, -32145547,
+ -31935317, -31725772, -31516915, -31308746, -31101266, -30894476,
+ -30688377, -30482969, -30278253, -30074231, -29870903, -29668269,
+ -29466331, -29265089, -29064543, -28864695, -28665546, -28467095,
+ -28269343, -28072291, -27875940, -27680290, -27485342, -27291096,
+ -27097553, -26904712, -26712576, -26521143, -26330415, -26140392,
+ -25951074, -25762462, -25574556, -25387356, -25200863, -25015077,
+ -24829998, -24645627, -24461964, -24279008, -24096761, -23915223,
+ -23734392, -23554271, -23374859, -23196155, -23018161, -22840876,
+ -22664301, -22488435, -22313278, -22138831, -21965093, -21792065,
+ -21619746, -21448136, -21277236, -21107045, -20937563, -20768791,
+ -20600727, -20433372, -20266726, -20100788, -19935559, -19771038,
+ -19607224, -19444119, -19281720, -19120029, -18959045, -18798767,
+ -18639196, -18480330, -18322170, -18164716, -18007966, -17851921,
+ -17696580, -17541942, -17388008, -17234777, -17082248, -16930421,
+ -16779295, -16628871, -16479146, -16330122, -16181797, -16034170,
+ -15887242, -15741012, -15595478, -15450641, -15306500, -15163054,
+ -15020302, -14878245, -14736880, -14596208, -14456228, -14316938,
+ -14178339, -14040430, -13903209, -13766677, -13630832, -13495673,
+ -13361200, -13227412, -13094307, -12961887, -12830148, -12699091,
+ -12568714, -12439017, -12309999, -12181659, -12053996, -11927008,
+ -11800696, -11675058, -11550093, -11425800, -11302178, -11179227,
+ -11056944, -10935330, -10814383, -10694101, -10574485, -10455532,
+ -10337243, -10219615, -10102647, -9986339, -9870689, -9755697,
+ -9641360, -9527679, -9414651, -9302276, -9190552, -9079478, -8969053,
+ -8859276, -8750146, -8641661, -8533819, -8426621, -8320064, -8214147,
+ -8108870, -8004230, -7900226, -7796857, -7694123, -7592020, -7490549,
+ -7389707, -7289494, -7189908, -7090947, -6992611, -6894897, -6797805,
+ -6701333, -6605480, -6510244, -6415623, -6321617, -6228224, -6135443,
+ -6043271, -5951708, -5860752, -5770402, -5680656, -5591512, -5502970,
+ -5415027, -5327682, -5240933, -5154780, -5069220, -4984252, -4899874,
+ -4816085, -4732883, -4650267, -4568235, -4486785, -4405917, -4325627,
+ -4245915, -4166780, -4088218, -4010230, -3932813, -3855965, -3779685,
+ -3703971, -3628822, -3554236, -3480211, -3406746, -3333839, -3261488,
+ -3189691, -3118448, -3047755, -2977612, -2908017, -2838968, -2770463,
+ -2702500, -2635079, -2568196, -2501851, -2436042, -2370767, -2306023,
+ -2241810, -2178126, -2114969, -2052336, -1990227, -1928640, -1867572,
+ -1807023, -1746989, -1687470, -1628464, -1569968, -1511982, -1454502,
+ -1397528, -1341058, -1285089, -1229621, -1174650, -1120176, -1066196,
+ -1012709, -959713, -907205, -855185, -803650, -752598, -702028,
+ -651938, -602325, -553189, -504526, -456336, -408617, -361366, -314581,
+ -268261, -222405, -177009, -132073, -87593, -43570, 0
+};
diff --git a/kernel/framework/audio/fltdata4_p.inc b/kernel/framework/audio/fltdata4_p.inc
new file mode 100644
index 0000000..f6eda34
--- /dev/null
+++ b/kernel/framework/audio/fltdata4_p.inc
@@ -0,0 +1,4832 @@
+/*
+ * Purpose: Filter coefficient tables for GRC3
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+static int32_t filter_data[32769] = {
+ 0, -1248, -2498, -3752, -5007, -6266, -7527, -8790, -10057, -11325,
+ -12597, -13870, -15147, -16426, -17707, -18991, -20277, -21566, -22857,
+ -24151, -25447, -26746, -28047, -29350, -30656, -31964, -33275, -34588,
+ -35903, -37221, -38541, -39863, -41188, -42515, -43844, -45176, -46510,
+ -47846, -49184, -50525, -51868, -53213, -54560, -55910, -57261, -58615,
+ -59971, -61330, -62690, -64053, -65417, -66784, -68153, -69524, -70897,
+ -72272, -73649, -75028, -76410, -77793, -79178, -80565, -81955, -83346,
+ -84739, -86134, -87531, -88930, -90331, -91734, -93139, -94545, -95954,
+ -97364, -98776, -100190, -101606, -103024, -104443, -105864, -107287,
+ -108712, -110138, -111567, -112997, -114428, -115861, -117296, -118733,
+ -120171, -121611, -123053, -124496, -125940, -127387, -128835, -130284,
+ -131735, -133188, -134642, -136097, -137554, -139013, -140473, -141934,
+ -143397, -144861, -146327, -147794, -149262, -150732, -152203, -153676,
+ -155150, -156625, -158101, -159579, -161058, -162538, -164020, -165503,
+ -166986, -168472, -169958, -171445, -172934, -174424, -175915, -177407,
+ -178900, -180394, -181889, -183385, -184883, -186381, -187880, -189381,
+ -190882, -192384, -193888, -195392, -196897, -198403, -199910, -201417,
+ -202926, -204435, -205945, -207456, -208968, -210481, -211994, -213508,
+ -215023, -216539, -218055, -219572, -221090, -222608, -224127, -225646,
+ -227166, -228687, -230208, -231730, -233253, -234776, -236299, -237823,
+ -239347, -240872, -242397, -243923, -245449, -246976, -248503, -250030,
+ -251557, -253085, -254614, -256142, -257671, -259200, -260729, -262259,
+ -263789, -265319, -266849, -268379, -269910, -271440, -272971, -274502,
+ -276033, -277564, -279094, -280625, -282157, -283688, -285218, -286749,
+ -288280, -289811, -291342, -292872, -294403, -295933, -297463, -298993,
+ -300523, -302053, -303582, -305111, -306640, -308169, -309697, -311225,
+ -312752, -314280, -315806, -317333, -318859, -320385, -321910, -323435,
+ -324959, -326483, -328006, -329528, -331051, -332572, -334093, -335614,
+ -337133, -338652, -340171, -341689, -343206, -344722, -346238, -347753,
+ -349267, -350780, -352293, -353804, -355315, -356825, -358334, -359843,
+ -361350, -362856, -364362, -365866, -367370, -368872, -370374, -371874,
+ -373373, -374872, -376369, -377865, -379360, -380853, -382346, -383837,
+ -385327, -386816, -388304, -389790, -391275, -392759, -394242, -395723,
+ -397203, -398681, -400158, -401633, -403107, -404580, -406051, -407521,
+ -408989, -410456, -411921, -413384, -414846, -416306, -417765, -419222,
+ -420677, -422131, -423583, -425033, -426482, -427928, -429373, -430816,
+ -432258, -433697, -435135, -436570, -438004, -439436, -440866, -442294,
+ -443720, -445144, -446566, -447986, -449404, -450820, -452234, -453645,
+ -455055, -456462, -457867, -459270, -460671, -462069, -463466, -464860,
+ -466251, -467641, -469028, -470413, -471795, -473175, -474553, -475928,
+ -477300, -478671, -480038, -481404, -482766, -484127, -485484, -486839,
+ -488192, -489542, -490889, -492233, -493575, -494914, -496251, -497584,
+ -498915, -500243, -501569, -502891, -504211, -505528, -506842, -508153,
+ -509461, -510766, -512068, -513367, -514664, -515957, -517247, -518534,
+ -519818, -521099, -522377, -523652, -524924, -526192, -527457, -528719,
+ -529978, -531234, -532486, -533735, -534980, -536223, -537462, -538697,
+ -539930, -541158, -542384, -543606, -544824, -546039, -547251, -548459,
+ -549663, -550864, -552061, -553255, -554445, -555631, -556814, -557993,
+ -559169, -560340, -561508, -562672, -563833, -564989, -566142, -567291,
+ -568436, -569577, -570714, -571848, -572977, -574102, -575224, -576341,
+ -577455, -578564, -579670, -580771, -581868, -582961, -584050, -585135,
+ -586216, -587293, -588365, -589433, -590497, -591556, -592612, -593663,
+ -594709, -595752, -596790, -597823, -598852, -599877, -600898, -601913,
+ -602925, -603932, -604934, -605932, -606926, -607914, -608899, -609878,
+ -610853, -611823, -612789, -613750, -614706, -615658, -616605, -617547,
+ -618484, -619417, -620344, -621267, -622185, -623099, -624007, -624910,
+ -625809, -626702, -627591, -628474, -629353, -630226, -631095, -631959,
+ -632817, -633670, -634519, -635362, -636200, -637032, -637860, -638682,
+ -639500, -640312, -641118, -641920, -642716, -643507, -644293, -645073,
+ -645848, -646617, -647381, -648140, -648893, -649641, -650383, -651120,
+ -651852, -652578, -653298, -654013, -654722, -655426, -656124, -656816,
+ -657503, -658184, -658859, -659529, -660193, -660851, -661504, -662151,
+ -662792, -663427, -664057, -664680, -665298, -665910, -666516, -667116,
+ -667710, -668299, -668881, -669457, -670028, -670592, -671151, -671703,
+ -672250, -672790, -673324, -673852, -674374, -674890, -675400, -675904,
+ -676401, -676892, -677377, -677856, -678329, -678795, -679255, -679709,
+ -680157, -680598, -681033, -681461, -681883, -682299, -682708, -683111,
+ -683508, -683898, -684282, -684659, -685030, -685394, -685752, -686103,
+ -686447, -686785, -687117, -687442, -687760, -688072, -688377, -688675,
+ -688967, -689252, -689530, -689802, -690067, -690325, -690577, -690821,
+ -691059, -691290, -691515, -691732, -691943, -692146, -692343, -692533,
+ -692717, -692893, -693062, -693225, -693380, -693529, -693670, -693805,
+ -693932, -694053, -694167, -694273, -694373, -694465, -694550, -694628,
+ -694700, -694764, -694820, -694870, -694913, -694948, -694976, -694997,
+ -695011, -695018, -695017, -695010, -694994, -694972, -694942, -694906,
+ -694861, -694810, -694751, -694685, -694611, -694530, -694442, -694346,
+ -694243, -694133, -694015, -693890, -693757, -693617, -693469, -693314,
+ -693151, -692981, -692804, -692619, -692426, -692226, -692018, -691803,
+ -691580, -691349, -691111, -690866, -690613, -690352, -690083, -689807,
+ -689523, -689232, -688933, -688626, -688312, -687990, -687660, -687322,
+ -686977, -686624, -686263, -685895, -685518, -685134, -684742, -684343,
+ -683935, -683520, -683097, -682666, -682228, -681781, -681327, -680864,
+ -680394, -679916, -679430, -678937, -678435, -677926, -677408, -676883,
+ -676349, -675808, -675259, -674702, -674137, -673564, -672983, -672394,
+ -671797, -671192, -670579, -669958, -669329, -668692, -668047, -667394,
+ -666733, -666064, -665386, -664701, -664008, -663307, -662597, -661880,
+ -661154, -660420, -659678, -658929, -658171, -657404, -656630, -655848,
+ -655057, -654259, -653452, -652637, -651814, -650983, -650144, -649296,
+ -648440, -647577, -646705, -645824, -644936, -644039, -643135, -642222,
+ -641301, -640371, -639434, -638488, -637534, -636572, -635601, -634623,
+ -633636, -632641, -631637, -630626, -629606, -628578, -627542, -626497,
+ -625445, -624384, -623314, -622237, -621151, -620057, -618955, -617844,
+ -616726, -615599, -614463, -613320, -612168, -611008, -609839, -608663,
+ -607478, -606285, -605083, -603873, -602655, -601429, -600195, -598952,
+ -597701, -596441, -595174, -593898, -592613, -591321, -590020, -588711,
+ -587394, -586068, -584734, -583392, -582042, -580683, -579316, -577941,
+ -576557, -575166, -573766, -572357, -570941, -569516, -568083, -566641,
+ -565192, -563734, -562268, -560794, -559311, -557820, -556321, -554814,
+ -553298, -551775, -550243, -548702, -547154, -545597, -544032, -542459,
+ -540878, -539288, -537691, -536085, -534471, -532848, -531218, -529579,
+ -527932, -526277, -524614, -522943, -521263, -519575, -517879, -516175,
+ -514463, -512743, -511015, -509278, -507533, -505781, -504020, -502251,
+ -500474, -498689, -496895, -495094, -493284, -491467, -489641, -487808,
+ -485966, -484116, -482259, -480393, -478519, -476637, -474747, -472850,
+ -470944, -469030, -467108, -465179, -463241, -461295, -459342, -457380,
+ -455410, -453433, -451448, -449454, -447453, -445444, -443427, -441403,
+ -439370, -437330, -435281, -433225, -431161, -429089, -427010, -424922,
+ -422827, -420724, -418613, -416495, -414368, -412234, -410093, -407943,
+ -405786, -403621, -401449, -399268, -397081, -394885, -392682, -390471,
+ -388253, -386027, -383793, -381552, -379303, -377047, -374783, -372511,
+ -370232, -367946, -365652, -363350, -361041, -358725, -356401, -354070,
+ -351731, -349385, -347032, -344671, -342302, -339927, -337544, -335153,
+ -332756, -330351, -327939, -325519, -323092, -320658, -318217, -315768,
+ -313313, -310850, -308380, -305903, -303418, -300927, -298428, -295922,
+ -293410, -290890, -288363, -285829, -283288, -280740, -278185, -275623,
+ -273054, -270478, -267895, -265306, -262709, -260106, -257495, -254878,
+ -252254, -249623, -246986, -244341, -241690, -239032, -236368, -233696,
+ -231018, -228333, -225642, -222944, -220240, -217528, -214811, -212086,
+ -209355, -206618, -203874, -201124, -198367, -195604, -192834, -190058,
+ -187275, -184486, -181691, -178889, -176081, -173267, -170447, -167620,
+ -164787, -161948, -159102, -156251, -153393, -150529, -147659, -144783,
+ -141901, -139013, -136119, -133219, -130312, -127400, -124482, -121558,
+ -118628, -115692, -112751, -109803, -106850, -103891, -100926, -97955,
+ -94979, -91997, -89009, -86016, -83017, -80012, -77002, -73986, -70965,
+ -67938, -64906, -61868, -58825, -55776, -52722, -49662, -46598, -43527,
+ -40452, -37371, -34285, -31194, -28098, -24996, -21889, -18777, -15660,
+ -12538, -9411, -6279, -3142, 0, 3147, 6299, 9456, 12618, 15784, 18956,
+ 22132, 25313, 28499, 31690, 34885, 38085, 41290, 44499, 47713, 50931,
+ 54154, 57382, 60614, 63850, 67091, 70336, 73586, 76840, 80098, 83361,
+ 86628, 89899, 93174, 96454, 99738, 103026, 106317, 109613, 112913,
+ 116218, 119526, 122838, 126153, 129473, 132797, 136125, 139456, 142791,
+ 146130, 149473, 152819, 156169, 159522, 162880, 166241, 169605, 172973,
+ 176344, 179719, 183097, 186479, 189864, 193252, 196644, 200039, 203437,
+ 206839, 210243, 213651, 217062, 220476, 223893, 227313, 230736, 234162,
+ 237591, 241023, 244457, 247895, 251335, 254779, 258224, 261673, 265124,
+ 268578, 272035, 275494, 278956, 282420, 285887, 289356, 292828, 296302,
+ 299778, 303257, 306738, 310221, 313706, 317194, 320684, 324176, 327670,
+ 331166, 334664, 338164, 341666, 345170, 348676, 352184, 355693, 359205,
+ 362718, 366233, 369749, 373268, 376787, 380309, 383832, 387356, 390882,
+ 394410, 397938, 401469, 405000, 408533, 412067, 415602, 419139, 422677,
+ 426216, 429755, 433296, 436839, 440382, 443926, 447470, 451016, 454563,
+ 458110, 461659, 465208, 468757, 472308, 475859, 479410, 482962, 486515,
+ 490068, 493622, 497176, 500730, 504285, 507840, 511395, 514951, 518507,
+ 522062, 525618, 529175, 532731, 536287, 539843, 543399, 546955, 550511,
+ 554067, 557622, 561177, 564732, 568287, 571841, 575395, 578948, 582501,
+ 586054, 589605, 593157, 596707, 600257, 603807, 607355, 610903, 614450,
+ 617996, 621541, 625085, 628629, 632171, 635712, 639252, 642791, 646329,
+ 649866, 653401, 656936, 660468, 664000, 667530, 671059, 674586, 678111,
+ 681636, 685158, 688679, 692198, 695716, 699232, 702746, 706258, 709768,
+ 713276, 716783, 720287, 723790, 727290, 730789, 734285, 737779, 741271,
+ 744760, 748247, 751732, 755215, 758695, 762172, 765648, 769120, 772590,
+ 776058, 779522, 782984, 786444, 789900, 793354, 796805, 800253, 803698,
+ 807140, 810579, 814015, 817448, 820878, 824304, 827728, 831148, 834565,
+ 837978, 841388, 844795, 848198, 851598, 854994, 858387, 861776, 865161,
+ 868543, 871921, 875295, 878665, 882031, 885394, 888752, 892107, 895458,
+ 898804, 902146, 905485, 908819, 912148, 915474, 918795, 922112, 925425,
+ 928733, 932036, 935335, 938630, 941920, 945205, 948485, 951761, 955032,
+ 958299, 961560, 964816, 968068, 971315, 974556, 977793, 981025, 984251,
+ 987472, 990688, 993899, 997104, 1000304, 1003499, 1006689, 1009872,
+ 1013051, 1016224, 1019391, 1022552, 1025708, 1028859, 1032003, 1035142,
+ 1038275, 1041402, 1044523, 1047638, 1050747, 1053851, 1056948, 1060039,
+ 1063123, 1066202, 1069274, 1072341, 1075400, 1078454, 1081501, 1084541,
+ 1087576, 1090603, 1093624, 1096639, 1099646, 1102647, 1105642, 1108629,
+ 1111610, 1114584, 1117551, 1120511, 1123465, 1126411, 1129350, 1132282,
+ 1135207, 1138125, 1141035, 1143938, 1146834, 1149723, 1152604, 1155478,
+ 1158344, 1161203, 1164055, 1166898, 1169735, 1172563, 1175384, 1178197,
+ 1181002, 1183800, 1186589, 1189371, 1192145, 1194910, 1197668, 1200418,
+ 1203159, 1205893, 1208618, 1211335, 1214044, 1216745, 1219437, 1222121,
+ 1224796, 1227463, 1230121, 1232771, 1235412, 1238045, 1240669, 1243284,
+ 1245891, 1248489, 1251078, 1253658, 1256229, 1258792, 1261345, 1263889,
+ 1266425, 1268951, 1271468, 1273976, 1276475, 1278964, 1281444, 1283915,
+ 1286377, 1288829, 1291271, 1293704, 1296128, 1298542, 1300947, 1303342,
+ 1305727, 1308102, 1310468, 1312824, 1315170, 1317506, 1319833, 1322149,
+ 1324456, 1326752, 1329038, 1331315, 1333581, 1335837, 1338083, 1340318,
+ 1342544, 1344758, 1346963, 1349157, 1351341, 1353514, 1355677, 1357829,
+ 1359971, 1362102, 1364223, 1366332, 1368431, 1370520, 1372597, 1374664,
+ 1376719, 1378764, 1380798, 1382821, 1384833, 1386834, 1388823, 1390802,
+ 1392770, 1394726, 1396671, 1398604, 1400527, 1402438, 1404338, 1406226,
+ 1408103, 1409968, 1411822, 1413664, 1415495, 1417314, 1419121, 1420917,
+ 1422701, 1424473, 1426233, 1427982, 1429719, 1431443, 1433156, 1434857,
+ 1436546, 1438223, 1439887, 1441540, 1443180, 1444809, 1446425, 1448028,
+ 1449620, 1451199, 1452766, 1454320, 1455862, 1457392, 1458909, 1460414,
+ 1461906, 1463385, 1464852, 1466306, 1467748, 1469177, 1470593, 1471996,
+ 1473386, 1474764, 1476129, 1477480, 1478819, 1480145, 1481458, 1482758,
+ 1484045, 1485319, 1486579, 1487827, 1489061, 1490282, 1491490, 1492684,
+ 1493865, 1495033, 1496187, 1497328, 1498456, 1499570, 1500671, 1501758,
+ 1502831, 1503891, 1504938, 1505970, 1506989, 1507995, 1508986, 1509964,
+ 1510928, 1511878, 1512814, 1513737, 1514645, 1515540, 1516420, 1517287,
+ 1518139, 1518978, 1519802, 1520613, 1521409, 1522191, 1522959, 1523712,
+ 1524451, 1525177, 1525887, 1526584, 1527266, 1527933, 1528587, 1529225,
+ 1529850, 1530460, 1531055, 1531636, 1532202, 1532754, 1533291, 1533813,
+ 1534321, 1534814, 1535292, 1535755, 1536204, 1536638, 1537057, 1537461,
+ 1537851, 1538225, 1538585, 1538929, 1539259, 1539574, 1539873, 1540158,
+ 1540427, 1540682, 1540921, 1541145, 1541354, 1541548, 1541726, 1541890,
+ 1542038, 1542171, 1542288, 1542390, 1542477, 1542549, 1542605, 1542646,
+ 1542671, 1542681, 1542675, 1542654, 1542617, 1542565, 1542497, 1542414,
+ 1542315, 1542200, 1542070, 1541924, 1541763, 1541586, 1541393, 1541184,
+ 1540959, 1540719, 1540463, 1540191, 1539904, 1539600, 1539281, 1538945,
+ 1538594, 1538227, 1537844, 1537445, 1537030, 1536599, 1536152, 1535689,
+ 1535209, 1534714, 1534203, 1533676, 1533132, 1532572, 1531997, 1531405,
+ 1530796, 1530172, 1529531, 1528875, 1528202, 1527512, 1526807, 1526085,
+ 1525347, 1524592, 1523821, 1523034, 1522230, 1521411, 1520574, 1519721,
+ 1518852, 1517967, 1517065, 1516146, 1515211, 1514260, 1513292, 1512307,
+ 1511306, 1510289, 1509255, 1508204, 1507137, 1506053, 1504953, 1503836,
+ 1502702, 1501552, 1500385, 1499201, 1498001, 1496784, 1495551, 1494300,
+ 1493033, 1491750, 1490449, 1489132, 1487798, 1486448, 1485080, 1483696,
+ 1482295, 1480878, 1479443, 1477992, 1476524, 1475039, 1473537, 1472019,
+ 1470483, 1468931, 1467362, 1465776, 1464173, 1462554, 1460917, 1459264,
+ 1457593, 1455906, 1454202, 1452481, 1450743, 1448988, 1447217, 1445428,
+ 1443622, 1441800, 1439960, 1438104, 1436230, 1434340, 1432433, 1430508,
+ 1428567, 1426609, 1424634, 1422642, 1420633, 1418607, 1416564, 1414504,
+ 1412427, 1410333, 1408222, 1406094, 1403949, 1401787, 1399608, 1397412,
+ 1395199, 1392969, 1390722, 1388459, 1386178, 1383880, 1381565, 1379233,
+ 1376884, 1374519, 1372136, 1369736, 1367320, 1364886, 1362435, 1359968,
+ 1357483, 1354981, 1352463, 1349927, 1347375, 1344805, 1342219, 1339616,
+ 1336995, 1334358, 1331704, 1329033, 1326345, 1323640, 1320918, 1318179,
+ 1315424, 1312651, 1309862, 1307055, 1304232, 1301392, 1298535, 1295661,
+ 1292770, 1289863, 1286938, 1283997, 1281039, 1278064, 1275073, 1272064,
+ 1269039, 1265997, 1262938, 1259862, 1256770, 1253661, 1250535, 1247392,
+ 1244233, 1241057, 1237864, 1234654, 1231428, 1228185, 1224926, 1221650,
+ 1218357, 1215047, 1211721, 1208379, 1205020, 1201644, 1198251, 1194842,
+ 1191417, 1187975, 1184516, 1181041, 1177550, 1174042, 1170517, 1166977,
+ 1163419, 1159845, 1156255, 1152649, 1149026, 1145387, 1141731, 1138059,
+ 1134371, 1130666, 1126945, 1123208, 1119455, 1115685, 1111900, 1108098,
+ 1104279, 1100445, 1096595, 1092728, 1088845, 1084947, 1081032, 1077101,
+ 1073154, 1069191, 1065212, 1061217, 1057206, 1053179, 1049136, 1045078,
+ 1041003, 1036913, 1032807, 1028685, 1024547, 1020393, 1016224, 1012039,
+ 1007838, 1003622, 999389, 995142, 990878, 986599, 982305, 977995,
+ 973669, 969328, 964971, 960599, 956212, 951809, 947391, 942957, 938508,
+ 934044, 929564, 925069, 920559, 916034, 911494, 906938, 902368, 897782,
+ 893181, 888565, 883934, 879288, 874627, 869952, 865261, 860555, 855835,
+ 851100, 846350, 841585, 836806, 832011, 827202, 822379, 817541, 812688,
+ 807821, 802939, 798043, 793132, 788207, 783267, 778313, 773345, 768362,
+ 763365, 758354, 753329, 748289, 743236, 738168, 733086, 727990, 722880,
+ 717756, 712618, 707467, 702301, 697122, 691928, 686721, 681501, 676266,
+ 671018, 665756, 660481, 655192, 649890, 644574, 639244, 633902, 628545,
+ 623176, 617793, 612397, 606988, 601565, 596130, 590681, 585219, 579744,
+ 574257, 568756, 563242, 557715, 552176, 546624, 541059, 535481, 529891,
+ 524288, 518672, 513044, 507403, 501750, 496084, 490406, 484716, 479013,
+ 473298, 467571, 461832, 456080, 450317, 444541, 438753, 432954, 427142,
+ 421318, 415483, 409636, 403777, 397907, 392024, 386131, 380225, 374308,
+ 368380, 362440, 356489, 350526, 344552, 338567, 332571, 326563, 320544,
+ 314515, 308474, 302422, 296360, 290286, 284202, 278107, 272001, 265884,
+ 259757, 253619, 247471, 241312, 235143, 228963, 222773, 216573, 210362,
+ 204141, 197911, 191670, 185419, 179157, 172886, 166606, 160315, 154014,
+ 147704, 141384, 135054, 128715, 122367, 116008, 109641, 103264, 96877,
+ 90482, 84077, 77663, 71240, 64808, 58366, 51916, 45457, 38989, 32513,
+ 26027, 19533, 13031, 6519, 0, -6528, -13064, -19609, -26163, -32724,
+ -39294, -45872, -52458, -59052, -65654, -72263, -78881, -85507, -92140,
+ -98781, -105429, -112085, -118748, -125419, -132098, -138783, -145476,
+ -152176, -158884, -165598, -172319, -179048, -185783, -192525, -199274,
+ -206030, -212792, -219561, -226337, -233119, -239907, -246702, -253503,
+ -260310, -267124, -273944, -280770, -287601, -294439, -301283, -308132,
+ -314987, -321848, -328715, -335587, -342464, -349347, -356236, -363130,
+ -370029, -376933, -383842, -390757, -397676, -404600, -411530, -418464,
+ -425403, -432346, -439294, -446247, -453204, -460166, -467132, -474102,
+ -481076, -488055, -495038, -502024, -509015, -516010, -523008, -530011,
+ -537017, -544026, -551040, -558056, -565076, -572100, -579127, -586157,
+ -593190, -600227, -607266, -614308, -621354, -628402, -635453, -642506,
+ -649563, -656621, -663683, -670746, -677813, -684881, -691952, -699024,
+ -706099, -713176, -720255, -727336, -734418, -741502, -748588, -755676,
+ -762765, -769856, -776947, -784041, -791135, -798231, -805328, -812426,
+ -819524, -826624, -833725, -840826, -847928, -855031, -862134, -869237,
+ -876341, -883446, -890550, -897655, -904760, -911865, -918970, -926075,
+ -933180, -940284, -947389, -954492, -961596, -968698, -975801, -982902,
+ -990003, -997103, -1004202, -1011300, -1018397, -1025493, -1032588,
+ -1039681, -1046774, -1053864, -1060954, -1068042, -1075128, -1082212,
+ -1089295, -1096376, -1103455, -1110531, -1117606, -1124679, -1131750,
+ -1138818, -1145884, -1152947, -1160008, -1167066, -1174122, -1181175,
+ -1188225, -1195272, -1202317, -1209358, -1216396, -1223431, -1230463,
+ -1237491, -1244516, -1251537, -1258555, -1265570, -1272580, -1279587,
+ -1286590, -1293589, -1300584, -1307575, -1314562, -1321544, -1328522,
+ -1335496, -1342465, -1349430, -1356390, -1363346, -1370297, -1377243,
+ -1384183, -1391119, -1398050, -1404976, -1411897, -1418812, -1425722,
+ -1432626, -1439525, -1446418, -1453306, -1460187, -1467063, -1473933,
+ -1480797, -1487655, -1494507, -1501353, -1508192, -1515025, -1521852,
+ -1528672, -1535485, -1542292, -1549092, -1555885, -1562671, -1569450,
+ -1576222, -1582987, -1589745, -1596496, -1603239, -1609974, -1616703,
+ -1623423, -1630136, -1636841, -1643538, -1650228, -1656909, -1663582,
+ -1670247, -1676904, -1683553, -1690193, -1696825, -1703448, -1710063,
+ -1716669, -1723266, -1729854, -1736434, -1743004, -1749565, -1756118,
+ -1762661, -1769194, -1775719, -1782233, -1788739, -1795234, -1801720,
+ -1808197, -1814663, -1821119, -1827566, -1834002, -1840429, -1846845,
+ -1853250, -1859646, -1866030, -1872405, -1878768, -1885121, -1891464,
+ -1897795, -1904115, -1910425, -1916723, -1923010, -1929286, -1935551,
+ -1941804, -1948046, -1954276, -1960495, -1966702, -1972897, -1979081,
+ -1985252, -1991411, -1997559, -2003694, -2009817, -2015927, -2022026,
+ -2028111, -2034185, -2040245, -2046293, -2052328, -2058351, -2064360,
+ -2070357, -2076340, -2082310, -2088267, -2094211, -2100141, -2106058,
+ -2111961, -2117851, -2123727, -2129589, -2135438, -2141272, -2147093,
+ -2152899, -2158692, -2164470, -2170234, -2175983, -2181718, -2187439,
+ -2193145, -2198836, -2204512, -2210174, -2215821, -2221453, -2227070,
+ -2232671, -2238258, -2243829, -2249385, -2254926, -2260451, -2265960,
+ -2271454, -2276932, -2282395, -2287841, -2293272, -2298686, -2304085,
+ -2309467, -2314833, -2320183, -2325517, -2330834, -2336134, -2341418,
+ -2346685, -2351936, -2357169, -2362386, -2367586, -2372769, -2377934,
+ -2383083, -2388214, -2393328, -2398425, -2403504, -2408565, -2413609,
+ -2418635, -2423644, -2428635, -2433607, -2438562, -2443499, -2448417,
+ -2453318, -2458200, -2463064, -2467909, -2472736, -2477545, -2482335,
+ -2487106, -2491858, -2496592, -2501307, -2506002, -2510679, -2515337,
+ -2519975, -2524594, -2529194, -2533775, -2538336, -2542877, -2547399,
+ -2551902, -2556384, -2560847, -2565290, -2569713, -2574116, -2578499,
+ -2582861, -2587204, -2591526, -2595828, -2600110, -2604371, -2608611,
+ -2612831, -2617030, -2621209, -2625366, -2629503, -2633619, -2637714,
+ -2641787, -2645840, -2649871, -2653881, -2657870, -2661838, -2665783,
+ -2669708, -2673610, -2677492, -2681351, -2685188, -2689004, -2692798,
+ -2696570, -2700319, -2704047, -2707752, -2711435, -2715096, -2718734,
+ -2722350, -2725944, -2729515, -2733063, -2736589, -2740092, -2743572,
+ -2747029, -2750463, -2753874, -2757262, -2760627, -2763969, -2767288,
+ -2770583, -2773855, -2777103, -2780328, -2783530, -2786708, -2789862,
+ -2792992, -2796099, -2799181, -2802240, -2805275, -2808286, -2811273,
+ -2814235, -2817174, -2820088, -2822978, -2825843, -2828684, -2831501,
+ -2834293, -2837060, -2839803, -2842521, -2845214, -2847882, -2850525,
+ -2853144, -2855737, -2858306, -2860849, -2863367, -2865860, -2868328,
+ -2870770, -2873187, -2875578, -2877944, -2880285, -2882599, -2884889,
+ -2887152, -2889390, -2891601, -2893787, -2895947, -2898081, -2900189,
+ -2902271, -2904327, -2906356, -2908360, -2910337, -2912288, -2914212,
+ -2916110, -2917981, -2919826, -2921644, -2923436, -2925201, -2926939,
+ -2928650, -2930335, -2931992, -2933623, -2935227, -2936803, -2938353,
+ -2939875, -2941371, -2942839, -2944280, -2945693, -2947079, -2948438,
+ -2949769, -2951073, -2952349, -2953598, -2954819, -2956012, -2957177,
+ -2958315, -2959425, -2960507, -2961562, -2962588, -2963586, -2964556,
+ -2965499, -2966413, -2967298, -2968156, -2968986, -2969787, -2970560,
+ -2971304, -2972020, -2972708, -2973367, -2973997, -2974599, -2975173,
+ -2975717, -2976234, -2976721, -2977179, -2977609, -2978010, -2978382,
+ -2978725, -2979039, -2979325, -2979581, -2979808, -2980006, -2980175,
+ -2980314, -2980425, -2980506, -2980558, -2980580, -2980574, -2980537,
+ -2980472, -2980377, -2980252, -2980098, -2979915, -2979702, -2979459,
+ -2979186, -2978884, -2978552, -2978191, -2977799, -2977378, -2976927,
+ -2976446, -2975936, -2975395, -2974824, -2974224, -2973593, -2972932,
+ -2972241, -2971520, -2970769, -2969988, -2969177, -2968335, -2967463,
+ -2966561, -2965629, -2964666, -2963673, -2962650, -2961596, -2960511,
+ -2959397, -2958252, -2957076, -2955870, -2954633, -2953366, -2952068,
+ -2950739, -2949380, -2947990, -2946570, -2945119, -2943637, -2942124,
+ -2940581, -2939007, -2937402, -2935766, -2934099, -2932402, -2930673,
+ -2928914, -2927124, -2925303, -2923451, -2921567, -2919653, -2917708,
+ -2915732, -2913725, -2911687, -2909618, -2907517, -2905386, -2903223,
+ -2901030, -2898805, -2896549, -2894262, -2891944, -2889594, -2887213,
+ -2884801, -2882358, -2879884, -2877378, -2874841, -2872273, -2869673,
+ -2867042, -2864380, -2861687, -2858962, -2856206, -2853418, -2850599,
+ -2847749, -2844868, -2841955, -2839010, -2836034, -2833027, -2829989,
+ -2826919, -2823817, -2820684, -2817520, -2814325, -2811097, -2807839,
+ -2804549, -2801227, -2797874, -2794490, -2791074, -2787627, -2784148,
+ -2780638, -2777096, -2773523, -2769918, -2766282, -2762615, -2758916,
+ -2755185, -2751423, -2747630, -2743805, -2739949, -2736061, -2732142,
+ -2728191, -2724209, -2720195, -2716150, -2712073, -2707966, -2703826,
+ -2699655, -2695453, -2691220, -2686954, -2682658, -2678330, -2673971,
+ -2669580, -2665158, -2660705, -2656220, -2651704, -2647157, -2642578,
+ -2637968, -2633327, -2628654, -2623951, -2619215, -2614449, -2609651,
+ -2604822, -2599962, -2595071, -2590148, -2585194, -2580209, -2575193,
+ -2570146, -2565068, -2559958, -2554818, -2549646, -2544443, -2539209,
+ -2533944, -2528648, -2523322, -2517964, -2512575, -2507155, -2501704,
+ -2496223, -2490710, -2485167, -2479593, -2473987, -2468352, -2462685,
+ -2456987, -2451259, -2445500, -2439711, -2433890, -2428039, -2422158,
+ -2416245, -2410303, -2404329, -2398325, -2392291, -2386226, -2380130,
+ -2374005, -2367848, -2361662, -2355445, -2349197, -2342920, -2336612,
+ -2330274, -2323906, -2317507, -2311078, -2304619, -2298131, -2291612,
+ -2285063, -2278484, -2271875, -2265236, -2258567, -2251868, -2245139,
+ -2238381, -2231593, -2224775, -2217927, -2211050, -2204143, -2197207,
+ -2190241, -2183245, -2176220, -2169165, -2162081, -2154968, -2147825,
+ -2140653, -2133451, -2126221, -2118961, -2111672, -2104354, -2097007,
+ -2089631, -2082226, -2074791, -2067328, -2059836, -2052316, -2044766,
+ -2037188, -2029581, -2021945, -2014281, -2006588, -1998867, -1991117,
+ -1983339, -1975532, -1967697, -1959834, -1951942, -1944022, -1936074,
+ -1928098, -1920094, -1912062, -1904002, -1895914, -1887798, -1879654,
+ -1871482, -1863283, -1855056, -1846802, -1838519, -1830210, -1821873,
+ -1813508, -1805116, -1796697, -1788251, -1779777, -1771276, -1762748,
+ -1754193, -1745611, -1737002, -1728367, -1719704, -1711015, -1702298,
+ -1693556, -1684786, -1675991, -1667168, -1658320, -1649444, -1640543,
+ -1631615, -1622661, -1613681, -1604675, -1595643, -1586585, -1577501,
+ -1568392, -1559256, -1550095, -1540908, -1531696, -1522458, -1513194,
+ -1503906, -1494592, -1485252, -1475888, -1466498, -1457083, -1447644,
+ -1438179, -1428690, -1419175, -1409636, -1400072, -1390484, -1380871,
+ -1371234, -1361572, -1351886, -1342176, -1332442, -1322683, -1312900,
+ -1303094, -1293263, -1283409, -1273531, -1263629, -1253704, -1243755,
+ -1233783, -1223787, -1213768, -1203725, -1193660, -1183571, -1173459,
+ -1163325, -1153167, -1142987, -1132784, -1122558, -1112310, -1102039,
+ -1091746, -1081430, -1071092, -1060732, -1050350, -1039946, -1029520,
+ -1019072, -1008602, -998111, -987597, -977063, -966507, -955929,
+ -945330, -934710, -924069, -913407, -902723, -892019, -881294, -870548,
+ -859782, -848995, -838188, -827360, -816512, -805643, -794755, -783846,
+ -772918, -761969, -751001, -740013, -729006, -717979, -706932, -695866,
+ -684781, -673677, -662553, -651411, -640250, -629069, -617871, -606653,
+ -595417, -584163, -572890, -561599, -550289, -538962, -527616, -516253,
+ -504872, -493473, -482057, -470623, -459171, -447702, -436216, -424713,
+ -413193, -401656, -390102, -378531, -366943, -355339, -343719, -332082,
+ -320428, -308759, -297073, -285372, -273655, -261921, -250173, -238408,
+ -226628, -214833, -203022, -191196, -179355, -167499, -155629, -143743,
+ -131843, -119928, -107998, -96055, -84097, -72124, -60138, -48138,
+ -36124, -24096, -12055, 0, 12068, 24150, 36245, 48353, 60474, 72608,
+ 84755, 96915, 109087, 121272, 133469, 145679, 157900, 170134, 182379,
+ 194637, 206906, 219187, 231479, 243783, 256098, 268424, 280761, 293110,
+ 305469, 317838, 330219, 342610, 355011, 367423, 379845, 392277, 404719,
+ 417171, 429632, 442103, 454584, 467074, 479573, 492082, 504599, 517126,
+ 529661, 542205, 554758, 567319, 579888, 592466, 605052, 617646, 630248,
+ 642857, 655475, 668099, 680732, 693371, 706018, 718672, 731332, 744000,
+ 756674, 769355, 782043, 794737, 807437, 820143, 832855, 845573, 858297,
+ 871027, 883762, 896502, 909248, 921999, 934755, 947516, 960282, 973052,
+ 985827, 998607, 1011391, 1024179, 1036971, 1049767, 1062567, 1075370,
+ 1088177, 1100988, 1113802, 1126619, 1139439, 1152262, 1165088, 1177917,
+ 1190749, 1203583, 1216419, 1229257, 1242098, 1254940, 1267784, 1280631,
+ 1293478, 1306327, 1319178, 1332029, 1344882, 1357736, 1370591, 1383446,
+ 1396302, 1409158, 1422015, 1434872, 1447729, 1460586, 1473442, 1486299,
+ 1499155, 1512010, 1524865, 1537719, 1550572, 1563424, 1576274, 1589124,
+ 1601971, 1614818, 1627662, 1640505, 1653346, 1666184, 1679021, 1691855,
+ 1704686, 1717515, 1730341, 1743165, 1755985, 1768802, 1781616, 1794426,
+ 1807233, 1820036, 1832836, 1845631, 1858422, 1871210, 1883993, 1896771,
+ 1909545, 1922314, 1935078, 1947837, 1960591, 1973340, 1986084, 1998822,
+ 2011554, 2024281, 2037001, 2049716, 2062424, 2075126, 2087822, 2100511,
+ 2113194, 2125869, 2138538, 2151199, 2163853, 2176500, 2189140, 2201771,
+ 2214395, 2227011, 2239619, 2252219, 2264811, 2277394, 2289968, 2302534,
+ 2315091, 2327639, 2340177, 2352707, 2365227, 2377738, 2390239, 2402730,
+ 2415212, 2427683, 2440144, 2452595, 2465035, 2477465, 2489884, 2502292,
+ 2514689, 2527075, 2539450, 2551813, 2564165, 2576505, 2588834, 2601150,
+ 2613454, 2625746, 2638026, 2650294, 2662548, 2674790, 2687019, 2699235,
+ 2711438, 2723628, 2735804, 2747967, 2760116, 2772251, 2784372, 2796479,
+ 2808572, 2820650, 2832714, 2844763, 2856798, 2868818, 2880822, 2892812,
+ 2904786, 2916744, 2928687, 2940615, 2952526, 2964422, 2976301, 2988164,
+ 3000011, 3011841, 3023655, 3035451, 3047231, 3058994, 3070739, 3082467,
+ 3094178, 3105871, 3117547, 3129204, 3140843, 3152465, 3164068, 3175652,
+ 3187219, 3198766, 3210294, 3221804, 3233295, 3244766, 3256218, 3267650,
+ 3279063, 3290456, 3301829, 3313183, 3324516, 3335828, 3347121, 3358392,
+ 3369643, 3380874, 3392083, 3403271, 3414438, 3425584, 3436708, 3447810,
+ 3458891, 3469950, 3480986, 3492001, 3502993, 3513963, 3524911, 3535835,
+ 3546737, 3557616, 3568472, 3579304, 3590114, 3600899, 3611661, 3622400,
+ 3633114, 3643805, 3654471, 3665113, 3675731, 3686324, 3696893, 3707436,
+ 3717955, 3728449, 3738918, 3749361, 3759779, 3770171, 3780537, 3790878,
+ 3801193, 3811481, 3821744, 3831980, 3842189, 3852372, 3862528, 3872658,
+ 3882760, 3892835, 3902883, 3912904, 3922897, 3932862, 3942800, 3952710,
+ 3962591, 3972445, 3982270, 3992067, 4001835, 4011575, 4021286, 4030968,
+ 4040621, 4050245, 4059839, 4069404, 4078940, 4088445, 4097922, 4107368,
+ 4116784, 4126170, 4135525, 4144850, 4154145, 4163409, 4172642, 4181845,
+ 4191016, 4200156, 4209265, 4218342, 4227388, 4236402, 4245385, 4254335,
+ 4263254, 4272140, 4280994, 4289816, 4298605, 4307361, 4316085, 4324776,
+ 4333434, 4342059, 4350650, 4359209, 4367733, 4376225, 4384682, 4393106,
+ 4401495, 4409851, 4418172, 4426459, 4434712, 4442930, 4451114, 4459262,
+ 4467376, 4475455, 4483499, 4491507, 4499480, 4507418, 4515320, 4523186,
+ 4531016, 4538811, 4546569, 4554292, 4561978, 4569627, 4577240, 4584817,
+ 4592356, 4599859, 4607325, 4614754, 4622146, 4629500, 4636817, 4644097,
+ 4651338, 4658542, 4665709, 4672837, 4679927, 4686979, 4693992, 4700968,
+ 4707904, 4714802, 4721662, 4728482, 4735264, 4742006, 4748710, 4755374,
+ 4761999, 4768584, 4775129, 4781635, 4788101, 4794528, 4800914, 4807260,
+ 4813566, 4819831, 4826056, 4832241, 4838385, 4844488, 4850550, 4856571,
+ 4862552, 4868491, 4874389, 4880245, 4886060, 4891834, 4897565, 4903255,
+ 4908904, 4914510, 4920074, 4925596, 4931076, 4936513, 4941908, 4947261,
+ 4952570, 4957837, 4963062, 4968243, 4973381, 4978476, 4983528, 4988537,
+ 4993502, 4998423, 5003301, 5008136, 5012926, 5017673, 5022375, 5027034,
+ 5031649, 5036219, 5040745, 5045226, 5049663, 5054055, 5058403, 5062706,
+ 5066963, 5071176, 5075344, 5079467, 5083544, 5087577, 5091563, 5095505,
+ 5099400, 5103250, 5107055, 5110813, 5114526, 5118192, 5121812, 5125387,
+ 5128915, 5132396, 5135831, 5139220, 5142562, 5145858, 5149106, 5152308,
+ 5155463, 5158571, 5161632, 5164646, 5167612, 5170532, 5173403, 5176228,
+ 5179005, 5181734, 5184415, 5187049, 5189635, 5192173, 5194663, 5197105,
+ 5199499, 5201845, 5204142, 5206391, 5208591, 5210743, 5212847, 5214902,
+ 5216908, 5218865, 5220773, 5222633, 5224443, 5226205, 5227917, 5229580,
+ 5231194, 5232759, 5234274, 5235740, 5237156, 5238522, 5239839, 5241106,
+ 5242324, 5243491, 5244609, 5245676, 5246694, 5247661, 5248579, 5249446,
+ 5250263, 5251029, 5251745, 5252411, 5253026, 5253590, 5254104, 5254567,
+ 5254980, 5255341, 5255652, 5255912, 5256121, 5256279, 5256385, 5256441,
+ 5256445, 5256398, 5256300, 5256151, 5255950, 5255698, 5255394, 5255039,
+ 5254632, 5254173, 5253663, 5253101, 5252487, 5251821, 5251104, 5250334,
+ 5249513, 5248639, 5247714, 5246736, 5245706, 5244624, 5243490, 5242303,
+ 5241064, 5239773, 5238430, 5237033, 5235585, 5234084, 5232530, 5230924,
+ 5229265, 5227553, 5225789, 5223972, 5222102, 5220179, 5218204, 5216175,
+ 5214094, 5211959, 5209772, 5207532, 5205238, 5202892, 5200492, 5198039,
+ 5195533, 5192974, 5190361, 5187695, 5184976, 5182204, 5179378, 5176499,
+ 5173567, 5170581, 5167541, 5164448, 5161302, 5158102, 5154848, 5151541,
+ 5148180, 5144766, 5141298, 5137776, 5134201, 5130572, 5126889, 5123152,
+ 5119362, 5115518, 5111620, 5107668, 5103663, 5099604, 5095490, 5091323,
+ 5087102, 5082827, 5078499, 5074116, 5069679, 5065189, 5060644, 5056046,
+ 5051393, 5046687, 5041926, 5037112, 5032243, 5027321, 5022344, 5017313,
+ 5012229, 5007090, 5001897, 4996651, 4991350, 4985995, 4980586, 4975123,
+ 4969606, 4964035, 4958410, 4952730, 4946997, 4941210, 4935368, 4929473,
+ 4923523, 4917520, 4911462, 4905351, 4899185, 4892965, 4886691, 4880364,
+ 4873982, 4867546, 4861056, 4854513, 4847915, 4841263, 4834558, 4827798,
+ 4820985, 4814117, 4807196, 4800221, 4793192, 4786109, 4778972, 4771782,
+ 4764537, 4757239, 4749887, 4742482, 4735022, 4727509, 4719942, 4712322,
+ 4704647, 4696919, 4689138, 4681303, 4673414, 4665472, 4657476, 4649427,
+ 4641324, 4633168, 4624959, 4616696, 4608380, 4600010, 4591587, 4583111,
+ 4574581, 4565998, 4557362, 4548673, 4539931, 4531136, 4522287, 4513386,
+ 4504432, 4495424, 4486364, 4477251, 4468085, 4458866, 4449594, 4440270,
+ 4430893, 4421463, 4411981, 4402446, 4392858, 4383218, 4373526, 4363781,
+ 4353984, 4344134, 4334232, 4324278, 4314272, 4304213, 4294103, 4283940,
+ 4273726, 4263459, 4253140, 4242770, 4232348, 4221874, 4211348, 4200771,
+ 4190142, 4179462, 4168730, 4157946, 4147112, 4136226, 4125288, 4114299,
+ 4103260, 4092169, 4081027, 4069834, 4058590, 4047295, 4035950, 4024553,
+ 4013106, 4001608, 3990060, 3978461, 3966812, 3955113, 3943363, 3931563,
+ 3919712, 3907812, 3895861, 3883861, 3871810, 3859710, 3847560, 3835360,
+ 3823111, 3810812, 3798464, 3786066, 3773619, 3761122, 3748576, 3735982,
+ 3723338, 3710645, 3697903, 3685113, 3672273, 3659385, 3646449, 3633463,
+ 3620430, 3607348, 3594218, 3581039, 3567813, 3554538, 3541216, 3527845,
+ 3514427, 3500961, 3487448, 3473887, 3460278, 3446623, 3432919, 3419169,
+ 3405372, 3391527, 3377636, 3363698, 3349713, 3335682, 3321604, 3307479,
+ 3293308, 3279091, 3264828, 3250519, 3236163, 3221762, 3207315, 3192822,
+ 3178284, 3163700, 3149070, 3134396, 3119676, 3104911, 3090101, 3075246,
+ 3060346, 3045402, 3030413, 3015379, 3000301, 2985179, 2970013, 2954802,
+ 2939548, 2924249, 2908907, 2893521, 2878092, 2862619, 2847103, 2831544,
+ 2815941, 2800296, 2784607, 2768876, 2753102, 2737286, 2721427, 2705526,
+ 2689582, 2673597, 2657569, 2641500, 2625389, 2609236, 2593042, 2576806,
+ 2560529, 2544211, 2527852, 2511452, 2495011, 2478530, 2462007, 2445445,
+ 2428842, 2412199, 2395516, 2378793, 2362030, 2345227, 2328385, 2311504,
+ 2294583, 2277622, 2260623, 2243585, 2226508, 2209393, 2192239, 2175046,
+ 2157815, 2140546, 2123239, 2105895, 2088512, 2071092, 2053634, 2036139,
+ 2018607, 2001037, 1983431, 1965788, 1948108, 1930392, 1912639, 1894850,
+ 1877025, 1859164, 1841267, 1823335, 1805366, 1787363, 1769324, 1751250,
+ 1733141, 1714997, 1696819, 1678606, 1660358, 1642077, 1623761, 1605411,
+ 1587027, 1568610, 1550159, 1531675, 1513157, 1494607, 1476023, 1457407,
+ 1438758, 1420077, 1401363, 1382617, 1363839, 1345030, 1326188, 1307315,
+ 1288411, 1269475, 1250508, 1231510, 1212482, 1193422, 1174333, 1155213,
+ 1136063, 1116882, 1097672, 1078433, 1059163, 1039865, 1020537, 1001180,
+ 981794, 962380, 942937, 923466, 903966, 884438, 864883, 845300, 825689,
+ 806050, 786385, 766692, 746973, 727227, 707454, 687655, 667829, 647978,
+ 628100, 608197, 588268, 568314, 548335, 528331, 508301, 488247, 468169,
+ 448066, 427939, 407788, 387614, 367415, 347193, 326948, 306680, 286388,
+ 266074, 245737, 225378, 204997, 184594, 164168, 143721, 123253, 102763,
+ 82252, 61720, 41167, 20593, 0, -20614, -41248, -61902, -82576, -103269,
+ -123982, -144714, -165465, -186234, -207023, -227829, -248654, -269497,
+ -290358, -311236, -332132, -353045, -373976, -394923, -415887, -436868,
+ -457864, -478877, -499906, -520951, -542012, -563087, -584178, -605284,
+ -626405, -647540, -668690, -689854, -711032, -732224, -753430, -774649,
+ -795881, -817127, -838385, -859656, -880939, -902235, -923543, -944863,
+ -966194, -987537, -1008891, -1030256, -1051632, -1073019, -1094417,
+ -1115824, -1137242, -1158670, -1180107, -1201554, -1223010, -1244475,
+ -1265949, -1287432, -1308924, -1330423, -1351931, -1373446, -1394970,
+ -1416500, -1438038, -1459583, -1481135, -1502694, -1524259, -1545830,
+ -1567407, -1588990, -1610579, -1632173, -1653773, -1675377, -1696986,
+ -1718600, -1740218, -1761841, -1783467, -1805097, -1826731, -1848367,
+ -1870008, -1891651, -1913296, -1934945, -1956595, -1978248, -1999902,
+ -2021558, -2043216, -2064875, -2086535, -2108195, -2129857, -2151518,
+ -2173180, -2194842, -2216504, -2238165, -2259826, -2281485, -2303144,
+ -2324801, -2346457, -2368111, -2389763, -2411412, -2433060, -2454705,
+ -2476347, -2497986, -2519622, -2541254, -2562883, -2584508, -2606128,
+ -2627745, -2649357, -2670964, -2692566, -2714163, -2735755, -2757341,
+ -2778921, -2800495, -2822063, -2843624, -2865179, -2886727, -2908267,
+ -2929800, -2951326, -2972844, -2994354, -3015855, -3037349, -3058833,
+ -3080309, -3101775, -3123233, -3144680, -3166118, -3187546, -3208964,
+ -3230371, -3251768, -3273154, -3294528, -3315892, -3337244, -3358584,
+ -3379912, -3401228, -3422532, -3443823, -3465101, -3486366, -3507618,
+ -3528856, -3550081, -3571291, -3592488, -3613670, -3634837, -3655990,
+ -3677127, -3698250, -3719356, -3740447, -3761523, -3782581, -3803624,
+ -3824650, -3845659, -3866651, -3887626, -3908583, -3929523, -3950444,
+ -3971348, -3992233, -4013099, -4033947, -4054775, -4075585, -4096374,
+ -4117144, -4137895, -4158624, -4179334, -4200023, -4220691, -4241338,
+ -4261964, -4282568, -4303151, -4323711, -4344250, -4364766, -4385259,
+ -4405730, -4426177, -4446602, -4467002, -4487379, -4507732, -4528061,
+ -4548366, -4568646, -4588901, -4609131, -4629336, -4649515, -4669668,
+ -4689796, -4709897, -4729972, -4750021, -4770042, -4790037, -4810004,
+ -4829944, -4849856, -4869740, -4889595, -4909423, -4929222, -4948992,
+ -4968733, -4988445, -5008127, -5027779, -5047402, -5066994, -5086557,
+ -5106088, -5125589, -5145058, -5164497, -5183904, -5203279, -5222622,
+ -5241933, -5261212, -5280458, -5299672, -5318852, -5337999, -5357113,
+ -5376193, -5395239, -5414251, -5433229, -5452172, -5471081, -5489954,
+ -5508792, -5527595, -5546362, -5565094, -5583789, -5602448, -5621070,
+ -5639656, -5658205, -5676717, -5695191, -5713627, -5732026, -5750387,
+ -5768710, -5786994, -5805239, -5823446, -5841614, -5859742, -5877830,
+ -5895879, -5913888, -5931857, -5949786, -5967673, -5985520, -6003326,
+ -6021091, -6038814, -6056496, -6074136, -6091733, -6109289, -6126802,
+ -6144272, -6161699, -6179083, -6196423, -6213721, -6230974, -6248183,
+ -6265348, -6282469, -6299545, -6316576, -6333562, -6350503, -6367399,
+ -6384249, -6401053, -6417811, -6434522, -6451187, -6467806, -6484377,
+ -6500902, -6517379, -6533808, -6550190, -6566524, -6582809, -6599047,
+ -6615236, -6631376, -6647467, -6663509, -6679501, -6695444, -6711337,
+ -6727181, -6742974, -6758716, -6774408, -6790050, -6805640, -6821179,
+ -6836667, -6852103, -6867487, -6882820, -6898100, -6913328, -6928503,
+ -6943625, -6958695, -6973711, -6988674, -7003583, -7018439, -7033241,
+ -7047988, -7062681, -7077320, -7091904, -7106433, -7120906, -7135325,
+ -7149688, -7163995, -7178246, -7192442, -7206581, -7220663, -7234689,
+ -7248658, -7262570, -7276424, -7290222, -7303961, -7317643, -7331267,
+ -7344833, -7358340, -7371789, -7385179, -7398510, -7411782, -7424995,
+ -7438148, -7451241, -7464275, -7477249, -7490162, -7503015, -7515808,
+ -7528539, -7541210, -7553820, -7566368, -7578855, -7591280, -7603644,
+ -7615945, -7628184, -7640361, -7652475, -7664526, -7676515, -7688440,
+ -7700303, -7712101, -7723836, -7735508, -7747115, -7758658, -7770137,
+ -7781552, -7792902, -7804187, -7815407, -7826562, -7837651, -7848675,
+ -7859633, -7870526, -7881352, -7892113, -7902807, -7913434, -7923995,
+ -7934489, -7944916, -7955275, -7965568, -7975793, -7985950, -7996039,
+ -8006061, -8016014, -8025899, -8035716, -8045463, -8055143, -8064753,
+ -8074294, -8083766, -8093168, -8102501, -8111764, -8120957, -8130080,
+ -8139133, -8148116, -8157028, -8165869, -8174640, -8183339, -8191968,
+ -8200525, -8209011, -8217425, -8225768, -8234039, -8242237, -8250364,
+ -8258418, -8266400, -8274309, -8282146, -8289909, -8297600, -8305217,
+ -8312761, -8320232, -8327629, -8334952, -8342202, -8349377, -8356478,
+ -8363505, -8370458, -8377336, -8384139, -8390868, -8397521, -8404100,
+ -8410603, -8417031, -8423383, -8429659, -8435860, -8441985, -8448034,
+ -8454007, -8459903, -8465723, -8471467, -8477134, -8482724, -8488237,
+ -8493673, -8499032, -8504313, -8509517, -8514644, -8519693, -8524664,
+ -8529557, -8534372, -8539109, -8543768, -8548349, -8552851, -8557274,
+ -8561618, -8565884, -8570071, -8574178, -8578207, -8582156, -8586026,
+ -8589816, -8593526, -8597157, -8600708, -8604179, -8607570, -8610881,
+ -8614111, -8617261, -8620331, -8623320, -8626228, -8629056, -8631802,
+ -8634468, -8637052, -8639555, -8641977, -8644317, -8646576, -8648754,
+ -8650849, -8652863, -8654795, -8656645, -8658413, -8660099, -8661702,
+ -8663223, -8664662, -8666018, -8667291, -8668482, -8669590, -8670615,
+ -8671557, -8672416, -8673192, -8673885, -8674494, -8675020, -8675462,
+ -8675821, -8676096, -8676288, -8676395, -8676419, -8676359, -8676215,
+ -8675986, -8675674, -8675277, -8674796, -8674231, -8673581, -8672846,
+ -8672027, -8671123, -8670135, -8669061, -8667903, -8666660, -8665331,
+ -8663918, -8662419, -8660836, -8659167, -8657412, -8655572, -8653647,
+ -8651636, -8649540, -8647358, -8645090, -8642737, -8640297, -8637772,
+ -8635161, -8632464, -8629681, -8626812, -8623857, -8620815, -8617687,
+ -8614474, -8611173, -8607787, -8604313, -8600754, -8597108, -8593375,
+ -8589556, -8585650, -8581658, -8577579, -8573413, -8569160, -8564820,
+ -8560394, -8555880, -8551280, -8546593, -8541818, -8536957, -8532008,
+ -8526973, -8521850, -8516640, -8511343, -8505959, -8500488, -8494929,
+ -8489283, -8483549, -8477728, -8471820, -8465825, -8459742, -8453571,
+ -8447313, -8440968, -8434535, -8428015, -8421407, -8414712, -8407929,
+ -8401058, -8394100, -8387054, -8379921, -8372700, -8365391, -8357995,
+ -8350511, -8342940, -8335281, -8327534, -8319699, -8311777, -8303767,
+ -8295670, -8287485, -8279212, -8270851, -8262403, -8253867, -8245244,
+ -8236533, -8227734, -8218847, -8209873, -8200811, -8191662, -8182425,
+ -8173100, -8163688, -8154188, -8144601, -8134926, -8125164, -8115314,
+ -8105376, -8095351, -8085239, -8075039, -8064751, -8054377, -8043915,
+ -8033365, -8022728, -8012004, -8001193, -7990294, -7979308, -7968235,
+ -7957074, -7945827, -7934492, -7923070, -7911562, -7899966, -7888283,
+ -7876513, -7864657, -7852713, -7840683, -7828565, -7816361, -7804071,
+ -7791693, -7779229, -7766678, -7754041, -7741317, -7728507, -7715611,
+ -7702628, -7689558, -7676403, -7663161, -7649833, -7636419, -7622919,
+ -7609333, -7595660, -7581902, -7568059, -7554129, -7540113, -7526012,
+ -7511826, -7497553, -7483196, -7468752, -7454224, -7439610, -7424911,
+ -7410127, -7395258, -7380303, -7365264, -7350140, -7334931, -7319637,
+ -7304258, -7288795, -7273248, -7257616, -7241899, -7226098, -7210214,
+ -7194244, -7178191, -7162054, -7145833, -7129528, -7113140, -7096667,
+ -7080112, -7063472, -7046750, -7029944, -7013054, -6996082, -6979027,
+ -6961888, -6944667, -6927363, -6909977, -6892508, -6874956, -6857322,
+ -6839606, -6821807, -6803927, -6785964, -6767920, -6749794, -6731586,
+ -6713296, -6694926, -6676473, -6657940, -6639325, -6620630, -6601853,
+ -6582996, -6564057, -6545039, -6525940, -6506760, -6487500, -6468160,
+ -6448740, -6429240, -6409661, -6390002, -6370263, -6350444, -6330547,
+ -6310570, -6290514, -6270380, -6250166, -6229874, -6209503, -6189054,
+ -6168527, -6147921, -6127237, -6106476, -6085636, -6064720, -6043725,
+ -6022653, -6001504, -5980278, -5958975, -5937595, -5916139, -5894605,
+ -5872996, -5851310, -5829548, -5807710, -5785797, -5763807, -5741743,
+ -5719602, -5697387, -5675096, -5652731, -5630291, -5607776, -5585186,
+ -5562523, -5539785, -5516973, -5494087, -5471128, -5448095, -5424989,
+ -5401809, -5378556, -5355231, -5331833, -5308362, -5284818, -5261203,
+ -5237515, -5213756, -5189925, -5166022, -5142047, -5118002, -5093885,
+ -5069698, -5045440, -5021111, -4996712, -4972243, -4947703, -4923094,
+ -4898415, -4873667, -4848849, -4823962, -4799006, -4773982, -4748889,
+ -4723727, -4698497, -4673200, -4647834, -4622401, -4596900, -4571332,
+ -4545696, -4519994, -4494226, -4468390, -4442488, -4416521, -4390487,
+ -4364387, -4338222, -4311992, -4285696, -4259336, -4232910, -4206420,
+ -4179866, -4153248, -4126565, -4099819, -4073009, -4046136, -4019200,
+ -3992201, -3965139, -3938015, -3910828, -3883579, -3856268, -3828896,
+ -3801462, -3773967, -3746411, -3718794, -3691116, -3663378, -3635580,
+ -3607722, -3579804, -3551826, -3523789, -3495694, -3467539, -3439326,
+ -3411054, -3382724, -3354336, -3325890, -3297387, -3268826, -3240209,
+ -3211534, -3182803, -3154016, -3125172, -3096273, -3067318, -3038307,
+ -3009241, -2980120, -2950945, -2921714, -2892430, -2863092, -2833699,
+ -2804253, -2774754, -2745202, -2715597, -2685939, -2656229, -2626467,
+ -2596653, -2566787, -2536870, -2506902, -2476883, -2446813, -2416693,
+ -2386523, -2356303, -2326033, -2295713, -2265345, -2234928, -2204462,
+ -2173948, -2143385, -2112775, -2082117, -2051411, -2020659, -1989860,
+ -1959014, -1928122, -1897183, -1866199, -1835170, -1804095, -1772975,
+ -1741810, -1710601, -1679347, -1648050, -1616709, -1585324, -1553897,
+ -1522426, -1490913, -1459357, -1427760, -1396120, -1364439, -1332717,
+ -1300953, -1269149, -1237305, -1205420, -1173495, -1141531, -1109527,
+ -1077485, -1045403, -1013283, -981125, -948928, -916694, -884423,
+ -852115, -819769, -787387, -754969, -722515, -690025, -657500, -624940,
+ -592344, -559714, -527050, -494352, -461620, -428855, -396057, -363226,
+ -330362, -297466, -264538, -231579, -198588, -165566, -132513, -99429,
+ -66316, -33173, 0, 33202, 66433, 99693, 132982, 166298, 199643, 233014,
+ 266413, 299839, 333292, 366771, 400276, 433806, 467363, 500944, 534549,
+ 568180, 601834, 635513, 669215, 702940, 736688, 770459, 804252, 838067,
+ 871904, 905762, 939642, 973542, 1007462, 1041403, 1075364, 1109344,
+ 1143343, 1177361, 1211398, 1245453, 1279526, 1313617, 1347725, 1381850,
+ 1415992, 1450150, 1484324, 1518514, 1552719, 1586939, 1621174, 1655424,
+ 1689688, 1723965, 1758256, 1792560, 1826877, 1861207, 1895549, 1929902,
+ 1964268, 1998644, 2033031, 2067429, 2101837, 2136255, 2170683, 2205120,
+ 2239566, 2274020, 2308483, 2342954, 2377432, 2411918, 2446411, 2480910,
+ 2515416, 2549927, 2584445, 2618967, 2653495, 2688027, 2722564, 2757104,
+ 2791649, 2826196, 2860747, 2895300, 2929856, 2964413, 2998973, 3033533,
+ 3068095, 3102657, 3137220, 3171782, 3206344, 3240906, 3275466, 3310025,
+ 3344583, 3379138, 3413691, 3448242, 3482789, 3517333, 3551873, 3586409,
+ 3620941, 3655468, 3689989, 3724506, 3759016, 3793521, 3828019, 3862510,
+ 3896994, 3931471, 3965940, 4000401, 4034853, 4069296, 4103730, 4138155,
+ 4172570, 4206974, 4241368, 4275751, 4310123, 4344484, 4378832, 4413168,
+ 4447491, 4481802, 4516099, 4550382, 4584652, 4618907, 4653147, 4687373,
+ 4721583, 4755777, 4789955, 4824117, 4858262, 4892390, 4926500, 4960593,
+ 4994667, 5028723, 5062760, 5096778, 5130776, 5164754, 5198713, 5232650,
+ 5266567, 5300462, 5334336, 5368187, 5402017, 5435823, 5469607, 5503367,
+ 5537104, 5570816, 5604504, 5638168, 5671806, 5705418, 5739005, 5772566,
+ 5806100, 5839607, 5873088, 5906540, 5939965, 5973361, 6006729, 6040067,
+ 6073377, 6106657, 6139906, 6173126, 6206315, 6239472, 6272598, 6305693,
+ 6338755, 6371785, 6404782, 6437746, 6470677, 6503573, 6536436, 6569264,
+ 6602057, 6634814, 6667536, 6700223, 6732872, 6765486, 6798062, 6830601,
+ 6863102, 6895565, 6927990, 6960376, 6992723, 7025030, 7057298, 7089526,
+ 7121713, 7153859, 7185964, 7218028, 7250050, 7282029, 7313966, 7345861,
+ 7377711, 7409519, 7441282, 7473001, 7504675, 7536305, 7567889, 7599427,
+ 7630919, 7662365, 7693765, 7725117, 7756422, 7787679, 7818887, 7850048,
+ 7881160, 7912222, 7943235, 7974199, 8005112, 8035974, 8066786, 8097547,
+ 8128256, 8158913, 8189518, 8220070, 8250569, 8281016, 8311408, 8341747,
+ 8372031, 8402261, 8432436, 8462555, 8492619, 8522627, 8552579, 8582474,
+ 8612312, 8642092, 8671815, 8701480, 8731087, 8760635, 8790124, 8819553,
+ 8848923, 8878233, 8907483, 8936671, 8965799, 8994865, 9023870, 9052812,
+ 9081693, 9110510, 9139265, 9167956, 9196583, 9225146, 9253645, 9282079,
+ 9310449, 9338752, 9366990, 9395162, 9423268, 9451307, 9479279, 9507184,
+ 9535021, 9562790, 9590490, 9618122, 9645685, 9673178, 9700602, 9727956,
+ 9755240, 9782453, 9809595, 9836666, 9863665, 9890592, 9917447, 9944230,
+ 9970940, 9997576, 10024139, 10050628, 10077043, 10103383, 10129648,
+ 10155839, 10181954, 10207993, 10233956, 10259843, 10285653, 10311386,
+ 10337041, 10362619, 10388119, 10413541, 10438884, 10464148, 10489333,
+ 10514438, 10539463, 10564409, 10589274, 10614058, 10638760, 10663382,
+ 10687922, 10712379, 10736755, 10761048, 10785258, 10809384, 10833427,
+ 10857386, 10881261, 10905052, 10928758, 10952378, 10975914, 10999363,
+ 11022727, 11046004, 11069195, 11092299, 11115316, 11138245, 11161086,
+ 11183840, 11206505, 11229081, 11251569, 11273967, 11296276, 11318494,
+ 11340623, 11362661, 11384609, 11406466, 11428231, 11449905, 11471487,
+ 11492976, 11514374, 11535678, 11556890, 11578008, 11599032, 11619963,
+ 11640800, 11661542, 11682190, 11702742, 11723199, 11743561, 11763827,
+ 11783997, 11804070, 11824047, 11843927, 11863709, 11883394, 11902982,
+ 11922471, 11941862, 11961154, 11980348, 11999442, 12018437, 12037333,
+ 12056128, 12074824, 12093418, 12111913, 12130306, 12148598, 12166788,
+ 12184876, 12202863, 12220747, 12238529, 12256208, 12273784, 12291256,
+ 12308625, 12325890, 12343051, 12360107, 12377059, 12393906, 12410648,
+ 12427285, 12443816, 12460241, 12476560, 12492772, 12508878, 12524877,
+ 12540769, 12556554, 12572231, 12587800, 12603262, 12618614, 12633859,
+ 12648994, 12664021, 12678938, 12693745, 12708443, 12723031, 12737509,
+ 12751876, 12766133, 12780278, 12794313, 12808236, 12822047, 12835747,
+ 12849334, 12862810, 12876172, 12889423, 12902560, 12915583, 12928494,
+ 12941291, 12953974, 12966543, 12978997, 12991337, 13003563, 13015673,
+ 13027669, 13039549, 13051313, 13062962, 13074494, 13085911, 13097211,
+ 13108394, 13119461, 13130410, 13141242, 13151957, 13162555, 13173034,
+ 13183395, 13193638, 13203763, 13213769, 13223656, 13233424, 13243073,
+ 13252602, 13262012, 13271302, 13280472, 13289522, 13298451, 13307260,
+ 13315948, 13324515, 13332961, 13341286, 13349489, 13357571, 13365531,
+ 13373368, 13381084, 13388677, 13396147, 13403495, 13410720, 13417822,
+ 13424800, 13431655, 13438387, 13444995, 13451478, 13457838, 13464073,
+ 13470184, 13476171, 13482032, 13487769, 13493381, 13498867, 13504228,
+ 13509464, 13514573, 13519557, 13524415, 13529147, 13533752, 13538231,
+ 13542583, 13546809, 13550907, 13554879, 13558723, 13562440, 13566029,
+ 13569491, 13572825, 13576031, 13579109, 13582059, 13584880, 13587573,
+ 13590138, 13592574, 13594880, 13597058, 13599107, 13601027, 13602817,
+ 13604477, 13606008, 13607410, 13608681, 13609822, 13610834, 13611715,
+ 13612465, 13613086, 13613575, 13613934, 13614163, 13614260, 13614226,
+ 13614061, 13613765, 13613338, 13612779, 13612088, 13611266, 13610313,
+ 13609227, 13608009, 13606659, 13605177, 13603563, 13601817, 13599938,
+ 13597926, 13595782, 13593506, 13591096, 13588553, 13585878, 13583069,
+ 13580128, 13577053, 13573845, 13570503, 13567028, 13563420, 13559677,
+ 13555801, 13551792, 13547648, 13543371, 13538960, 13534414, 13529735,
+ 13524921, 13519973, 13514891, 13509674, 13504323, 13498837, 13493217,
+ 13487463, 13481573, 13475549, 13469390, 13463096, 13456668, 13450104,
+ 13443406, 13436572, 13429604, 13422500, 13415261, 13407887, 13400378,
+ 13392733, 13384954, 13377038, 13368988, 13360802, 13352480, 13344023,
+ 13335431, 13326703, 13317839, 13308840, 13299705, 13290435, 13281029,
+ 13271487, 13261809, 13251996, 13242047, 13231962, 13221742, 13211385,
+ 13200893, 13190265, 13179501, 13168602, 13157566, 13146395, 13135088,
+ 13123645, 13112066, 13100351, 13088501, 13076514, 13064392, 13052134,
+ 13039740, 13027210, 13014544, 13001743, 12988806, 12975733, 12962524,
+ 12949180, 12935699, 12922083, 12908332, 12894444, 12880421, 12866263,
+ 12851969, 12837539, 12822974, 12808273, 12793436, 12778465, 12763357,
+ 12748115, 12732737, 12717223, 12701575, 12685791, 12669872, 12653818,
+ 12637629, 12621304, 12604845, 12588251, 12571522, 12554657, 12537659,
+ 12520525, 12503256, 12485853, 12468316, 12450644, 12432837, 12414896,
+ 12396821, 12378611, 12360267, 12341789, 12323177, 12304431, 12285551,
+ 12266537, 12247389, 12228107, 12208692, 12189144, 12169461, 12149646,
+ 12129697, 12109615, 12089399, 12069051, 12048570, 12027956, 12007209,
+ 11986329, 11965316, 11944172, 11922894, 11901485, 11879943, 11858269,
+ 11836463, 11814525, 11792455, 11770254, 11747921, 11725456, 11702860,
+ 11680133, 11657275, 11634285, 11611165, 11587914, 11564532, 11541019,
+ 11517376, 11493603, 11469699, 11445666, 11421502, 11397209, 11372786,
+ 11348233, 11323551, 11298739, 11273799, 11248729, 11223530, 11198203,
+ 11172747, 11147163, 11121450, 11095609, 11069640, 11043543, 11017318,
+ 10990965, 10964486, 10937878, 10911144, 10884283, 10857295, 10830180,
+ 10802938, 10775571, 10748077, 10720457, 10692711, 10664839, 10636842,
+ 10608720, 10580472, 10552099, 10523602, 10494979, 10466233, 10437361,
+ 10408366, 10379247, 10350004, 10320637, 10291147, 10261533, 10231797,
+ 10201938, 10171956, 10141851, 10111624, 10081275, 10050805, 10020212,
+ 9989498, 9958662, 9927706, 9896628, 9865430, 9834112, 9802672, 9771113,
+ 9739434, 9707636, 9675717, 9643680, 9611523, 9579248, 9546854, 9514341,
+ 9481711, 9448962, 9416096, 9383112, 9350011, 9316792, 9283457, 9250006,
+ 9216437, 9182753, 9148953, 9115037, 9081005, 9046859, 9012597, 8978221,
+ 8943730, 8909125, 8874405, 8839572, 8804626, 8769566, 8734393, 8699107,
+ 8663709, 8628198, 8592576, 8556841, 8520995, 8485038, 8448970, 8412790,
+ 8376501, 8340101, 8303591, 8266972, 8230243, 8193404, 8156457, 8119402,
+ 8082237, 8044965, 8007585, 7970097, 7932502, 7894801, 7856992, 7819077,
+ 7781055, 7742928, 7704695, 7666357, 7627914, 7589366, 7550714, 7511957,
+ 7473097, 7434133, 7395066, 7355895, 7316622, 7277247, 7237770, 7198190,
+ 7158509, 7118727, 7078844, 7038861, 6998777, 6958593, 6918310, 6877927,
+ 6837445, 6796864, 6756185, 6715408, 6674533, 6633560, 6592491, 6551324,
+ 6510061, 6468702, 6427247, 6385696, 6344050, 6302309, 6260474, 6218544,
+ 6176520, 6134403, 6092192, 6049889, 6007493, 5965005, 5922424, 5879753,
+ 5836990, 5794136, 5751191, 5708156, 5665032, 5621818, 5578514, 5535122,
+ 5491641, 5448072, 5404416, 5360672, 5316841, 5272923, 5228918, 5184828,
+ 5140652, 5096391, 5052045, 5007614, 4963099, 4918500, 4873818, 4829052,
+ 4784204, 4739273, 4694260, 4649166, 4603990, 4558734, 4513396, 4467979,
+ 4422482, 4376906, 4331250, 4285516, 4239703, 4193813, 4147845, 4101800,
+ 4055678, 4009480, 3963205, 3916856, 3870431, 3823931, 3777356, 3730708,
+ 3683986, 3637191, 3590323, 3543382, 3496369, 3449285, 3402130, 3354903,
+ 3307606, 3260239, 3212802, 3165296, 3117721, 3070078, 3022367, 2974588,
+ 2926741, 2878828, 2830849, 2782803, 2734692, 2686515, 2638274, 2589969,
+ 2541599, 2493166, 2444670, 2396112, 2347490, 2298808, 2250063, 2201258,
+ 2152392, 2103466, 2054480, 2005435, 1956331, 1907169, 1857948, 1808670,
+ 1759335, 1709943, 1660495, 1610990, 1561431, 1511816, 1462147, 1412424,
+ 1362647, 1312817, 1262934, 1212998, 1163011, 1112972, 1062883, 1012742,
+ 962552, 912311, 862022, 811684, 761297, 710862, 660380, 609851, 559275,
+ 508654, 457986, 407273, 356516, 305714, 254869, 203980, 153048, 102074,
+ 51057, 0, -51098, -102238, -153418, -204637, -255896, -307193, -358529,
+ -409903, -461314, -512762, -564246, -615766, -667322, -718913, -770538,
+ -822198, -873891, -925617, -977376, -1029167, -1080990, -1132844,
+ -1184729, -1236644, -1288589, -1340563, -1392566, -1444597, -1496657,
+ -1548743, -1600857, -1652997, -1705163, -1757355, -1809571, -1861812,
+ -1914077, -1966366, -2018677, -2071012, -2123368, -2175746, -2228145,
+ -2280564, -2333004, -2385463, -2437941, -2490438, -2542953, -2595486,
+ -2648036, -2700603, -2753186, -2805784, -2858398, -2911026, -2963668,
+ -3016324, -3068994, -3121676, -3174370, -3227076, -3279793, -3332521,
+ -3385258, -3438006, -3490763, -3543528, -3596302, -3649083, -3701871,
+ -3754666, -3807468, -3860274, -3913086, -3965903, -4018724, -4071548,
+ -4124376, -4177206, -4230038, -4282872, -4335706, -4388542, -4441377,
+ -4494212, -4547046, -4599878, -4652709, -4705537, -4758362, -4811183,
+ -4864001, -4916813, -4969621, -5022423, -5075219, -5128009, -5180791,
+ -5233566, -5286332, -5339090, -5391838, -5444577, -5497306, -5550023,
+ -5602730, -5655425, -5708107, -5760777, -5813433, -5866075, -5918703,
+ -5971316, -6023914, -6076495, -6129060, -6181609, -6234139, -6286652,
+ -6339146, -6391621, -6444076, -6496511, -6548926, -6601319, -6653691,
+ -6706040, -6758367, -6810670, -6862950, -6915205, -6967435, -7019640,
+ -7071820, -7123972, -7176098, -7228196, -7280267, -7332308, -7384321,
+ -7436304, -7488257, -7540180, -7592071, -7643931, -7695758, -7747553,
+ -7799314, -7851042, -7902735, -7954393, -8006016, -8057603, -8109154,
+ -8160668, -8212144, -8263582, -8314982, -8366343, -8417664, -8468945,
+ -8520185, -8571384, -8622542, -8673657, -8724730, -8775759, -8826744,
+ -8877685, -8928581, -8979432, -9030237, -9080996, -9131707, -9182371,
+ -9232987, -9283554, -9334073, -9384541, -9434960, -9485328, -9535644,
+ -9585909, -9636122, -9686282, -9736389, -9786441, -9836440, -9886383,
+ -9936272, -9986104, -10035880, -10085598, -10135260, -10184863,
+ -10234408, -10283893, -10333319, -10382685, -10431990, -10481235,
+ -10530417, -10579537, -10628594, -10677588, -10726519, -10775385,
+ -10824186, -10872921, -10921591, -10970195, -11018731, -11067200,
+ -11115601, -11163934, -11212197, -11260391, -11308515, -11356569,
+ -11404551, -11452461, -11500300, -11548066, -11595758, -11643377,
+ -11690922, -11738392, -11785786, -11833105, -11880348, -11927514,
+ -11974602, -12021613, -12068545, -12115399, -12162173, -12208867,
+ -12255481, -12302013, -12348465, -12394834, -12441121, -12487325,
+ -12533446, -12579482, -12625434, -12671301, -12717082, -12762778,
+ -12808387, -12853908, -12899343, -12944689, -12989946, -13035115,
+ -13080194, -13125182, -13170081, -13214888, -13259603, -13304226,
+ -13348757, -13393195, -13437539, -13481788, -13525944, -13570004,
+ -13613968, -13657836, -13701608, -13745282, -13788859, -13832338,
+ -13875718, -13918999, -13962181, -14005262, -14048242, -14091122,
+ -14133900, -14176576, -14219149, -14261619, -14303986, -14346249,
+ -14388407, -14430460, -14472407, -14514249, -14555984, -14597612,
+ -14639132, -14680545, -14721849, -14763044, -14804130, -14845106,
+ -14885972, -14926727, -14967370, -15007902, -15048321, -15088627,
+ -15128821, -15168900, -15208866, -15248716, -15288452, -15328072,
+ -15367576, -15406963, -15446233, -15485386, -15524421, -15563337,
+ -15602134, -15640812, -15679370, -15717808, -15756125, -15794321,
+ -15832395, -15870347, -15908176, -15945882, -15983465, -16020924,
+ -16058258, -16095467, -16132551, -16169508, -16206340, -16243045,
+ -16279623, -16316073, -16352394, -16388588, -16424652, -16460587,
+ -16496392, -16532066, -16567610, -16603023, -16638304, -16673452,
+ -16708468, -16743351, -16778101, -16812717, -16847198, -16881545,
+ -16915756, -16949832, -16983771, -17017574, -17051241, -17084769,
+ -17118160, -17151413, -17184527, -17217502, -17250338, -17283033,
+ -17315588, -17348002, -17380275, -17412407, -17444396, -17476243,
+ -17507947, -17539508, -17570925, -17602197, -17633325, -17664309,
+ -17695146, -17725838, -17756384, -17786783, -17817036, -17847140,
+ -17877097, -17906906, -17936566, -17966077, -17995438, -18024650,
+ -18053711, -18082622, -18111381, -18139990, -18168446, -18196750,
+ -18224902, -18252900, -18280746, -18308437, -18335974, -18363357,
+ -18390585, -18417657, -18444574, -18471334, -18497939, -18524386,
+ -18550676, -18576809, -18602783, -18628599, -18654257, -18679755,
+ -18705094, -18730273, -18755292, -18780151, -18804848, -18829384,
+ -18853759, -18877971, -18902021, -18925909, -18949633, -18973194,
+ -18996591, -19019824, -19042893, -19065796, -19088535, -19111108,
+ -19133515, -19155756, -19177830, -19199737, -19221477, -19243050,
+ -19264454, -19285691, -19306758, -19327657, -19348386, -19368946,
+ -19389336, -19409556, -19429605, -19449483, -19469190, -19488726,
+ -19508089, -19527280, -19546299, -19565145, -19583818, -19602317,
+ -19620643, -19638794, -19656771, -19674574, -19692201, -19709653,
+ -19726929, -19744030, -19760954, -19777702, -19794273, -19810667,
+ -19826883, -19842922, -19858782, -19874465, -19889969, -19905294,
+ -19920439, -19935406, -19950192, -19964799, -19979225, -19993471,
+ -20007536, -20021420, -20035122, -20048643, -20061982, -20075139,
+ -20088113, -20100905, -20113513, -20125938, -20138180, -20150238,
+ -20162112, -20173802, -20185307, -20196627, -20207763, -20218712,
+ -20229477, -20240056, -20250448, -20260654, -20270674, -20280507,
+ -20290153, -20299612, -20308883, -20317967, -20326863, -20335570,
+ -20344089, -20352420, -20360561, -20368514, -20376277, -20383851,
+ -20391235, -20398429, -20405432, -20412246, -20418869, -20425301,
+ -20431542, -20437592, -20443450, -20449117, -20454592, -20459875,
+ -20464965, -20469863, -20474569, -20479082, -20483402, -20487528,
+ -20491461, -20495201, -20498747, -20502099, -20505257, -20508220,
+ -20510989, -20513563, -20515943, -20518128, -20520117, -20521911,
+ -20523509, -20524912, -20526119, -20527130, -20527945, -20528564,
+ -20528986, -20529211, -20529240, -20529072, -20528706, -20528144,
+ -20527384, -20526426, -20525271, -20523918, -20522367, -20520618,
+ -20518671, -20516526, -20514182, -20511639, -20508898, -20505958,
+ -20502818, -20499480, -20495943, -20492206, -20488270, -20484134,
+ -20479798, -20475263, -20470528, -20465593, -20460457, -20455122,
+ -20449586, -20443849, -20437913, -20431775, -20425437, -20418898,
+ -20412158, -20405217, -20398075, -20390732, -20383188, -20375442,
+ -20367495, -20359347, -20350997, -20342445, -20333692, -20324737,
+ -20315580, -20306221, -20296660, -20286897, -20276932, -20266765,
+ -20256396, -20245825, -20235051, -20224075, -20212896, -20201515,
+ -20189932, -20178146, -20166157, -20153966, -20141572, -20128976,
+ -20116176, -20103174, -20089970, -20076562, -20062951, -20049138,
+ -20035122, -20020903, -20006481, -19991856, -19977028, -19961997,
+ -19946764, -19931327, -19915687, -19899844, -19883799, -19867550,
+ -19851098, -19834444, -19817586, -19800526, -19783262, -19765796,
+ -19748126, -19730254, -19712179, -19693901, -19675420, -19656736,
+ -19637850, -19618760, -19599468, -19579974, -19560276, -19540376,
+ -19520273, -19499968, -19479460, -19458750, -19437837, -19416722,
+ -19395405, -19373885, -19352163, -19330239, -19308113, -19285785,
+ -19263255, -19240522, -19217588, -19194453, -19171115, -19147576,
+ -19123835, -19099893, -19075749, -19051404, -19026858, -19002110,
+ -18977162, -18952012, -18926661, -18901110, -18875358, -18849405,
+ -18823252, -18796898, -18770344, -18743590, -18716636, -18689481,
+ -18662127, -18634573, -18606819, -18578866, -18550713, -18522361,
+ -18493810, -18465059, -18436110, -18406962, -18377615, -18348070,
+ -18318326, -18288384, -18258243, -18227905, -18197369, -18166635,
+ -18135704, -18104575, -18073249, -18041726, -18010005, -17978088,
+ -17945975, -17913664, -17881158, -17848455, -17815557, -17782462,
+ -17749172, -17715686, -17682005, -17648129, -17614058, -17579792,
+ -17545332, -17510677, -17475828, -17440785, -17405548, -17370118,
+ -17334494, -17298676, -17262666, -17226463, -17190067, -17153479,
+ -17116699, -17079726, -17042562, -17005206, -16967659, -16929920,
+ -16891991, -16853871, -16815560, -16777059, -16738368, -16699488,
+ -16660417, -16621158, -16581709, -16542071, -16502245, -16462230,
+ -16422027, -16381636, -16341058, -16300292, -16259339, -16218199,
+ -16176872, -16135359, -16093660, -16051775, -16009705, -15967449,
+ -15925008, -15882382, -15839571, -15796577, -15753398, -15710036,
+ -15666490, -15622761, -15578849, -15534755, -15490478, -15446020,
+ -15401379, -15356558, -15311555, -15266371, -15221007, -15175462,
+ -15129738, -15083834, -15037751, -14991489, -14945048, -14898428,
+ -14851631, -14804656, -14757503, -14710174, -14662667, -14614984,
+ -14567125, -14519090, -14470880, -14422495, -14373935, -14325200,
+ -14276291, -14227209, -14177953, -14128524, -14078922, -14029148,
+ -13979201, -13929083, -13878794, -13828334, -13777703, -13726902,
+ -13675930, -13624790, -13573480, -13522001, -13470354, -13418539,
+ -13366556, -13314406, -13262089, -13209605, -13156955, -13104140,
+ -13051159, -12998013, -12944702, -12891227, -12837588, -12783786,
+ -12729820, -12675692, -12621402, -12566950, -12512336, -12457561,
+ -12402626, -12347530, -12292275, -12236860, -12181286, -12125553,
+ -12069663, -12013614, -11957408, -11901046, -11844527, -11787851,
+ -11731021, -11674035, -11616894, -11559599, -11502150, -11444547,
+ -11386792, -11328884, -11270824, -11212612, -11154249, -11095735,
+ -11037071, -10978257, -10919293, -10860181, -10800920, -10741511,
+ -10681954, -10622251, -10562400, -10502404, -10442261, -10381974,
+ -10321542, -10260965, -10200245, -10139381, -10078374, -10017225,
+ -9955934, -9894502, -9832928, -9771215, -9709361, -9647368, -9585235,
+ -9522965, -9460556, -9398010, -9335327, -9272507, -9209552, -9146461,
+ -9083235, -9019874, -8956380, -8892752, -8828991, -8765098, -8701073,
+ -8636916, -8572629, -8508211, -8443664, -8378987, -8314182, -8249248,
+ -8184186, -8118998, -8053683, -7988241, -7922674, -7856983, -7791166,
+ -7725226, -7659162, -7592975, -7526667, -7460236, -7393684, -7327011,
+ -7260219, -7193307, -7126275, -7059126, -6991858, -6924473, -6856972,
+ -6789354, -6721620, -6653772, -6585809, -6517732, -6449542, -6381239,
+ -6312823, -6244296, -6175658, -6106910, -6038052, -5969084, -5900007,
+ -5830823, -5761531, -5692132, -5622626, -5553015, -5483298, -5413477,
+ -5343552, -5273523, -5203392, -5133158, -5062823, -4992387, -4921850,
+ -4851214, -4780478, -4709644, -4638712, -4567682, -4496556, -4425333,
+ -4354015, -4282602, -4211094, -4139493, -4067799, -3996013, -3924134,
+ -3852165, -3780105, -3707955, -3635715, -3563387, -3490971, -3418467,
+ -3345877, -3273201, -3200439, -3127592, -3054660, -2981646, -2908548,
+ -2835368, -2762106, -2688763, -2615340, -2541837, -2468255, -2394595,
+ -2320857, -2247041, -2173150, -2099182, -2025139, -1951022, -1876831,
+ -1802566, -1728229, -1653821, -1579341, -1504790, -1430170, -1355480,
+ -1280722, -1205896, -1131003, -1056043, -981017, -905927, -830771,
+ -755552, -680270, -604925, -529518, -454051, -378523, -302935, -227288,
+ -151583, -75820, 0, 75876, 151808, 227795, 303836, 379931, 456078,
+ 532278, 608529, 684831, 761183, 837585, 914035, 990533, 1067079,
+ 1143671, 1220309, 1296992, 1373719, 1450491, 1527305, 1604162, 1681060,
+ 1758000, 1834979, 1911998, 1989056, 2066152, 2143285, 2220455, 2297661,
+ 2374902, 2452178, 2529487, 2606830, 2684204, 2761611, 2839048, 2916515,
+ 2994012, 3071538, 3149092, 3226673, 3304280, 3381913, 3459572, 3537255,
+ 3614961, 3692690, 3770442, 3848215, 3926008, 4003822, 4081655, 4159506,
+ 4237375, 4315261, 4393164, 4471082, 4549015, 4626961, 4704922, 4782894,
+ 4860879, 4938875, 5016881, 5094897, 5172921, 5250954, 5328994, 5407041,
+ 5485094, 5563152, 5641214, 5719280, 5797349, 5875420, 5953492, 6031565,
+ 6109638, 6187710, 6265781, 6343849, 6421914, 6499975, 6578032, 6656083,
+ 6734128, 6812166, 6890197, 6968219, 7046232, 7124235, 7202228, 7280209,
+ 7358177, 7436133, 7514075, 7592003, 7669916, 7747812, 7825692, 7903554,
+ 7981398, 8059223, 8137028, 8214813, 8292576, 8370317, 8448035, 8525730,
+ 8603400, 8681046, 8758665, 8836257, 8913822, 8991359, 9068867, 9146345,
+ 9223793, 9301209, 9378594, 9455945, 9533263, 9610546, 9687795, 9765007,
+ 9842183, 9919321, 9996421, 10073483, 10150504, 10227485, 10304424,
+ 10381322, 10458177, 10534988, 10611754, 10688476, 10765152, 10841781,
+ 10918362, 10994895, 11071380, 11147814, 11224198, 11300531, 11376811,
+ 11453039, 11529213, 11605332, 11681397, 11757405, 11833357, 11909251,
+ 11985087, 12060864, 12136581, 12212237, 12287832, 12363365, 12438835,
+ 12514242, 12589583, 12664860, 12740071, 12815215, 12890291, 12965299,
+ 13040238, 13115107, 13189905, 13264633, 13339287, 13413869, 13488377,
+ 13562811, 13637170, 13711452, 13785658, 13859786, 13933835, 14007806,
+ 14081697, 14155507, 14229235, 14302882, 14376445, 14449925, 14523320,
+ 14596630, 14669854, 14742992, 14816041, 14889002, 14961875, 15034657,
+ 15107349, 15179949, 15252457, 15324872, 15397194, 15469421, 15541553,
+ 15613588, 15685527, 15757369, 15829112, 15900757, 15972301, 16043745,
+ 16115088, 16186328, 16257466, 16328500, 16399430, 16470254, 16540973,
+ 16611585, 16682090, 16752486, 16822774, 16892952, 16963019, 17032976,
+ 17102820, 17172552, 17242171, 17311675, 17381064, 17450338, 17519495,
+ 17588535, 17657457, 17726260, 17794944, 17863508, 17931951, 18000272,
+ 18068470, 18136546, 18204498, 18272324, 18340026, 18407601, 18475050,
+ 18542371, 18609564, 18676627, 18743561, 18810364, 18877035, 18943575,
+ 19009982, 19076255, 19142394, 19208398, 19274267, 19339998, 19405593,
+ 19471050, 19536368, 19601547, 19666585, 19731483, 19796239, 19860853,
+ 19925324, 19989651, 20053834, 20117871, 20181763, 20245508, 20309105,
+ 20372555, 20435855, 20499007, 20562007, 20624858, 20687556, 20750102,
+ 20812495, 20874734, 20936819, 20998748, 21060522, 21122139, 21183598,
+ 21244900, 21306043, 21367026, 21427849, 21488512, 21549013, 21609351,
+ 21669527, 21729539, 21789386, 21849069, 21908586, 21967937, 22027120,
+ 22086136, 22144983, 22203661, 22262169, 22320506, 22378672, 22436667,
+ 22494488, 22552137, 22609611, 22666911, 22724036, 22780984, 22837756,
+ 22894351, 22950767, 23007005, 23063064, 23118942, 23174640, 23230156,
+ 23285490, 23340642, 23395610, 23450395, 23504994, 23559409, 23613637,
+ 23667678, 23721533, 23775199, 23828677, 23881965, 23935064, 23987972,
+ 24040689, 24093214, 24145546, 24197685, 24249631, 24301382, 24352938,
+ 24404299, 24455463, 24506430, 24557199, 24607770, 24658143, 24708316,
+ 24758289, 24808061, 24857631, 24907000, 24956166, 25005129, 25053888,
+ 25102443, 25150792, 25198936, 25246874, 25294604, 25342128, 25389443,
+ 25436549, 25483446, 25530133, 25576609, 25622875, 25668928, 25714770,
+ 25760398, 25805813, 25851014, 25896000, 25940771, 25985326, 26029664,
+ 26073786, 26117690, 26161375, 26204842, 26248090, 26291117, 26333925,
+ 26376511, 26418875, 26461017, 26502937, 26544633, 26586105, 26627353,
+ 26668376, 26709173, 26749745, 26790089, 26830206, 26870096, 26909757,
+ 26949189, 26988392, 27027365, 27066108, 27104619, 27142899, 27180947,
+ 27218762, 27256344, 27293692, 27330806, 27367685, 27404329, 27440738,
+ 27476910, 27512845, 27548542, 27584002, 27619224, 27654206, 27688950,
+ 27723453, 27757716, 27791738, 27825519, 27859057, 27892354, 27925407,
+ 27958217, 27990783, 28023105, 28055182, 28087014, 28118600, 28149939,
+ 28181032, 28211877, 28242475, 28272825, 28302926, 28332777, 28362379,
+ 28391732, 28420833, 28449684, 28478283, 28506630, 28534725, 28562567,
+ 28590156, 28617491, 28644572, 28671398, 28697969, 28724285, 28750345,
+ 28776149, 28801696, 28826985, 28852017, 28876791, 28901307, 28925563,
+ 28949561, 28973298, 28996775, 29019992, 29042948, 29065643, 29088075,
+ 29110246, 29132154, 29153798, 29175180, 29196298, 29217151, 29237740,
+ 29258064, 29278123, 29297916, 29317443, 29336703, 29355697, 29374423,
+ 29392882, 29411073, 29428995, 29446649, 29464034, 29481149, 29497994,
+ 29514570, 29530875, 29546909, 29562672, 29578163, 29593382, 29608330,
+ 29623004, 29637406, 29651535, 29665390, 29678971, 29692278, 29705310,
+ 29718068, 29730550, 29742757, 29754688, 29766343, 29777721, 29788823,
+ 29799648, 29810195, 29820465, 29830457, 29840171, 29849606, 29858762,
+ 29867639, 29876237, 29884555, 29892593, 29900351, 29907829, 29915025,
+ 29921941, 29928575, 29934928, 29940999, 29946788, 29952294, 29957518,
+ 29962459, 29967117, 29971491, 29975582, 29979389, 29982912, 29986151,
+ 29989105, 29991774, 29994159, 29996258, 29998071, 29999599, 30000841,
+ 30001797, 30002467, 30002850, 30002946, 30002756, 30002278, 30001513,
+ 30000460, 29999119, 29997491, 29995574, 29993370, 29990876, 29988094,
+ 29985023, 29981663, 29978014, 29974075, 29969847, 29965329, 29960522,
+ 29955424, 29950036, 29944358, 29938389, 29932129, 29925579, 29918738,
+ 29911605, 29904182, 29896467, 29888460, 29880162, 29871572, 29862691,
+ 29853517, 29844051, 29834293, 29824242, 29813899, 29803264, 29792336,
+ 29781115, 29769601, 29757794, 29745694, 29733301, 29720615, 29707635,
+ 29694362, 29680795, 29666935, 29652781, 29638333, 29623592, 29608557,
+ 29593227, 29577604, 29561687, 29545475, 29528969, 29512170, 29495075,
+ 29477687, 29460004, 29442027, 29423755, 29405189, 29386329, 29367174,
+ 29347724, 29327980, 29307941, 29287607, 29266979, 29246057, 29224839,
+ 29203327, 29181521, 29159419, 29137023, 29114333, 29091347, 29068068,
+ 29044493, 29020624, 28996461, 28972002, 28947250, 28922203, 28896861,
+ 28871225, 28845295, 28819070, 28792551, 28765737, 28738630, 28711228,
+ 28683532, 28655543, 28627259, 28598681, 28569809, 28540644, 28511185,
+ 28481432, 28451386, 28421046, 28390413, 28359487, 28328267, 28296754,
+ 28264948, 28232849, 28200458, 28167773, 28134796, 28101527, 28067965,
+ 28034111, 27999964, 27965526, 27930796, 27895774, 27860460, 27824854,
+ 27788958, 27752770, 27716291, 27679520, 27642460, 27605108, 27567466,
+ 27529533, 27491311, 27452798, 27413995, 27374903, 27335521, 27295850,
+ 27255889, 27215640, 27175102, 27134275, 27093159, 27051756, 27010064,
+ 26968084, 26925817, 26883262, 26840420, 26797291, 26753875, 26710173,
+ 26666183, 26621908, 26577347, 26532500, 26487368, 26441950, 26396247,
+ 26350259, 26303987, 26257431, 26210590, 26163466, 26116058, 26068366,
+ 26020392, 25972135, 25923595, 25874773, 25825669, 25776283, 25726615,
+ 25676667, 25626438, 25575928, 25525137, 25474067, 25422717, 25371087,
+ 25319178, 25266991, 25214525, 25161780, 25108758, 25055458, 25001881,
+ 24948027, 24893896, 24839488, 24784805, 24729846, 24674612, 24619103,
+ 24563319, 24507261, 24450928, 24394323, 24337443, 24280291, 24222867,
+ 24165170, 24107201, 24048961, 23990449, 23931667, 23872615, 23813293,
+ 23753700, 23693839, 23633709, 23573310, 23512644, 23451709, 23390508,
+ 23329039, 23267304, 23205303, 23143036, 23080504, 23017708, 22954646,
+ 22891321, 22827732, 22763880, 22699766, 22635388, 22570750, 22505849,
+ 22440688, 22375266, 22309584, 22243643, 22177442, 22110982, 22044264,
+ 21977289, 21910056, 21842566, 21774819, 21706817, 21638559, 21570046,
+ 21501279, 21432257, 21362982, 21293454, 21223673, 21153640, 21083356,
+ 21012820, 20942034, 20870997, 20799712, 20728176, 20656393, 20584361,
+ 20512082, 20439556, 20366783, 20293764, 20220500, 20146991, 20073237,
+ 19999240, 19924999, 19850516, 19775790, 19700823, 19625614, 19550165,
+ 19474476, 19398547, 19322380, 19245974, 19169331, 19092450, 19015332,
+ 18937979, 18860390, 18782566, 18704508, 18626216, 18547691, 18468933,
+ 18389944, 18310723, 18231271, 18151589, 18071678, 17991538, 17911169,
+ 17830573, 17749749, 17668699, 17587423, 17505922, 17424196, 17342246,
+ 17260073, 17177677, 17095059, 17012219, 16929159, 16845878, 16762378,
+ 16678659, 16594721, 16510566, 16426195, 16341606, 16256803, 16171784,
+ 16086551, 16001104, 15915445, 15829573, 15743489, 15657195, 15570690,
+ 15483976, 15397053, 15309921, 15222583, 15135037, 15047285, 14959328,
+ 14871166, 14782800, 14694231, 14605460, 14516486, 14427311, 14337936,
+ 14248361, 14158587, 14068614, 13978445, 13888078, 13797515, 13706757,
+ 13615804, 13524657, 13433317, 13341785, 13250061, 13158146, 13066040,
+ 12973746, 12881262, 12788591, 12695733, 12602688, 12509457, 12416042,
+ 12322442, 12228660, 12134694, 12040547, 11946219, 11851710, 11757022,
+ 11662156, 11567111, 11471890, 11376492, 11280918, 11185170, 11089248,
+ 10993153, 10896885, 10800446, 10703836, 10607057, 10510108, 10412991,
+ 10315706, 10218255, 10120638, 10022856, 9924910, 9826800, 9728528,
+ 9630094, 9531499, 9432744, 9333830, 9234758, 9135528, 9036141, 8936599,
+ 8836901, 8737050, 8637045, 8536888, 8436579, 8336119, 8235509, 8134751,
+ 8033844, 7932790, 7831590, 7730244, 7628753, 7527119, 7425342, 7323422,
+ 7221362, 7119161, 7016821, 6914342, 6811725, 6708972, 6606083, 6503059,
+ 6399901, 6296610, 6193187, 6089632, 5985947, 5882132, 5778188, 5674117,
+ 5569919, 5465595, 5361146, 5256572, 5151876, 5047057, 4942117, 4837057,
+ 4731877, 4626579, 4521163, 4415630, 4309981, 4204218, 4098340, 3992350,
+ 3886248, 3780034, 3673711, 3567278, 3460737, 3354088, 3247334, 3140473,
+ 3033509, 2926440, 2819270, 2711997, 2604624, 2497152, 2389580, 2281911,
+ 2174145, 2066283, 1958327, 1850276, 1742133, 1633897, 1525571, 1417155,
+ 1308649, 1200056, 1091375, 982609, 873757, 764821, 655803, 546702,
+ 437519, 328257, 218916, 109496, 0, -109572, -219220, -328943, -438738,
+ -548606, -658544, -768553, -878631, -988778, -1098991, -1209270,
+ -1319615, -1430024, -1540495, -1651029, -1761624, -1872279, -1982993,
+ -2093765, -2204593, -2315478, -2426418, -2537411, -2648458, -2759556,
+ -2870705, -2981904, -3093152, -3204447, -3315789, -3427177, -3538609,
+ -3650085, -3761603, -3873163, -3984763, -4096403, -4208081, -4319796,
+ -4431547, -4543334, -4655155, -4767009, -4878895, -4990813, -5102760,
+ -5214736, -5326740, -5438770, -5550827, -5662908, -5775013, -5887140,
+ -5999289, -6111458, -6223647, -6335854, -6448078, -6560319, -6672575,
+ -6784844, -6897127, -7009422, -7121727, -7234043, -7346367, -7458698,
+ -7571037, -7683380, -7795729, -7908080, -8020434, -8132789, -8245145,
+ -8357499, -8469851, -8582200, -8694545, -8806885, -8919218, -9031544,
+ -9143862, -9256170, -9368467, -9480752, -9593025, -9705283, -9817527,
+ -9929755, -10041965, -10154157, -10266330, -10378482, -10490613,
+ -10602721, -10714805, -10826865, -10938898, -11050905, -11162883,
+ -11274833, -11386752, -11498639, -11610495, -11722316, -11834103,
+ -11945854, -12057569, -12169245, -12280883, -12392480, -12504036,
+ -12615549, -12727020, -12838445, -12949825, -13061159, -13172444,
+ -13283681, -13394867, -13506002, -13617085, -13728115, -13839090,
+ -13950010, -14060873, -14171679, -14282425, -14393112, -14503737,
+ -14614301, -14724801, -14835236, -14945607, -15055910, -15166146,
+ -15276314, -15386411, -15496437, -15606392, -15716273, -15826079,
+ -15935811, -16045466, -16155043, -16264542, -16373960, -16483298,
+ -16592554, -16701726, -16810815, -16919818, -17028735, -17137564,
+ -17246304, -17354955, -17463515, -17571982, -17680357, -17788638,
+ -17896823, -18004912, -18112904, -18220797, -18328590, -18436282,
+ -18543873, -18651360, -18758744, -18866022, -18973194, -19080259,
+ -19187215, -19294062, -19400797, -19507421, -19613933, -19720330,
+ -19826612, -19932778, -20038827, -20144757, -20250568, -20356258,
+ -20461826, -20567272, -20672594, -20777791, -20882862, -20987806,
+ -21092621, -21197307, -21301863, -21406287, -21510579, -21614737,
+ -21718760, -21822648, -21926398, -22030010, -22133483, -22236816,
+ -22340008, -22443057, -22545963, -22648724, -22751339, -22853808,
+ -22956129, -23058301, -23160323, -23262194, -23363913, -23465478,
+ -23566890, -23668146, -23769245, -23870187, -23970970, -24071594,
+ -24172057, -24272358, -24372496, -24472470, -24572279, -24671922,
+ -24771397, -24870705, -24969843, -25068811, -25167607, -25266231,
+ -25364681, -25462957, -25561057, -25658980, -25756725, -25854291,
+ -25951678, -26048883, -26145906, -26242747, -26339403, -26435873,
+ -26532158, -26628255, -26724164, -26819884, -26915413, -27010750,
+ -27105895, -27200846, -27295603, -27390164, -27484528, -27578695,
+ -27672662, -27766430, -27859997, -27953362, -28046524, -28139483,
+ -28232236, -28324783, -28417123, -28509255, -28601178, -28692890,
+ -28784392, -28875681, -28966758, -29057619, -29148266, -29238697,
+ -29328910, -29418905, -29508680, -29598236, -29687570, -29776681,
+ -29865570, -29954234, -30042672, -30130885, -30218870, -30306627,
+ -30394154, -30481451, -30568517, -30655350, -30741950, -30828316,
+ -30914447, -31000341, -31085998, -31171417, -31256596, -31341536,
+ -31426234, -31510690, -31594903, -31678872, -31762595, -31846073,
+ -31929304, -32012286, -32095020, -32177504, -32259737, -32341718,
+ -32423447, -32504922, -32586142, -32667106, -32747814, -32828264,
+ -32908456, -32988388, -33068060, -33147471, -33226619, -33305505,
+ -33384126, -33462482, -33540572, -33618395, -33695950, -33773237,
+ -33850254, -33927000, -34003475, -34079677, -34155606, -34231260,
+ -34306640, -34381743, -34456569, -34531118, -34605387, -34679377,
+ -34753086, -34826514, -34899659, -34972521, -35045098, -35117391,
+ -35189398, -35261117, -35332549, -35403693, -35474547, -35545110,
+ -35615383, -35685363, -35755050, -35824443, -35893542, -35962345,
+ -36030851, -36099060, -36166971, -36234583, -36301895, -36368907,
+ -36435617, -36502024, -36568128, -36633928, -36699424, -36764613,
+ -36829496, -36894071, -36958338, -37022296, -37085945, -37149282,
+ -37212308, -37275021, -37337422, -37399508, -37461280, -37522736,
+ -37583875, -37644698, -37705202, -37765388, -37825254, -37884800,
+ -37944024, -38002927, -38061506, -38119763, -38177695, -38235302,
+ -38292583, -38349537, -38406164, -38462463, -38518433, -38574074,
+ -38629384, -38684362, -38739009, -38793323, -38847304, -38900951,
+ -38954262, -39007238, -39059878, -39112181, -39164145, -39215771,
+ -39267058, -39318005, -39368611, -39418876, -39468798, -39518378,
+ -39567614, -39616505, -39665052, -39713253, -39761108, -39808615,
+ -39855775, -39902587, -39949049, -39995161, -40040923, -40086334,
+ -40131393, -40176099, -40220452, -40264451, -40308096, -40351386,
+ -40394319, -40436897, -40479117, -40520979, -40562483, -40603628,
+ -40644413, -40684838, -40724902, -40764604, -40803944, -40842922,
+ -40881535, -40919785, -40957670, -40995190, -41032344, -41069131,
+ -41105551, -41141604, -41177288, -41212603, -41247549, -41282125,
+ -41316330, -41350164, -41383626, -41416715, -41449432, -41481775,
+ -41513744, -41545339, -41576558, -41607402, -41637869, -41667960,
+ -41697673, -41727008, -41755965, -41784542, -41812741, -41840559,
+ -41867996, -41895053, -41921728, -41948020, -41973930, -41999457,
+ -42024601, -42049360, -42073735, -42097724, -42121328, -42144545,
+ -42167377, -42189821, -42211877, -42233545, -42254825, -42275716,
+ -42296218, -42316330, -42336051, -42355381, -42374321, -42392868,
+ -42411024, -42428787, -42446157, -42463133, -42479716, -42495904,
+ -42511698, -42527096, -42542099, -42556706, -42570917, -42584731,
+ -42598147, -42611166, -42623788, -42636010, -42647834, -42659259,
+ -42670285, -42680911, -42691136, -42700961, -42710384, -42719407,
+ -42728028, -42736246, -42744063, -42751476, -42758487, -42765094,
+ -42771297, -42777097, -42782491, -42787481, -42792066, -42796246,
+ -42800020, -42803388, -42806350, -42808905, -42811053, -42812794,
+ -42814127, -42815052, -42815570, -42815679, -42815380, -42814671,
+ -42813554, -42812027, -42810090, -42807744, -42804987, -42801820,
+ -42798242, -42794253, -42789853, -42785041, -42779818, -42774183,
+ -42768136, -42761676, -42754804, -42747520, -42739822, -42731711,
+ -42723187, -42714249, -42704897, -42695132, -42684952, -42674358,
+ -42663350, -42651927, -42640089, -42627836, -42615168, -42602085,
+ -42588586, -42574671, -42560341, -42545595, -42530433, -42514854,
+ -42498860, -42482448, -42465621, -42448376, -42430715, -42412637,
+ -42394142, -42375230, -42355900, -42336153, -42315989, -42295407,
+ -42274408, -42252991, -42231156, -42208904, -42186233, -42163145,
+ -42139639, -42115714, -42091372, -42066611, -42041432, -42015835,
+ -41989820, -41963386, -41936534, -41909264, -41881575, -41853468,
+ -41824942, -41795998, -41766636, -41736855, -41706655, -41676038,
+ -41645002, -41613547, -41581674, -41549383, -41516673, -41483546,
+ -41450000, -41416035, -41381653, -41346852, -41311634, -41275997,
+ -41239943, -41203470, -41166580, -41129272, -41091546, -41053403,
+ -41014842, -40975864, -40936469, -40896656, -40856426, -40815780,
+ -40774716, -40733235, -40691338, -40649024, -40606294, -40563148,
+ -40519585, -40475607, -40431212, -40386402, -40341176, -40295535,
+ -40249478, -40203007, -40156120, -40108819, -40061103, -40012972,
+ -39964427, -39915469, -39866096, -39816310, -39766110, -39715497,
+ -39664471, -39613032, -39561181, -39508917, -39456241, -39403153,
+ -39349653, -39295741, -39241419, -39186685, -39131541, -39075986,
+ -39020021, -38963646, -38906861, -38849667, -38792063, -38734051,
+ -38675630, -38616801, -38557563, -38497918, -38437865, -38377406,
+ -38316539, -38255266, -38193587, -38131501, -38069010, -38006114,
+ -37942813, -37879107, -37814997, -37750484, -37685566, -37620246,
+ -37554522, -37488396, -37421868, -37354938, -37287607, -37219874,
+ -37151741, -37083208, -37014275, -36944942, -36875211, -36805080,
+ -36734552, -36663625, -36592301, -36520580, -36448463, -36375949,
+ -36303039, -36229734, -36156034, -36081940, -36007452, -35932570,
+ -35857295, -35781627, -35705567, -35629116, -35552273, -35475039,
+ -35397415, -35319402, -35240999, -35162207, -35083026, -35003458,
+ -34923503, -34843160, -34762432, -34681317, -34599818, -34517933,
+ -34435664, -34353012, -34269976, -34186558, -34102757, -34018575,
+ -33934012, -33849068, -33763745, -33678042, -33591961, -33505501,
+ -33418664, -33331449, -33243858, -33155892, -33067549, -32978833,
+ -32889742, -32800278, -32710440, -32620231, -32529650, -32438698,
+ -32347375, -32255683, -32163621, -32071191, -31978393, -31885228,
+ -31791696, -31697799, -31603536, -31508908, -31413916, -31318561,
+ -31222844, -31126764, -31030323, -30933522, -30836360, -30738840,
+ -30640961, -30542724, -30444130, -30345179, -30245873, -30146212,
+ -30046196, -29945827, -29845105, -29744031, -29642605, -29540829,
+ -29438703, -29336228, -29233404, -29130233, -29026714, -28922850,
+ -28818640, -28714086, -28609187, -28503946, -28398362, -28292437,
+ -28186171, -28079565, -27972620, -27865337, -27757716, -27649758,
+ -27541465, -27432836, -27323873, -27214576, -27104947, -26994986,
+ -26884694, -26774071, -26663120, -26551840, -26440232, -26328297,
+ -26216037, -26103451, -25990541, -25877308, -25763752, -25649875,
+ -25535677, -25421159, -25306322, -25191167, -25075694, -24959906,
+ -24843802, -24727383, -24610651, -24493606, -24376249, -24258581,
+ -24140604, -24022317, -23903723, -23784821, -23665612, -23546099,
+ -23426281, -23306160, -23185736, -23065010, -22943985, -22822659,
+ -22701035, -22579113, -22456894, -22334380, -22211570, -22088467,
+ -21965072, -21841384, -21717405, -21593137, -21468580, -21343734,
+ -21218602, -21093185, -20967482, -20841495, -20715226, -20588675,
+ -20461843, -20334731, -20207341, -20079673, -19951728, -19823508,
+ -19695013, -19566245, -19437204, -19307891, -19178309, -19048457,
+ -18918337, -18787949, -18657296, -18526377, -18395195, -18263750,
+ -18132043, -18000075, -17867848, -17735362, -17602618, -17469619,
+ -17336364, -17202855, -17069093, -16935079, -16800814, -16666300,
+ -16531537, -16396526, -16261270, -16125768, -15990022, -15854033,
+ -15717803, -15581332, -15444621, -15307672, -15170486, -15033064,
+ -14895407, -14757516, -14619393, -14481039, -14342454, -14203640,
+ -14064599, -13925330, -13785836, -13646118, -13506177, -13366014,
+ -13225630, -13085027, -12944205, -12803166, -12661911, -12520442,
+ -12378759, -12236863, -12094757, -11952441, -11809916, -11667183,
+ -11524245, -11381101, -11237754, -11094204, -10950453, -10806502,
+ -10662352, -10518005, -10373461, -10228723, -10083790, -9938665,
+ -9793349, -9647843, -9502148, -9356266, -9210198, -9063944, -8917507,
+ -8770888, -8624087, -8477107, -8329949, -8182613, -8035101, -7887414,
+ -7739554, -7591523, -7443320, -7294948, -7146408, -6997701, -6848828,
+ -6699792, -6550592, -6401231, -6251710, -6102030, -5952192, -5802198,
+ -5652049, -5501747, -5351292, -5200686, -5049931, -4899027, -4747977,
+ -4596781, -4445441, -4293958, -4142334, -3990569, -3838666, -3686625,
+ -3534448, -3382137, -3229692, -3077115, -2924408, -2771571, -2618607,
+ -2465516, -2312300, -2158961, -2005499, -1851916, -1698214, -1544394,
+ -1390456, -1236404, -1082238, -927959, -773568, -619068, -464460,
+ -309745, -154924, 0, 155027, 310156, 465385, 620712, 776136, 931656,
+ 1087270, 1242977, 1398775, 1554663, 1710639, 1866703, 2022852, 2179085,
+ 2335401, 2491799, 2648276, 2804832, 2961464, 3118173, 3274955, 3431810,
+ 3588736, 3745732, 3902796, 4059926, 4217123, 4374383, 4531705, 4689089,
+ 4846532, 5004033, 5161590, 5319203, 5476869, 5634588, 5792357, 5950175,
+ 6108041, 6265954, 6423911, 6581911, 6739954, 6898036, 7056158, 7214316,
+ 7372511, 7530740, 7689002, 7847296, 8005619, 8163971, 8322349, 8480753,
+ 8639181, 8797632, 8956103, 9114594, 9273103, 9431628, 9590168, 9748721,
+ 9907287, 10065862, 10224447, 10383039, 10541637, 10700240, 10858845,
+ 11017451, 11176057, 11334662, 11493264, 11651860, 11810451, 11969033,
+ 12127607, 12286169, 12444719, 12603256, 12761777, 12920281, 13078766,
+ 13237232, 13395676, 13554097, 13712494, 13870864, 14029207, 14187521,
+ 14345804, 14504055, 14662272, 14820453, 14978598, 15136705, 15294772,
+ 15452797, 15610780, 15768718, 15926609, 16084454, 16242249, 16399993,
+ 16557686, 16715324, 16872908, 17030434, 17187902, 17345310, 17502657,
+ 17659941, 17817160, 17974313, 18131399, 18288415, 18445361, 18602234,
+ 18759034, 18915758, 19072405, 19228974, 19385462, 19541870, 19698194,
+ 19854433, 20010586, 20166652, 20322628, 20478514, 20634306, 20790005,
+ 20945609, 21101115, 21256523, 21411831, 21567037, 21722140, 21877138,
+ 22032029, 22186813, 22341487, 22496050, 22650501, 22804838, 22959059,
+ 23113162, 23267147, 23421012, 23574755, 23728375, 23881869, 24035237,
+ 24188477, 24341587, 24494567, 24647413, 24800125, 24952702, 25105141,
+ 25257441, 25409601, 25561619, 25713494, 25865223, 26016806, 26168240,
+ 26319525, 26470659, 26621640, 26772466, 26923137, 27073650, 27224004,
+ 27374198, 27524230, 27674098, 27823801, 27973337, 28122706, 28271904,
+ 28420931, 28569786, 28718466, 28866970, 29015296, 29163444, 29311412,
+ 29459197, 29606799, 29754215, 29901445, 30048487, 30195340, 30342001,
+ 30488469, 30634743, 30780822, 30926703, 31072385, 31217867, 31363147,
+ 31508224, 31653096, 31797761, 31942218, 32086466, 32230503, 32374328,
+ 32517939, 32661334, 32804512, 32947471, 33090211, 33232728, 33375023,
+ 33517094, 33658938, 33800554, 33941942, 34083099, 34224024, 34364715,
+ 34505172, 34645391, 34785373, 34925115, 35064616, 35203875, 35342889,
+ 35481658, 35620180, 35758453, 35896477, 36034249, 36171768, 36309033,
+ 36446042, 36582793, 36719286, 36855518, 36991489, 37127196, 37262638,
+ 37397815, 37532723, 37667363, 37801732, 37935829, 38069652, 38203200,
+ 38336472, 38469466, 38602181, 38734615, 38866767, 38998635, 39130218,
+ 39261514, 39392522, 39523241, 39653669, 39783805, 39913647, 40043194,
+ 40172444, 40301396, 40430048, 40558400, 40686449, 40814195, 40941635,
+ 41068769, 41195595, 41322111, 41448317, 41574210, 41699790, 41825054,
+ 41950002, 42074633, 42198944, 42322934, 42446603, 42569948, 42692968,
+ 42815661, 42938028, 43060065, 43181772, 43303147, 43424189, 43544897,
+ 43665269, 43785303, 43904999, 44024355, 44143370, 44262041, 44380369,
+ 44498352, 44615987, 44733275, 44850213, 44966800, 45083036, 45198917,
+ 45314444, 45429615, 45544428, 45658882, 45772977, 45886709, 46000079,
+ 46113085, 46225726, 46337999, 46449905, 46561441, 46672607, 46783400,
+ 46893820, 47003866, 47113536, 47222829, 47331743, 47440277, 47548430,
+ 47656201, 47763589, 47870591, 47977208, 48083437, 48189277, 48294727,
+ 48399787, 48504453, 48608726, 48712604, 48816086, 48919170, 49021855,
+ 49124141, 49226025, 49327507, 49428585, 49529259, 49629526, 49729385,
+ 49828837, 49927878, 50026509, 50124727, 50222531, 50319922, 50416896,
+ 50513453, 50609592, 50705312, 50800611, 50895488, 50989943, 51083973,
+ 51177578, 51270756, 51363507, 51455828, 51547720, 51639181, 51730209,
+ 51820804, 51910965, 52000689, 52089977, 52178827, 52267237, 52355208,
+ 52442736, 52529823, 52616465, 52702663, 52788415, 52873720, 52958577,
+ 53042984, 53126942, 53210447, 53293501, 53376100, 53458246, 53539935,
+ 53621167, 53701942, 53782258, 53862113, 53941508, 54020440, 54098909,
+ 54176914, 54254453, 54331526, 54408132, 54484269, 54559937, 54635134,
+ 54709860, 54784113, 54857892, 54931197, 55004027, 55076379, 55148255,
+ 55219651, 55290568, 55361005, 55430959, 55500432, 55569420, 55637925,
+ 55705943, 55773476, 55840521, 55907077, 55973144, 56038721, 56103807,
+ 56168401, 56232501, 56296108, 56359219, 56421835, 56483954, 56545575,
+ 56606697, 56667320, 56727442, 56787064, 56846182, 56904798, 56962910,
+ 57020517, 57077618, 57134212, 57190299, 57245877, 57300947, 57355506,
+ 57409554, 57463090, 57516113, 57568624, 57620619, 57672100, 57723064,
+ 57773512, 57823442, 57872854, 57921746, 57970118, 58017970, 58065300,
+ 58112107, 58158391, 58204151, 58249386, 58294096, 58338279, 58381935,
+ 58425063, 58467663, 58509733, 58551273, 58592282, 58632760, 58672705,
+ 58712117, 58750995, 58789339, 58827148, 58864420, 58901156, 58937355,
+ 58973016, 59008138, 59042720, 59076762, 59110264, 59143224, 59175642,
+ 59207517, 59238849, 59269637, 59299880, 59329577, 59358729, 59387334,
+ 59415391, 59442901, 59469862, 59496274, 59522137, 59547449, 59572209,
+ 59596419, 59620076, 59643181, 59665732, 59687729, 59709172, 59730060,
+ 59750392, 59770168, 59789388, 59808050, 59826154, 59843700, 59860688,
+ 59877115, 59892983, 59908291, 59923038, 59937223, 59950846, 59963907,
+ 59976405, 59988340, 59999710, 60010517, 60020758, 60030435, 60039545,
+ 60048089, 60056067, 60063478, 60070321, 60076596, 60082302, 60087440,
+ 60092009, 60096007, 60099436, 60102295, 60104582, 60106298, 60107443,
+ 60108015, 60108015, 60107443, 60106297, 60104577, 60102284, 60099417,
+ 60095975, 60091958, 60087366, 60082198, 60076454, 60070134, 60063238,
+ 60055765, 60047714, 60039086, 60029881, 60020097, 60009735, 59998794,
+ 59987275, 59975176, 59962499, 59949241, 59935404, 59920986, 59905988,
+ 59890409, 59874250, 59857509, 59840188, 59822284, 59803799, 59784732,
+ 59765083, 59744852, 59724038, 59702642, 59680662, 59658100, 59634955,
+ 59611226, 59586914, 59562018, 59536538, 59510475, 59483827, 59456595,
+ 59428779, 59400379, 59371394, 59341824, 59311670, 59280931, 59249607,
+ 59217698, 59185204, 59152125, 59118461, 59084212, 59049377, 59013957,
+ 58977951, 58941361, 58904184, 58866423, 58828075, 58789143, 58749624,
+ 58709520, 58668831, 58627556, 58585696, 58543250, 58500219, 58456602,
+ 58412400, 58367613, 58322240, 58276282, 58229739, 58182611, 58134898,
+ 58086599, 58037716, 57988248, 57938196, 57887558, 57836336, 57784530,
+ 57732140, 57679165, 57625606, 57571464, 57516737, 57461427, 57405534,
+ 57349057, 57291997, 57234354, 57176128, 57117319, 57057928, 56997955,
+ 56937400, 56876262, 56814543, 56752243, 56689361, 56625899, 56561855,
+ 56497231, 56432027, 56366242, 56299878, 56232934, 56165411, 56097308,
+ 56028627, 55959368, 55889530, 55819114, 55748121, 55676550, 55604403,
+ 55531678, 55458377, 55384501, 55310048, 55235020, 55159417, 55083240,
+ 55006488, 54929162, 54851262, 54772790, 54693744, 54614126, 54533935,
+ 54453173, 54371840, 54289936, 54207461, 54124417, 54040802, 53956619,
+ 53871866, 53786546, 53700657, 53614201, 53527178, 53439588, 53351432,
+ 53262711, 53173425, 53083574, 52993158, 52902180, 52810638, 52718533,
+ 52625866, 52532638, 52438849, 52344499, 52249589, 52154120, 52058091,
+ 51961505, 51864360, 51766659, 51668400, 51569586, 51470216, 51370291,
+ 51269812, 51168779, 51067193, 50965054, 50862364, 50759122, 50655330,
+ 50550987, 50446096, 50340655, 50234666, 50128130, 50021048, 49913419,
+ 49805244, 49696525, 49587262, 49477456, 49367107, 49256215, 49144783,
+ 49032810, 48920297, 48807245, 48693655, 48579527, 48464862, 48349661,
+ 48233924, 48117653, 48000848, 47883510, 47765639, 47647237, 47528304,
+ 47408841, 47288849, 47168329, 47047281, 46925706, 46803605, 46680979,
+ 46557828, 46434154, 46309958, 46185240, 46060000, 45934241, 45807962,
+ 45681165, 45553851, 45426020, 45297673, 45168812, 45039436, 44909548,
+ 44779147, 44648235, 44516813, 44384881, 44252441, 44119494, 43986040,
+ 43852080, 43717616, 43582648, 43447177, 43311204, 43174730, 43037757,
+ 42900285, 42762315, 42623848, 42484885, 42345427, 42205475, 42065031,
+ 41924094, 41782667, 41640750, 41498345, 41355451, 41212071, 41068205,
+ 40923855, 40779021, 40633705, 40487908, 40341630, 40194873, 40047638,
+ 39899926, 39751738, 39603075, 39453939, 39304330, 39154250, 39003699,
+ 38852679, 38701191, 38549236, 38396815, 38243930, 38090581, 37936770,
+ 37782498, 37627766, 37472575, 37316926, 37160821, 37004261, 36847247,
+ 36689780, 36531861, 36373492, 36214674, 36055408, 35895695, 35735537,
+ 35574934, 35413889, 35252401, 35090474, 34928107, 34765301, 34602060,
+ 34438382, 34274271, 34109727, 33944751, 33779345, 33613510, 33447247,
+ 33280558, 33113443, 32945905, 32777945, 32609563, 32440762, 32271542,
+ 32101905, 31931853, 31761386, 31590506, 31419214, 31247512, 31075401,
+ 30902883, 30729958, 30556628, 30382896, 30208761, 30034225, 29859291,
+ 29683958, 29508229, 29332106, 29155588, 28978679, 28801379, 28623690,
+ 28445612, 28267149, 28088301, 27909069, 27729455, 27549461, 27369088,
+ 27188337, 27007210, 26825708, 26643834, 26461587, 26278971, 26095986,
+ 25912634, 25728916, 25544834, 25360389, 25175584, 24990419, 24804896,
+ 24619016, 24432782, 24246194, 24059255, 23871965, 23684326, 23496341,
+ 23308009, 23119334, 22930316, 22740958, 22551260, 22361225, 22170853,
+ 21980147, 21789108, 21597738, 21406038, 21214010, 21021656, 20828977,
+ 20635974, 20442651, 20249007, 20055045, 19860766, 19666172, 19471265,
+ 19276047, 19080518, 18884681, 18688537, 18492088, 18295336, 18098282,
+ 17900928, 17703276, 17505327, 17307084, 17108547, 16909719, 16710601,
+ 16511194, 16311502, 16111524, 15911264, 15710723, 15509902, 15308803,
+ 15107428, 14905780, 14703858, 14501666, 14299205, 14096476, 13893482,
+ 13690224, 13486704, 13282924, 13078886, 12874591, 12670041, 12465238,
+ 12260183, 12054880, 11849328, 11643530, 11437489, 11231205, 11024680,
+ 10817917, 10610917, 10403682, 10196214, 9988514, 9780585, 9572428,
+ 9364045, 9155438, 8946609, 8737559, 8528291, 8318806, 8109107, 7899194,
+ 7689070, 7478737, 7268197, 7057451, 6846502, 6635351, 6424000, 6212451,
+ 6000706, 5788767, 5576636, 5364314, 5151804, 4939107, 4726225, 4513161,
+ 4299915, 4086491, 3872890, 3659114, 3445164, 3231043, 3016753, 2802296,
+ 2587673, 2372886, 2157938, 1942831, 1727565, 1512144, 1296569, 1080842,
+ 864966, 648941, 432771, 216456, 0, -216596, -433331, -650202, -867206,
+ -1084343, -1301611, -1519006, -1736528, -1954173, -2171941, -2389829,
+ -2607836, -2825958, -3044195, -3262544, -3481003, -3699570, -3918244,
+ -4137021, -4355901, -4574881, -4793959, -5013133, -5232401, -5451761,
+ -5671211, -5890749, -6110373, -6330081, -6549871, -6769740, -6989687,
+ -7209710, -7429807, -7649975, -7870213, -8090518, -8310889, -8531323,
+ -8751818, -8972373, -9192985, -9413652, -9634372, -9855144, -10075964,
+ -10296831, -10517743, -10738697, -10959692, -11180726, -11401796,
+ -11622901, -11844038, -12065205, -12286400, -12507622, -12728867,
+ -12950134, -13171421, -13392726, -13614046, -13835380, -14056725,
+ -14278079, -14499441, -14720808, -14942177, -15163548, -15384917,
+ -15606283, -15827644, -16048997, -16270340, -16491671, -16712989,
+ -16934290, -17155574, -17376837, -17598077, -17819294, -18040483,
+ -18261644, -18482774, -18703871, -18924932, -19145957, -19366942,
+ -19587885, -19808785, -20029639, -20250446, -20471202, -20691906,
+ -20912555, -21133148, -21353683, -21574157, -21794568, -22014913,
+ -22235192, -22455402, -22675540, -22895604, -23115593, -23335503,
+ -23555334, -23775083, -23994747, -24214325, -24433814, -24653213,
+ -24872518, -25091729, -25310842, -25529856, -25748768, -25967577,
+ -26186280, -26404875, -26623360, -26841733, -27059991, -27278133,
+ -27496156, -27714058, -27931837, -28149491, -28367018, -28584415,
+ -28801681, -29018813, -29235808, -29452666, -29669384, -29885959,
+ -30102389, -30318673, -30534808, -30750792, -30966622, -31182298,
+ -31397816, -31613174, -31828370, -32043403, -32258269, -32472968,
+ -32687495, -32901851, -33116031, -33330035, -33543859, -33757503,
+ -33970963, -34184238, -34397325, -34610222, -34822927, -35035438,
+ -35247754, -35459870, -35671786, -35883500, -36095009, -36306310,
+ -36517403, -36728284, -36938952, -37149405, -37359640, -37569655,
+ -37779448, -37989016, -38198359, -38407473, -38616357, -38825008,
+ -39033425, -39241604, -39449544, -39657243, -39864699, -40071909,
+ -40278872, -40485585, -40692046, -40898253, -41104204, -41309897,
+ -41515329, -41720499, -41925405, -42130043, -42334413, -42538512,
+ -42742337, -42945888, -43149161, -43352154, -43554867, -43757295,
+ -43959438, -44161293, -44362857, -44564130, -44765109, -44965791,
+ -45166175, -45366258, -45566039, -45765515, -45964684, -46163544,
+ -46362093, -46560330, -46758251, -46955855, -47153139, -47350102,
+ -47546742, -47743056, -47939042, -48134699, -48330023, -48525014,
+ -48719669, -48913986, -49107963, -49301597, -49494888, -49687832,
+ -49880427, -50072673, -50264565, -50456104, -50647285, -50838109,
+ -51028571, -51218671, -51408406, -51597774, -51786773, -51975401,
+ -52163657, -52351537, -52539041, -52726166, -52912909, -53099270,
+ -53285245, -53470833, -53656033, -53840841, -54025255, -54209275,
+ -54392898, -54576121, -54758944, -54941363, -55123377, -55304984,
+ -55486181, -55666968, -55847341, -56027300, -56206841, -56385963,
+ -56564664, -56742943, -56920796, -57098222, -57275219, -57451786,
+ -57627919, -57803618, -57978880, -58153704, -58328087, -58502027,
+ -58675523, -58848572, -59021173, -59193323, -59365022, -59536266,
+ -59707054, -59877384, -60047254, -60216662, -60385607, -60554085,
+ -60722096, -60889638, -61056709, -61223306, -61389428, -61555072,
+ -61720238, -61884924, -62049126, -62212844, -62376075, -62538819,
+ -62701072, -62862833, -63024100, -63184871, -63345145, -63504919,
+ -63664192, -63822962, -63981227, -64138986, -64296235, -64452974,
+ -64609201, -64764914, -64920111, -65074790, -65228950, -65382589,
+ -65535704, -65688295, -65840358, -65991894, -66142899, -66293372,
+ -66443311, -66592715, -66741581, -66889908, -67037695, -67184938,
+ -67331638, -67477791, -67623396, -67768452, -67912956, -68056907,
+ -68200304, -68343144, -68485425, -68627147, -68768307, -68908904,
+ -69048936, -69188401, -69327297, -69465623, -69603378, -69740559,
+ -69877164, -70013193, -70148643, -70283514, -70417802, -70551507,
+ -70684626, -70817159, -70949103, -71080458, -71211220, -71341390,
+ -71470964, -71599942, -71728322, -71856101, -71983280, -72109855,
+ -72235826, -72361191, -72485948, -72610095, -72733632, -72856556,
+ -72978867, -73100561, -73221639, -73342097, -73461936, -73581153,
+ -73699746, -73817715, -73935057, -74051771, -74167856, -74283310,
+ -74398131, -74512319, -74625871, -74738786, -74851063, -74962700,
+ -75073695, -75184048, -75293756, -75402819, -75511234, -75619001,
+ -75726118, -75832583, -75938395, -76043553, -76148055, -76251899,
+ -76355085, -76457611, -76559476, -76660677, -76761215, -76861087,
+ -76960291, -77058828, -77156694, -77253890, -77350413, -77446262,
+ -77541436, -77635933, -77729753, -77822893, -77915353, -78007131,
+ -78098226, -78188637, -78278362, -78367399, -78455749, -78543408,
+ -78630377, -78716654, -78802237, -78887126, -78971318, -79054814,
+ -79137611, -79219708, -79301104, -79381798, -79461789, -79541075,
+ -79619656, -79697529, -79774694, -79851150, -79926895, -80001929,
+ -80076249, -80149856, -80222747, -80294922, -80366379, -80437117,
+ -80507136, -80576434, -80645010, -80712862, -80779990, -80846393,
+ -80912069, -80977018, -81041237, -81104727, -81167487, -81229514,
+ -81290808, -81351368, -81411193, -81470282, -81528634, -81586248,
+ -81643122, -81699256, -81754649, -81809299, -81863207, -81916370,
+ -81968787, -82020459, -82071383, -82121559, -82170986, -82219663,
+ -82267589, -82314763, -82361184, -82406851, -82451763, -82495920,
+ -82539320, -82581963, -82623847, -82664972, -82705337, -82744941,
+ -82783783, -82821862, -82859178, -82895729, -82931515, -82966535,
+ -83000788, -83034273, -83066989, -83098936, -83130113, -83160519,
+ -83190153, -83219014, -83247103, -83274417, -83300956, -83326719,
+ -83351707, -83375917, -83399349, -83422003, -83443878, -83464972,
+ -83485286, -83504818, -83523569, -83541536, -83558721, -83575121,
+ -83590736, -83605566, -83619610, -83632867, -83645337, -83657018,
+ -83667912, -83678016, -83687330, -83695854, -83703586, -83710528,
+ -83716677, -83722033, -83726596, -83730365, -83733340, -83735520,
+ -83736904, -83737492, -83737284, -83736279, -83734476, -83731875,
+ -83728476, -83724277, -83719280, -83713482, -83706884, -83699484,
+ -83691284, -83682282, -83672477, -83661870, -83650460, -83638247,
+ -83625230, -83611408, -83596782, -83581350, -83565114, -83548071,
+ -83530223, -83511568, -83492106, -83471837, -83450761, -83428877,
+ -83406184, -83382684, -83358374, -83333256, -83307328, -83280591,
+ -83253044, -83224687, -83195519, -83165541, -83134752, -83103152,
+ -83070741, -83037518, -83003483, -82968637, -82932978, -82896507,
+ -82859224, -82821128, -82782219, -82742497, -82701962, -82660614,
+ -82618453, -82575478, -82531689, -82487087, -82441670, -82395440,
+ -82348396, -82300538, -82251865, -82202379, -82152078, -82100962,
+ -82049033, -81996289, -81942730, -81888357, -81833170, -81777168,
+ -81720351, -81662721, -81604275, -81545016, -81484942, -81424054,
+ -81362351, -81299834, -81236503, -81172358, -81107400, -81041627,
+ -80975040, -80907640, -80839426, -80770399, -80700558, -80629905,
+ -80558438, -80486158, -80413066, -80339161, -80264444, -80188914,
+ -80112573, -80035420, -79957455, -79878679, -79799091, -79718693,
+ -79637484, -79555465, -79472636, -79388996, -79304547, -79219289,
+ -79133222, -79046345, -78958661, -78870168, -78780867, -78690759,
+ -78599844, -78508122, -78415593, -78322258, -78228118, -78133172,
+ -78037421, -77940866, -77843506, -77745342, -77646375, -77546605,
+ -77446033, -77344658, -77242482, -77139504, -77035726, -76931148,
+ -76825769, -76719591, -76612615, -76504840, -76396267, -76286897,
+ -76176730, -76065767, -75954009, -75841455, -75728106, -75613963,
+ -75499027, -75383298, -75266777, -75149464, -75031359, -74912465,
+ -74792780, -74672306, -74551043, -74428993, -74306155, -74182530,
+ -74058120, -73932924, -73806943, -73680179, -73552631, -73424300,
+ -73295188, -73165295, -73034621, -72903167, -72770935, -72637924,
+ -72504136, -72369571, -72234231, -72098115, -71961225, -71823562,
+ -71685125, -71545917, -71405938, -71265189, -71123670, -70981383,
+ -70838328, -70694506, -70549918, -70404566, -70258449, -70111568,
+ -69963926, -69815522, -69666357, -69516432, -69365749, -69214309,
+ -69062111, -68909157, -68755449, -68600986, -68445771, -68289804,
+ -68133086, -67975617, -67817400, -67658435, -67498723, -67338265,
+ -67177062, -67015116, -66852426, -66688995, -66524824, -66359913,
+ -66194263, -66027876, -65860753, -65692895, -65524303, -65354978,
+ -65184921, -65014134, -64842617, -64670372, -64497399, -64323701,
+ -64149278, -63974132, -63798263, -63621672, -63444362, -63266333,
+ -63087587, -62908124, -62727946, -62547055, -62365450, -62183135,
+ -62000109, -61816375, -61631933, -61446785, -61260932, -61074376,
+ -60887118, -60699158, -60510499, -60321142, -60131087, -59940337,
+ -59748893, -59556757, -59363928, -59170410, -58976203, -58781309,
+ -58585729, -58389464, -58192516, -57994887, -57796578, -57597590,
+ -57397924, -57197583, -56996567, -56794879, -56592519, -56389489,
+ -56185791, -55981426, -55776395, -55570701, -55364344, -55157327,
+ -54949650, -54741315, -54532324, -54322678, -54112380, -53901430,
+ -53689829, -53477581, -53264686, -53051146, -52836962, -52622136,
+ -52406670, -52190565, -51973823, -51756446, -51538435, -51319793,
+ -51100519, -50880617, -50660088, -50438934, -50217156, -49994756,
+ -49771735, -49548096, -49323841, -49098970, -48873486, -48647390,
+ -48420685, -48193371, -47965451, -47736927, -47507799, -47278071,
+ -47047743, -46816819, -46585298, -46353184, -46120477, -45887181,
+ -45653296, -45418825, -45183769, -44948130, -44711911, -44475112,
+ -44237736, -43999785, -43761261, -43522165, -43282499, -43042266,
+ -42801467, -42560103, -42318178, -42075693, -41832650, -41589051,
+ -41344898, -41100192, -40854936, -40609132, -40362781, -40115886,
+ -39868449, -39620472, -39371956, -39122903, -38873317, -38623198,
+ -38372549, -38121372, -37869668, -37617440, -37364691, -37111421,
+ -36857633, -36603330, -36348512, -36093183, -35837345, -35580998,
+ -35324147, -35066792, -34808936, -34550580, -34291728, -34032381,
+ -33772542, -33512212, -33251393, -32990088, -32728299, -32466029,
+ -32203279, -31940051, -31676348, -31412171, -31147524, -30882408,
+ -30616826, -30350779, -30084270, -29817301, -29549875, -29281994,
+ -29013659, -28744873, -28475639, -28205959, -27935834, -27665268,
+ -27394262, -27122819, -26850941, -26578630, -26305889, -26032720,
+ -25759125, -25485107, -25210668, -24935810, -24660536, -24384848,
+ -24108748, -23832238, -23555322, -23278001, -23000278, -22722155,
+ -22443634, -22164719, -21885410, -21605712, -21325625, -21045153,
+ -20764298, -20483062, -20201447, -19919457, -19637094, -19354360,
+ -19071257, -18787788, -18503955, -18219761, -17935209, -17650300,
+ -17365037, -17079423, -16793461, -16507152, -16220499, -15933505,
+ -15646172, -15358503, -15070500, -14782165, -14493502, -14204513,
+ -13915200, -13625566, -13335613, -13045344, -12754761, -12463868,
+ -12172666, -11881158, -11589347, -11297235, -11004825, -10712119,
+ -10419121, -10125832, -9832255, -9538393, -9244249, -8949824, -8655122,
+ -8360146, -8064897, -7769378, -7473593, -7177544, -6881233, -6584663,
+ -6287836, -5990756, -5693425, -5395846, -5098020, -4799952, -4501644,
+ -4203097, -3904316, -3605303, -3306059, -3006589, -2706895, -2406979,
+ -2106844, -1806493, -1505928, -1205153, -904170, -602981, -301590, 0,
+ 301788, 603770, 905944, 1208307, 1510856, 1813588, 2116501, 2419592,
+ 2722858, 3026297, 3329905, 3633680, 3937619, 4241719, 4545978, 4850392,
+ 5154959, 5459677, 5764542, 6069551, 6374702, 6679992, 6985418, 7290977,
+ 7596667, 7902485, 8208427, 8514492, 8820676, 9126976, 9433390, 9739914,
+ 10046547, 10353284, 10660124, 10967063, 11274098, 11581227, 11888447,
+ 12195755, 12503149, 12810624, 13118179, 13425810, 13733515, 14041291,
+ 14349134, 14657043, 14965013, 15273043, 15581130, 15889270, 16197460,
+ 16505698, 16813981, 17122306, 17430670, 17739070, 18047504, 18355967,
+ 18664458, 18972974, 19281511, 19590067, 19898638, 20207223, 20515817,
+ 20824418, 21133024, 21441630, 21750235, 22058835, 22367428, 22676010,
+ 22984578, 23293130, 23601663, 23910173, 24218658, 24527115, 24835541,
+ 25143932, 25452287, 25760601, 26068873, 26377099, 26685276, 26993401,
+ 27301471, 27609484, 27917436, 28225324, 28533146, 28840898, 29148578,
+ 29456182, 29763707, 30071152, 30378511, 30685784, 30992966, 31300055,
+ 31607047, 31913941, 32220732, 32527417, 32833995, 33140461, 33446814,
+ 33753049, 34059164, 34365156, 34671021, 34976758, 35282363, 35587833,
+ 35893164, 36198355, 36503401, 36808301, 37113051, 37417647, 37722088,
+ 38026370, 38330490, 38634445, 38938232, 39241848, 39545290, 39848555,
+ 40151641, 40454543, 40757260, 41059788, 41362124, 41664265, 41966208,
+ 42267951, 42569489, 42870821, 43171943, 43472852, 43773545, 44074020,
+ 44374273, 44674301, 44974101, 45273670, 45573006, 45872105, 46170964,
+ 46469580, 46767951, 47066073, 47363943, 47661559, 47958917, 48256014,
+ 48552848, 48849414, 49145712, 49441736, 49737485, 50032956, 50328144,
+ 50623048, 50917665, 51211991, 51506024, 51799760, 52093196, 52386331,
+ 52679159, 52971680, 53263888, 53555783, 53847360, 54138617, 54429550,
+ 54720158, 55010436, 55300382, 55589992, 55879265, 56168196, 56456784,
+ 56745024, 57032915, 57320452, 57607633, 57894456, 58180917, 58467013,
+ 58752741, 59038099, 59323083, 59607691, 59891919, 60175764, 60459224,
+ 60742296, 61024976, 61307262, 61589152, 61870640, 62151726, 62432406,
+ 62712677, 62992537, 63271981, 63551008, 63829614, 64107797, 64385554,
+ 64662881, 64939776, 65216235, 65492257, 65767838, 66042974, 66317664,
+ 66591905, 66865693, 67139025, 67411899, 67684312, 67956260, 68227742,
+ 68498754, 68769293, 69039356, 69308941, 69578045, 69846664, 70114796,
+ 70382438, 70649587, 70916241, 71182396, 71448050, 71713199, 71977841,
+ 72241974, 72505593, 72768697, 73031283, 73293347, 73554887, 73815901,
+ 74076384, 74336335, 74595750, 74854628, 75112964, 75370756, 75628002,
+ 75884699, 76140843, 76396432, 76651464, 76905935, 77159842, 77413183,
+ 77665956, 77918157, 78169783, 78420832, 78671301, 78921188, 79170489,
+ 79419202, 79667323, 79914851, 80161783, 80408115, 80653846, 80898972,
+ 81143490, 81387398, 81630694, 81873374, 82115436, 82356877, 82597694,
+ 82837885, 83077447, 83316377, 83554673, 83792332, 84029351, 84265728,
+ 84501460, 84736544, 84970978, 85204758, 85437883, 85670350, 85902156,
+ 86133298, 86363774, 86593581, 86822716, 87051178, 87278963, 87506068,
+ 87732492, 87958231, 88183284, 88407646, 88631317, 88854292, 89076570,
+ 89298148, 89519024, 89739194, 89958657, 90177410, 90395450, 90612775,
+ 90829382, 91045268, 91260432, 91474871, 91688581, 91901562, 92113809,
+ 92325321, 92536095, 92746129, 92955420, 93163965, 93371763, 93578811,
+ 93785106, 93990646, 94195428, 94399450, 94602710, 94805205, 95006932,
+ 95207890, 95408076, 95607487, 95806121, 96003976, 96201049, 96397338,
+ 96592840, 96787553, 96981476, 97174604, 97366937, 97558471, 97749205,
+ 97939135, 98128261, 98316578, 98504086, 98690781, 98876662, 99061726,
+ 99245971, 99429394, 99611993, 99793767, 99974712, 100154826, 100334108,
+ 100512555, 100690164, 100866934, 101042862, 101217946, 101392183,
+ 101565573, 101738111, 101909797, 102080628, 102250601, 102419715,
+ 102587968, 102755357, 102921880, 103087534, 103252319, 103416231,
+ 103579269, 103741430, 103902713, 104063115, 104222633, 104381267,
+ 104539014, 104695871, 104851838, 105006911, 105161088, 105314368,
+ 105466749, 105618228, 105768803, 105918473, 106067235, 106215088,
+ 106362029, 106508056, 106653168, 106797362, 106940636, 107082989,
+ 107224419, 107364923, 107504499, 107643146, 107780862, 107917645,
+ 108053493, 108188403, 108322375, 108455406, 108587494, 108718638,
+ 108848835, 108978084, 109106383, 109233729, 109360122, 109485559,
+ 109610039, 109733559, 109856119, 109977715, 110098347, 110218012,
+ 110336709, 110454435, 110571190, 110686972, 110801778, 110915607,
+ 111028457, 111140327, 111251215, 111361118, 111470036, 111577967,
+ 111684909, 111790860, 111895819, 111999784, 112102754, 112204726,
+ 112305699, 112405672, 112504643, 112602610, 112699572, 112795527,
+ 112890473, 112984409, 113077334, 113169246, 113260143, 113350023,
+ 113438886, 113526730, 113613553, 113699353, 113784130, 113867882,
+ 113950606, 114032303, 114112970, 114192606, 114271209, 114348778,
+ 114425312, 114500809, 114575267, 114648687, 114721065, 114792400,
+ 114862692, 114931939, 115000139, 115067291, 115133395, 115198447,
+ 115262448, 115325396, 115387290, 115448127, 115507908, 115566630,
+ 115624293, 115680895, 115736436, 115790912, 115844325, 115896672,
+ 115947951, 115998163, 116047306, 116095377, 116142378, 116188305,
+ 116233159, 116276937, 116319640, 116361265, 116401811, 116441278,
+ 116479664, 116516969, 116553191, 116588328, 116622381, 116655348,
+ 116687228, 116718020, 116747723, 116776335, 116803857, 116830287,
+ 116855623, 116879865, 116903013, 116925065, 116946019, 116965876,
+ 116984634, 117002293, 117018851, 117034307, 117048661, 117061912,
+ 117074059, 117085101, 117095038, 117103867, 117111590, 117118204,
+ 117123709, 117128104, 117131389, 117133562, 117134623, 117134571,
+ 117133406, 117131126, 117127731, 117123220, 117117593, 117110849,
+ 117102986, 117094005, 117083905, 117072685, 117060344, 117046883,
+ 117032299, 117016593, 116999764, 116981811, 116962735, 116942533,
+ 116921206, 116898753, 116875174, 116850468, 116824635, 116797673,
+ 116769583, 116740364, 116710015, 116678537, 116645928, 116612189,
+ 116577318, 116541315, 116504180, 116465913, 116426513, 116385979,
+ 116344312, 116301511, 116257575, 116212505, 116166299, 116118958,
+ 116070482, 116020869, 115970120, 115918234, 115865212, 115811052,
+ 115755755, 115699321, 115641748, 115583037, 115523188, 115462201,
+ 115400075, 115336810, 115272406, 115206863, 115140180, 115072358,
+ 115003397, 114933296, 114862054, 114789674, 114716153, 114641492,
+ 114565691, 114488749, 114410668, 114331446, 114251085, 114169582,
+ 114086940, 114003158, 113918235, 113832172, 113744969, 113656626,
+ 113567143, 113476520, 113384757, 113291854, 113197812, 113102631,
+ 113006310, 112908850, 112810250, 112710512, 112609635, 112507620,
+ 112404467, 112300175, 112194745, 112088178, 111980473, 111871631,
+ 111761652, 111650537, 111538285, 111424898, 111310374, 111194715,
+ 111077921, 110959992, 110840929, 110720732, 110599401, 110476937,
+ 110353340, 110228610, 110102748, 109975755, 109847631, 109718376,
+ 109587990, 109456475, 109323830, 109190056, 109055155, 108919125,
+ 108781968, 108643684, 108504274, 108363739, 108222078, 108079293,
+ 107935383, 107790351, 107644196, 107496919, 107348520, 107199000,
+ 107048361, 106896602, 106743724, 106589728, 106434614, 106278384,
+ 106121038, 105962577, 105803001, 105642312, 105480509, 105317595,
+ 105153568, 104988432, 104822185, 104654830, 104486366, 104316796,
+ 104146118, 103974336, 103801448, 103627457, 103452363, 103276166,
+ 103098869, 102920472, 102740975, 102560380, 102378688, 102195900,
+ 102012016, 101827038, 101640967, 101453803, 101265548, 101076203,
+ 100885769, 100694246, 100501637, 100307941, 100113161, 99917297,
+ 99720351, 99522323, 99323214, 99123026, 98921761, 98719418, 98516000,
+ 98311507, 98105941, 97899303, 97691594, 97482816, 97272969, 97062055,
+ 96850075, 96637031, 96422923, 96207753, 95991523, 95774234, 95555886,
+ 95336482, 95116023, 94894509, 94671943, 94448327, 94223660, 93997945,
+ 93771183, 93543376, 93314524, 93084630, 92853695, 92621720, 92388708,
+ 92154658, 91919574, 91683455, 91446305, 91208124, 90968914, 90728677,
+ 90487414, 90245127, 90001817, 89757486, 89512135, 89265767, 89018382,
+ 88769983, 88520571, 88270147, 88018715, 87766274, 87512827, 87258376,
+ 87002922, 86746467, 86489013, 86230561, 85971114, 85710673, 85449239,
+ 85186815, 84923403, 84659004, 84393620, 84127252, 83859904, 83591576,
+ 83322271, 83051990, 82780736, 82508509, 82235313, 81961148, 81686018,
+ 81409924, 81132867, 80854850, 80575875, 80295943, 80015058, 79733220,
+ 79450432, 79166695, 78882013, 78596386, 78309817, 78022308, 77733862,
+ 77444479, 77154163, 76862915, 76570737, 76277632, 75983602, 75688649,
+ 75392774, 75095981, 74798271, 74499647, 74200111, 73899665, 73598310,
+ 73296051, 72992887, 72688823, 72383860, 72078000, 71771246, 71463601,
+ 71155065, 70845642, 70535334, 70224143, 69912072, 69599122, 69285297,
+ 68970599, 68655029, 68338591, 68021287, 67703119, 67384090, 67064201,
+ 66743457, 66421858, 66099407, 65776108, 65451961, 65126971, 64801139,
+ 64474467, 64146959, 63818617, 63489443, 63159440, 62828611, 62496957,
+ 62164482, 61831189, 61497079, 61162155, 60826420, 60489877, 60152528,
+ 59814376, 59475424, 59135673, 58795128, 58453789, 58111661, 57768746,
+ 57425047, 57080565, 56735305, 56389268, 56042458, 55694877, 55346527,
+ 54997413, 54647536, 54296899, 53945505, 53593357, 53240458, 52886810,
+ 52532417, 52177280, 51821404, 51464790, 51107442, 50749363, 50390555,
+ 50031021, 49670765, 49309789, 48948095, 48585688, 48222570, 47858743,
+ 47494212, 47128978, 46763044, 46396415, 46029092, 45661079, 45292378,
+ 44922993, 44552927, 44182183, 43810763, 43438671, 43065910, 42692483,
+ 42318392, 41943642, 41568235, 41192175, 40815463, 40438104, 40060101,
+ 39681456, 39302173, 38922255, 38541705, 38160527, 37778723, 37396296,
+ 37013250, 36629589, 36245314, 35860430, 35474940, 35088846, 34702152,
+ 34314862, 33926978, 33538504, 33149443, 32759798, 32369573, 31978771,
+ 31587395, 31195449, 30802935, 30409857, 30016219, 29622024, 29227274,
+ 28831974, 28436127, 28039736, 27642805, 27245336, 26847334, 26448801,
+ 26049742, 25650158, 25250055, 24849435, 24448302, 24046659, 23644509,
+ 23241857, 22838705, 22435056, 22030916, 21626286, 21221170, 20815573,
+ 20409497, 20002945, 19595922, 19188431, 18780475, 18372058, 17963184,
+ 17553856, 17144077, 16733851, 16323182, 15912074, 15500529, 15088551,
+ 14676145, 14263313, 13850059, 13436387, 13022301, 12607803, 12192899,
+ 11777590, 11361882, 10945777, 10529279, 10112392, 9695120, 9277466,
+ 8859434, 8441028, 8022251, 7603106, 7183599, 6763732, 6343509, 5922934,
+ 5502010, 5080742, 4659132, 4237186, 3814906, 3392296, 2969360, 2546102,
+ 2122526, 1698635, 1274433, 849924, 425111, 0, -425407, -851107,
+ -1277094, -1703366, -2129918, -2556747, -2983849, -3411219, -3838855,
+ -4266752, -4694906, -5123314, -5551971, -5980874, -6410019, -6839402,
+ -7269020, -7698867, -8128941, -8559237, -8989752, -9420481, -9851421,
+ -10282568, -10713918, -11145467, -11577211, -12009145, -12441267,
+ -12873573, -13306057, -13738717, -14171548, -14604546, -15037708,
+ -15471029, -15904505, -16338133, -16771909, -17205828, -17639886,
+ -18074080, -18508405, -18942858, -19377435, -19812131, -20246942,
+ -20681864, -21116895, -21552028, -21987261, -22422589, -22858008,
+ -23293515, -23729104, -24164773, -24600517, -25036332, -25472213,
+ -25908158, -26344162, -26780220, -27216329, -27652484, -28088682,
+ -28524918, -28961189, -29397490, -29833817, -30270166, -30706533,
+ -31142914, -31579304, -32015701, -32452098, -32888493, -33324882,
+ -33761259, -34197622, -34633966, -35070286, -35506579, -35942840,
+ -36379066, -36815252, -37251394, -37687488, -38123530, -38559516,
+ -38995441, -39431301, -39867093, -40302812, -40738453, -41174014,
+ -41609488, -42044874, -42480165, -42915358, -43350450, -43785435,
+ -44220309, -44655069, -45089710, -45524228, -45958619, -46392879,
+ -46827003, -47260987, -47694827, -48128519, -48562059, -48995442,
+ -49428664, -49861722, -50294610, -50727325, -51159862, -51592218,
+ -52024388, -52456368, -52888153, -53319740, -53751124, -54182301,
+ -54613267, -55044017, -55474548, -55904855, -56334934, -56764781,
+ -57194391, -57623760, -58052885, -58481761, -58910383, -59338747,
+ -59766850, -60194687, -60622254, -61049546, -61476559, -61903290,
+ -62329733, -62755885, -63181742, -63607299, -64032552, -64457496,
+ -64882128, -65306444, -65730439, -66154108, -66577448, -67000455,
+ -67423123, -67845450, -68267431, -68689061, -69110336, -69531253,
+ -69951806, -70371992, -70791807, -71211245, -71630304, -72048979,
+ -72467265, -72885158, -73302655, -73719750, -74136441, -74552721,
+ -74968588, -75384037, -75799064, -76213665, -76627835, -77041570,
+ -77454866, -77867719, -78280125, -78692079, -79103577, -79514615,
+ -79925189, -80335295, -80744928, -81154085, -81562760, -81970950,
+ -82378651, -82785858, -83192568, -83598775, -84004477, -84409668,
+ -84814345, -85218503, -85622138, -86025246, -86427824, -86829865,
+ -87231368, -87632326, -88032737, -88432596, -88831899, -89230641,
+ -89628819, -90026428, -90423464, -90819924, -91215802, -91611096,
+ -92005800, -92399910, -92793423, -93186334, -93578639, -93970334,
+ -94361415, -94751878, -95141719, -95530933, -95919516, -96307465,
+ -96694774, -97081441, -97467461, -97852830, -98237544, -98621598,
+ -99004989, -99387712, -99769764, -100151141, -100531837, -100911850,
+ -101291175, -101669808, -102047745, -102424982, -102801515, -103177340,
+ -103552453, -103926849, -104300525, -104673477, -105045701, -105417193,
+ -105787948, -106157962, -106527233, -106895754, -107263524, -107630537,
+ -107996790, -108362278, -108726998, -109090946, -109454117, -109816508,
+ -110178114, -110538933, -110898959, -111258189, -111616619, -111974245,
+ -112331063, -112687069, -113042259, -113396629, -113750175, -114102894,
+ -114454781, -114805833, -115156046, -115505415, -115853937, -116201608,
+ -116548424, -116894381, -117239475, -117583703, -117927061, -118269544,
+ -118611149, -118951872, -119291709, -119630657, -119968711, -120305868,
+ -120642124, -120977475, -121311917, -121645446, -121978059, -122309752,
+ -122640522, -122970363, -123299273, -123627248, -123954284, -124280377,
+ -124605524, -124929720, -125252963, -125575247, -125896571, -126216929,
+ -126536318, -126854735, -127172176, -127488637, -127804114, -128118604,
+ -128432103, -128744607, -129056113, -129366617, -129676116, -129984605,
+ -130292082, -130598542, -130903982, -131208398, -131511787, -131814145,
+ -132115469, -132415755, -132714999, -133013198, -133310348, -133606446,
+ -133901488, -134195470, -134488390, -134780243, -135071026, -135360736,
+ -135649369, -135936921, -136223390, -136508771, -136793061, -137076257,
+ -137358355, -137639352, -137919244, -138198028, -138475700, -138752257,
+ -139027696, -139302014, -139575206, -139847269, -140118201, -140387997,
+ -140656655, -140924171, -141190541, -141455763, -141719832, -141982746,
+ -142244502, -142505096, -142764524, -143022784, -143279873, -143535786,
+ -143790521, -144044074, -144296443, -144547623, -144797612, -145046407,
+ -145294004, -145540400, -145785592, -146029577, -146272351, -146513912,
+ -146754256, -146993381, -147231282, -147467957, -147703403, -147937616,
+ -148170594, -148402334, -148632832, -148862085, -149090090, -149316845,
+ -149542346, -149766590, -149989574, -150211295, -150431750, -150650936,
+ -150868850, -151085490, -151300852, -151514933, -151727730, -151939240,
+ -152149461, -152358390, -152566023, -152772357, -152977391, -153181120,
+ -153383543, -153584655, -153784455, -153982940, -154180106, -154375952,
+ -154570473, -154763668, -154955533, -155146065, -155335263, -155523123,
+ -155709643, -155894819, -156078649, -156261131, -156442261, -156622037,
+ -156800457, -156977517, -157153215, -157327548, -157500514, -157672110,
+ -157842333, -158011181, -158178651, -158344741, -158509448, -158672770,
+ -158834703, -158995246, -159154396, -159312150, -159468506, -159623461,
+ -159777013, -159929160, -160079899, -160229227, -160377142, -160523642,
+ -160668724, -160812386, -160954626, -161095440, -161234827, -161372785,
+ -161509311, -161644402, -161778057, -161910272, -162041047, -162170378,
+ -162298263, -162424700, -162549686, -162673220, -162795300, -162915922,
+ -163035085, -163152787, -163269025, -163383797, -163497102, -163608936,
+ -163719299, -163828187, -163935598, -164041531, -164145984, -164248954,
+ -164350439, -164450437, -164548947, -164645966, -164741492, -164835523,
+ -164928058, -165019093, -165108628, -165196661, -165283188, -165368210,
+ -165451722, -165533725, -165614215, -165693191, -165770652, -165846594,
+ -165921017, -165993918, -166065297, -166135150, -166203476, -166270274,
+ -166335542, -166399277, -166461479, -166522145, -166581274, -166638864,
+ -166694913, -166749420, -166802384, -166853801, -166903672, -166951994,
+ -166998765, -167043985, -167087651, -167129762, -167170316, -167209312,
+ -167246748, -167282623, -167316936, -167349684, -167380867, -167410483,
+ -167438530, -167465007, -167489913, -167513247, -167535006, -167555189,
+ -167573796, -167590824, -167606274, -167620142, -167632428, -167643130,
+ -167652248, -167659780, -167665725, -167670081, -167672848, -167674024,
+ -167673608, -167671598, -167667994, -167662795, -167655999, -167647605,
+ -167637612, -167626019, -167612825, -167598029, -167581630, -167563627,
+ -167544018, -167522803, -167499981, -167475550, -167449511, -167421861,
+ -167392600, -167361727, -167329241, -167295141, -167259427, -167222097,
+ -167183150, -167142587, -167100405, -167056604, -167011184, -166964143,
+ -166915481, -166865197, -166813290, -166759760, -166704606, -166647826,
+ -166589422, -166529391, -166467733, -166404448, -166339534, -166272992,
+ -166204821, -166135020, -166063588, -165990526, -165915831, -165839505,
+ -165761547, -165681955, -165600730, -165517871, -165433377, -165347249,
+ -165259485, -165170086, -165079051, -164986379, -164892071, -164796126,
+ -164698543, -164599322, -164498464, -164395967, -164291832, -164186058,
+ -164078644, -163969592, -163858900, -163746568, -163632597, -163516986,
+ -163399734, -163280842, -163160310, -163038138, -162914324, -162788871,
+ -162661776, -162533041, -162402665, -162270648, -162136991, -162001693,
+ -161864754, -161726174, -161585954, -161444094, -161300593, -161155452,
+ -161008670, -160860249, -160710188, -160558487, -160405147, -160250167,
+ -160093549, -159935291, -159775395, -159613861, -159450689, -159285879,
+ -159119431, -158951347, -158781626, -158610268, -158437275, -158262646,
+ -158086381, -157908482, -157728948, -157547781, -157364980, -157180547,
+ -156994480, -156806782, -156617453, -156426492, -156233902, -156039681,
+ -155843832, -155646353, -155447248, -155246514, -155044154, -154840169,
+ -154634557, -154427322, -154218462, -154007980, -153795875, -153582148,
+ -153366801, -153149833, -152931247, -152711042, -152489219, -152265780,
+ -152040724, -151814054, -151585770, -151355873, -151124363, -150891242,
+ -150656511, -150420171, -150182222, -149942666, -149701504, -149458736,
+ -149214365, -148968390, -148720813, -148471635, -148220858, -147968482,
+ -147714508, -147458938, -147201773, -146943014, -146682662, -146420719,
+ -146157185, -145892063, -145625353, -145357056, -145087174, -144815709,
+ -144542661, -144268032, -143991823, -143714036, -143434671, -143153732,
+ -142871218, -142587132, -142301474, -142014247, -141725451, -141435089,
+ -141143162, -140849671, -140554618, -140258005, -139959832, -139660103,
+ -139358818, -139055978, -138751586, -138445644, -138138153, -137829114,
+ -137518529, -137206401, -136892731, -136577520, -136260770, -135942484,
+ -135622663, -135301308, -134978423, -134654007, -134328064, -134000596,
+ -133671603, -133341089, -133009055, -132675502, -132340434, -132003851,
+ -131665756, -131326151, -130985038, -130642420, -130298297, -129952672,
+ -129605547, -129256925, -128906807, -128555195, -128202093, -127847501,
+ -127491422, -127133858, -126774812, -126414285, -126052280, -125688800,
+ -125323845, -124957420, -124589525, -124220164, -123849339, -123477051,
+ -123103304, -122728099, -122351440, -121973328, -121593766, -121212757,
+ -120830302, -120446405, -120061067, -119674292, -119286082, -118896439,
+ -118505366, -118112865, -117718939, -117323591, -116926824, -116528639,
+ -116129039, -115728028, -115325607, -114921780, -114516549, -114109917,
+ -113701887, -113292460, -112881641, -112469432, -112055836, -111640855,
+ -111224492, -110806750, -110387633, -109967142, -109545280, -109122052,
+ -108697459, -108271504, -107844190, -107415521, -106985499, -106554127,
+ -106121409, -105687346, -105251943, -104815203, -104377127, -103937720,
+ -103496984, -103054923, -102611540, -102166837, -101720818, -101273487,
+ -100824846, -100374898, -99923646, -99471095, -99017247, -98562105,
+ -98105672, -97647953, -97188949, -96728665, -96267104, -95804268,
+ -95340163, -94874789, -94408152, -93940255, -93471100, -93000692,
+ -92529033, -92056128, -91581979, -91106591, -90629965, -90152107,
+ -89673020, -89192707, -88711171, -88228417, -87744447, -87259266,
+ -86772876, -86285282, -85796488, -85306496, -84815310, -84322935,
+ -83829373, -83334629, -82838707, -82341609, -81843339, -81343902,
+ -80843302, -80341541, -79838624, -79334554, -78829336, -78322972,
+ -77815468, -77306827, -76797052, -76286148, -75774119, -75260967,
+ -74746698, -74231316, -73714823, -73197225, -72678525, -72158727,
+ -71637835, -71115853, -70592785, -70068635, -69543408, -69017107,
+ -68489736, -67961300, -67431803, -66901248, -66369640, -65836983,
+ -65303281, -64768538, -64232759, -63695947, -63158107, -62619244,
+ -62079361, -61538462, -60996552, -60453635, -59909716, -59364798,
+ -58818887, -58271985, -57724099, -57175231, -56625387, -56074570,
+ -55522785, -54970037, -54416330, -53861668, -53306056, -52749498,
+ -52191999, -51633563, -51074194, -50513898, -49952678, -49390539,
+ -48827486, -48263523, -47698654, -47132885, -46566220, -45998664,
+ -45430220, -44860894, -44290691, -43719614, -43147669, -42574860,
+ -42001192, -41426669, -40851297, -40275080, -39698022, -39120129,
+ -38541405, -37961855, -37381483, -36800295, -36218295, -35635488,
+ -35051879, -34467473, -33882274, -33296287, -32709518, -32121970,
+ -31533649, -30944560, -30354708, -29764097, -29172733, -28580620,
+ -27987763, -27394168, -26799839, -26204781, -25608999, -25012498,
+ -24415284, -23817360, -23218733, -22619407, -22019388, -21418679,
+ -20817287, -20215217, -19612473, -19009060, -18404985, -17800251,
+ -17194864, -16588829, -15982152, -15374836, -14766889, -14158314,
+ -13549117, -12939303, -12328877, -11717845, -11106212, -10493982,
+ -9881162, -9267756, -8653770, -8039209, -7424078, -6808382, -6192128,
+ -5575319, -4957962, -4340062, -3721624, -3102653, -2483155, -1863136,
+ -1242600, -621552, 0, 622053, 1244601, 1867638, 2491160, 3115160,
+ 3739634, 4364575, 4989979, 5615839, 6242150, 6868908, 7496106, 8123739,
+ 8751801, 9380286, 10009191, 10638508, 11268232, 11898358, 12528880,
+ 13159793, 13791090, 14422767, 15054818, 15687237, 16320019, 16953158,
+ 17586648, 18220484, 18854660, 19489170, 20124010, 20759172, 21394652,
+ 22030444, 22666542, 23302940, 23939634, 24576616, 25213882, 25851425,
+ 26489240, 27127322, 27765664, 28404260, 29043106, 29682194, 30321521,
+ 30961078, 31600862, 32240866, 32881084, 33521511, 34162140, 34802966,
+ 35443983, 36085186, 36726568, 37368123, 38009847, 38651732, 39293773,
+ 39935964, 40578300, 41220774, 41863381, 42506114, 43148968, 43791937,
+ 44435015, 45078196, 45721474, 46364843, 47008298, 47651832, 48295439,
+ 48939114, 49582851, 50226643, 50870484, 51514370, 52158293, 52802248,
+ 53446228, 54090229, 54734243, 55378265, 56022288, 56666308, 57310317,
+ 57954310, 58598281, 59242223, 59886131, 60529999, 61173821, 61817590,
+ 62461300, 63104946, 63748522, 64392021, 65035437, 65678765, 66321997,
+ 66965129, 67608154, 68251066, 68893858, 69536526, 70179062, 70821461,
+ 71463716, 72105822, 72747772, 73389560, 74031180, 74672626, 75313892,
+ 75954971, 76595859, 77236547, 77877031, 78517304, 79157360, 79797193,
+ 80436797, 81076165, 81715292, 82354171, 82992796, 83631161, 84269260,
+ 84907086, 85544634, 86181898, 86818870, 87455545, 88091918, 88727980,
+ 89363727, 89999153, 90634250, 91269014, 91903436, 92537513, 93171237,
+ 93804601, 94437601, 95070229, 95702480, 96334347, 96965824, 97596906,
+ 98227584, 98857855, 99487710, 100117145, 100746152, 101374726,
+ 102002860, 102630549, 103257785, 103884564, 104510878, 105136721,
+ 105762087, 106386970, 107011364, 107635262, 108258659, 108881547,
+ 109503922, 110125775, 110747103, 111367897, 111988152, 112607862,
+ 113227020, 113845620, 114463657, 115081123, 115698013, 116314320,
+ 116930038, 117545161, 118159682, 118773596, 119386896, 119999577,
+ 120611630, 121223052, 121833835, 122443972, 123053459, 123662289,
+ 124270454, 124877950, 125484770, 126090908, 126696358, 127301112,
+ 127905166, 128508513, 129111147, 129713061, 130314249, 130914706,
+ 131514424, 132113399, 132711622, 133309089, 133905793, 134501729,
+ 135096888, 135691267, 136284858, 136877655, 137469652, 138060842,
+ 138651221, 139240781, 139829516, 140417420, 141004487, 141590712,
+ 142176086, 142760605, 143344263, 143927052, 144508968, 145090003,
+ 145670152, 146249409, 146827767, 147405220, 147981762, 148557388,
+ 149132090, 149705863, 150278700, 150850597, 151421545, 151991540,
+ 152560575, 153128644, 153695741, 154261859, 154826994, 155391138,
+ 155954286, 156516431, 157077568, 157637690, 158196792, 158754866,
+ 159311908, 159867911, 160422869, 160976776, 161529626, 162081413,
+ 162632131, 163181774, 163730335, 164277809, 164824191, 165369473,
+ 165913649, 166456715, 166998663, 167539489, 168079185, 168617745,
+ 169155165, 169691438, 170226557, 170760518, 171293314, 171824938,
+ 172355386, 172884651, 173412728, 173939609, 174465290, 174989765,
+ 175513027, 176035072, 176555891, 177075481, 177593835, 178110947,
+ 178626812, 179141423, 179654774, 180166860, 180677675, 181187214,
+ 181695469, 182202436, 182708109, 183212481, 183715547, 184217302,
+ 184717739, 185216853, 185714637, 186211087, 186706196, 187199958,
+ 187692369, 188183421, 188673110, 189161429, 189648374, 190133938,
+ 190618115, 191100900, 191582287, 192062271, 192540845, 193018005,
+ 193493744, 193968057, 194440939, 194912383, 195382383, 195850936,
+ 196318034, 196783672, 197247845, 197710546, 198171772, 198631515,
+ 199089770, 199546533, 200001796, 200455555, 200907805, 201358539,
+ 201807752, 202255439, 202701595, 203146213, 203589288, 204030816,
+ 204470789, 204909204, 205346055, 205781335, 206215040, 206647165,
+ 207077703, 207506650, 207934001, 208359749, 208783890, 209206418,
+ 209627328, 210046614, 210464272, 210880295, 211294680, 211707419,
+ 212118509, 212527944, 212935718, 213341827, 213746265, 214149027,
+ 214550107, 214949502, 215347204, 215743210, 216137514, 216530111,
+ 216920996, 217310163, 217697608, 218083325, 218467310, 218849557,
+ 219230061, 219608818, 219985821, 220361067, 220734550, 221106265,
+ 221476206, 221844370, 222210751, 222575344, 222938145, 223299147,
+ 223658347, 224015739, 224371319, 224725081, 225077022, 225427134,
+ 225775415, 226121859, 226466462, 226809218, 227150122, 227489171,
+ 227826359, 228161681, 228495133, 228826709, 229156406, 229484218,
+ 229810141, 230134170, 230456300, 230776527, 231094846, 231411252,
+ 231725742, 232038309, 232348950, 232657660, 232964434, 233269268,
+ 233572158, 233873098, 234172085, 234469113, 234764179, 235057277,
+ 235348404, 235637555, 235924725, 236209910, 236493106, 236774308,
+ 237053512, 237330714, 237605909, 237879092, 238150260, 238419408,
+ 238686532, 238951628, 239214691, 239475718, 239734703, 239991642,
+ 240246533, 240499369, 240750148, 240998864, 241245515, 241490095,
+ 241732600, 241973028, 242211372, 242447630, 242681797, 242913869,
+ 243143842, 243371713, 243597477, 243821130, 244042668, 244262087,
+ 244479384, 244694555, 244907595, 245118500, 245327268, 245533893,
+ 245738373, 245940702, 246140879, 246338898, 246534756, 246728449,
+ 246919973, 247109326, 247296502, 247481499, 247664312, 247844939,
+ 248023374, 248199616, 248373659, 248545501, 248715138, 248882567,
+ 249047783, 249210784, 249371565, 249530124, 249686456, 249840559,
+ 249992429, 250142063, 250289456, 250434607, 250577511, 250718164,
+ 250856565, 250992708, 251126592, 251258213, 251387567, 251514651,
+ 251639462, 251761997, 251882253, 252000226, 252115914, 252229312,
+ 252340418, 252449230, 252555743, 252659954, 252761862, 252861462,
+ 252958751, 253053727, 253146387, 253236728, 253324746, 253410438,
+ 253493803, 253574837, 253653536, 253729899, 253803922, 253875603,
+ 253944938, 254011926, 254076563, 254138846, 254198773, 254256341,
+ 254311547, 254364389, 254414864, 254462969, 254508702, 254552060,
+ 254593041, 254631642, 254667860, 254701693, 254733139, 254762195,
+ 254788858, 254813126, 254834997, 254854468, 254871538, 254886202,
+ 254898460, 254908309, 254915746, 254920769, 254923376, 254923565,
+ 254921334, 254916680, 254909600, 254900094, 254888159, 254873792,
+ 254856991, 254837756, 254816082, 254791969, 254765414, 254736415,
+ 254704971, 254671079, 254634737, 254595943, 254554697, 254510994,
+ 254464835, 254416216, 254365137, 254311594, 254255587, 254197114,
+ 254136173, 254072762, 254006879, 253938524, 253867693, 253794386,
+ 253718601, 253640336, 253559590, 253476361, 253390647, 253302448,
+ 253211761, 253118585, 253022919, 252924761, 252824110, 252720964,
+ 252615322, 252507183, 252396545, 252283407, 252167768, 252049626,
+ 251928981, 251805830, 251680173, 251552009, 251421336, 251288153,
+ 251152459, 251014254, 250873535, 250730302, 250584555, 250436290,
+ 250285509, 250132210, 249976391, 249818053, 249657194, 249493812,
+ 249327909, 249159481, 248988530, 248815053, 248639050, 248460521,
+ 248279464, 248095879, 247909765, 247721122, 247529949, 247336245,
+ 247140010, 246941242, 246739943, 246536110, 246329744, 246120843,
+ 245909409, 245695439, 245478934, 245259893, 245038316, 244814202,
+ 244587552, 244358364, 244126639, 243892377, 243655576, 243416237,
+ 243174359, 242929944, 242682989, 242433495, 242181463, 241926891,
+ 241669780, 241410130, 241147941, 240883212, 240615944, 240346138,
+ 240073792, 239798906, 239521483, 239241520, 238959018, 238673979,
+ 238386401, 238096285, 237803631, 237508439, 237210711, 236910446,
+ 236607644, 236302305, 235994432, 235684022, 235371078, 235055599,
+ 234737586, 234417040, 234093960, 233768348, 233440204, 233109529,
+ 232776323, 232440587, 232102322, 231761528, 231418205, 231072356,
+ 230723980, 230373078, 230019651, 229663700, 229305226, 228944229,
+ 228580711, 228214672, 227846113, 227475036, 227101440, 226725328,
+ 226346701, 225965558, 225581902, 225195733, 224807053, 224415863,
+ 224022164, 223625956, 223227243, 222826023, 222422300, 222016073,
+ 221607345, 221196117, 220782389, 220366165, 219947444, 219526228,
+ 219102519, 218676319, 218247628, 217816448, 217382781, 216946628,
+ 216507991, 216066872, 215623272, 215177193, 214728636, 214277604,
+ 213824097, 213368118, 212909669, 212448751, 211985366, 211519515,
+ 211051202, 210580427, 210107193, 209631502, 209153355, 208672754,
+ 208189702, 207704201, 207216252, 206725858, 206233021, 205737742,
+ 205240025, 204739871, 204237282, 203732261, 203224810, 202714931,
+ 202202626, 201687899, 201170750, 200651183, 200129200, 199604803,
+ 199077994, 198548777, 198017154, 197483127, 196946698, 196407871,
+ 195866647, 195323030, 194777022, 194228626, 193677844, 193124679,
+ 192569133, 192011211, 191450913, 190888244, 190323205, 189755800,
+ 189186032, 188613903, 188039416, 187462575, 186883382, 186301840,
+ 185717952, 185131722, 184543151, 183952244, 183359004, 182763433,
+ 182165534, 181565312, 180962768, 180357907, 179750731, 179141244,
+ 178529449, 177915349, 177298948, 176680248, 176059254, 175435969,
+ 174810396, 174182539, 173552400, 172919984, 172285295, 171648335,
+ 171009108, 170367617, 169723867, 169077861, 168429603, 167779096,
+ 167126344, 166471351, 165814120, 165154656, 164492961, 163829041,
+ 163162898, 162494537, 161823961, 161151174, 160476181, 159798985,
+ 159119590, 158438000, 157754220, 157068253, 156380103, 155689775,
+ 154997272, 154302599, 153605760, 152906759, 152205600, 151502287,
+ 150796826, 150089219, 149379472, 148667588, 147953572, 147237429,
+ 146519162, 145798777, 145076277, 144351667, 143624951, 142896135,
+ 142165222, 141432218, 140697126, 139959951, 139220698, 138479372,
+ 137735977, 136990518, 136242999, 135493426, 134741803, 133988134,
+ 133232426, 132474681, 131714907, 130953106, 130189284, 129423447,
+ 128655598, 127885743, 127113887, 126340035, 125564192, 124786363,
+ 124006552, 123224766, 122441009, 121655286, 120867603, 120077964,
+ 119286376, 118492842, 117697369, 116899961, 116100624, 115299364,
+ 114496184, 113691092, 112884092, 112075190, 111264391, 110451700,
+ 109637123, 108820666, 108002333, 107182132, 106360066, 105536142,
+ 104710365, 103882741, 103053275, 102221974, 101388842, 100553886,
+ 99717111, 98878523, 98038128, 97195931, 96351939, 95506157, 94658591,
+ 93809247, 92958130, 92105248, 91250605, 90394207, 89536061, 88676173,
+ 87814549, 86951194, 86086114, 85219317, 84350807, 83480592, 82608677,
+ 81735068, 80859771, 79982794, 79104141, 78223820, 77341836, 76458196,
+ 75572906, 74685972, 73797401, 72907200, 72015374, 71121930, 70226874,
+ 69330213, 68431954, 67532102, 66630665, 65727649, 64823060, 63916906,
+ 63009192, 62099925, 61189112, 60276760, 59362875, 58447463, 57530533,
+ 56612090, 55692141, 54770693, 53847753, 52923327, 51997423, 51070047,
+ 50141206, 49210907, 48279157, 47345963, 46411332, 45475270, 44537786,
+ 43598885, 42658575, 41716863, 40773756, 39829261, 38883385, 37936135,
+ 36987519, 36037543, 35086216, 34133543, 33179532, 32224191, 31267527,
+ 30309547, 29350258, 28389667, 27427783, 26464612, 25500161, 24534439,
+ 23567452, 22599208, 21629714, 20658979, 19687008, 18713811, 17739393,
+ 16763764, 15786930, 14808899, 13829678, 12849276, 11867700, 10884957,
+ 9901055, 8916002, 7929806, 6942474, 5954014, 4964433, 3973740, 2981943,
+ 1989048, 995064, 0, -996138, -1993342, -2991603, -3990914, -4991267,
+ -5992654, -6995066, -7998497, -9002937, -10008380, -11014816,
+ -12022238, -13030638, -14040007, -15050338, -16061623, -17073853,
+ -18087020, -19101116, -20116133, -21132063, -22148897, -23166627,
+ -24185246, -25204744, -26225113, -27246346, -28268434, -29291368,
+ -30315140, -31339743, -32365166, -33391403, -34418445, -35446283,
+ -36474908, -37504313, -38534489, -39565428, -40597120, -41629558,
+ -42662733, -43696636, -44731259, -45766594, -46802631, -47839362,
+ -48876778, -49914872, -50953633, -51993054, -53033126, -54073841,
+ -55115188, -56157161, -57199749, -58242945, -59286739, -60331123,
+ -61376088, -62421625, -63467725, -64514380, -65561581, -66609318,
+ -67657583, -68706367, -69755662, -70805457, -71855745, -72906517,
+ -73957762, -75009473, -76061641, -77114256, -78167309, -79220792,
+ -80274696, -81329010, -82383727, -83438837, -84494331, -85550200,
+ -86606436, -87663027, -88719967, -89777245, -90834852, -91892780,
+ -92951018, -94009558, -95068391, -96127507, -97186897, -98246552,
+ -99306463, -100366620, -101427014, -102487635, -103548476, -104609525,
+ -105670774, -106732213, -107793833, -108855625, -109917580, -110979687,
+ -112041938, -113104323, -114166832, -115229457, -116292188, -117355015,
+ -118417929, -119480920, -120543980, -121607097, -122670264, -123733470,
+ -124796706, -125859962, -126923229, -127986497, -129049756, -130112998,
+ -131176212, -132239389, -133302520, -134365594, -135428601, -136491534,
+ -137554380, -138617132, -139679780, -140742312, -141804721, -142866996,
+ -143929128, -144991107, -146052922, -147114565, -148176026, -149237294,
+ -150298361, -151359216, -152419850, -153480252, -154540413, -155600324,
+ -156659973, -157719353, -158778452, -159837260, -160895769, -161953968,
+ -163011847, -164069397, -165126607, -166183468, -167239969, -168296102,
+ -169351855, -170407219, -171462185, -172516741, -173570879, -174624587,
+ -175677858, -176730679, -177783042, -178834936, -179886352, -180937278,
+ -181987707, -183037626, -184087028, -185135900, -186184234, -187232019,
+ -188279245, -189325903, -190371981, -191417471, -192462362, -193506643,
+ -194550306, -195593340, -196635734, -197677479, -198718564, -199758980,
+ -200798716, -201837762, -202876109, -203913745, -204950661, -205986847,
+ -207022293, -208056987, -209090922, -210124085, -211156467, -212188058,
+ -213218847, -214248825, -215277982, -216306306, -217333788, -218360418,
+ -219386185, -220411080, -221435092, -222458210, -223480426, -224501727,
+ -225522105, -226541549, -227560049, -228577594, -229594175, -230609781,
+ -231624401, -232638027, -233650646, -234662250, -235672827, -236682368,
+ -237690863, -238698300, -239704670, -240709963, -241714168, -242717276,
+ -243719275, -244720155, -245719906, -246718519, -247715982, -248712285,
+ -249707419, -250701372, -251694134, -252685696, -253676047, -254665176,
+ -255653074, -256639729, -257625133, -258609273, -259592141, -260573726,
+ -261554017, -262533004, -263510677, -264487026, -265462040, -266435709,
+ -267408022, -268378970, -269348542, -270316728, -271283517, -272248899,
+ -273212864, -274175402, -275136501, -276096153, -277054346, -278011071,
+ -278966316, -279920072, -280872329, -281823075, -282772301, -283719997,
+ -284666152, -285610755, -286553797, -287495267, -288435156, -289373452,
+ -290310145, -291245225, -292178682, -293110505, -294040685, -294969210,
+ -295896071, -296821258, -297744759, -298666565, -299586666, -300505051,
+ -301421709, -302336632, -303249807, -304161226, -305070878, -305978752,
+ -306884838, -307789127, -308691607, -309592269, -310491103, -311388097,
+ -312283242, -313176528, -314067944, -314957481, -315845127, -316730873,
+ -317614708, -318496623, -319376607, -320254649, -321130740, -322004870,
+ -322877028, -323747204, -324615388, -325481569, -326345738, -327207885,
+ -328067998, -328926069, -329782086, -330636040, -331487921, -332337718,
+ -333185422, -334031021, -334874507, -335715868, -336555095, -337392178,
+ -338227107, -339059870, -339890460, -340718864, -341545074, -342369079,
+ -343190869, -344010434, -344827764, -345642849, -346455678, -347266243,
+ -348074532, -348880536, -349684245, -350485648, -351284736, -352081499,
+ -352875927, -353668009, -354457737, -355245099, -356030085, -356812687,
+ -357592894, -358370696, -359146083, -359919045, -360689572, -361457655,
+ -362223283, -362986447, -363747136, -364505341, -365261052, -366014260,
+ -366764953, -367513123, -368258760, -369001853, -369742393, -370480370,
+ -371215775, -371948597, -372678827, -373406455, -374131471, -374853866,
+ -375573630, -376290752, -377005224, -377717036, -378426177, -379132639,
+ -379836411, -380537484, -381235849, -381931494, -382624412, -383314592,
+ -384002025, -384686701, -385368610, -386047743, -386724090, -387397643,
+ -388068390, -388736323, -389401432, -390063708, -390723140, -391379721,
+ -392033439, -392684286, -393332252, -393977328, -394619504, -395258771,
+ -395895120, -396528540, -397159023, -397786559, -398411139, -399032754,
+ -399651393, -400267049, -400879711, -401489370, -402096017, -402699643,
+ -403300238, -403897793, -404492299, -405083746, -405672126, -406257430,
+ -406839647, -407418769, -407994787, -408567691, -409137472, -409704122,
+ -410267631, -410827990, -411385190, -411939222, -412490077, -413037745,
+ -413582218, -414123487, -414661543, -415196377, -415727979, -416256341,
+ -416781455, -417303310, -417821898, -418337210, -418849238, -419357972,
+ -419863404, -420365525, -420864325, -421359797, -421851931, -422340718,
+ -422826151, -423308219, -423786915, -424262229, -424734154, -425202679,
+ -425667798, -426129500, -426587777, -427042622, -427494024, -427941976,
+ -428386469, -428827494, -429265043, -429699107, -430129679, -430556749,
+ -430980308, -431400349, -431816864, -432229842, -432639277, -433045160,
+ -433447483, -433846236, -434241412, -434633003, -435021000, -435405395,
+ -435786180, -436163346, -436536885, -436906790, -437273051, -437635661,
+ -437994611, -438349894, -438701501, -439049424, -439393655, -439734187,
+ -440071010, -440404117, -440733501, -441059152, -441381063, -441699227,
+ -442013635, -442324279, -442631151, -442934244, -443233549, -443529059,
+ -443820767, -444108663, -444392742, -444672993, -444949411, -445221987,
+ -445490714, -445755583, -446016588, -446273721, -446526973, -446776338,
+ -447021808, -447263375, -447501032, -447734771, -447964585, -448190467,
+ -448412408, -448630401, -448844440, -449054517, -449260623, -449462753,
+ -449660898, -449855052, -450045206, -450231355, -450413490, -450591604,
+ -450765691, -450935742, -451101752, -451263712, -451421615, -451575456,
+ -451725225, -451870917, -452012525, -452150041, -452283458, -452412770,
+ -452537969, -452659049, -452776003, -452888824, -452997505, -453102039,
+ -453202419, -453298639, -453390692, -453478572, -453562270, -453641782,
+ -453717100, -453788217, -453855127, -453917824, -453976300, -454030550,
+ -454080567, -454126343, -454167873, -454205151, -454238170, -454266923,
+ -454291404, -454311607, -454327525, -454339153, -454346483, -454349511,
+ -454348228, -454342630, -454332709, -454318461, -454299878, -454276955,
+ -454249685, -454218063, -454182082, -454141737, -454097021, -454047928,
+ -453994454, -453936590, -453874333, -453807675, -453736612, -453661136,
+ -453581244, -453496927, -453408182, -453315003, -453217382, -453115316,
+ -453008798, -452897823, -452782384, -452662478, -452538097, -452409237,
+ -452275892, -452138057, -451995726, -451848893, -451697554, -451541703,
+ -451381335, -451216445, -451047026, -450873075, -450694585, -450511552,
+ -450323970, -450131835, -449935140, -449733882, -449528055, -449317654,
+ -449102674, -448883110, -448658957, -448430210, -448196864, -447958915,
+ -447716358, -447469187, -447217399, -446960987, -446699948, -446434277,
+ -446163969, -445889020, -445609425, -445325179, -445036277, -444742716,
+ -444444491, -444141597, -443834029, -443521784, -443204857, -442883244,
+ -442556940, -442225941, -441890243, -441549841, -441204731, -440854909,
+ -440500372, -440141114, -439777131, -439408420, -439034977, -438656797,
+ -438273877, -437886212, -437493799, -437096633, -436694711, -436288029,
+ -435876584, -435460370, -435039386, -434613626, -434183087, -433747765,
+ -433307658, -432862761, -432413070, -431958582, -431499294, -431035202,
+ -430566303, -430092593, -429614068, -429130726, -428642563, -428149575,
+ -427651760, -427149114, -426641634, -426129317, -425612159, -425090157,
+ -424563309, -424031611, -423495060, -422953654, -422407388, -421856261,
+ -421300269, -420739409, -420173679, -419603076, -419027596, -418447237,
+ -417861997, -417271872, -416676861, -416076959, -415472166, -414862477,
+ -414247891, -413628405, -413004016, -412374722, -411740521, -411101410,
+ -410457387, -409808449, -409154594, -408495821, -407832125, -407163507,
+ -406489962, -405811489, -405128087, -404439752, -403746483, -403048277,
+ -402345133, -401637049, -400924023, -400206053, -399483137, -398755273,
+ -398022459, -397284694, -396541975, -395794302, -395041672, -394284084,
+ -393521536, -392754027, -391981555, -391204118, -390421715, -389634345,
+ -388842006, -388044696, -387242415, -386435161, -385622932, -384805728,
+ -383983547, -383156388, -382324250, -381487132, -380645032, -379797949,
+ -378945883, -378088833, -377226797, -376359774, -375487764, -374610766,
+ -373728778, -372841801, -371949833, -371052873, -370150921, -369243976,
+ -368332038, -367415105, -366493178, -365566255, -364634336, -363697422,
+ -362755510, -361808601, -360856694, -359899790, -358937887, -357970985,
+ -356999085, -356022185, -355040287, -354053388, -353061490, -352064593,
+ -351062696, -350055799, -349043902, -348027005, -347005109, -345978213,
+ -344946318, -343909423, -342867530, -341820637, -340768746, -339711857,
+ -338649970, -337583085, -336511203, -335434325, -334352450, -333265579,
+ -332173713, -331076853, -329974998, -328868150, -327756309, -326639476,
+ -325517652, -324390837, -323259033, -322122239, -320980458, -319833689,
+ -318681934, -317525194, -316363470, -315196762, -314025072, -312848401,
+ -311666751, -310480121, -309288514, -308091931, -306890373, -305683841,
+ -304472336, -303255861, -302034415, -300808002, -299576622, -298340277,
+ -297098968, -295852697, -294601466, -293345276, -292084128, -290818025,
+ -289546969, -288270960, -286990002, -285704095, -284413241, -283117443,
+ -281816703, -280511022, -279200402, -277884846, -276564356, -275238933,
+ -273908580, -272573299, -271233092, -269887962, -268537910, -267182940,
+ -265823052, -264458251, -263088538, -261713915, -260334386, -258949952,
+ -257560617, -256166382, -254767251, -253363226, -251954310, -250540505,
+ -249121814, -247698241, -246269787, -244836456, -243398250, -241955173,
+ -240507228, -239054417, -237596744, -236134211, -234666822, -233194579,
+ -231717487, -230235548, -228748765, -227257141, -225760681, -224259387,
+ -222753263, -221242311, -219726536, -218205941, -216680530, -215150305,
+ -213615271, -212075431, -210530789, -208981348, -207427112, -205868085,
+ -204304271, -202735673, -201162296, -199584143, -198001217, -196413524,
+ -194821067, -193223849, -191621876, -190015151, -188403677, -186787461,
+ -185166504, -183540813, -181910390, -180275241, -178635369, -176990779,
+ -175341475, -173687462, -172028743, -170365325, -168697210, -167024404,
+ -165346912, -163664737, -161977884, -160286359, -158590165, -156889308,
+ -155183793, -153473623, -151758805, -150039342, -148315240, -146586504,
+ -144853138, -143115148, -141372539, -139625316, -137873484, -136117048,
+ -134356012, -132590384, -130820167, -129045367, -127265989, -125482039,
+ -123693522, -121900444, -120102809, -118300623, -116493892, -114682622,
+ -112866817, -111046484, -109221628, -107392255, -105558371, -103719981,
+ -101877091, -100029706, -98177833, -96321478, -94460646, -92595344,
+ -90725577, -88851351, -86972673, -85089548, -83201982, -81309983,
+ -79413554, -77512704, -75607439, -73697763, -71783685, -69865209,
+ -67942343, -66015093, -64083465, -62147465, -60207101, -58262379,
+ -56313304, -54359885, -52402127, -50440037, -48473622, -46502888,
+ -44527842, -42548492, -40564843, -38576903, -36584678, -34588176,
+ -32587403, -30582366, -28573073, -26559529, -24541744, -22519722,
+ -20493472, -18463001, -16428316, -14389424, -12346332, -10299048,
+ -8247579, -6191932, -4132115, -2068135, 0, 2072283, 4148707, 6229264,
+ 8313947, 10402747, 12495658, 14592671, 16693779, 18798974, 20908249,
+ 23021595, 25139005, 27260471, 29385985, 31515539, 33649126, 35786737,
+ 37928364, 40074000, 42223636, 44377264, 46534876, 48696464, 50862019,
+ 53031534, 55205001, 57382410, 59563755, 61749025, 63938214, 66131312,
+ 68328312, 70529204, 72733981, 74942633, 77155153, 79371531, 81591760,
+ 83815830, 86043733, 88275460, 90511002, 92750351, 94993498, 97240434,
+ 99491150, 101745638, 104003888, 106265892, 108531640, 110801124,
+ 113074335, 115351264, 117631900, 119916237, 122204263, 124495971,
+ 126791351, 129090394, 131393090, 133699430, 136009405, 138323006,
+ 140640224, 142961048, 145285470, 147613479, 149945068, 152280225,
+ 154618942, 156961209, 159307016, 161656355, 164009214, 166365585,
+ 168725458, 171088822, 173455670, 175825989, 178199772, 180577007,
+ 182957686, 185341798, 187729333, 190120281, 192514633, 194912378,
+ 197313507, 199718008, 202125873, 204537091, 206951653, 209369546,
+ 211790763, 214215292, 216643123, 219074246, 221508651, 223946326,
+ 226387263, 228831451, 231278878, 233729536, 236183412, 238640498,
+ 241100782, 243564253, 246030902, 248500717, 250973689, 253449805,
+ 255929057, 258411432, 260896921, 263385513, 265877196, 268371960,
+ 270869795, 273370689, 275874631, 278381611, 280891618, 283404640,
+ 285920667, 288439688, 290961692, 293486667, 296014604, 298545489,
+ 301079313, 303616065, 306155732, 308698305, 311243771, 313792120,
+ 316343340, 318897420, 321454348, 324014114, 326576706, 329142112,
+ 331710321, 334281322, 336855103, 339431653, 342010961, 344593014,
+ 347177801, 349765310, 352355531, 354948451, 357544059, 360142343,
+ 362743291, 365346892, 367953133, 370562004, 373173492, 375787586,
+ 378404273, 381023542, 383645382, 386269779, 388896722, 391526200,
+ 394158200, 396792710, 399429719, 402069213, 404711182, 407355613,
+ 410002494, 412651813, 415303557, 417957715, 420614275, 423273223,
+ 425934549, 428598239, 431264281, 433932664, 436603375, 439276401,
+ 441951730, 444629350, 447309248, 449991412, 452675830, 455362488,
+ 458051376, 460742479, 463435786, 466131283, 468828960, 471528802,
+ 474230797, 476934933, 479641196, 482349576, 485060057, 487772629,
+ 490487278, 493203991, 495922756, 498643560, 501366390, 504091233,
+ 506818077, 509546908, 512277714, 515010482, 517745198, 520481851,
+ 523220427, 525960913, 528703295, 531447562, 534193700, 536941696,
+ 539691537, 542443209, 545196700, 547951997, 550709087, 553467955,
+ 556228590, 558990978, 561755105, 564520959, 567288527, 570057794,
+ 572828748, 575601376, 578375663, 581151598, 583929166, 586708354,
+ 589489149, 592271537, 595055505, 597841039, 600628127, 603416754,
+ 606206907, 608998573, 611791738, 614586389, 617382511, 620180092,
+ 622979118, 625779575, 628581450, 631384729, 634189399, 636995445,
+ 639802854, 642611613, 645421708, 648233124, 651045849, 653859868,
+ 656675168, 659491736, 662309556, 665128616, 667948901, 670770399,
+ 673593094, 676416973, 679242022, 682068228, 684895576, 687724053,
+ 690553644, 693384336, 696216115, 699048966, 701882876, 704717831,
+ 707553817, 710390819, 713228824, 716067817, 718907785, 721748713,
+ 724590588, 727433395, 730277121, 733121750, 735967269, 738813664,
+ 741660921, 744509025, 747357962, 750207719, 753058280, 755909631,
+ 758761760, 761614650, 764468288, 767322660, 770177751, 773033547,
+ 775890034, 778747197, 781605023, 784463496, 787322602, 790182328,
+ 793042658, 795903579, 798765076, 801627134, 804489739, 807352877,
+ 810216534, 813080694, 815945344, 818810468, 821676053, 824542084,
+ 827408547, 830275427, 833142709, 836010379, 838878423, 841746825,
+ 844615572, 847484649, 850354042, 853223735, 856093714, 858963965,
+ 861834472, 864705223, 867576201, 870447392, 873318781, 876190355,
+ 879062098, 881933996, 884806033, 887678196, 890550469, 893422839,
+ 896295290, 899167807, 902040376, 904912983, 907785612, 910658248,
+ 913530878, 916403486, 919276057, 922148578, 925021032, 927893406,
+ 930765684, 933637853, 936509896, 939381799, 942253548, 945125127,
+ 947996522, 950867719, 953738701, 956609455, 959479966, 962350218,
+ 965220197, 968089889, 970959277, 973828348, 976697087, 979565478,
+ 982433508, 985301160, 988168420, 991035274, 993901706, 996767702,
+ 999633246, 1002498324, 1005362921, 1008227022, 1011090612, 1013953676,
+ 1016816200, 1019678167, 1022539565, 1025400377, 1028260588, 1031120185,
+ 1033979151, 1036837472, 1039695133, 1042552119, 1045408415, 1048264007,
+ 1051118878, 1053973015, 1056826403, 1059679025, 1062530869, 1065381918,
+ 1068232157, 1071081573, 1073930149, 1076777870, 1079624723, 1082470692,
+ 1085315761, 1088159917, 1091003143, 1093845426, 1096686750, 1099527100,
+ 1102366461, 1105204819, 1108042158, 1110878463, 1113713720, 1116547913,
+ 1119381028, 1122213049, 1125043962, 1127873752, 1130702403, 1133529902,
+ 1136356232, 1139181379, 1142005328, 1144828063, 1147649571, 1150469837,
+ 1153288844, 1156106578, 1158923025, 1161738170, 1164551996, 1167364490,
+ 1170175637, 1172985422, 1175793829, 1178600844, 1181406452, 1184210637,
+ 1187013386, 1189814683, 1192614513, 1195412862, 1198209714, 1201005055,
+ 1203798869, 1206591142, 1209381858, 1212171004, 1214958564, 1217744523,
+ 1220528866, 1223311579, 1226092646, 1228872053, 1231649785, 1234425827,
+ 1237200164, 1239972782, 1242743665, 1245512798, 1248280168, 1251045758,
+ 1253809555, 1256571543, 1259331707, 1262090033, 1264846506, 1267601112,
+ 1270353834, 1273104660, 1275853573, 1278600559, 1281345603, 1284088691,
+ 1286829807, 1289568938, 1292306067, 1295041182, 1297774266, 1300505305,
+ 1303234285, 1305961190, 1308686006, 1311408719, 1314129313, 1316847774,
+ 1319564087, 1322278238, 1324990211, 1327699993, 1330407569, 1333112923,
+ 1335816042, 1338516911, 1341215515, 1343911839, 1346605870, 1349297591,
+ 1351986990, 1354674051, 1357358759, 1360041101, 1362721061, 1365398625,
+ 1368073779, 1370746508, 1373416797, 1376084633, 1378750000, 1381412884,
+ 1384073270, 1386731145, 1389386494, 1392039302, 1394689554, 1397337237,
+ 1399982336, 1402624837, 1405264725, 1407901986, 1410536606, 1413168569,
+ 1415797863, 1418424472, 1421048382, 1423669579, 1426288049, 1428903777,
+ 1431516749, 1434126950, 1436734368, 1439338986, 1441940792, 1444539770,
+ 1447135907, 1449729189, 1452319601, 1454907129, 1457491759, 1460073476,
+ 1462652268, 1465228119, 1467801015, 1470370943, 1472937888, 1475501836,
+ 1478062774, 1480620687, 1483175561, 1485727381, 1488276136, 1490821809,
+ 1493364387, 1495903857, 1498440204, 1500973414, 1503503474, 1506030369,
+ 1508554086, 1511074610, 1513591929, 1516106027, 1518616892, 1521124509,
+ 1523628865, 1526129946, 1528627738, 1531122227, 1533613400, 1536101243,
+ 1538585742, 1541066883, 1543544653, 1546019038, 1548490025, 1550957600,
+ 1553421749, 1555882458, 1558339715, 1560793505, 1563243816, 1565690632,
+ 1568133942, 1570573731, 1573009986, 1575442693, 1577871840, 1580297412,
+ 1582719396, 1585137779, 1587552548, 1589963688, 1592371188, 1594775032,
+ 1597175209, 1599571705, 1601964506, 1604353599, 1606738972, 1609120610,
+ 1611498500, 1613872631, 1616242987, 1618609557, 1620972326, 1623331282,
+ 1625686413, 1628037703, 1630385142, 1632728715, 1635068410, 1637404213,
+ 1639736112, 1642064093, 1644388145, 1646708253, 1649024405, 1651336588,
+ 1653644789, 1655948995, 1658249194, 1660545373, 1662837519, 1665125619,
+ 1667409660, 1669689630, 1671965516, 1674237305, 1676504985, 1678768543,
+ 1681027966, 1683283243, 1685534359, 1687781303, 1690024062, 1692262624,
+ 1694496976, 1696727106, 1698953001, 1701174649, 1703392037, 1705605153,
+ 1707813985, 1710018520, 1712218747, 1714414651, 1716606223, 1718793448,
+ 1720976316, 1723154813, 1725328928, 1727498648, 1729663961, 1731824856,
+ 1733981320, 1736133340, 1738280906, 1740424004, 1742562624, 1744696752,
+ 1746826377, 1748951487, 1751072071, 1753188116, 1755299610, 1757406541,
+ 1759508899, 1761606670, 1763699844, 1765788408, 1767872350, 1769951660,
+ 1772026325, 1774096334, 1776161675, 1778222336, 1780278306, 1782329574,
+ 1784376128, 1786417955, 1788455046, 1790487388, 1792514971, 1794537781,
+ 1796555810, 1798569044, 1800577472, 1802581084, 1804579868, 1806573812,
+ 1808562907, 1810547139, 1812526499, 1814500974, 1816470555, 1818435230,
+ 1820394987, 1822349816, 1824299705, 1826244645, 1828184623, 1830119629,
+ 1832049652, 1833974681, 1835894705, 1837809714, 1839719696, 1841624641,
+ 1843524538, 1845419376, 1847309145, 1849193834, 1851073432, 1852947929,
+ 1854817314, 1856681577, 1858540707, 1860394693, 1862243526, 1864087194,
+ 1865925687, 1867758996, 1869587108, 1871410015, 1873227706, 1875040170,
+ 1876847398, 1878649379, 1880446103, 1882237559, 1884023738, 1885804630,
+ 1887580224, 1889350510, 1891115479, 1892875121, 1894629424, 1896378381,
+ 1898121979, 1899860211, 1901593065, 1903320533, 1905042604, 1906759268,
+ 1908470516, 1910176338, 1911876725, 1913571666, 1915261153, 1916945175,
+ 1918623723, 1920296788, 1921964360, 1923626430, 1925282988, 1926934024,
+ 1928579530, 1930219496, 1931853913, 1933482771, 1935106061, 1936723775,
+ 1938335902, 1939942434, 1941543362, 1943138676, 1944728368, 1946312428,
+ 1947890847, 1949463617, 1951030728, 1952592172, 1954147940, 1955698022,
+ 1957242411, 1958781096, 1960314071, 1961841325, 1963362850, 1964878638,
+ 1966388680, 1967892967, 1969391490, 1970884242, 1972371214, 1973852396,
+ 1975327782, 1976797362, 1978261128, 1979719072, 1981171185, 1982617459,
+ 1984057887, 1985492459, 1986921167, 1988344004, 1989760961, 1991172031,
+ 1992577204, 1993976474, 1995369832, 1996757271, 1998138781, 1999514356,
+ 2000883988, 2002247669, 2003605391, 2004957146, 2006302927, 2007642725,
+ 2008976534, 2010304346, 2011626153, 2012941947, 2014251722, 2015555469,
+ 2016853181, 2018144851, 2019430472, 2020710035, 2021983535, 2023250962,
+ 2024512311, 2025767574, 2027016744, 2028259814, 2029496777, 2030727625,
+ 2031952351, 2033170949, 2034383412, 2035589732, 2036789904, 2037983919,
+ 2039171771, 2040353454, 2041528960, 2042698283, 2043861416, 2045018353,
+ 2046169086, 2047313610, 2048451918, 2049584003, 2050709859, 2051829480,
+ 2052942858, 2054049988, 2055150863, 2056245477, 2057333824, 2058415897,
+ 2059491691, 2060561199, 2061624414, 2062681332, 2063731946, 2064776249,
+ 2065814237, 2066845902, 2067871240, 2068890243, 2069902908, 2070909226,
+ 2071909194, 2072902804, 2073890052, 2074870932, 2075845438, 2076813564,
+ 2077775305, 2078730656, 2079679611, 2080622164, 2081558311, 2082488045,
+ 2083411362, 2084328257, 2085238723, 2086142755, 2087040350, 2087931501,
+ 2088816203, 2089694451, 2090566241, 2091431566, 2092290424, 2093142807,
+ 2093988712, 2094828133, 2095661066, 2096487506, 2097307449, 2098120889,
+ 2098927821, 2099728243, 2100522147, 2101309531, 2102090390, 2102864719,
+ 2103632513, 2104393769, 2105148481, 2105896646, 2106638260, 2107373317,
+ 2108101815, 2108823748, 2109539112, 2110247904, 2110950119, 2111645754,
+ 2112334804, 2113017265, 2113693133, 2114362406, 2115025078, 2115681145,
+ 2116330605, 2116973454, 2117609687, 2118239301, 2118862293, 2119478658,
+ 2120088394, 2120691497, 2121287963, 2121877789, 2122460972, 2123037508,
+ 2123607394, 2124170626, 2124727202, 2125277118, 2125820372, 2126356959,
+ 2126886877, 2127410122, 2127926693, 2128436585, 2128939797, 2129436324,
+ 2129926164, 2130409315, 2130885774, 2131355537, 2131818602, 2132274967,
+ 2132724629, 2133167585, 2133603833, 2134033369, 2134456193, 2134872301,
+ 2135281691, 2135684361, 2136080307, 2136469529, 2136852024, 2137227789,
+ 2137596822, 2137959122, 2138314686, 2138663512, 2139005598, 2139340943,
+ 2139669543, 2139991398, 2140306506, 2140614864, 2140916471, 2141211325,
+ 2141499425, 2141780769, 2142055355, 2142323181, 2142584247, 2142838550,
+ 2143086090, 2143326864, 2143560871, 2143788111, 2144008581, 2144222280,
+ 2144429208, 2144629363, 2144822743, 2145009348, 2145189177, 2145362229,
+ 2145528502, 2145687996, 2145840710, 2145986642, 2146125793, 2146258161,
+ 2146383745, 2146502545, 2146614560, 2146719790, 2146818233, 2146909890,
+ 2146994759, 2147072841, 2147144134, 2147208639, 2147266355, 2147317281,
+ 2147361418, 2147398765, 2147429322, 2147453089, 2147470065, 2147480251,
+ 2147483646, 2147480251, 2147470065, 2147453089, 2147429322, 2147398765,
+ 2147361418, 2147317281, 2147266355, 2147208639, 2147144134, 2147072841,
+ 2146994759, 2146909890, 2146818233, 2146719790, 2146614560, 2146502545,
+ 2146383745, 2146258161, 2146125793, 2145986642, 2145840710, 2145687996,
+ 2145528502, 2145362229, 2145189177, 2145009348, 2144822743, 2144629363,
+ 2144429208, 2144222280, 2144008581, 2143788111, 2143560871, 2143326864,
+ 2143086090, 2142838550, 2142584247, 2142323181, 2142055355, 2141780769,
+ 2141499425, 2141211325, 2140916471, 2140614864, 2140306506, 2139991398,
+ 2139669543, 2139340943, 2139005598, 2138663512, 2138314686, 2137959122,
+ 2137596822, 2137227789, 2136852024, 2136469529, 2136080307, 2135684361,
+ 2135281691, 2134872301, 2134456193, 2134033369, 2133603833, 2133167585,
+ 2132724629, 2132274967, 2131818602, 2131355537, 2130885774, 2130409315,
+ 2129926164, 2129436324, 2128939797, 2128436585, 2127926693, 2127410122,
+ 2126886877, 2126356959, 2125820372, 2125277118, 2124727202, 2124170626,
+ 2123607394, 2123037508, 2122460972, 2121877789, 2121287963, 2120691497,
+ 2120088394, 2119478658, 2118862293, 2118239301, 2117609687, 2116973454,
+ 2116330605, 2115681145, 2115025078, 2114362406, 2113693133, 2113017265,
+ 2112334804, 2111645754, 2110950119, 2110247904, 2109539112, 2108823748,
+ 2108101815, 2107373317, 2106638260, 2105896646, 2105148481, 2104393769,
+ 2103632513, 2102864719, 2102090390, 2101309531, 2100522147, 2099728243,
+ 2098927821, 2098120889, 2097307449, 2096487506, 2095661066, 2094828133,
+ 2093988712, 2093142807, 2092290424, 2091431566, 2090566241, 2089694451,
+ 2088816203, 2087931501, 2087040350, 2086142755, 2085238723, 2084328257,
+ 2083411362, 2082488045, 2081558311, 2080622164, 2079679611, 2078730656,
+ 2077775305, 2076813564, 2075845438, 2074870932, 2073890052, 2072902804,
+ 2071909194, 2070909226, 2069902908, 2068890243, 2067871240, 2066845902,
+ 2065814237, 2064776249, 2063731946, 2062681332, 2061624414, 2060561199,
+ 2059491691, 2058415897, 2057333824, 2056245477, 2055150863, 2054049988,
+ 2052942858, 2051829480, 2050709859, 2049584003, 2048451918, 2047313610,
+ 2046169086, 2045018353, 2043861416, 2042698283, 2041528960, 2040353454,
+ 2039171771, 2037983919, 2036789904, 2035589732, 2034383412, 2033170949,
+ 2031952351, 2030727625, 2029496777, 2028259814, 2027016744, 2025767574,
+ 2024512311, 2023250962, 2021983535, 2020710035, 2019430472, 2018144851,
+ 2016853181, 2015555469, 2014251722, 2012941947, 2011626153, 2010304346,
+ 2008976534, 2007642725, 2006302927, 2004957146, 2003605391, 2002247669,
+ 2000883988, 1999514356, 1998138781, 1996757271, 1995369832, 1993976474,
+ 1992577204, 1991172031, 1989760961, 1988344004, 1986921167, 1985492459,
+ 1984057887, 1982617459, 1981171185, 1979719072, 1978261128, 1976797362,
+ 1975327782, 1973852396, 1972371214, 1970884242, 1969391490, 1967892967,
+ 1966388680, 1964878638, 1963362850, 1961841325, 1960314071, 1958781096,
+ 1957242411, 1955698022, 1954147940, 1952592172, 1951030728, 1949463617,
+ 1947890847, 1946312428, 1944728368, 1943138676, 1941543362, 1939942434,
+ 1938335902, 1936723775, 1935106061, 1933482771, 1931853913, 1930219496,
+ 1928579530, 1926934024, 1925282988, 1923626430, 1921964360, 1920296788,
+ 1918623723, 1916945175, 1915261153, 1913571666, 1911876725, 1910176338,
+ 1908470516, 1906759268, 1905042604, 1903320533, 1901593065, 1899860211,
+ 1898121979, 1896378381, 1894629424, 1892875121, 1891115479, 1889350510,
+ 1887580224, 1885804630, 1884023738, 1882237559, 1880446103, 1878649379,
+ 1876847398, 1875040170, 1873227706, 1871410015, 1869587108, 1867758996,
+ 1865925687, 1864087194, 1862243526, 1860394693, 1858540707, 1856681577,
+ 1854817314, 1852947929, 1851073432, 1849193834, 1847309145, 1845419376,
+ 1843524538, 1841624641, 1839719696, 1837809714, 1835894705, 1833974681,
+ 1832049652, 1830119629, 1828184623, 1826244645, 1824299705, 1822349816,
+ 1820394987, 1818435230, 1816470555, 1814500974, 1812526499, 1810547139,
+ 1808562907, 1806573812, 1804579868, 1802581084, 1800577472, 1798569044,
+ 1796555810, 1794537781, 1792514971, 1790487388, 1788455046, 1786417955,
+ 1784376128, 1782329574, 1780278306, 1778222336, 1776161675, 1774096334,
+ 1772026325, 1769951660, 1767872350, 1765788408, 1763699844, 1761606670,
+ 1759508899, 1757406541, 1755299610, 1753188116, 1751072071, 1748951487,
+ 1746826377, 1744696752, 1742562624, 1740424004, 1738280906, 1736133340,
+ 1733981320, 1731824856, 1729663961, 1727498648, 1725328928, 1723154813,
+ 1720976316, 1718793448, 1716606223, 1714414651, 1712218747, 1710018520,
+ 1707813985, 1705605153, 1703392037, 1701174649, 1698953001, 1696727106,
+ 1694496976, 1692262624, 1690024062, 1687781303, 1685534359, 1683283243,
+ 1681027966, 1678768543, 1676504985, 1674237305, 1671965516, 1669689630,
+ 1667409660, 1665125619, 1662837519, 1660545373, 1658249194, 1655948995,
+ 1653644789, 1651336588, 1649024405, 1646708253, 1644388145, 1642064093,
+ 1639736112, 1637404213, 1635068410, 1632728715, 1630385142, 1628037703,
+ 1625686413, 1623331282, 1620972326, 1618609557, 1616242987, 1613872631,
+ 1611498500, 1609120610, 1606738972, 1604353599, 1601964506, 1599571705,
+ 1597175209, 1594775032, 1592371188, 1589963688, 1587552548, 1585137779,
+ 1582719396, 1580297412, 1577871840, 1575442693, 1573009986, 1570573731,
+ 1568133942, 1565690632, 1563243816, 1560793505, 1558339715, 1555882458,
+ 1553421749, 1550957600, 1548490025, 1546019038, 1543544653, 1541066883,
+ 1538585742, 1536101243, 1533613400, 1531122227, 1528627738, 1526129946,
+ 1523628865, 1521124509, 1518616892, 1516106027, 1513591929, 1511074610,
+ 1508554086, 1506030369, 1503503474, 1500973414, 1498440204, 1495903857,
+ 1493364387, 1490821809, 1488276136, 1485727381, 1483175561, 1480620687,
+ 1478062774, 1475501836, 1472937888, 1470370943, 1467801015, 1465228119,
+ 1462652268, 1460073476, 1457491759, 1454907129, 1452319601, 1449729189,
+ 1447135907, 1444539770, 1441940792, 1439338986, 1436734368, 1434126950,
+ 1431516749, 1428903777, 1426288049, 1423669579, 1421048382, 1418424472,
+ 1415797863, 1413168569, 1410536606, 1407901986, 1405264725, 1402624837,
+ 1399982336, 1397337237, 1394689554, 1392039302, 1389386494, 1386731145,
+ 1384073270, 1381412884, 1378750000, 1376084633, 1373416797, 1370746508,
+ 1368073779, 1365398625, 1362721061, 1360041101, 1357358759, 1354674051,
+ 1351986990, 1349297591, 1346605870, 1343911839, 1341215515, 1338516911,
+ 1335816042, 1333112923, 1330407569, 1327699993, 1324990211, 1322278238,
+ 1319564087, 1316847774, 1314129313, 1311408719, 1308686006, 1305961190,
+ 1303234285, 1300505305, 1297774266, 1295041182, 1292306067, 1289568938,
+ 1286829807, 1284088691, 1281345603, 1278600559, 1275853573, 1273104660,
+ 1270353834, 1267601112, 1264846506, 1262090033, 1259331707, 1256571543,
+ 1253809555, 1251045758, 1248280168, 1245512798, 1242743665, 1239972782,
+ 1237200164, 1234425827, 1231649785, 1228872053, 1226092646, 1223311579,
+ 1220528866, 1217744523, 1214958564, 1212171004, 1209381858, 1206591142,
+ 1203798869, 1201005055, 1198209714, 1195412862, 1192614513, 1189814683,
+ 1187013386, 1184210637, 1181406452, 1178600844, 1175793829, 1172985422,
+ 1170175637, 1167364490, 1164551996, 1161738170, 1158923025, 1156106578,
+ 1153288844, 1150469837, 1147649571, 1144828063, 1142005328, 1139181379,
+ 1136356232, 1133529902, 1130702403, 1127873752, 1125043962, 1122213049,
+ 1119381028, 1116547913, 1113713720, 1110878463, 1108042158, 1105204819,
+ 1102366461, 1099527100, 1096686750, 1093845426, 1091003143, 1088159917,
+ 1085315761, 1082470692, 1079624723, 1076777870, 1073930149, 1071081573,
+ 1068232157, 1065381918, 1062530869, 1059679025, 1056826403, 1053973015,
+ 1051118878, 1048264007, 1045408415, 1042552119, 1039695133, 1036837472,
+ 1033979151, 1031120185, 1028260588, 1025400377, 1022539565, 1019678167,
+ 1016816200, 1013953676, 1011090612, 1008227022, 1005362921, 1002498324,
+ 999633246, 996767702, 993901706, 991035274, 988168420, 985301160,
+ 982433508, 979565478, 976697087, 973828348, 970959277, 968089889,
+ 965220197, 962350218, 959479966, 956609455, 953738701, 950867719,
+ 947996522, 945125127, 942253548, 939381799, 936509896, 933637853,
+ 930765684, 927893406, 925021032, 922148578, 919276057, 916403486,
+ 913530878, 910658248, 907785612, 904912983, 902040376, 899167807,
+ 896295290, 893422839, 890550469, 887678196, 884806033, 881933996,
+ 879062098, 876190355, 873318781, 870447392, 867576201, 864705223,
+ 861834472, 858963965, 856093714, 853223735, 850354042, 847484649,
+ 844615572, 841746825, 838878423, 836010379, 833142709, 830275427,
+ 827408547, 824542084, 821676053, 818810468, 815945344, 813080694,
+ 810216534, 807352877, 804489739, 801627134, 798765076, 795903579,
+ 793042658, 790182328, 787322602, 784463496, 781605023, 778747197,
+ 775890034, 773033547, 770177751, 767322660, 764468288, 761614650,
+ 758761760, 755909631, 753058280, 750207719, 747357962, 744509025,
+ 741660921, 738813664, 735967269, 733121750, 730277121, 727433395,
+ 724590588, 721748713, 718907785, 716067817, 713228824, 710390819,
+ 707553817, 704717831, 701882876, 699048966, 696216115, 693384336,
+ 690553644, 687724053, 684895576, 682068228, 679242022, 676416973,
+ 673593094, 670770399, 667948901, 665128616, 662309556, 659491736,
+ 656675168, 653859868, 651045849, 648233124, 645421708, 642611613,
+ 639802854, 636995445, 634189399, 631384729, 628581450, 625779575,
+ 622979118, 620180092, 617382511, 614586389, 611791738, 608998573,
+ 606206907, 603416754, 600628127, 597841039, 595055505, 592271537,
+ 589489149, 586708354, 583929166, 581151598, 578375663, 575601376,
+ 572828748, 570057794, 567288527, 564520959, 561755105, 558990978,
+ 556228590, 553467955, 550709087, 547951997, 545196700, 542443209,
+ 539691537, 536941696, 534193700, 531447562, 528703295, 525960913,
+ 523220427, 520481851, 517745198, 515010482, 512277714, 509546908,
+ 506818077, 504091233, 501366390, 498643560, 495922756, 493203991,
+ 490487278, 487772629, 485060057, 482349576, 479641196, 476934933,
+ 474230797, 471528802, 468828960, 466131283, 463435786, 460742479,
+ 458051376, 455362488, 452675830, 449991412, 447309248, 444629350,
+ 441951730, 439276401, 436603375, 433932664, 431264281, 428598239,
+ 425934549, 423273223, 420614275, 417957715, 415303557, 412651813,
+ 410002494, 407355613, 404711182, 402069213, 399429719, 396792710,
+ 394158200, 391526200, 388896722, 386269779, 383645382, 381023542,
+ 378404273, 375787586, 373173492, 370562004, 367953133, 365346892,
+ 362743291, 360142343, 357544059, 354948451, 352355531, 349765310,
+ 347177801, 344593014, 342010961, 339431653, 336855103, 334281322,
+ 331710321, 329142112, 326576706, 324014114, 321454348, 318897420,
+ 316343340, 313792120, 311243771, 308698305, 306155732, 303616065,
+ 301079313, 298545489, 296014604, 293486667, 290961692, 288439688,
+ 285920667, 283404640, 280891618, 278381611, 275874631, 273370689,
+ 270869795, 268371960, 265877196, 263385513, 260896921, 258411432,
+ 255929057, 253449805, 250973689, 248500717, 246030902, 243564253,
+ 241100782, 238640498, 236183412, 233729536, 231278878, 228831451,
+ 226387263, 223946326, 221508651, 219074246, 216643123, 214215292,
+ 211790763, 209369546, 206951653, 204537091, 202125873, 199718008,
+ 197313507, 194912378, 192514633, 190120281, 187729333, 185341798,
+ 182957686, 180577007, 178199772, 175825989, 173455670, 171088822,
+ 168725458, 166365585, 164009214, 161656355, 159307016, 156961209,
+ 154618942, 152280225, 149945068, 147613479, 145285470, 142961048,
+ 140640224, 138323006, 136009405, 133699430, 131393090, 129090394,
+ 126791351, 124495971, 122204263, 119916237, 117631900, 115351264,
+ 113074335, 110801124, 108531640, 106265892, 104003888, 101745638,
+ 99491150, 97240434, 94993498, 92750351, 90511002, 88275460, 86043733,
+ 83815830, 81591760, 79371531, 77155153, 74942633, 72733981, 70529204,
+ 68328312, 66131312, 63938214, 61749025, 59563755, 57382410, 55205001,
+ 53031534, 50862019, 48696464, 46534876, 44377264, 42223636, 40074000,
+ 37928364, 35786737, 33649126, 31515539, 29385985, 27260471, 25139005,
+ 23021595, 20908249, 18798974, 16693779, 14592671, 12495658, 10402747,
+ 8313947, 6229264, 4148707, 2072283, 0, -2068135, -4132115, -6191932,
+ -8247579, -10299048, -12346332, -14389424, -16428316, -18463001,
+ -20493472, -22519722, -24541744, -26559529, -28573073, -30582366,
+ -32587403, -34588176, -36584678, -38576903, -40564843, -42548492,
+ -44527842, -46502888, -48473622, -50440037, -52402127, -54359885,
+ -56313304, -58262379, -60207101, -62147465, -64083465, -66015093,
+ -67942343, -69865209, -71783685, -73697763, -75607439, -77512704,
+ -79413554, -81309983, -83201982, -85089548, -86972673, -88851351,
+ -90725577, -92595344, -94460646, -96321478, -98177833, -100029706,
+ -101877091, -103719981, -105558371, -107392255, -109221628, -111046484,
+ -112866817, -114682622, -116493892, -118300623, -120102809, -121900444,
+ -123693522, -125482039, -127265989, -129045367, -130820167, -132590384,
+ -134356012, -136117048, -137873484, -139625316, -141372539, -143115148,
+ -144853138, -146586504, -148315240, -150039342, -151758805, -153473623,
+ -155183793, -156889308, -158590165, -160286359, -161977884, -163664737,
+ -165346912, -167024404, -168697210, -170365325, -172028743, -173687462,
+ -175341475, -176990779, -178635369, -180275241, -181910390, -183540813,
+ -185166504, -186787461, -188403677, -190015151, -191621876, -193223849,
+ -194821067, -196413524, -198001217, -199584143, -201162296, -202735673,
+ -204304271, -205868085, -207427112, -208981348, -210530789, -212075431,
+ -213615271, -215150305, -216680530, -218205941, -219726536, -221242311,
+ -222753263, -224259387, -225760681, -227257141, -228748765, -230235548,
+ -231717487, -233194579, -234666822, -236134211, -237596744, -239054417,
+ -240507228, -241955173, -243398250, -244836456, -246269787, -247698241,
+ -249121814, -250540505, -251954310, -253363226, -254767251, -256166382,
+ -257560617, -258949952, -260334386, -261713915, -263088538, -264458251,
+ -265823052, -267182940, -268537910, -269887962, -271233092, -272573299,
+ -273908580, -275238933, -276564356, -277884846, -279200402, -280511022,
+ -281816703, -283117443, -284413241, -285704095, -286990002, -288270960,
+ -289546969, -290818025, -292084128, -293345276, -294601466, -295852697,
+ -297098968, -298340277, -299576622, -300808002, -302034415, -303255861,
+ -304472336, -305683841, -306890373, -308091931, -309288514, -310480121,
+ -311666751, -312848401, -314025072, -315196762, -316363470, -317525194,
+ -318681934, -319833689, -320980458, -322122239, -323259033, -324390837,
+ -325517652, -326639476, -327756309, -328868150, -329974998, -331076853,
+ -332173713, -333265579, -334352450, -335434325, -336511203, -337583085,
+ -338649970, -339711857, -340768746, -341820637, -342867530, -343909423,
+ -344946318, -345978213, -347005109, -348027005, -349043902, -350055799,
+ -351062696, -352064593, -353061490, -354053388, -355040287, -356022185,
+ -356999085, -357970985, -358937887, -359899790, -360856694, -361808601,
+ -362755510, -363697422, -364634336, -365566255, -366493178, -367415105,
+ -368332038, -369243976, -370150921, -371052873, -371949833, -372841801,
+ -373728778, -374610766, -375487764, -376359774, -377226797, -378088833,
+ -378945883, -379797949, -380645032, -381487132, -382324250, -383156388,
+ -383983547, -384805728, -385622932, -386435161, -387242415, -388044696,
+ -388842006, -389634345, -390421715, -391204118, -391981555, -392754027,
+ -393521536, -394284084, -395041672, -395794302, -396541975, -397284694,
+ -398022459, -398755273, -399483137, -400206053, -400924023, -401637049,
+ -402345133, -403048277, -403746483, -404439752, -405128087, -405811489,
+ -406489962, -407163507, -407832125, -408495821, -409154594, -409808449,
+ -410457387, -411101410, -411740521, -412374722, -413004016, -413628405,
+ -414247891, -414862477, -415472166, -416076959, -416676861, -417271872,
+ -417861997, -418447237, -419027596, -419603076, -420173679, -420739409,
+ -421300269, -421856261, -422407388, -422953654, -423495060, -424031611,
+ -424563309, -425090157, -425612159, -426129317, -426641634, -427149114,
+ -427651760, -428149575, -428642563, -429130726, -429614068, -430092593,
+ -430566303, -431035202, -431499294, -431958582, -432413070, -432862761,
+ -433307658, -433747765, -434183087, -434613626, -435039386, -435460370,
+ -435876584, -436288029, -436694711, -437096633, -437493799, -437886212,
+ -438273877, -438656797, -439034977, -439408420, -439777131, -440141114,
+ -440500372, -440854909, -441204731, -441549841, -441890243, -442225941,
+ -442556940, -442883244, -443204857, -443521784, -443834029, -444141597,
+ -444444491, -444742716, -445036277, -445325179, -445609425, -445889020,
+ -446163969, -446434277, -446699948, -446960987, -447217399, -447469187,
+ -447716358, -447958915, -448196864, -448430210, -448658957, -448883110,
+ -449102674, -449317654, -449528055, -449733882, -449935140, -450131835,
+ -450323970, -450511552, -450694585, -450873075, -451047026, -451216445,
+ -451381335, -451541703, -451697554, -451848893, -451995726, -452138057,
+ -452275892, -452409237, -452538097, -452662478, -452782384, -452897823,
+ -453008798, -453115316, -453217382, -453315003, -453408182, -453496927,
+ -453581244, -453661136, -453736612, -453807675, -453874333, -453936590,
+ -453994454, -454047928, -454097021, -454141737, -454182082, -454218063,
+ -454249685, -454276955, -454299878, -454318461, -454332709, -454342630,
+ -454348228, -454349511, -454346483, -454339153, -454327525, -454311607,
+ -454291404, -454266923, -454238170, -454205151, -454167873, -454126343,
+ -454080567, -454030550, -453976300, -453917824, -453855127, -453788217,
+ -453717100, -453641782, -453562270, -453478572, -453390692, -453298639,
+ -453202419, -453102039, -452997505, -452888824, -452776003, -452659049,
+ -452537969, -452412770, -452283458, -452150041, -452012525, -451870917,
+ -451725225, -451575456, -451421615, -451263712, -451101752, -450935742,
+ -450765691, -450591604, -450413490, -450231355, -450045206, -449855052,
+ -449660898, -449462753, -449260623, -449054517, -448844440, -448630401,
+ -448412408, -448190467, -447964585, -447734771, -447501032, -447263375,
+ -447021808, -446776338, -446526973, -446273721, -446016588, -445755583,
+ -445490714, -445221987, -444949411, -444672993, -444392742, -444108663,
+ -443820767, -443529059, -443233549, -442934244, -442631151, -442324279,
+ -442013635, -441699227, -441381063, -441059152, -440733501, -440404117,
+ -440071010, -439734187, -439393655, -439049424, -438701501, -438349894,
+ -437994611, -437635661, -437273051, -436906790, -436536885, -436163346,
+ -435786180, -435405395, -435021000, -434633003, -434241412, -433846236,
+ -433447483, -433045160, -432639277, -432229842, -431816864, -431400349,
+ -430980308, -430556749, -430129679, -429699107, -429265043, -428827494,
+ -428386469, -427941976, -427494024, -427042622, -426587777, -426129500,
+ -425667798, -425202679, -424734154, -424262229, -423786915, -423308219,
+ -422826151, -422340718, -421851931, -421359797, -420864325, -420365525,
+ -419863404, -419357972, -418849238, -418337210, -417821898, -417303310,
+ -416781455, -416256341, -415727979, -415196377, -414661543, -414123487,
+ -413582218, -413037745, -412490077, -411939222, -411385190, -410827990,
+ -410267631, -409704122, -409137472, -408567691, -407994787, -407418769,
+ -406839647, -406257430, -405672126, -405083746, -404492299, -403897793,
+ -403300238, -402699643, -402096017, -401489370, -400879711, -400267049,
+ -399651393, -399032754, -398411139, -397786559, -397159023, -396528540,
+ -395895120, -395258771, -394619504, -393977328, -393332252, -392684286,
+ -392033439, -391379721, -390723140, -390063708, -389401432, -388736323,
+ -388068390, -387397643, -386724090, -386047743, -385368610, -384686701,
+ -384002025, -383314592, -382624412, -381931494, -381235849, -380537484,
+ -379836411, -379132639, -378426177, -377717036, -377005224, -376290752,
+ -375573630, -374853866, -374131471, -373406455, -372678827, -371948597,
+ -371215775, -370480370, -369742393, -369001853, -368258760, -367513123,
+ -366764953, -366014260, -365261052, -364505341, -363747136, -362986447,
+ -362223283, -361457655, -360689572, -359919045, -359146083, -358370696,
+ -357592894, -356812687, -356030085, -355245099, -354457737, -353668009,
+ -352875927, -352081499, -351284736, -350485648, -349684245, -348880536,
+ -348074532, -347266243, -346455678, -345642849, -344827764, -344010434,
+ -343190869, -342369079, -341545074, -340718864, -339890460, -339059870,
+ -338227107, -337392178, -336555095, -335715868, -334874507, -334031021,
+ -333185422, -332337718, -331487921, -330636040, -329782086, -328926069,
+ -328067998, -327207885, -326345738, -325481569, -324615388, -323747204,
+ -322877028, -322004870, -321130740, -320254649, -319376607, -318496623,
+ -317614708, -316730873, -315845127, -314957481, -314067944, -313176528,
+ -312283242, -311388097, -310491103, -309592269, -308691607, -307789127,
+ -306884838, -305978752, -305070878, -304161226, -303249807, -302336632,
+ -301421709, -300505051, -299586666, -298666565, -297744759, -296821258,
+ -295896071, -294969210, -294040685, -293110505, -292178682, -291245225,
+ -290310145, -289373452, -288435156, -287495267, -286553797, -285610755,
+ -284666152, -283719997, -282772301, -281823075, -280872329, -279920072,
+ -278966316, -278011071, -277054346, -276096153, -275136501, -274175402,
+ -273212864, -272248899, -271283517, -270316728, -269348542, -268378970,
+ -267408022, -266435709, -265462040, -264487026, -263510677, -262533004,
+ -261554017, -260573726, -259592141, -258609273, -257625133, -256639729,
+ -255653074, -254665176, -253676047, -252685696, -251694134, -250701372,
+ -249707419, -248712285, -247715982, -246718519, -245719906, -244720155,
+ -243719275, -242717276, -241714168, -240709963, -239704670, -238698300,
+ -237690863, -236682368, -235672827, -234662250, -233650646, -232638027,
+ -231624401, -230609781, -229594175, -228577594, -227560049, -226541549,
+ -225522105, -224501727, -223480426, -222458210, -221435092, -220411080,
+ -219386185, -218360418, -217333788, -216306306, -215277982, -214248825,
+ -213218847, -212188058, -211156467, -210124085, -209090922, -208056987,
+ -207022293, -205986847, -204950661, -203913745, -202876109, -201837762,
+ -200798716, -199758980, -198718564, -197677479, -196635734, -195593340,
+ -194550306, -193506643, -192462362, -191417471, -190371981, -189325903,
+ -188279245, -187232019, -186184234, -185135900, -184087028, -183037626,
+ -181987707, -180937278, -179886352, -178834936, -177783042, -176730679,
+ -175677858, -174624587, -173570879, -172516741, -171462185, -170407219,
+ -169351855, -168296102, -167239969, -166183468, -165126607, -164069397,
+ -163011847, -161953968, -160895769, -159837260, -158778452, -157719353,
+ -156659973, -155600324, -154540413, -153480252, -152419850, -151359216,
+ -150298361, -149237294, -148176026, -147114565, -146052922, -144991107,
+ -143929128, -142866996, -141804721, -140742312, -139679780, -138617132,
+ -137554380, -136491534, -135428601, -134365594, -133302520, -132239389,
+ -131176212, -130112998, -129049756, -127986497, -126923229, -125859962,
+ -124796706, -123733470, -122670264, -121607097, -120543980, -119480920,
+ -118417929, -117355015, -116292188, -115229457, -114166832, -113104323,
+ -112041938, -110979687, -109917580, -108855625, -107793833, -106732213,
+ -105670774, -104609525, -103548476, -102487635, -101427014, -100366620,
+ -99306463, -98246552, -97186897, -96127507, -95068391, -94009558,
+ -92951018, -91892780, -90834852, -89777245, -88719967, -87663027,
+ -86606436, -85550200, -84494331, -83438837, -82383727, -81329010,
+ -80274696, -79220792, -78167309, -77114256, -76061641, -75009473,
+ -73957762, -72906517, -71855745, -70805457, -69755662, -68706367,
+ -67657583, -66609318, -65561581, -64514380, -63467725, -62421625,
+ -61376088, -60331123, -59286739, -58242945, -57199749, -56157161,
+ -55115188, -54073841, -53033126, -51993054, -50953633, -49914872,
+ -48876778, -47839362, -46802631, -45766594, -44731259, -43696636,
+ -42662733, -41629558, -40597120, -39565428, -38534489, -37504313,
+ -36474908, -35446283, -34418445, -33391403, -32365166, -31339743,
+ -30315140, -29291368, -28268434, -27246346, -26225113, -25204744,
+ -24185246, -23166627, -22148897, -21132063, -20116133, -19101116,
+ -18087020, -17073853, -16061623, -15050338, -14040007, -13030638,
+ -12022238, -11014816, -10008380, -9002937, -7998497, -6995066,
+ -5992654, -4991267, -3990914, -2991603, -1993342, -996138, 0, 995064,
+ 1989048, 2981943, 3973740, 4964433, 5954014, 6942474, 7929806, 8916002,
+ 9901055, 10884957, 11867700, 12849276, 13829678, 14808899, 15786930,
+ 16763764, 17739393, 18713811, 19687008, 20658979, 21629714, 22599208,
+ 23567452, 24534439, 25500161, 26464612, 27427783, 28389667, 29350258,
+ 30309547, 31267527, 32224191, 33179532, 34133543, 35086216, 36037543,
+ 36987519, 37936135, 38883385, 39829261, 40773756, 41716863, 42658575,
+ 43598885, 44537786, 45475270, 46411332, 47345963, 48279157, 49210907,
+ 50141206, 51070047, 51997423, 52923327, 53847753, 54770693, 55692141,
+ 56612090, 57530533, 58447463, 59362875, 60276760, 61189112, 62099925,
+ 63009192, 63916906, 64823060, 65727649, 66630665, 67532102, 68431954,
+ 69330213, 70226874, 71121930, 72015374, 72907200, 73797401, 74685972,
+ 75572906, 76458196, 77341836, 78223820, 79104141, 79982794, 80859771,
+ 81735068, 82608677, 83480592, 84350807, 85219317, 86086114, 86951194,
+ 87814549, 88676173, 89536061, 90394207, 91250605, 92105248, 92958130,
+ 93809247, 94658591, 95506157, 96351939, 97195931, 98038128, 98878523,
+ 99717111, 100553886, 101388842, 102221974, 103053275, 103882741,
+ 104710365, 105536142, 106360066, 107182132, 108002333, 108820666,
+ 109637123, 110451700, 111264391, 112075190, 112884092, 113691092,
+ 114496184, 115299364, 116100624, 116899961, 117697369, 118492842,
+ 119286376, 120077964, 120867603, 121655286, 122441009, 123224766,
+ 124006552, 124786363, 125564192, 126340035, 127113887, 127885743,
+ 128655598, 129423447, 130189284, 130953106, 131714907, 132474681,
+ 133232426, 133988134, 134741803, 135493426, 136242999, 136990518,
+ 137735977, 138479372, 139220698, 139959951, 140697126, 141432218,
+ 142165222, 142896135, 143624951, 144351667, 145076277, 145798777,
+ 146519162, 147237429, 147953572, 148667588, 149379472, 150089219,
+ 150796826, 151502287, 152205600, 152906759, 153605760, 154302599,
+ 154997272, 155689775, 156380103, 157068253, 157754220, 158438000,
+ 159119590, 159798985, 160476181, 161151174, 161823961, 162494537,
+ 163162898, 163829041, 164492961, 165154656, 165814120, 166471351,
+ 167126344, 167779096, 168429603, 169077861, 169723867, 170367617,
+ 171009108, 171648335, 172285295, 172919984, 173552400, 174182539,
+ 174810396, 175435969, 176059254, 176680248, 177298948, 177915349,
+ 178529449, 179141244, 179750731, 180357907, 180962768, 181565312,
+ 182165534, 182763433, 183359004, 183952244, 184543151, 185131722,
+ 185717952, 186301840, 186883382, 187462575, 188039416, 188613903,
+ 189186032, 189755800, 190323205, 190888244, 191450913, 192011211,
+ 192569133, 193124679, 193677844, 194228626, 194777022, 195323030,
+ 195866647, 196407871, 196946698, 197483127, 198017154, 198548777,
+ 199077994, 199604803, 200129200, 200651183, 201170750, 201687899,
+ 202202626, 202714931, 203224810, 203732261, 204237282, 204739871,
+ 205240025, 205737742, 206233021, 206725858, 207216252, 207704201,
+ 208189702, 208672754, 209153355, 209631502, 210107193, 210580427,
+ 211051202, 211519515, 211985366, 212448751, 212909669, 213368118,
+ 213824097, 214277604, 214728636, 215177193, 215623272, 216066872,
+ 216507991, 216946628, 217382781, 217816448, 218247628, 218676319,
+ 219102519, 219526228, 219947444, 220366165, 220782389, 221196117,
+ 221607345, 222016073, 222422300, 222826023, 223227243, 223625956,
+ 224022164, 224415863, 224807053, 225195733, 225581902, 225965558,
+ 226346701, 226725328, 227101440, 227475036, 227846113, 228214672,
+ 228580711, 228944229, 229305226, 229663700, 230019651, 230373078,
+ 230723980, 231072356, 231418205, 231761528, 232102322, 232440587,
+ 232776323, 233109529, 233440204, 233768348, 234093960, 234417040,
+ 234737586, 235055599, 235371078, 235684022, 235994432, 236302305,
+ 236607644, 236910446, 237210711, 237508439, 237803631, 238096285,
+ 238386401, 238673979, 238959018, 239241520, 239521483, 239798906,
+ 240073792, 240346138, 240615944, 240883212, 241147941, 241410130,
+ 241669780, 241926891, 242181463, 242433495, 242682989, 242929944,
+ 243174359, 243416237, 243655576, 243892377, 244126639, 244358364,
+ 244587552, 244814202, 245038316, 245259893, 245478934, 245695439,
+ 245909409, 246120843, 246329744, 246536110, 246739943, 246941242,
+ 247140010, 247336245, 247529949, 247721122, 247909765, 248095879,
+ 248279464, 248460521, 248639050, 248815053, 248988530, 249159481,
+ 249327909, 249493812, 249657194, 249818053, 249976391, 250132210,
+ 250285509, 250436290, 250584555, 250730302, 250873535, 251014254,
+ 251152459, 251288153, 251421336, 251552009, 251680173, 251805830,
+ 251928981, 252049626, 252167768, 252283407, 252396545, 252507183,
+ 252615322, 252720964, 252824110, 252924761, 253022919, 253118585,
+ 253211761, 253302448, 253390647, 253476361, 253559590, 253640336,
+ 253718601, 253794386, 253867693, 253938524, 254006879, 254072762,
+ 254136173, 254197114, 254255587, 254311594, 254365137, 254416216,
+ 254464835, 254510994, 254554697, 254595943, 254634737, 254671079,
+ 254704971, 254736415, 254765414, 254791969, 254816082, 254837756,
+ 254856991, 254873792, 254888159, 254900094, 254909600, 254916680,
+ 254921334, 254923565, 254923376, 254920769, 254915746, 254908309,
+ 254898460, 254886202, 254871538, 254854468, 254834997, 254813126,
+ 254788858, 254762195, 254733139, 254701693, 254667860, 254631642,
+ 254593041, 254552060, 254508702, 254462969, 254414864, 254364389,
+ 254311547, 254256341, 254198773, 254138846, 254076563, 254011926,
+ 253944938, 253875603, 253803922, 253729899, 253653536, 253574837,
+ 253493803, 253410438, 253324746, 253236728, 253146387, 253053727,
+ 252958751, 252861462, 252761862, 252659954, 252555743, 252449230,
+ 252340418, 252229312, 252115914, 252000226, 251882253, 251761997,
+ 251639462, 251514651, 251387567, 251258213, 251126592, 250992708,
+ 250856565, 250718164, 250577511, 250434607, 250289456, 250142063,
+ 249992429, 249840559, 249686456, 249530124, 249371565, 249210784,
+ 249047783, 248882567, 248715138, 248545501, 248373659, 248199616,
+ 248023374, 247844939, 247664312, 247481499, 247296502, 247109326,
+ 246919973, 246728449, 246534756, 246338898, 246140879, 245940702,
+ 245738373, 245533893, 245327268, 245118500, 244907595, 244694555,
+ 244479384, 244262087, 244042668, 243821130, 243597477, 243371713,
+ 243143842, 242913869, 242681797, 242447630, 242211372, 241973028,
+ 241732600, 241490095, 241245515, 240998864, 240750148, 240499369,
+ 240246533, 239991642, 239734703, 239475718, 239214691, 238951628,
+ 238686532, 238419408, 238150260, 237879092, 237605909, 237330714,
+ 237053512, 236774308, 236493106, 236209910, 235924725, 235637555,
+ 235348404, 235057277, 234764179, 234469113, 234172085, 233873098,
+ 233572158, 233269268, 232964434, 232657660, 232348950, 232038309,
+ 231725742, 231411252, 231094846, 230776527, 230456300, 230134170,
+ 229810141, 229484218, 229156406, 228826709, 228495133, 228161681,
+ 227826359, 227489171, 227150122, 226809218, 226466462, 226121859,
+ 225775415, 225427134, 225077022, 224725081, 224371319, 224015739,
+ 223658347, 223299147, 222938145, 222575344, 222210751, 221844370,
+ 221476206, 221106265, 220734550, 220361067, 219985821, 219608818,
+ 219230061, 218849557, 218467310, 218083325, 217697608, 217310163,
+ 216920996, 216530111, 216137514, 215743210, 215347204, 214949502,
+ 214550107, 214149027, 213746265, 213341827, 212935718, 212527944,
+ 212118509, 211707419, 211294680, 210880295, 210464272, 210046614,
+ 209627328, 209206418, 208783890, 208359749, 207934001, 207506650,
+ 207077703, 206647165, 206215040, 205781335, 205346055, 204909204,
+ 204470789, 204030816, 203589288, 203146213, 202701595, 202255439,
+ 201807752, 201358539, 200907805, 200455555, 200001796, 199546533,
+ 199089770, 198631515, 198171772, 197710546, 197247845, 196783672,
+ 196318034, 195850936, 195382383, 194912383, 194440939, 193968057,
+ 193493744, 193018005, 192540845, 192062271, 191582287, 191100900,
+ 190618115, 190133938, 189648374, 189161429, 188673110, 188183421,
+ 187692369, 187199958, 186706196, 186211087, 185714637, 185216853,
+ 184717739, 184217302, 183715547, 183212481, 182708109, 182202436,
+ 181695469, 181187214, 180677675, 180166860, 179654774, 179141423,
+ 178626812, 178110947, 177593835, 177075481, 176555891, 176035072,
+ 175513027, 174989765, 174465290, 173939609, 173412728, 172884651,
+ 172355386, 171824938, 171293314, 170760518, 170226557, 169691438,
+ 169155165, 168617745, 168079185, 167539489, 166998663, 166456715,
+ 165913649, 165369473, 164824191, 164277809, 163730335, 163181774,
+ 162632131, 162081413, 161529626, 160976776, 160422869, 159867911,
+ 159311908, 158754866, 158196792, 157637690, 157077568, 156516431,
+ 155954286, 155391138, 154826994, 154261859, 153695741, 153128644,
+ 152560575, 151991540, 151421545, 150850597, 150278700, 149705863,
+ 149132090, 148557388, 147981762, 147405220, 146827767, 146249409,
+ 145670152, 145090003, 144508968, 143927052, 143344263, 142760605,
+ 142176086, 141590712, 141004487, 140417420, 139829516, 139240781,
+ 138651221, 138060842, 137469652, 136877655, 136284858, 135691267,
+ 135096888, 134501729, 133905793, 133309089, 132711622, 132113399,
+ 131514424, 130914706, 130314249, 129713061, 129111147, 128508513,
+ 127905166, 127301112, 126696358, 126090908, 125484770, 124877950,
+ 124270454, 123662289, 123053459, 122443972, 121833835, 121223052,
+ 120611630, 119999577, 119386896, 118773596, 118159682, 117545161,
+ 116930038, 116314320, 115698013, 115081123, 114463657, 113845620,
+ 113227020, 112607862, 111988152, 111367897, 110747103, 110125775,
+ 109503922, 108881547, 108258659, 107635262, 107011364, 106386970,
+ 105762087, 105136721, 104510878, 103884564, 103257785, 102630549,
+ 102002860, 101374726, 100746152, 100117145, 99487710, 98857855,
+ 98227584, 97596906, 96965824, 96334347, 95702480, 95070229, 94437601,
+ 93804601, 93171237, 92537513, 91903436, 91269014, 90634250, 89999153,
+ 89363727, 88727980, 88091918, 87455545, 86818870, 86181898, 85544634,
+ 84907086, 84269260, 83631161, 82992796, 82354171, 81715292, 81076165,
+ 80436797, 79797193, 79157360, 78517304, 77877031, 77236547, 76595859,
+ 75954971, 75313892, 74672626, 74031180, 73389560, 72747772, 72105822,
+ 71463716, 70821461, 70179062, 69536526, 68893858, 68251066, 67608154,
+ 66965129, 66321997, 65678765, 65035437, 64392021, 63748522, 63104946,
+ 62461300, 61817590, 61173821, 60529999, 59886131, 59242223, 58598281,
+ 57954310, 57310317, 56666308, 56022288, 55378265, 54734243, 54090229,
+ 53446228, 52802248, 52158293, 51514370, 50870484, 50226643, 49582851,
+ 48939114, 48295439, 47651832, 47008298, 46364843, 45721474, 45078196,
+ 44435015, 43791937, 43148968, 42506114, 41863381, 41220774, 40578300,
+ 39935964, 39293773, 38651732, 38009847, 37368123, 36726568, 36085186,
+ 35443983, 34802966, 34162140, 33521511, 32881084, 32240866, 31600862,
+ 30961078, 30321521, 29682194, 29043106, 28404260, 27765664, 27127322,
+ 26489240, 25851425, 25213882, 24576616, 23939634, 23302940, 22666542,
+ 22030444, 21394652, 20759172, 20124010, 19489170, 18854660, 18220484,
+ 17586648, 16953158, 16320019, 15687237, 15054818, 14422767, 13791090,
+ 13159793, 12528880, 11898358, 11268232, 10638508, 10009191, 9380286,
+ 8751801, 8123739, 7496106, 6868908, 6242150, 5615839, 4989979, 4364575,
+ 3739634, 3115160, 2491160, 1867638, 1244601, 622053, 0, -621552,
+ -1242600, -1863136, -2483155, -3102653, -3721624, -4340062, -4957962,
+ -5575319, -6192128, -6808382, -7424078, -8039209, -8653770, -9267756,
+ -9881162, -10493982, -11106212, -11717845, -12328877, -12939303,
+ -13549117, -14158314, -14766889, -15374836, -15982152, -16588829,
+ -17194864, -17800251, -18404985, -19009060, -19612473, -20215217,
+ -20817287, -21418679, -22019388, -22619407, -23218733, -23817360,
+ -24415284, -25012498, -25608999, -26204781, -26799839, -27394168,
+ -27987763, -28580620, -29172733, -29764097, -30354708, -30944560,
+ -31533649, -32121970, -32709518, -33296287, -33882274, -34467473,
+ -35051879, -35635488, -36218295, -36800295, -37381483, -37961855,
+ -38541405, -39120129, -39698022, -40275080, -40851297, -41426669,
+ -42001192, -42574860, -43147669, -43719614, -44290691, -44860894,
+ -45430220, -45998664, -46566220, -47132885, -47698654, -48263523,
+ -48827486, -49390539, -49952678, -50513898, -51074194, -51633563,
+ -52191999, -52749498, -53306056, -53861668, -54416330, -54970037,
+ -55522785, -56074570, -56625387, -57175231, -57724099, -58271985,
+ -58818887, -59364798, -59909716, -60453635, -60996552, -61538462,
+ -62079361, -62619244, -63158107, -63695947, -64232759, -64768538,
+ -65303281, -65836983, -66369640, -66901248, -67431803, -67961300,
+ -68489736, -69017107, -69543408, -70068635, -70592785, -71115853,
+ -71637835, -72158727, -72678525, -73197225, -73714823, -74231316,
+ -74746698, -75260967, -75774119, -76286148, -76797052, -77306827,
+ -77815468, -78322972, -78829336, -79334554, -79838624, -80341541,
+ -80843302, -81343902, -81843339, -82341609, -82838707, -83334629,
+ -83829373, -84322935, -84815310, -85306496, -85796488, -86285282,
+ -86772876, -87259266, -87744447, -88228417, -88711171, -89192707,
+ -89673020, -90152107, -90629965, -91106591, -91581979, -92056128,
+ -92529033, -93000692, -93471100, -93940255, -94408152, -94874789,
+ -95340163, -95804268, -96267104, -96728665, -97188949, -97647953,
+ -98105672, -98562105, -99017247, -99471095, -99923646, -100374898,
+ -100824846, -101273487, -101720818, -102166837, -102611540, -103054923,
+ -103496984, -103937720, -104377127, -104815203, -105251943, -105687346,
+ -106121409, -106554127, -106985499, -107415521, -107844190, -108271504,
+ -108697459, -109122052, -109545280, -109967142, -110387633, -110806750,
+ -111224492, -111640855, -112055836, -112469432, -112881641, -113292460,
+ -113701887, -114109917, -114516549, -114921780, -115325607, -115728028,
+ -116129039, -116528639, -116926824, -117323591, -117718939, -118112865,
+ -118505366, -118896439, -119286082, -119674292, -120061067, -120446405,
+ -120830302, -121212757, -121593766, -121973328, -122351440, -122728099,
+ -123103304, -123477051, -123849339, -124220164, -124589525, -124957420,
+ -125323845, -125688800, -126052280, -126414285, -126774812, -127133858,
+ -127491422, -127847501, -128202093, -128555195, -128906807, -129256925,
+ -129605547, -129952672, -130298297, -130642420, -130985038, -131326151,
+ -131665756, -132003851, -132340434, -132675502, -133009055, -133341089,
+ -133671603, -134000596, -134328064, -134654007, -134978423, -135301308,
+ -135622663, -135942484, -136260770, -136577520, -136892731, -137206401,
+ -137518529, -137829114, -138138153, -138445644, -138751586, -139055978,
+ -139358818, -139660103, -139959832, -140258005, -140554618, -140849671,
+ -141143162, -141435089, -141725451, -142014247, -142301474, -142587132,
+ -142871218, -143153732, -143434671, -143714036, -143991823, -144268032,
+ -144542661, -144815709, -145087174, -145357056, -145625353, -145892063,
+ -146157185, -146420719, -146682662, -146943014, -147201773, -147458938,
+ -147714508, -147968482, -148220858, -148471635, -148720813, -148968390,
+ -149214365, -149458736, -149701504, -149942666, -150182222, -150420171,
+ -150656511, -150891242, -151124363, -151355873, -151585770, -151814054,
+ -152040724, -152265780, -152489219, -152711042, -152931247, -153149833,
+ -153366801, -153582148, -153795875, -154007980, -154218462, -154427322,
+ -154634557, -154840169, -155044154, -155246514, -155447248, -155646353,
+ -155843832, -156039681, -156233902, -156426492, -156617453, -156806782,
+ -156994480, -157180547, -157364980, -157547781, -157728948, -157908482,
+ -158086381, -158262646, -158437275, -158610268, -158781626, -158951347,
+ -159119431, -159285879, -159450689, -159613861, -159775395, -159935291,
+ -160093549, -160250167, -160405147, -160558487, -160710188, -160860249,
+ -161008670, -161155452, -161300593, -161444094, -161585954, -161726174,
+ -161864754, -162001693, -162136991, -162270648, -162402665, -162533041,
+ -162661776, -162788871, -162914324, -163038138, -163160310, -163280842,
+ -163399734, -163516986, -163632597, -163746568, -163858900, -163969592,
+ -164078644, -164186058, -164291832, -164395967, -164498464, -164599322,
+ -164698543, -164796126, -164892071, -164986379, -165079051, -165170086,
+ -165259485, -165347249, -165433377, -165517871, -165600730, -165681955,
+ -165761547, -165839505, -165915831, -165990526, -166063588, -166135020,
+ -166204821, -166272992, -166339534, -166404448, -166467733, -166529391,
+ -166589422, -166647826, -166704606, -166759760, -166813290, -166865197,
+ -166915481, -166964143, -167011184, -167056604, -167100405, -167142587,
+ -167183150, -167222097, -167259427, -167295141, -167329241, -167361727,
+ -167392600, -167421861, -167449511, -167475550, -167499981, -167522803,
+ -167544018, -167563627, -167581630, -167598029, -167612825, -167626019,
+ -167637612, -167647605, -167655999, -167662795, -167667994, -167671598,
+ -167673608, -167674024, -167672848, -167670081, -167665725, -167659780,
+ -167652248, -167643130, -167632428, -167620142, -167606274, -167590824,
+ -167573796, -167555189, -167535006, -167513247, -167489913, -167465007,
+ -167438530, -167410483, -167380867, -167349684, -167316936, -167282623,
+ -167246748, -167209312, -167170316, -167129762, -167087651, -167043985,
+ -166998765, -166951994, -166903672, -166853801, -166802384, -166749420,
+ -166694913, -166638864, -166581274, -166522145, -166461479, -166399277,
+ -166335542, -166270274, -166203476, -166135150, -166065297, -165993918,
+ -165921017, -165846594, -165770652, -165693191, -165614215, -165533725,
+ -165451722, -165368210, -165283188, -165196661, -165108628, -165019093,
+ -164928058, -164835523, -164741492, -164645966, -164548947, -164450437,
+ -164350439, -164248954, -164145984, -164041531, -163935598, -163828187,
+ -163719299, -163608936, -163497102, -163383797, -163269025, -163152787,
+ -163035085, -162915922, -162795300, -162673220, -162549686, -162424700,
+ -162298263, -162170378, -162041047, -161910272, -161778057, -161644402,
+ -161509311, -161372785, -161234827, -161095440, -160954626, -160812386,
+ -160668724, -160523642, -160377142, -160229227, -160079899, -159929160,
+ -159777013, -159623461, -159468506, -159312150, -159154396, -158995246,
+ -158834703, -158672770, -158509448, -158344741, -158178651, -158011181,
+ -157842333, -157672110, -157500514, -157327548, -157153215, -156977517,
+ -156800457, -156622037, -156442261, -156261131, -156078649, -155894819,
+ -155709643, -155523123, -155335263, -155146065, -154955533, -154763668,
+ -154570473, -154375952, -154180106, -153982940, -153784455, -153584655,
+ -153383543, -153181120, -152977391, -152772357, -152566023, -152358390,
+ -152149461, -151939240, -151727730, -151514933, -151300852, -151085490,
+ -150868850, -150650936, -150431750, -150211295, -149989574, -149766590,
+ -149542346, -149316845, -149090090, -148862085, -148632832, -148402334,
+ -148170594, -147937616, -147703403, -147467957, -147231282, -146993381,
+ -146754256, -146513912, -146272351, -146029577, -145785592, -145540400,
+ -145294004, -145046407, -144797612, -144547623, -144296443, -144044074,
+ -143790521, -143535786, -143279873, -143022784, -142764524, -142505096,
+ -142244502, -141982746, -141719832, -141455763, -141190541, -140924171,
+ -140656655, -140387997, -140118201, -139847269, -139575206, -139302014,
+ -139027696, -138752257, -138475700, -138198028, -137919244, -137639352,
+ -137358355, -137076257, -136793061, -136508771, -136223390, -135936921,
+ -135649369, -135360736, -135071026, -134780243, -134488390, -134195470,
+ -133901488, -133606446, -133310348, -133013198, -132714999, -132415755,
+ -132115469, -131814145, -131511787, -131208398, -130903982, -130598542,
+ -130292082, -129984605, -129676116, -129366617, -129056113, -128744607,
+ -128432103, -128118604, -127804114, -127488637, -127172176, -126854735,
+ -126536318, -126216929, -125896571, -125575247, -125252963, -124929720,
+ -124605524, -124280377, -123954284, -123627248, -123299273, -122970363,
+ -122640522, -122309752, -121978059, -121645446, -121311917, -120977475,
+ -120642124, -120305868, -119968711, -119630657, -119291709, -118951872,
+ -118611149, -118269544, -117927061, -117583703, -117239475, -116894381,
+ -116548424, -116201608, -115853937, -115505415, -115156046, -114805833,
+ -114454781, -114102894, -113750175, -113396629, -113042259, -112687069,
+ -112331063, -111974245, -111616619, -111258189, -110898959, -110538933,
+ -110178114, -109816508, -109454117, -109090946, -108726998, -108362278,
+ -107996790, -107630537, -107263524, -106895754, -106527233, -106157962,
+ -105787948, -105417193, -105045701, -104673477, -104300525, -103926849,
+ -103552453, -103177340, -102801515, -102424982, -102047745, -101669808,
+ -101291175, -100911850, -100531837, -100151141, -99769764, -99387712,
+ -99004989, -98621598, -98237544, -97852830, -97467461, -97081441,
+ -96694774, -96307465, -95919516, -95530933, -95141719, -94751878,
+ -94361415, -93970334, -93578639, -93186334, -92793423, -92399910,
+ -92005800, -91611096, -91215802, -90819924, -90423464, -90026428,
+ -89628819, -89230641, -88831899, -88432596, -88032737, -87632326,
+ -87231368, -86829865, -86427824, -86025246, -85622138, -85218503,
+ -84814345, -84409668, -84004477, -83598775, -83192568, -82785858,
+ -82378651, -81970950, -81562760, -81154085, -80744928, -80335295,
+ -79925189, -79514615, -79103577, -78692079, -78280125, -77867719,
+ -77454866, -77041570, -76627835, -76213665, -75799064, -75384037,
+ -74968588, -74552721, -74136441, -73719750, -73302655, -72885158,
+ -72467265, -72048979, -71630304, -71211245, -70791807, -70371992,
+ -69951806, -69531253, -69110336, -68689061, -68267431, -67845450,
+ -67423123, -67000455, -66577448, -66154108, -65730439, -65306444,
+ -64882128, -64457496, -64032552, -63607299, -63181742, -62755885,
+ -62329733, -61903290, -61476559, -61049546, -60622254, -60194687,
+ -59766850, -59338747, -58910383, -58481761, -58052885, -57623760,
+ -57194391, -56764781, -56334934, -55904855, -55474548, -55044017,
+ -54613267, -54182301, -53751124, -53319740, -52888153, -52456368,
+ -52024388, -51592218, -51159862, -50727325, -50294610, -49861722,
+ -49428664, -48995442, -48562059, -48128519, -47694827, -47260987,
+ -46827003, -46392879, -45958619, -45524228, -45089710, -44655069,
+ -44220309, -43785435, -43350450, -42915358, -42480165, -42044874,
+ -41609488, -41174014, -40738453, -40302812, -39867093, -39431301,
+ -38995441, -38559516, -38123530, -37687488, -37251394, -36815252,
+ -36379066, -35942840, -35506579, -35070286, -34633966, -34197622,
+ -33761259, -33324882, -32888493, -32452098, -32015701, -31579304,
+ -31142914, -30706533, -30270166, -29833817, -29397490, -28961189,
+ -28524918, -28088682, -27652484, -27216329, -26780220, -26344162,
+ -25908158, -25472213, -25036332, -24600517, -24164773, -23729104,
+ -23293515, -22858008, -22422589, -21987261, -21552028, -21116895,
+ -20681864, -20246942, -19812131, -19377435, -18942858, -18508405,
+ -18074080, -17639886, -17205828, -16771909, -16338133, -15904505,
+ -15471029, -15037708, -14604546, -14171548, -13738717, -13306057,
+ -12873573, -12441267, -12009145, -11577211, -11145467, -10713918,
+ -10282568, -9851421, -9420481, -8989752, -8559237, -8128941, -7698867,
+ -7269020, -6839402, -6410019, -5980874, -5551971, -5123314, -4694906,
+ -4266752, -3838855, -3411219, -2983849, -2556747, -2129918, -1703366,
+ -1277094, -851107, -425407, 0, 425111, 849924, 1274433, 1698635,
+ 2122526, 2546102, 2969360, 3392296, 3814906, 4237186, 4659132, 5080742,
+ 5502010, 5922934, 6343509, 6763732, 7183599, 7603106, 8022251, 8441028,
+ 8859434, 9277466, 9695120, 10112392, 10529279, 10945777, 11361882,
+ 11777590, 12192899, 12607803, 13022301, 13436387, 13850059, 14263313,
+ 14676145, 15088551, 15500529, 15912074, 16323182, 16733851, 17144077,
+ 17553856, 17963184, 18372058, 18780475, 19188431, 19595922, 20002945,
+ 20409497, 20815573, 21221170, 21626286, 22030916, 22435056, 22838705,
+ 23241857, 23644509, 24046659, 24448302, 24849435, 25250055, 25650158,
+ 26049742, 26448801, 26847334, 27245336, 27642805, 28039736, 28436127,
+ 28831974, 29227274, 29622024, 30016219, 30409857, 30802935, 31195449,
+ 31587395, 31978771, 32369573, 32759798, 33149443, 33538504, 33926978,
+ 34314862, 34702152, 35088846, 35474940, 35860430, 36245314, 36629589,
+ 37013250, 37396296, 37778723, 38160527, 38541705, 38922255, 39302173,
+ 39681456, 40060101, 40438104, 40815463, 41192175, 41568235, 41943642,
+ 42318392, 42692483, 43065910, 43438671, 43810763, 44182183, 44552927,
+ 44922993, 45292378, 45661079, 46029092, 46396415, 46763044, 47128978,
+ 47494212, 47858743, 48222570, 48585688, 48948095, 49309789, 49670765,
+ 50031021, 50390555, 50749363, 51107442, 51464790, 51821404, 52177280,
+ 52532417, 52886810, 53240458, 53593357, 53945505, 54296899, 54647536,
+ 54997413, 55346527, 55694877, 56042458, 56389268, 56735305, 57080565,
+ 57425047, 57768746, 58111661, 58453789, 58795128, 59135673, 59475424,
+ 59814376, 60152528, 60489877, 60826420, 61162155, 61497079, 61831189,
+ 62164482, 62496957, 62828611, 63159440, 63489443, 63818617, 64146959,
+ 64474467, 64801139, 65126971, 65451961, 65776108, 66099407, 66421858,
+ 66743457, 67064201, 67384090, 67703119, 68021287, 68338591, 68655029,
+ 68970599, 69285297, 69599122, 69912072, 70224143, 70535334, 70845642,
+ 71155065, 71463601, 71771246, 72078000, 72383860, 72688823, 72992887,
+ 73296051, 73598310, 73899665, 74200111, 74499647, 74798271, 75095981,
+ 75392774, 75688649, 75983602, 76277632, 76570737, 76862915, 77154163,
+ 77444479, 77733862, 78022308, 78309817, 78596386, 78882013, 79166695,
+ 79450432, 79733220, 80015058, 80295943, 80575875, 80854850, 81132867,
+ 81409924, 81686018, 81961148, 82235313, 82508509, 82780736, 83051990,
+ 83322271, 83591576, 83859904, 84127252, 84393620, 84659004, 84923403,
+ 85186815, 85449239, 85710673, 85971114, 86230561, 86489013, 86746467,
+ 87002922, 87258376, 87512827, 87766274, 88018715, 88270147, 88520571,
+ 88769983, 89018382, 89265767, 89512135, 89757486, 90001817, 90245127,
+ 90487414, 90728677, 90968914, 91208124, 91446305, 91683455, 91919574,
+ 92154658, 92388708, 92621720, 92853695, 93084630, 93314524, 93543376,
+ 93771183, 93997945, 94223660, 94448327, 94671943, 94894509, 95116023,
+ 95336482, 95555886, 95774234, 95991523, 96207753, 96422923, 96637031,
+ 96850075, 97062055, 97272969, 97482816, 97691594, 97899303, 98105941,
+ 98311507, 98516000, 98719418, 98921761, 99123026, 99323214, 99522323,
+ 99720351, 99917297, 100113161, 100307941, 100501637, 100694246,
+ 100885769, 101076203, 101265548, 101453803, 101640967, 101827038,
+ 102012016, 102195900, 102378688, 102560380, 102740975, 102920472,
+ 103098869, 103276166, 103452363, 103627457, 103801448, 103974336,
+ 104146118, 104316796, 104486366, 104654830, 104822185, 104988432,
+ 105153568, 105317595, 105480509, 105642312, 105803001, 105962577,
+ 106121038, 106278384, 106434614, 106589728, 106743724, 106896602,
+ 107048361, 107199000, 107348520, 107496919, 107644196, 107790351,
+ 107935383, 108079293, 108222078, 108363739, 108504274, 108643684,
+ 108781968, 108919125, 109055155, 109190056, 109323830, 109456475,
+ 109587990, 109718376, 109847631, 109975755, 110102748, 110228610,
+ 110353340, 110476937, 110599401, 110720732, 110840929, 110959992,
+ 111077921, 111194715, 111310374, 111424898, 111538285, 111650537,
+ 111761652, 111871631, 111980473, 112088178, 112194745, 112300175,
+ 112404467, 112507620, 112609635, 112710512, 112810250, 112908850,
+ 113006310, 113102631, 113197812, 113291854, 113384757, 113476520,
+ 113567143, 113656626, 113744969, 113832172, 113918235, 114003158,
+ 114086940, 114169582, 114251085, 114331446, 114410668, 114488749,
+ 114565691, 114641492, 114716153, 114789674, 114862054, 114933296,
+ 115003397, 115072358, 115140180, 115206863, 115272406, 115336810,
+ 115400075, 115462201, 115523188, 115583037, 115641748, 115699321,
+ 115755755, 115811052, 115865212, 115918234, 115970120, 116020869,
+ 116070482, 116118958, 116166299, 116212505, 116257575, 116301511,
+ 116344312, 116385979, 116426513, 116465913, 116504180, 116541315,
+ 116577318, 116612189, 116645928, 116678537, 116710015, 116740364,
+ 116769583, 116797673, 116824635, 116850468, 116875174, 116898753,
+ 116921206, 116942533, 116962735, 116981811, 116999764, 117016593,
+ 117032299, 117046883, 117060344, 117072685, 117083905, 117094005,
+ 117102986, 117110849, 117117593, 117123220, 117127731, 117131126,
+ 117133406, 117134571, 117134623, 117133562, 117131389, 117128104,
+ 117123709, 117118204, 117111590, 117103867, 117095038, 117085101,
+ 117074059, 117061912, 117048661, 117034307, 117018851, 117002293,
+ 116984634, 116965876, 116946019, 116925065, 116903013, 116879865,
+ 116855623, 116830287, 116803857, 116776335, 116747723, 116718020,
+ 116687228, 116655348, 116622381, 116588328, 116553191, 116516969,
+ 116479664, 116441278, 116401811, 116361265, 116319640, 116276937,
+ 116233159, 116188305, 116142378, 116095377, 116047306, 115998163,
+ 115947951, 115896672, 115844325, 115790912, 115736436, 115680895,
+ 115624293, 115566630, 115507908, 115448127, 115387290, 115325396,
+ 115262448, 115198447, 115133395, 115067291, 115000139, 114931939,
+ 114862692, 114792400, 114721065, 114648687, 114575267, 114500809,
+ 114425312, 114348778, 114271209, 114192606, 114112970, 114032303,
+ 113950606, 113867882, 113784130, 113699353, 113613553, 113526730,
+ 113438886, 113350023, 113260143, 113169246, 113077334, 112984409,
+ 112890473, 112795527, 112699572, 112602610, 112504643, 112405672,
+ 112305699, 112204726, 112102754, 111999784, 111895819, 111790860,
+ 111684909, 111577967, 111470036, 111361118, 111251215, 111140327,
+ 111028457, 110915607, 110801778, 110686972, 110571190, 110454435,
+ 110336709, 110218012, 110098347, 109977715, 109856119, 109733559,
+ 109610039, 109485559, 109360122, 109233729, 109106383, 108978084,
+ 108848835, 108718638, 108587494, 108455406, 108322375, 108188403,
+ 108053493, 107917645, 107780862, 107643146, 107504499, 107364923,
+ 107224419, 107082989, 106940636, 106797362, 106653168, 106508056,
+ 106362029, 106215088, 106067235, 105918473, 105768803, 105618228,
+ 105466749, 105314368, 105161088, 105006911, 104851838, 104695871,
+ 104539014, 104381267, 104222633, 104063115, 103902713, 103741430,
+ 103579269, 103416231, 103252319, 103087534, 102921880, 102755357,
+ 102587968, 102419715, 102250601, 102080628, 101909797, 101738111,
+ 101565573, 101392183, 101217946, 101042862, 100866934, 100690164,
+ 100512555, 100334108, 100154826, 99974712, 99793767, 99611993,
+ 99429394, 99245971, 99061726, 98876662, 98690781, 98504086, 98316578,
+ 98128261, 97939135, 97749205, 97558471, 97366937, 97174604, 96981476,
+ 96787553, 96592840, 96397338, 96201049, 96003976, 95806121, 95607487,
+ 95408076, 95207890, 95006932, 94805205, 94602710, 94399450, 94195428,
+ 93990646, 93785106, 93578811, 93371763, 93163965, 92955420, 92746129,
+ 92536095, 92325321, 92113809, 91901562, 91688581, 91474871, 91260432,
+ 91045268, 90829382, 90612775, 90395450, 90177410, 89958657, 89739194,
+ 89519024, 89298148, 89076570, 88854292, 88631317, 88407646, 88183284,
+ 87958231, 87732492, 87506068, 87278963, 87051178, 86822716, 86593581,
+ 86363774, 86133298, 85902156, 85670350, 85437883, 85204758, 84970978,
+ 84736544, 84501460, 84265728, 84029351, 83792332, 83554673, 83316377,
+ 83077447, 82837885, 82597694, 82356877, 82115436, 81873374, 81630694,
+ 81387398, 81143490, 80898972, 80653846, 80408115, 80161783, 79914851,
+ 79667323, 79419202, 79170489, 78921188, 78671301, 78420832, 78169783,
+ 77918157, 77665956, 77413183, 77159842, 76905935, 76651464, 76396432,
+ 76140843, 75884699, 75628002, 75370756, 75112964, 74854628, 74595750,
+ 74336335, 74076384, 73815901, 73554887, 73293347, 73031283, 72768697,
+ 72505593, 72241974, 71977841, 71713199, 71448050, 71182396, 70916241,
+ 70649587, 70382438, 70114796, 69846664, 69578045, 69308941, 69039356,
+ 68769293, 68498754, 68227742, 67956260, 67684312, 67411899, 67139025,
+ 66865693, 66591905, 66317664, 66042974, 65767838, 65492257, 65216235,
+ 64939776, 64662881, 64385554, 64107797, 63829614, 63551008, 63271981,
+ 62992537, 62712677, 62432406, 62151726, 61870640, 61589152, 61307262,
+ 61024976, 60742296, 60459224, 60175764, 59891919, 59607691, 59323083,
+ 59038099, 58752741, 58467013, 58180917, 57894456, 57607633, 57320452,
+ 57032915, 56745024, 56456784, 56168196, 55879265, 55589992, 55300382,
+ 55010436, 54720158, 54429550, 54138617, 53847360, 53555783, 53263888,
+ 52971680, 52679159, 52386331, 52093196, 51799760, 51506024, 51211991,
+ 50917665, 50623048, 50328144, 50032956, 49737485, 49441736, 49145712,
+ 48849414, 48552848, 48256014, 47958917, 47661559, 47363943, 47066073,
+ 46767951, 46469580, 46170964, 45872105, 45573006, 45273670, 44974101,
+ 44674301, 44374273, 44074020, 43773545, 43472852, 43171943, 42870821,
+ 42569489, 42267951, 41966208, 41664265, 41362124, 41059788, 40757260,
+ 40454543, 40151641, 39848555, 39545290, 39241848, 38938232, 38634445,
+ 38330490, 38026370, 37722088, 37417647, 37113051, 36808301, 36503401,
+ 36198355, 35893164, 35587833, 35282363, 34976758, 34671021, 34365156,
+ 34059164, 33753049, 33446814, 33140461, 32833995, 32527417, 32220732,
+ 31913941, 31607047, 31300055, 30992966, 30685784, 30378511, 30071152,
+ 29763707, 29456182, 29148578, 28840898, 28533146, 28225324, 27917436,
+ 27609484, 27301471, 26993401, 26685276, 26377099, 26068873, 25760601,
+ 25452287, 25143932, 24835541, 24527115, 24218658, 23910173, 23601663,
+ 23293130, 22984578, 22676010, 22367428, 22058835, 21750235, 21441630,
+ 21133024, 20824418, 20515817, 20207223, 19898638, 19590067, 19281511,
+ 18972974, 18664458, 18355967, 18047504, 17739070, 17430670, 17122306,
+ 16813981, 16505698, 16197460, 15889270, 15581130, 15273043, 14965013,
+ 14657043, 14349134, 14041291, 13733515, 13425810, 13118179, 12810624,
+ 12503149, 12195755, 11888447, 11581227, 11274098, 10967063, 10660124,
+ 10353284, 10046547, 9739914, 9433390, 9126976, 8820676, 8514492,
+ 8208427, 7902485, 7596667, 7290977, 6985418, 6679992, 6374702, 6069551,
+ 5764542, 5459677, 5154959, 4850392, 4545978, 4241719, 3937619, 3633680,
+ 3329905, 3026297, 2722858, 2419592, 2116501, 1813588, 1510856, 1208307,
+ 905944, 603770, 301788, 0, -301590, -602981, -904170, -1205153,
+ -1505928, -1806493, -2106844, -2406979, -2706895, -3006589, -3306059,
+ -3605303, -3904316, -4203097, -4501644, -4799952, -5098020, -5395846,
+ -5693425, -5990756, -6287836, -6584663, -6881233, -7177544, -7473593,
+ -7769378, -8064897, -8360146, -8655122, -8949824, -9244249, -9538393,
+ -9832255, -10125832, -10419121, -10712119, -11004825, -11297235,
+ -11589347, -11881158, -12172666, -12463868, -12754761, -13045344,
+ -13335613, -13625566, -13915200, -14204513, -14493502, -14782165,
+ -15070500, -15358503, -15646172, -15933505, -16220499, -16507152,
+ -16793461, -17079423, -17365037, -17650300, -17935209, -18219761,
+ -18503955, -18787788, -19071257, -19354360, -19637094, -19919457,
+ -20201447, -20483062, -20764298, -21045153, -21325625, -21605712,
+ -21885410, -22164719, -22443634, -22722155, -23000278, -23278001,
+ -23555322, -23832238, -24108748, -24384848, -24660536, -24935810,
+ -25210668, -25485107, -25759125, -26032720, -26305889, -26578630,
+ -26850941, -27122819, -27394262, -27665268, -27935834, -28205959,
+ -28475639, -28744873, -29013659, -29281994, -29549875, -29817301,
+ -30084270, -30350779, -30616826, -30882408, -31147524, -31412171,
+ -31676348, -31940051, -32203279, -32466029, -32728299, -32990088,
+ -33251393, -33512212, -33772542, -34032381, -34291728, -34550580,
+ -34808936, -35066792, -35324147, -35580998, -35837345, -36093183,
+ -36348512, -36603330, -36857633, -37111421, -37364691, -37617440,
+ -37869668, -38121372, -38372549, -38623198, -38873317, -39122903,
+ -39371956, -39620472, -39868449, -40115886, -40362781, -40609132,
+ -40854936, -41100192, -41344898, -41589051, -41832650, -42075693,
+ -42318178, -42560103, -42801467, -43042266, -43282499, -43522165,
+ -43761261, -43999785, -44237736, -44475112, -44711911, -44948130,
+ -45183769, -45418825, -45653296, -45887181, -46120477, -46353184,
+ -46585298, -46816819, -47047743, -47278071, -47507799, -47736927,
+ -47965451, -48193371, -48420685, -48647390, -48873486, -49098970,
+ -49323841, -49548096, -49771735, -49994756, -50217156, -50438934,
+ -50660088, -50880617, -51100519, -51319793, -51538435, -51756446,
+ -51973823, -52190565, -52406670, -52622136, -52836962, -53051146,
+ -53264686, -53477581, -53689829, -53901430, -54112380, -54322678,
+ -54532324, -54741315, -54949650, -55157327, -55364344, -55570701,
+ -55776395, -55981426, -56185791, -56389489, -56592519, -56794879,
+ -56996567, -57197583, -57397924, -57597590, -57796578, -57994887,
+ -58192516, -58389464, -58585729, -58781309, -58976203, -59170410,
+ -59363928, -59556757, -59748893, -59940337, -60131087, -60321142,
+ -60510499, -60699158, -60887118, -61074376, -61260932, -61446785,
+ -61631933, -61816375, -62000109, -62183135, -62365450, -62547055,
+ -62727946, -62908124, -63087587, -63266333, -63444362, -63621672,
+ -63798263, -63974132, -64149278, -64323701, -64497399, -64670372,
+ -64842617, -65014134, -65184921, -65354978, -65524303, -65692895,
+ -65860753, -66027876, -66194263, -66359913, -66524824, -66688995,
+ -66852426, -67015116, -67177062, -67338265, -67498723, -67658435,
+ -67817400, -67975617, -68133086, -68289804, -68445771, -68600986,
+ -68755449, -68909157, -69062111, -69214309, -69365749, -69516432,
+ -69666357, -69815522, -69963926, -70111568, -70258449, -70404566,
+ -70549918, -70694506, -70838328, -70981383, -71123670, -71265189,
+ -71405938, -71545917, -71685125, -71823562, -71961225, -72098115,
+ -72234231, -72369571, -72504136, -72637924, -72770935, -72903167,
+ -73034621, -73165295, -73295188, -73424300, -73552631, -73680179,
+ -73806943, -73932924, -74058120, -74182530, -74306155, -74428993,
+ -74551043, -74672306, -74792780, -74912465, -75031359, -75149464,
+ -75266777, -75383298, -75499027, -75613963, -75728106, -75841455,
+ -75954009, -76065767, -76176730, -76286897, -76396267, -76504840,
+ -76612615, -76719591, -76825769, -76931148, -77035726, -77139504,
+ -77242482, -77344658, -77446033, -77546605, -77646375, -77745342,
+ -77843506, -77940866, -78037421, -78133172, -78228118, -78322258,
+ -78415593, -78508122, -78599844, -78690759, -78780867, -78870168,
+ -78958661, -79046345, -79133222, -79219289, -79304547, -79388996,
+ -79472636, -79555465, -79637484, -79718693, -79799091, -79878679,
+ -79957455, -80035420, -80112573, -80188914, -80264444, -80339161,
+ -80413066, -80486158, -80558438, -80629905, -80700558, -80770399,
+ -80839426, -80907640, -80975040, -81041627, -81107400, -81172358,
+ -81236503, -81299834, -81362351, -81424054, -81484942, -81545016,
+ -81604275, -81662721, -81720351, -81777168, -81833170, -81888357,
+ -81942730, -81996289, -82049033, -82100962, -82152078, -82202379,
+ -82251865, -82300538, -82348396, -82395440, -82441670, -82487087,
+ -82531689, -82575478, -82618453, -82660614, -82701962, -82742497,
+ -82782219, -82821128, -82859224, -82896507, -82932978, -82968637,
+ -83003483, -83037518, -83070741, -83103152, -83134752, -83165541,
+ -83195519, -83224687, -83253044, -83280591, -83307328, -83333256,
+ -83358374, -83382684, -83406184, -83428877, -83450761, -83471837,
+ -83492106, -83511568, -83530223, -83548071, -83565114, -83581350,
+ -83596782, -83611408, -83625230, -83638247, -83650460, -83661870,
+ -83672477, -83682282, -83691284, -83699484, -83706884, -83713482,
+ -83719280, -83724277, -83728476, -83731875, -83734476, -83736279,
+ -83737284, -83737492, -83736904, -83735520, -83733340, -83730365,
+ -83726596, -83722033, -83716677, -83710528, -83703586, -83695854,
+ -83687330, -83678016, -83667912, -83657018, -83645337, -83632867,
+ -83619610, -83605566, -83590736, -83575121, -83558721, -83541536,
+ -83523569, -83504818, -83485286, -83464972, -83443878, -83422003,
+ -83399349, -83375917, -83351707, -83326719, -83300956, -83274417,
+ -83247103, -83219014, -83190153, -83160519, -83130113, -83098936,
+ -83066989, -83034273, -83000788, -82966535, -82931515, -82895729,
+ -82859178, -82821862, -82783783, -82744941, -82705337, -82664972,
+ -82623847, -82581963, -82539320, -82495920, -82451763, -82406851,
+ -82361184, -82314763, -82267589, -82219663, -82170986, -82121559,
+ -82071383, -82020459, -81968787, -81916370, -81863207, -81809299,
+ -81754649, -81699256, -81643122, -81586248, -81528634, -81470282,
+ -81411193, -81351368, -81290808, -81229514, -81167487, -81104727,
+ -81041237, -80977018, -80912069, -80846393, -80779990, -80712862,
+ -80645010, -80576434, -80507136, -80437117, -80366379, -80294922,
+ -80222747, -80149856, -80076249, -80001929, -79926895, -79851150,
+ -79774694, -79697529, -79619656, -79541075, -79461789, -79381798,
+ -79301104, -79219708, -79137611, -79054814, -78971318, -78887126,
+ -78802237, -78716654, -78630377, -78543408, -78455749, -78367399,
+ -78278362, -78188637, -78098226, -78007131, -77915353, -77822893,
+ -77729753, -77635933, -77541436, -77446262, -77350413, -77253890,
+ -77156694, -77058828, -76960291, -76861087, -76761215, -76660677,
+ -76559476, -76457611, -76355085, -76251899, -76148055, -76043553,
+ -75938395, -75832583, -75726118, -75619001, -75511234, -75402819,
+ -75293756, -75184048, -75073695, -74962700, -74851063, -74738786,
+ -74625871, -74512319, -74398131, -74283310, -74167856, -74051771,
+ -73935057, -73817715, -73699746, -73581153, -73461936, -73342097,
+ -73221639, -73100561, -72978867, -72856556, -72733632, -72610095,
+ -72485948, -72361191, -72235826, -72109855, -71983280, -71856101,
+ -71728322, -71599942, -71470964, -71341390, -71211220, -71080458,
+ -70949103, -70817159, -70684626, -70551507, -70417802, -70283514,
+ -70148643, -70013193, -69877164, -69740559, -69603378, -69465623,
+ -69327297, -69188401, -69048936, -68908904, -68768307, -68627147,
+ -68485425, -68343144, -68200304, -68056907, -67912956, -67768452,
+ -67623396, -67477791, -67331638, -67184938, -67037695, -66889908,
+ -66741581, -66592715, -66443311, -66293372, -66142899, -65991894,
+ -65840358, -65688295, -65535704, -65382589, -65228950, -65074790,
+ -64920111, -64764914, -64609201, -64452974, -64296235, -64138986,
+ -63981227, -63822962, -63664192, -63504919, -63345145, -63184871,
+ -63024100, -62862833, -62701072, -62538819, -62376075, -62212844,
+ -62049126, -61884924, -61720238, -61555072, -61389428, -61223306,
+ -61056709, -60889638, -60722096, -60554085, -60385607, -60216662,
+ -60047254, -59877384, -59707054, -59536266, -59365022, -59193323,
+ -59021173, -58848572, -58675523, -58502027, -58328087, -58153704,
+ -57978880, -57803618, -57627919, -57451786, -57275219, -57098222,
+ -56920796, -56742943, -56564664, -56385963, -56206841, -56027300,
+ -55847341, -55666968, -55486181, -55304984, -55123377, -54941363,
+ -54758944, -54576121, -54392898, -54209275, -54025255, -53840841,
+ -53656033, -53470833, -53285245, -53099270, -52912909, -52726166,
+ -52539041, -52351537, -52163657, -51975401, -51786773, -51597774,
+ -51408406, -51218671, -51028571, -50838109, -50647285, -50456104,
+ -50264565, -50072673, -49880427, -49687832, -49494888, -49301597,
+ -49107963, -48913986, -48719669, -48525014, -48330023, -48134699,
+ -47939042, -47743056, -47546742, -47350102, -47153139, -46955855,
+ -46758251, -46560330, -46362093, -46163544, -45964684, -45765515,
+ -45566039, -45366258, -45166175, -44965791, -44765109, -44564130,
+ -44362857, -44161293, -43959438, -43757295, -43554867, -43352154,
+ -43149161, -42945888, -42742337, -42538512, -42334413, -42130043,
+ -41925405, -41720499, -41515329, -41309897, -41104204, -40898253,
+ -40692046, -40485585, -40278872, -40071909, -39864699, -39657243,
+ -39449544, -39241604, -39033425, -38825008, -38616357, -38407473,
+ -38198359, -37989016, -37779448, -37569655, -37359640, -37149405,
+ -36938952, -36728284, -36517403, -36306310, -36095009, -35883500,
+ -35671786, -35459870, -35247754, -35035438, -34822927, -34610222,
+ -34397325, -34184238, -33970963, -33757503, -33543859, -33330035,
+ -33116031, -32901851, -32687495, -32472968, -32258269, -32043403,
+ -31828370, -31613174, -31397816, -31182298, -30966622, -30750792,
+ -30534808, -30318673, -30102389, -29885959, -29669384, -29452666,
+ -29235808, -29018813, -28801681, -28584415, -28367018, -28149491,
+ -27931837, -27714058, -27496156, -27278133, -27059991, -26841733,
+ -26623360, -26404875, -26186280, -25967577, -25748768, -25529856,
+ -25310842, -25091729, -24872518, -24653213, -24433814, -24214325,
+ -23994747, -23775083, -23555334, -23335503, -23115593, -22895604,
+ -22675540, -22455402, -22235192, -22014913, -21794568, -21574157,
+ -21353683, -21133148, -20912555, -20691906, -20471202, -20250446,
+ -20029639, -19808785, -19587885, -19366942, -19145957, -18924932,
+ -18703871, -18482774, -18261644, -18040483, -17819294, -17598077,
+ -17376837, -17155574, -16934290, -16712989, -16491671, -16270340,
+ -16048997, -15827644, -15606283, -15384917, -15163548, -14942177,
+ -14720808, -14499441, -14278079, -14056725, -13835380, -13614046,
+ -13392726, -13171421, -12950134, -12728867, -12507622, -12286400,
+ -12065205, -11844038, -11622901, -11401796, -11180726, -10959692,
+ -10738697, -10517743, -10296831, -10075964, -9855144, -9634372,
+ -9413652, -9192985, -8972373, -8751818, -8531323, -8310889, -8090518,
+ -7870213, -7649975, -7429807, -7209710, -6989687, -6769740, -6549871,
+ -6330081, -6110373, -5890749, -5671211, -5451761, -5232401, -5013133,
+ -4793959, -4574881, -4355901, -4137021, -3918244, -3699570, -3481003,
+ -3262544, -3044195, -2825958, -2607836, -2389829, -2171941, -1954173,
+ -1736528, -1519006, -1301611, -1084343, -867206, -650202, -433331,
+ -216596, 0, 216456, 432771, 648941, 864966, 1080842, 1296569, 1512144,
+ 1727565, 1942831, 2157938, 2372886, 2587673, 2802296, 3016753, 3231043,
+ 3445164, 3659114, 3872890, 4086491, 4299915, 4513161, 4726225, 4939107,
+ 5151804, 5364314, 5576636, 5788767, 6000706, 6212451, 6424000, 6635351,
+ 6846502, 7057451, 7268197, 7478737, 7689070, 7899194, 8109107, 8318806,
+ 8528291, 8737559, 8946609, 9155438, 9364045, 9572428, 9780585, 9988514,
+ 10196214, 10403682, 10610917, 10817917, 11024680, 11231205, 11437489,
+ 11643530, 11849328, 12054880, 12260183, 12465238, 12670041, 12874591,
+ 13078886, 13282924, 13486704, 13690224, 13893482, 14096476, 14299205,
+ 14501666, 14703858, 14905780, 15107428, 15308803, 15509902, 15710723,
+ 15911264, 16111524, 16311502, 16511194, 16710601, 16909719, 17108547,
+ 17307084, 17505327, 17703276, 17900928, 18098282, 18295336, 18492088,
+ 18688537, 18884681, 19080518, 19276047, 19471265, 19666172, 19860766,
+ 20055045, 20249007, 20442651, 20635974, 20828977, 21021656, 21214010,
+ 21406038, 21597738, 21789108, 21980147, 22170853, 22361225, 22551260,
+ 22740958, 22930316, 23119334, 23308009, 23496341, 23684326, 23871965,
+ 24059255, 24246194, 24432782, 24619016, 24804896, 24990419, 25175584,
+ 25360389, 25544834, 25728916, 25912634, 26095986, 26278971, 26461587,
+ 26643834, 26825708, 27007210, 27188337, 27369088, 27549461, 27729455,
+ 27909069, 28088301, 28267149, 28445612, 28623690, 28801379, 28978679,
+ 29155588, 29332106, 29508229, 29683958, 29859291, 30034225, 30208761,
+ 30382896, 30556628, 30729958, 30902883, 31075401, 31247512, 31419214,
+ 31590506, 31761386, 31931853, 32101905, 32271542, 32440762, 32609563,
+ 32777945, 32945905, 33113443, 33280558, 33447247, 33613510, 33779345,
+ 33944751, 34109727, 34274271, 34438382, 34602060, 34765301, 34928107,
+ 35090474, 35252401, 35413889, 35574934, 35735537, 35895695, 36055408,
+ 36214674, 36373492, 36531861, 36689780, 36847247, 37004261, 37160821,
+ 37316926, 37472575, 37627766, 37782498, 37936770, 38090581, 38243930,
+ 38396815, 38549236, 38701191, 38852679, 39003699, 39154250, 39304330,
+ 39453939, 39603075, 39751738, 39899926, 40047638, 40194873, 40341630,
+ 40487908, 40633705, 40779021, 40923855, 41068205, 41212071, 41355451,
+ 41498345, 41640750, 41782667, 41924094, 42065031, 42205475, 42345427,
+ 42484885, 42623848, 42762315, 42900285, 43037757, 43174730, 43311204,
+ 43447177, 43582648, 43717616, 43852080, 43986040, 44119494, 44252441,
+ 44384881, 44516813, 44648235, 44779147, 44909548, 45039436, 45168812,
+ 45297673, 45426020, 45553851, 45681165, 45807962, 45934241, 46060000,
+ 46185240, 46309958, 46434154, 46557828, 46680979, 46803605, 46925706,
+ 47047281, 47168329, 47288849, 47408841, 47528304, 47647237, 47765639,
+ 47883510, 48000848, 48117653, 48233924, 48349661, 48464862, 48579527,
+ 48693655, 48807245, 48920297, 49032810, 49144783, 49256215, 49367107,
+ 49477456, 49587262, 49696525, 49805244, 49913419, 50021048, 50128130,
+ 50234666, 50340655, 50446096, 50550987, 50655330, 50759122, 50862364,
+ 50965054, 51067193, 51168779, 51269812, 51370291, 51470216, 51569586,
+ 51668400, 51766659, 51864360, 51961505, 52058091, 52154120, 52249589,
+ 52344499, 52438849, 52532638, 52625866, 52718533, 52810638, 52902180,
+ 52993158, 53083574, 53173425, 53262711, 53351432, 53439588, 53527178,
+ 53614201, 53700657, 53786546, 53871866, 53956619, 54040802, 54124417,
+ 54207461, 54289936, 54371840, 54453173, 54533935, 54614126, 54693744,
+ 54772790, 54851262, 54929162, 55006488, 55083240, 55159417, 55235020,
+ 55310048, 55384501, 55458377, 55531678, 55604403, 55676550, 55748121,
+ 55819114, 55889530, 55959368, 56028627, 56097308, 56165411, 56232934,
+ 56299878, 56366242, 56432027, 56497231, 56561855, 56625899, 56689361,
+ 56752243, 56814543, 56876262, 56937400, 56997955, 57057928, 57117319,
+ 57176128, 57234354, 57291997, 57349057, 57405534, 57461427, 57516737,
+ 57571464, 57625606, 57679165, 57732140, 57784530, 57836336, 57887558,
+ 57938196, 57988248, 58037716, 58086599, 58134898, 58182611, 58229739,
+ 58276282, 58322240, 58367613, 58412400, 58456602, 58500219, 58543250,
+ 58585696, 58627556, 58668831, 58709520, 58749624, 58789143, 58828075,
+ 58866423, 58904184, 58941361, 58977951, 59013957, 59049377, 59084212,
+ 59118461, 59152125, 59185204, 59217698, 59249607, 59280931, 59311670,
+ 59341824, 59371394, 59400379, 59428779, 59456595, 59483827, 59510475,
+ 59536538, 59562018, 59586914, 59611226, 59634955, 59658100, 59680662,
+ 59702642, 59724038, 59744852, 59765083, 59784732, 59803799, 59822284,
+ 59840188, 59857509, 59874250, 59890409, 59905988, 59920986, 59935404,
+ 59949241, 59962499, 59975176, 59987275, 59998794, 60009735, 60020097,
+ 60029881, 60039086, 60047714, 60055765, 60063238, 60070134, 60076454,
+ 60082198, 60087366, 60091958, 60095975, 60099417, 60102284, 60104577,
+ 60106297, 60107443, 60108015, 60108015, 60107443, 60106298, 60104582,
+ 60102295, 60099436, 60096007, 60092009, 60087440, 60082302, 60076596,
+ 60070321, 60063478, 60056067, 60048089, 60039545, 60030435, 60020758,
+ 60010517, 59999710, 59988340, 59976405, 59963907, 59950846, 59937223,
+ 59923038, 59908291, 59892983, 59877115, 59860688, 59843700, 59826154,
+ 59808050, 59789388, 59770168, 59750392, 59730060, 59709172, 59687729,
+ 59665732, 59643181, 59620076, 59596419, 59572209, 59547449, 59522137,
+ 59496274, 59469862, 59442901, 59415391, 59387334, 59358729, 59329577,
+ 59299880, 59269637, 59238849, 59207517, 59175642, 59143224, 59110264,
+ 59076762, 59042720, 59008138, 58973016, 58937355, 58901156, 58864420,
+ 58827148, 58789339, 58750995, 58712117, 58672705, 58632760, 58592282,
+ 58551273, 58509733, 58467663, 58425063, 58381935, 58338279, 58294096,
+ 58249386, 58204151, 58158391, 58112107, 58065300, 58017970, 57970118,
+ 57921746, 57872854, 57823442, 57773512, 57723064, 57672100, 57620619,
+ 57568624, 57516113, 57463090, 57409554, 57355506, 57300947, 57245877,
+ 57190299, 57134212, 57077618, 57020517, 56962910, 56904798, 56846182,
+ 56787064, 56727442, 56667320, 56606697, 56545575, 56483954, 56421835,
+ 56359219, 56296108, 56232501, 56168401, 56103807, 56038721, 55973144,
+ 55907077, 55840521, 55773476, 55705943, 55637925, 55569420, 55500432,
+ 55430959, 55361005, 55290568, 55219651, 55148255, 55076379, 55004027,
+ 54931197, 54857892, 54784113, 54709860, 54635134, 54559937, 54484269,
+ 54408132, 54331526, 54254453, 54176914, 54098909, 54020440, 53941508,
+ 53862113, 53782258, 53701942, 53621167, 53539935, 53458246, 53376100,
+ 53293501, 53210447, 53126942, 53042984, 52958577, 52873720, 52788415,
+ 52702663, 52616465, 52529823, 52442736, 52355208, 52267237, 52178827,
+ 52089977, 52000689, 51910965, 51820804, 51730209, 51639181, 51547720,
+ 51455828, 51363507, 51270756, 51177578, 51083973, 50989943, 50895488,
+ 50800611, 50705312, 50609592, 50513453, 50416896, 50319922, 50222531,
+ 50124727, 50026509, 49927878, 49828837, 49729385, 49629526, 49529259,
+ 49428585, 49327507, 49226025, 49124141, 49021855, 48919170, 48816086,
+ 48712604, 48608726, 48504453, 48399787, 48294727, 48189277, 48083437,
+ 47977208, 47870591, 47763589, 47656201, 47548430, 47440277, 47331743,
+ 47222829, 47113536, 47003866, 46893820, 46783400, 46672607, 46561441,
+ 46449905, 46337999, 46225726, 46113085, 46000079, 45886709, 45772977,
+ 45658882, 45544428, 45429615, 45314444, 45198917, 45083036, 44966800,
+ 44850213, 44733275, 44615987, 44498352, 44380369, 44262041, 44143370,
+ 44024355, 43904999, 43785303, 43665269, 43544897, 43424189, 43303147,
+ 43181772, 43060065, 42938028, 42815661, 42692968, 42569948, 42446603,
+ 42322934, 42198944, 42074633, 41950002, 41825054, 41699790, 41574210,
+ 41448317, 41322111, 41195595, 41068769, 40941635, 40814195, 40686449,
+ 40558400, 40430048, 40301396, 40172444, 40043194, 39913647, 39783805,
+ 39653669, 39523241, 39392522, 39261514, 39130218, 38998635, 38866767,
+ 38734615, 38602181, 38469466, 38336472, 38203200, 38069652, 37935829,
+ 37801732, 37667363, 37532723, 37397815, 37262638, 37127196, 36991489,
+ 36855518, 36719286, 36582793, 36446042, 36309033, 36171768, 36034249,
+ 35896477, 35758453, 35620180, 35481658, 35342889, 35203875, 35064616,
+ 34925115, 34785373, 34645391, 34505172, 34364715, 34224024, 34083099,
+ 33941942, 33800554, 33658938, 33517094, 33375023, 33232728, 33090211,
+ 32947471, 32804512, 32661334, 32517939, 32374328, 32230503, 32086466,
+ 31942218, 31797761, 31653096, 31508224, 31363147, 31217867, 31072385,
+ 30926703, 30780822, 30634743, 30488469, 30342001, 30195340, 30048487,
+ 29901445, 29754215, 29606799, 29459197, 29311412, 29163444, 29015296,
+ 28866970, 28718466, 28569786, 28420931, 28271904, 28122706, 27973337,
+ 27823801, 27674098, 27524230, 27374198, 27224004, 27073650, 26923137,
+ 26772466, 26621640, 26470659, 26319525, 26168240, 26016806, 25865223,
+ 25713494, 25561619, 25409601, 25257441, 25105141, 24952702, 24800125,
+ 24647413, 24494567, 24341587, 24188477, 24035237, 23881869, 23728375,
+ 23574755, 23421012, 23267147, 23113162, 22959059, 22804838, 22650501,
+ 22496050, 22341487, 22186813, 22032029, 21877138, 21722140, 21567037,
+ 21411831, 21256523, 21101115, 20945609, 20790005, 20634306, 20478514,
+ 20322628, 20166652, 20010586, 19854433, 19698194, 19541870, 19385462,
+ 19228974, 19072405, 18915758, 18759034, 18602234, 18445361, 18288415,
+ 18131399, 17974313, 17817160, 17659941, 17502657, 17345310, 17187902,
+ 17030434, 16872908, 16715324, 16557686, 16399993, 16242249, 16084454,
+ 15926609, 15768718, 15610780, 15452797, 15294772, 15136705, 14978598,
+ 14820453, 14662272, 14504055, 14345804, 14187521, 14029207, 13870864,
+ 13712494, 13554097, 13395676, 13237232, 13078766, 12920281, 12761777,
+ 12603256, 12444719, 12286169, 12127607, 11969033, 11810451, 11651860,
+ 11493264, 11334662, 11176057, 11017451, 10858845, 10700240, 10541637,
+ 10383039, 10224447, 10065862, 9907287, 9748721, 9590168, 9431628,
+ 9273103, 9114594, 8956103, 8797632, 8639181, 8480753, 8322349, 8163971,
+ 8005619, 7847296, 7689002, 7530740, 7372511, 7214316, 7056158, 6898036,
+ 6739954, 6581911, 6423911, 6265954, 6108041, 5950175, 5792357, 5634588,
+ 5476869, 5319203, 5161590, 5004033, 4846532, 4689089, 4531705, 4374383,
+ 4217123, 4059926, 3902796, 3745732, 3588736, 3431810, 3274955, 3118173,
+ 2961464, 2804832, 2648276, 2491799, 2335401, 2179085, 2022852, 1866703,
+ 1710639, 1554663, 1398775, 1242977, 1087270, 931656, 776136, 620712,
+ 465385, 310156, 155027, 0, -154924, -309745, -464460, -619068, -773568,
+ -927959, -1082238, -1236404, -1390456, -1544394, -1698214, -1851916,
+ -2005499, -2158961, -2312300, -2465516, -2618607, -2771571, -2924408,
+ -3077115, -3229692, -3382137, -3534448, -3686625, -3838666, -3990569,
+ -4142334, -4293958, -4445441, -4596781, -4747977, -4899027, -5049931,
+ -5200686, -5351292, -5501747, -5652049, -5802198, -5952192, -6102030,
+ -6251710, -6401231, -6550592, -6699792, -6848828, -6997701, -7146408,
+ -7294948, -7443320, -7591523, -7739554, -7887414, -8035101, -8182613,
+ -8329949, -8477107, -8624087, -8770888, -8917507, -9063944, -9210198,
+ -9356266, -9502148, -9647843, -9793349, -9938665, -10083790, -10228723,
+ -10373461, -10518005, -10662352, -10806502, -10950453, -11094204,
+ -11237754, -11381101, -11524245, -11667183, -11809916, -11952441,
+ -12094757, -12236863, -12378759, -12520442, -12661911, -12803166,
+ -12944205, -13085027, -13225630, -13366014, -13506177, -13646118,
+ -13785836, -13925330, -14064599, -14203640, -14342454, -14481039,
+ -14619393, -14757516, -14895407, -15033064, -15170486, -15307672,
+ -15444621, -15581332, -15717803, -15854033, -15990022, -16125768,
+ -16261270, -16396526, -16531537, -16666300, -16800814, -16935079,
+ -17069093, -17202855, -17336364, -17469619, -17602618, -17735362,
+ -17867848, -18000075, -18132043, -18263750, -18395195, -18526377,
+ -18657296, -18787949, -18918337, -19048457, -19178309, -19307891,
+ -19437204, -19566245, -19695013, -19823508, -19951728, -20079673,
+ -20207341, -20334731, -20461843, -20588675, -20715226, -20841495,
+ -20967482, -21093185, -21218602, -21343734, -21468580, -21593137,
+ -21717405, -21841384, -21965072, -22088467, -22211570, -22334380,
+ -22456894, -22579113, -22701035, -22822659, -22943985, -23065010,
+ -23185736, -23306160, -23426281, -23546099, -23665612, -23784821,
+ -23903723, -24022317, -24140604, -24258581, -24376249, -24493606,
+ -24610651, -24727383, -24843802, -24959906, -25075694, -25191167,
+ -25306322, -25421159, -25535677, -25649875, -25763752, -25877308,
+ -25990541, -26103451, -26216037, -26328297, -26440232, -26551840,
+ -26663120, -26774071, -26884694, -26994986, -27104947, -27214576,
+ -27323873, -27432836, -27541465, -27649758, -27757716, -27865337,
+ -27972620, -28079565, -28186171, -28292437, -28398362, -28503946,
+ -28609187, -28714086, -28818640, -28922850, -29026714, -29130233,
+ -29233404, -29336228, -29438703, -29540829, -29642605, -29744031,
+ -29845105, -29945827, -30046196, -30146212, -30245873, -30345179,
+ -30444130, -30542724, -30640961, -30738840, -30836360, -30933522,
+ -31030323, -31126764, -31222844, -31318561, -31413916, -31508908,
+ -31603536, -31697799, -31791696, -31885228, -31978393, -32071191,
+ -32163621, -32255683, -32347375, -32438698, -32529650, -32620231,
+ -32710440, -32800278, -32889742, -32978833, -33067549, -33155892,
+ -33243858, -33331449, -33418664, -33505501, -33591961, -33678042,
+ -33763745, -33849068, -33934012, -34018575, -34102757, -34186558,
+ -34269976, -34353012, -34435664, -34517933, -34599818, -34681317,
+ -34762432, -34843160, -34923503, -35003458, -35083026, -35162207,
+ -35240999, -35319402, -35397415, -35475039, -35552273, -35629116,
+ -35705567, -35781627, -35857295, -35932570, -36007452, -36081940,
+ -36156034, -36229734, -36303039, -36375949, -36448463, -36520580,
+ -36592301, -36663625, -36734552, -36805080, -36875211, -36944942,
+ -37014275, -37083208, -37151741, -37219874, -37287607, -37354938,
+ -37421868, -37488396, -37554522, -37620246, -37685566, -37750484,
+ -37814997, -37879107, -37942813, -38006114, -38069010, -38131501,
+ -38193587, -38255266, -38316539, -38377406, -38437865, -38497918,
+ -38557563, -38616801, -38675630, -38734051, -38792063, -38849667,
+ -38906861, -38963646, -39020021, -39075986, -39131541, -39186685,
+ -39241419, -39295741, -39349653, -39403153, -39456241, -39508917,
+ -39561181, -39613032, -39664471, -39715497, -39766110, -39816310,
+ -39866096, -39915469, -39964427, -40012972, -40061103, -40108819,
+ -40156120, -40203007, -40249478, -40295535, -40341176, -40386402,
+ -40431212, -40475607, -40519585, -40563148, -40606294, -40649024,
+ -40691338, -40733235, -40774716, -40815780, -40856426, -40896656,
+ -40936469, -40975864, -41014842, -41053403, -41091546, -41129272,
+ -41166580, -41203470, -41239943, -41275997, -41311634, -41346852,
+ -41381653, -41416035, -41450000, -41483546, -41516673, -41549383,
+ -41581674, -41613547, -41645002, -41676038, -41706655, -41736855,
+ -41766636, -41795998, -41824942, -41853468, -41881575, -41909264,
+ -41936534, -41963386, -41989820, -42015835, -42041432, -42066611,
+ -42091372, -42115714, -42139639, -42163145, -42186233, -42208904,
+ -42231156, -42252991, -42274408, -42295407, -42315989, -42336153,
+ -42355900, -42375230, -42394142, -42412637, -42430715, -42448376,
+ -42465621, -42482448, -42498860, -42514854, -42530433, -42545595,
+ -42560341, -42574671, -42588586, -42602085, -42615168, -42627836,
+ -42640089, -42651927, -42663350, -42674358, -42684952, -42695132,
+ -42704897, -42714249, -42723187, -42731711, -42739822, -42747520,
+ -42754804, -42761676, -42768136, -42774183, -42779818, -42785041,
+ -42789853, -42794253, -42798242, -42801820, -42804987, -42807744,
+ -42810090, -42812027, -42813554, -42814671, -42815380, -42815679,
+ -42815570, -42815052, -42814127, -42812794, -42811053, -42808905,
+ -42806350, -42803388, -42800020, -42796246, -42792066, -42787481,
+ -42782491, -42777097, -42771297, -42765094, -42758487, -42751476,
+ -42744063, -42736246, -42728028, -42719407, -42710384, -42700961,
+ -42691136, -42680911, -42670285, -42659259, -42647834, -42636010,
+ -42623788, -42611166, -42598147, -42584731, -42570917, -42556706,
+ -42542099, -42527096, -42511698, -42495904, -42479716, -42463133,
+ -42446157, -42428787, -42411024, -42392868, -42374321, -42355381,
+ -42336051, -42316330, -42296218, -42275716, -42254825, -42233545,
+ -42211877, -42189821, -42167377, -42144545, -42121328, -42097724,
+ -42073735, -42049360, -42024601, -41999457, -41973930, -41948020,
+ -41921728, -41895053, -41867996, -41840559, -41812741, -41784542,
+ -41755965, -41727008, -41697673, -41667960, -41637869, -41607402,
+ -41576558, -41545339, -41513744, -41481775, -41449432, -41416715,
+ -41383626, -41350164, -41316330, -41282125, -41247549, -41212603,
+ -41177288, -41141604, -41105551, -41069131, -41032344, -40995190,
+ -40957670, -40919785, -40881535, -40842922, -40803944, -40764604,
+ -40724902, -40684838, -40644413, -40603628, -40562483, -40520979,
+ -40479117, -40436897, -40394319, -40351386, -40308096, -40264451,
+ -40220452, -40176099, -40131393, -40086334, -40040923, -39995161,
+ -39949049, -39902587, -39855775, -39808615, -39761108, -39713253,
+ -39665052, -39616505, -39567614, -39518378, -39468798, -39418876,
+ -39368611, -39318005, -39267058, -39215771, -39164145, -39112181,
+ -39059878, -39007238, -38954262, -38900951, -38847304, -38793323,
+ -38739009, -38684362, -38629384, -38574074, -38518433, -38462463,
+ -38406164, -38349537, -38292583, -38235302, -38177695, -38119763,
+ -38061506, -38002927, -37944024, -37884800, -37825254, -37765388,
+ -37705202, -37644698, -37583875, -37522736, -37461280, -37399508,
+ -37337422, -37275021, -37212308, -37149282, -37085945, -37022296,
+ -36958338, -36894071, -36829496, -36764613, -36699424, -36633928,
+ -36568128, -36502024, -36435617, -36368907, -36301895, -36234583,
+ -36166971, -36099060, -36030851, -35962345, -35893542, -35824443,
+ -35755050, -35685363, -35615383, -35545110, -35474547, -35403693,
+ -35332549, -35261117, -35189398, -35117391, -35045098, -34972521,
+ -34899659, -34826514, -34753086, -34679377, -34605387, -34531118,
+ -34456569, -34381743, -34306640, -34231260, -34155606, -34079677,
+ -34003475, -33927000, -33850254, -33773237, -33695950, -33618395,
+ -33540572, -33462482, -33384126, -33305505, -33226619, -33147471,
+ -33068060, -32988388, -32908456, -32828264, -32747814, -32667106,
+ -32586142, -32504922, -32423447, -32341718, -32259737, -32177504,
+ -32095020, -32012286, -31929304, -31846073, -31762595, -31678872,
+ -31594903, -31510690, -31426234, -31341536, -31256596, -31171417,
+ -31085998, -31000341, -30914447, -30828316, -30741950, -30655350,
+ -30568517, -30481451, -30394154, -30306627, -30218870, -30130885,
+ -30042672, -29954234, -29865570, -29776681, -29687570, -29598236,
+ -29508680, -29418905, -29328910, -29238697, -29148266, -29057619,
+ -28966758, -28875681, -28784392, -28692890, -28601178, -28509255,
+ -28417123, -28324783, -28232236, -28139483, -28046524, -27953362,
+ -27859997, -27766430, -27672662, -27578695, -27484528, -27390164,
+ -27295603, -27200846, -27105895, -27010750, -26915413, -26819884,
+ -26724164, -26628255, -26532158, -26435873, -26339403, -26242747,
+ -26145906, -26048883, -25951678, -25854291, -25756725, -25658980,
+ -25561057, -25462957, -25364681, -25266231, -25167607, -25068811,
+ -24969843, -24870705, -24771397, -24671922, -24572279, -24472470,
+ -24372496, -24272358, -24172057, -24071594, -23970970, -23870187,
+ -23769245, -23668146, -23566890, -23465478, -23363913, -23262194,
+ -23160323, -23058301, -22956129, -22853808, -22751339, -22648724,
+ -22545963, -22443057, -22340008, -22236816, -22133483, -22030010,
+ -21926398, -21822648, -21718760, -21614737, -21510579, -21406287,
+ -21301863, -21197307, -21092621, -20987806, -20882862, -20777791,
+ -20672594, -20567272, -20461826, -20356258, -20250568, -20144757,
+ -20038827, -19932778, -19826612, -19720330, -19613933, -19507421,
+ -19400797, -19294062, -19187215, -19080259, -18973194, -18866022,
+ -18758744, -18651360, -18543873, -18436282, -18328590, -18220797,
+ -18112904, -18004912, -17896823, -17788638, -17680357, -17571982,
+ -17463515, -17354955, -17246304, -17137564, -17028735, -16919818,
+ -16810815, -16701726, -16592554, -16483298, -16373960, -16264542,
+ -16155043, -16045466, -15935811, -15826079, -15716273, -15606392,
+ -15496437, -15386411, -15276314, -15166146, -15055910, -14945607,
+ -14835236, -14724801, -14614301, -14503737, -14393112, -14282425,
+ -14171679, -14060873, -13950010, -13839090, -13728115, -13617085,
+ -13506002, -13394867, -13283681, -13172444, -13061159, -12949825,
+ -12838445, -12727020, -12615549, -12504036, -12392480, -12280883,
+ -12169245, -12057569, -11945854, -11834103, -11722316, -11610495,
+ -11498639, -11386752, -11274833, -11162883, -11050905, -10938898,
+ -10826865, -10714805, -10602721, -10490613, -10378482, -10266330,
+ -10154157, -10041965, -9929755, -9817527, -9705283, -9593025, -9480752,
+ -9368467, -9256170, -9143862, -9031544, -8919218, -8806885, -8694545,
+ -8582200, -8469851, -8357499, -8245145, -8132789, -8020434, -7908080,
+ -7795729, -7683380, -7571037, -7458698, -7346367, -7234043, -7121727,
+ -7009422, -6897127, -6784844, -6672575, -6560319, -6448078, -6335854,
+ -6223647, -6111458, -5999289, -5887140, -5775013, -5662908, -5550827,
+ -5438770, -5326740, -5214736, -5102760, -4990813, -4878895, -4767009,
+ -4655155, -4543334, -4431547, -4319796, -4208081, -4096403, -3984763,
+ -3873163, -3761603, -3650085, -3538609, -3427177, -3315789, -3204447,
+ -3093152, -2981904, -2870705, -2759556, -2648458, -2537411, -2426418,
+ -2315478, -2204593, -2093765, -1982993, -1872279, -1761624, -1651029,
+ -1540495, -1430024, -1319615, -1209270, -1098991, -988778, -878631,
+ -768553, -658544, -548606, -438738, -328943, -219220, -109572, 0,
+ 109496, 218916, 328257, 437519, 546702, 655803, 764821, 873757, 982609,
+ 1091375, 1200056, 1308649, 1417155, 1525571, 1633897, 1742133, 1850276,
+ 1958327, 2066283, 2174145, 2281911, 2389580, 2497152, 2604624, 2711997,
+ 2819270, 2926440, 3033509, 3140473, 3247334, 3354088, 3460737, 3567278,
+ 3673711, 3780034, 3886248, 3992350, 4098340, 4204218, 4309981, 4415630,
+ 4521163, 4626579, 4731877, 4837057, 4942117, 5047057, 5151876, 5256572,
+ 5361146, 5465595, 5569919, 5674117, 5778188, 5882132, 5985947, 6089632,
+ 6193187, 6296610, 6399901, 6503059, 6606083, 6708972, 6811725, 6914342,
+ 7016821, 7119161, 7221362, 7323422, 7425342, 7527119, 7628753, 7730244,
+ 7831590, 7932790, 8033844, 8134751, 8235509, 8336119, 8436579, 8536888,
+ 8637045, 8737050, 8836901, 8936599, 9036141, 9135528, 9234758, 9333830,
+ 9432744, 9531499, 9630094, 9728528, 9826800, 9924910, 10022856,
+ 10120638, 10218255, 10315706, 10412991, 10510108, 10607057, 10703836,
+ 10800446, 10896885, 10993153, 11089248, 11185170, 11280918, 11376492,
+ 11471890, 11567111, 11662156, 11757022, 11851710, 11946219, 12040547,
+ 12134694, 12228660, 12322442, 12416042, 12509457, 12602688, 12695733,
+ 12788591, 12881262, 12973746, 13066040, 13158146, 13250061, 13341785,
+ 13433317, 13524657, 13615804, 13706757, 13797515, 13888078, 13978445,
+ 14068614, 14158587, 14248361, 14337936, 14427311, 14516486, 14605460,
+ 14694231, 14782800, 14871166, 14959328, 15047285, 15135037, 15222583,
+ 15309921, 15397053, 15483976, 15570690, 15657195, 15743489, 15829573,
+ 15915445, 16001104, 16086551, 16171784, 16256803, 16341606, 16426195,
+ 16510566, 16594721, 16678659, 16762378, 16845878, 16929159, 17012219,
+ 17095059, 17177677, 17260073, 17342246, 17424196, 17505922, 17587423,
+ 17668699, 17749749, 17830573, 17911169, 17991538, 18071678, 18151589,
+ 18231271, 18310723, 18389944, 18468933, 18547691, 18626216, 18704508,
+ 18782566, 18860390, 18937979, 19015332, 19092450, 19169331, 19245974,
+ 19322380, 19398547, 19474476, 19550165, 19625614, 19700823, 19775790,
+ 19850516, 19924999, 19999240, 20073237, 20146991, 20220500, 20293764,
+ 20366783, 20439556, 20512082, 20584361, 20656393, 20728176, 20799712,
+ 20870997, 20942034, 21012820, 21083356, 21153640, 21223673, 21293454,
+ 21362982, 21432257, 21501279, 21570046, 21638559, 21706817, 21774819,
+ 21842566, 21910056, 21977289, 22044264, 22110982, 22177442, 22243643,
+ 22309584, 22375266, 22440688, 22505849, 22570750, 22635388, 22699766,
+ 22763880, 22827732, 22891321, 22954646, 23017708, 23080504, 23143036,
+ 23205303, 23267304, 23329039, 23390508, 23451709, 23512644, 23573310,
+ 23633709, 23693839, 23753700, 23813293, 23872615, 23931667, 23990449,
+ 24048961, 24107201, 24165170, 24222867, 24280291, 24337443, 24394323,
+ 24450928, 24507261, 24563319, 24619103, 24674612, 24729846, 24784805,
+ 24839488, 24893896, 24948027, 25001881, 25055458, 25108758, 25161780,
+ 25214525, 25266991, 25319178, 25371087, 25422717, 25474067, 25525137,
+ 25575928, 25626438, 25676667, 25726615, 25776283, 25825669, 25874773,
+ 25923595, 25972135, 26020392, 26068366, 26116058, 26163466, 26210590,
+ 26257431, 26303987, 26350259, 26396247, 26441950, 26487368, 26532500,
+ 26577347, 26621908, 26666183, 26710173, 26753875, 26797291, 26840420,
+ 26883262, 26925817, 26968084, 27010064, 27051756, 27093159, 27134275,
+ 27175102, 27215640, 27255889, 27295850, 27335521, 27374903, 27413995,
+ 27452798, 27491311, 27529533, 27567466, 27605108, 27642460, 27679520,
+ 27716291, 27752770, 27788958, 27824854, 27860460, 27895774, 27930796,
+ 27965526, 27999964, 28034111, 28067965, 28101527, 28134796, 28167773,
+ 28200458, 28232849, 28264948, 28296754, 28328267, 28359487, 28390413,
+ 28421046, 28451386, 28481432, 28511185, 28540644, 28569809, 28598681,
+ 28627259, 28655543, 28683532, 28711228, 28738630, 28765737, 28792551,
+ 28819070, 28845295, 28871225, 28896861, 28922203, 28947250, 28972002,
+ 28996461, 29020624, 29044493, 29068068, 29091347, 29114333, 29137023,
+ 29159419, 29181521, 29203327, 29224839, 29246057, 29266979, 29287607,
+ 29307941, 29327980, 29347724, 29367174, 29386329, 29405189, 29423755,
+ 29442027, 29460004, 29477687, 29495075, 29512170, 29528969, 29545475,
+ 29561687, 29577604, 29593227, 29608557, 29623592, 29638333, 29652781,
+ 29666935, 29680795, 29694362, 29707635, 29720615, 29733301, 29745694,
+ 29757794, 29769601, 29781115, 29792336, 29803264, 29813899, 29824242,
+ 29834293, 29844051, 29853517, 29862691, 29871572, 29880162, 29888460,
+ 29896467, 29904182, 29911605, 29918738, 29925579, 29932129, 29938389,
+ 29944358, 29950036, 29955424, 29960522, 29965329, 29969847, 29974075,
+ 29978014, 29981663, 29985023, 29988094, 29990876, 29993370, 29995574,
+ 29997491, 29999119, 30000460, 30001513, 30002278, 30002756, 30002946,
+ 30002850, 30002467, 30001797, 30000841, 29999599, 29998071, 29996258,
+ 29994159, 29991774, 29989105, 29986151, 29982912, 29979389, 29975582,
+ 29971491, 29967117, 29962459, 29957518, 29952294, 29946788, 29940999,
+ 29934928, 29928575, 29921941, 29915025, 29907829, 29900351, 29892593,
+ 29884555, 29876237, 29867639, 29858762, 29849606, 29840171, 29830457,
+ 29820465, 29810195, 29799648, 29788823, 29777721, 29766343, 29754688,
+ 29742757, 29730550, 29718068, 29705310, 29692278, 29678971, 29665390,
+ 29651535, 29637406, 29623004, 29608330, 29593382, 29578163, 29562672,
+ 29546909, 29530875, 29514570, 29497994, 29481149, 29464034, 29446649,
+ 29428995, 29411073, 29392882, 29374423, 29355697, 29336703, 29317443,
+ 29297916, 29278123, 29258064, 29237740, 29217151, 29196298, 29175180,
+ 29153798, 29132154, 29110246, 29088075, 29065643, 29042948, 29019992,
+ 28996775, 28973298, 28949561, 28925563, 28901307, 28876791, 28852017,
+ 28826985, 28801696, 28776149, 28750345, 28724285, 28697969, 28671398,
+ 28644572, 28617491, 28590156, 28562567, 28534725, 28506630, 28478283,
+ 28449684, 28420833, 28391732, 28362379, 28332777, 28302926, 28272825,
+ 28242475, 28211877, 28181032, 28149939, 28118600, 28087014, 28055182,
+ 28023105, 27990783, 27958217, 27925407, 27892354, 27859057, 27825519,
+ 27791738, 27757716, 27723453, 27688950, 27654206, 27619224, 27584002,
+ 27548542, 27512845, 27476910, 27440738, 27404329, 27367685, 27330806,
+ 27293692, 27256344, 27218762, 27180947, 27142899, 27104619, 27066108,
+ 27027365, 26988392, 26949189, 26909757, 26870096, 26830206, 26790089,
+ 26749745, 26709173, 26668376, 26627353, 26586105, 26544633, 26502937,
+ 26461017, 26418875, 26376511, 26333925, 26291117, 26248090, 26204842,
+ 26161375, 26117690, 26073786, 26029664, 25985326, 25940771, 25896000,
+ 25851014, 25805813, 25760398, 25714770, 25668928, 25622875, 25576609,
+ 25530133, 25483446, 25436549, 25389443, 25342128, 25294604, 25246874,
+ 25198936, 25150792, 25102443, 25053888, 25005129, 24956166, 24907000,
+ 24857631, 24808061, 24758289, 24708316, 24658143, 24607770, 24557199,
+ 24506430, 24455463, 24404299, 24352938, 24301382, 24249631, 24197685,
+ 24145546, 24093214, 24040689, 23987972, 23935064, 23881965, 23828677,
+ 23775199, 23721533, 23667678, 23613637, 23559409, 23504994, 23450395,
+ 23395610, 23340642, 23285490, 23230156, 23174640, 23118942, 23063064,
+ 23007005, 22950767, 22894351, 22837756, 22780984, 22724036, 22666911,
+ 22609611, 22552137, 22494488, 22436667, 22378672, 22320506, 22262169,
+ 22203661, 22144983, 22086136, 22027120, 21967937, 21908586, 21849069,
+ 21789386, 21729539, 21669527, 21609351, 21549013, 21488512, 21427849,
+ 21367026, 21306043, 21244900, 21183598, 21122139, 21060522, 20998748,
+ 20936819, 20874734, 20812495, 20750102, 20687556, 20624858, 20562007,
+ 20499007, 20435855, 20372555, 20309105, 20245508, 20181763, 20117871,
+ 20053834, 19989651, 19925324, 19860853, 19796239, 19731483, 19666585,
+ 19601547, 19536368, 19471050, 19405593, 19339998, 19274267, 19208398,
+ 19142394, 19076255, 19009982, 18943575, 18877035, 18810364, 18743561,
+ 18676627, 18609564, 18542371, 18475050, 18407601, 18340026, 18272324,
+ 18204498, 18136546, 18068470, 18000272, 17931951, 17863508, 17794944,
+ 17726260, 17657457, 17588535, 17519495, 17450338, 17381064, 17311675,
+ 17242171, 17172552, 17102820, 17032976, 16963019, 16892952, 16822774,
+ 16752486, 16682090, 16611585, 16540973, 16470254, 16399430, 16328500,
+ 16257466, 16186328, 16115088, 16043745, 15972301, 15900757, 15829112,
+ 15757369, 15685527, 15613588, 15541553, 15469421, 15397194, 15324872,
+ 15252457, 15179949, 15107349, 15034657, 14961875, 14889002, 14816041,
+ 14742992, 14669854, 14596630, 14523320, 14449925, 14376445, 14302882,
+ 14229235, 14155507, 14081697, 14007806, 13933835, 13859786, 13785658,
+ 13711452, 13637170, 13562811, 13488377, 13413869, 13339287, 13264633,
+ 13189905, 13115107, 13040238, 12965299, 12890291, 12815215, 12740071,
+ 12664860, 12589583, 12514242, 12438835, 12363365, 12287832, 12212237,
+ 12136581, 12060864, 11985087, 11909251, 11833357, 11757405, 11681397,
+ 11605332, 11529213, 11453039, 11376811, 11300531, 11224198, 11147814,
+ 11071380, 10994895, 10918362, 10841781, 10765152, 10688476, 10611754,
+ 10534988, 10458177, 10381322, 10304424, 10227485, 10150504, 10073483,
+ 9996421, 9919321, 9842183, 9765007, 9687795, 9610546, 9533263, 9455945,
+ 9378594, 9301209, 9223793, 9146345, 9068867, 8991359, 8913822, 8836257,
+ 8758665, 8681046, 8603400, 8525730, 8448035, 8370317, 8292576, 8214813,
+ 8137028, 8059223, 7981398, 7903554, 7825692, 7747812, 7669916, 7592003,
+ 7514075, 7436133, 7358177, 7280209, 7202228, 7124235, 7046232, 6968219,
+ 6890197, 6812166, 6734128, 6656083, 6578032, 6499975, 6421914, 6343849,
+ 6265781, 6187710, 6109638, 6031565, 5953492, 5875420, 5797349, 5719280,
+ 5641214, 5563152, 5485094, 5407041, 5328994, 5250954, 5172921, 5094897,
+ 5016881, 4938875, 4860879, 4782894, 4704922, 4626961, 4549015, 4471082,
+ 4393164, 4315261, 4237375, 4159506, 4081655, 4003822, 3926008, 3848215,
+ 3770442, 3692690, 3614961, 3537255, 3459572, 3381913, 3304280, 3226673,
+ 3149092, 3071538, 2994012, 2916515, 2839048, 2761611, 2684204, 2606830,
+ 2529487, 2452178, 2374902, 2297661, 2220455, 2143285, 2066152, 1989056,
+ 1911998, 1834979, 1758000, 1681060, 1604162, 1527305, 1450491, 1373719,
+ 1296992, 1220309, 1143671, 1067079, 990533, 914035, 837585, 761183,
+ 684831, 608529, 532278, 456078, 379931, 303836, 227795, 151808, 75876,
+ 0, -75820, -151583, -227288, -302935, -378523, -454051, -529518,
+ -604925, -680270, -755552, -830771, -905927, -981017, -1056043,
+ -1131003, -1205896, -1280722, -1355480, -1430170, -1504790, -1579341,
+ -1653821, -1728229, -1802566, -1876831, -1951022, -2025139, -2099182,
+ -2173150, -2247041, -2320857, -2394595, -2468255, -2541837, -2615340,
+ -2688763, -2762106, -2835368, -2908548, -2981646, -3054660, -3127592,
+ -3200439, -3273201, -3345877, -3418467, -3490971, -3563387, -3635715,
+ -3707955, -3780105, -3852165, -3924134, -3996013, -4067799, -4139493,
+ -4211094, -4282602, -4354015, -4425333, -4496556, -4567682, -4638712,
+ -4709644, -4780478, -4851214, -4921850, -4992387, -5062823, -5133158,
+ -5203392, -5273523, -5343552, -5413477, -5483298, -5553015, -5622626,
+ -5692132, -5761531, -5830823, -5900007, -5969084, -6038052, -6106910,
+ -6175658, -6244296, -6312823, -6381239, -6449542, -6517732, -6585809,
+ -6653772, -6721620, -6789354, -6856972, -6924473, -6991858, -7059126,
+ -7126275, -7193307, -7260219, -7327011, -7393684, -7460236, -7526667,
+ -7592975, -7659162, -7725226, -7791166, -7856983, -7922674, -7988241,
+ -8053683, -8118998, -8184186, -8249248, -8314182, -8378987, -8443664,
+ -8508211, -8572629, -8636916, -8701073, -8765098, -8828991, -8892752,
+ -8956380, -9019874, -9083235, -9146461, -9209552, -9272507, -9335327,
+ -9398010, -9460556, -9522965, -9585235, -9647368, -9709361, -9771215,
+ -9832928, -9894502, -9955934, -10017225, -10078374, -10139381,
+ -10200245, -10260965, -10321542, -10381974, -10442261, -10502404,
+ -10562400, -10622251, -10681954, -10741511, -10800920, -10860181,
+ -10919293, -10978257, -11037071, -11095735, -11154249, -11212612,
+ -11270824, -11328884, -11386792, -11444547, -11502150, -11559599,
+ -11616894, -11674035, -11731021, -11787851, -11844527, -11901046,
+ -11957408, -12013614, -12069663, -12125553, -12181286, -12236860,
+ -12292275, -12347530, -12402626, -12457561, -12512336, -12566950,
+ -12621402, -12675692, -12729820, -12783786, -12837588, -12891227,
+ -12944702, -12998013, -13051159, -13104140, -13156955, -13209605,
+ -13262089, -13314406, -13366556, -13418539, -13470354, -13522001,
+ -13573480, -13624790, -13675930, -13726902, -13777703, -13828334,
+ -13878794, -13929083, -13979201, -14029148, -14078922, -14128524,
+ -14177953, -14227209, -14276291, -14325200, -14373935, -14422495,
+ -14470880, -14519090, -14567125, -14614984, -14662667, -14710174,
+ -14757503, -14804656, -14851631, -14898428, -14945048, -14991489,
+ -15037751, -15083834, -15129738, -15175462, -15221007, -15266371,
+ -15311555, -15356558, -15401379, -15446020, -15490478, -15534755,
+ -15578849, -15622761, -15666490, -15710036, -15753398, -15796577,
+ -15839571, -15882382, -15925008, -15967449, -16009705, -16051775,
+ -16093660, -16135359, -16176872, -16218199, -16259339, -16300292,
+ -16341058, -16381636, -16422027, -16462230, -16502245, -16542071,
+ -16581709, -16621158, -16660417, -16699488, -16738368, -16777059,
+ -16815560, -16853871, -16891991, -16929920, -16967659, -17005206,
+ -17042562, -17079726, -17116699, -17153479, -17190067, -17226463,
+ -17262666, -17298676, -17334494, -17370118, -17405548, -17440785,
+ -17475828, -17510677, -17545332, -17579792, -17614058, -17648129,
+ -17682005, -17715686, -17749172, -17782462, -17815557, -17848455,
+ -17881158, -17913664, -17945975, -17978088, -18010005, -18041726,
+ -18073249, -18104575, -18135704, -18166635, -18197369, -18227905,
+ -18258243, -18288384, -18318326, -18348070, -18377615, -18406962,
+ -18436110, -18465059, -18493810, -18522361, -18550713, -18578866,
+ -18606819, -18634573, -18662127, -18689481, -18716636, -18743590,
+ -18770344, -18796898, -18823252, -18849405, -18875358, -18901110,
+ -18926661, -18952012, -18977162, -19002110, -19026858, -19051404,
+ -19075749, -19099893, -19123835, -19147576, -19171115, -19194453,
+ -19217588, -19240522, -19263255, -19285785, -19308113, -19330239,
+ -19352163, -19373885, -19395405, -19416722, -19437837, -19458750,
+ -19479460, -19499968, -19520273, -19540376, -19560276, -19579974,
+ -19599468, -19618760, -19637850, -19656736, -19675420, -19693901,
+ -19712179, -19730254, -19748126, -19765796, -19783262, -19800526,
+ -19817586, -19834444, -19851098, -19867550, -19883799, -19899844,
+ -19915687, -19931327, -19946764, -19961997, -19977028, -19991856,
+ -20006481, -20020903, -20035122, -20049138, -20062951, -20076562,
+ -20089970, -20103174, -20116176, -20128976, -20141572, -20153966,
+ -20166157, -20178146, -20189932, -20201515, -20212896, -20224075,
+ -20235051, -20245825, -20256396, -20266765, -20276932, -20286897,
+ -20296660, -20306221, -20315580, -20324737, -20333692, -20342445,
+ -20350997, -20359347, -20367495, -20375442, -20383188, -20390732,
+ -20398075, -20405217, -20412158, -20418898, -20425437, -20431775,
+ -20437913, -20443849, -20449586, -20455122, -20460457, -20465593,
+ -20470528, -20475263, -20479798, -20484134, -20488270, -20492206,
+ -20495943, -20499480, -20502818, -20505958, -20508898, -20511639,
+ -20514182, -20516526, -20518671, -20520618, -20522367, -20523918,
+ -20525271, -20526426, -20527384, -20528144, -20528706, -20529072,
+ -20529240, -20529211, -20528986, -20528564, -20527945, -20527130,
+ -20526119, -20524912, -20523509, -20521911, -20520117, -20518128,
+ -20515943, -20513563, -20510989, -20508220, -20505257, -20502099,
+ -20498747, -20495201, -20491461, -20487528, -20483402, -20479082,
+ -20474569, -20469863, -20464965, -20459875, -20454592, -20449117,
+ -20443450, -20437592, -20431542, -20425301, -20418869, -20412246,
+ -20405432, -20398429, -20391235, -20383851, -20376277, -20368514,
+ -20360561, -20352420, -20344089, -20335570, -20326863, -20317967,
+ -20308883, -20299612, -20290153, -20280507, -20270674, -20260654,
+ -20250448, -20240056, -20229477, -20218712, -20207763, -20196627,
+ -20185307, -20173802, -20162112, -20150238, -20138180, -20125938,
+ -20113513, -20100905, -20088113, -20075139, -20061982, -20048643,
+ -20035122, -20021420, -20007536, -19993471, -19979225, -19964799,
+ -19950192, -19935406, -19920439, -19905294, -19889969, -19874465,
+ -19858782, -19842922, -19826883, -19810667, -19794273, -19777702,
+ -19760954, -19744030, -19726929, -19709653, -19692201, -19674574,
+ -19656771, -19638794, -19620643, -19602317, -19583818, -19565145,
+ -19546299, -19527280, -19508089, -19488726, -19469190, -19449483,
+ -19429605, -19409556, -19389336, -19368946, -19348386, -19327657,
+ -19306758, -19285691, -19264454, -19243050, -19221477, -19199737,
+ -19177830, -19155756, -19133515, -19111108, -19088535, -19065796,
+ -19042893, -19019824, -18996591, -18973194, -18949633, -18925909,
+ -18902021, -18877971, -18853759, -18829384, -18804848, -18780151,
+ -18755292, -18730273, -18705094, -18679755, -18654257, -18628599,
+ -18602783, -18576809, -18550676, -18524386, -18497939, -18471334,
+ -18444574, -18417657, -18390585, -18363357, -18335974, -18308437,
+ -18280746, -18252900, -18224902, -18196750, -18168446, -18139990,
+ -18111381, -18082622, -18053711, -18024650, -17995438, -17966077,
+ -17936566, -17906906, -17877097, -17847140, -17817036, -17786783,
+ -17756384, -17725838, -17695146, -17664309, -17633325, -17602197,
+ -17570925, -17539508, -17507947, -17476243, -17444396, -17412407,
+ -17380275, -17348002, -17315588, -17283033, -17250338, -17217502,
+ -17184527, -17151413, -17118160, -17084769, -17051241, -17017574,
+ -16983771, -16949832, -16915756, -16881545, -16847198, -16812717,
+ -16778101, -16743351, -16708468, -16673452, -16638304, -16603023,
+ -16567610, -16532066, -16496392, -16460587, -16424652, -16388588,
+ -16352394, -16316073, -16279623, -16243045, -16206340, -16169508,
+ -16132551, -16095467, -16058258, -16020924, -15983465, -15945882,
+ -15908176, -15870347, -15832395, -15794321, -15756125, -15717808,
+ -15679370, -15640812, -15602134, -15563337, -15524421, -15485386,
+ -15446233, -15406963, -15367576, -15328072, -15288452, -15248716,
+ -15208866, -15168900, -15128821, -15088627, -15048321, -15007902,
+ -14967370, -14926727, -14885972, -14845106, -14804130, -14763044,
+ -14721849, -14680545, -14639132, -14597612, -14555984, -14514249,
+ -14472407, -14430460, -14388407, -14346249, -14303986, -14261619,
+ -14219149, -14176576, -14133900, -14091122, -14048242, -14005262,
+ -13962181, -13918999, -13875718, -13832338, -13788859, -13745282,
+ -13701608, -13657836, -13613968, -13570004, -13525944, -13481788,
+ -13437539, -13393195, -13348757, -13304226, -13259603, -13214888,
+ -13170081, -13125182, -13080194, -13035115, -12989946, -12944689,
+ -12899343, -12853908, -12808387, -12762778, -12717082, -12671301,
+ -12625434, -12579482, -12533446, -12487325, -12441121, -12394834,
+ -12348465, -12302013, -12255481, -12208867, -12162173, -12115399,
+ -12068545, -12021613, -11974602, -11927514, -11880348, -11833105,
+ -11785786, -11738392, -11690922, -11643377, -11595758, -11548066,
+ -11500300, -11452461, -11404551, -11356569, -11308515, -11260391,
+ -11212197, -11163934, -11115601, -11067200, -11018731, -10970195,
+ -10921591, -10872921, -10824186, -10775385, -10726519, -10677588,
+ -10628594, -10579537, -10530417, -10481235, -10431990, -10382685,
+ -10333319, -10283893, -10234408, -10184863, -10135260, -10085598,
+ -10035880, -9986104, -9936272, -9886383, -9836440, -9786441, -9736389,
+ -9686282, -9636122, -9585909, -9535644, -9485328, -9434960, -9384541,
+ -9334073, -9283554, -9232987, -9182371, -9131707, -9080996, -9030237,
+ -8979432, -8928581, -8877685, -8826744, -8775759, -8724730, -8673657,
+ -8622542, -8571384, -8520185, -8468945, -8417664, -8366343, -8314982,
+ -8263582, -8212144, -8160668, -8109154, -8057603, -8006016, -7954393,
+ -7902735, -7851042, -7799314, -7747553, -7695758, -7643931, -7592071,
+ -7540180, -7488257, -7436304, -7384321, -7332308, -7280267, -7228196,
+ -7176098, -7123972, -7071820, -7019640, -6967435, -6915205, -6862950,
+ -6810670, -6758367, -6706040, -6653691, -6601319, -6548926, -6496511,
+ -6444076, -6391621, -6339146, -6286652, -6234139, -6181609, -6129060,
+ -6076495, -6023914, -5971316, -5918703, -5866075, -5813433, -5760777,
+ -5708107, -5655425, -5602730, -5550023, -5497306, -5444577, -5391838,
+ -5339090, -5286332, -5233566, -5180791, -5128009, -5075219, -5022423,
+ -4969621, -4916813, -4864001, -4811183, -4758362, -4705537, -4652709,
+ -4599878, -4547046, -4494212, -4441377, -4388542, -4335706, -4282872,
+ -4230038, -4177206, -4124376, -4071548, -4018724, -3965903, -3913086,
+ -3860274, -3807468, -3754666, -3701871, -3649083, -3596302, -3543528,
+ -3490763, -3438006, -3385258, -3332521, -3279793, -3227076, -3174370,
+ -3121676, -3068994, -3016324, -2963668, -2911026, -2858398, -2805784,
+ -2753186, -2700603, -2648036, -2595486, -2542953, -2490438, -2437941,
+ -2385463, -2333004, -2280564, -2228145, -2175746, -2123368, -2071012,
+ -2018677, -1966366, -1914077, -1861812, -1809571, -1757355, -1705163,
+ -1652997, -1600857, -1548743, -1496657, -1444597, -1392566, -1340563,
+ -1288589, -1236644, -1184729, -1132844, -1080990, -1029167, -977376,
+ -925617, -873891, -822198, -770538, -718913, -667322, -615766, -564246,
+ -512762, -461314, -409903, -358529, -307193, -255896, -204637, -153418,
+ -102238, -51098, 0, 51057, 102074, 153048, 203980, 254869, 305714,
+ 356516, 407273, 457986, 508654, 559275, 609851, 660380, 710862, 761297,
+ 811684, 862022, 912311, 962552, 1012742, 1062883, 1112972, 1163011,
+ 1212998, 1262934, 1312817, 1362647, 1412424, 1462147, 1511816, 1561431,
+ 1610990, 1660495, 1709943, 1759335, 1808670, 1857948, 1907169, 1956331,
+ 2005435, 2054480, 2103466, 2152392, 2201258, 2250063, 2298808, 2347490,
+ 2396112, 2444670, 2493166, 2541599, 2589969, 2638274, 2686515, 2734692,
+ 2782803, 2830849, 2878828, 2926741, 2974588, 3022367, 3070078, 3117721,
+ 3165296, 3212802, 3260239, 3307606, 3354903, 3402130, 3449285, 3496369,
+ 3543382, 3590323, 3637191, 3683986, 3730708, 3777356, 3823931, 3870431,
+ 3916856, 3963205, 4009480, 4055678, 4101800, 4147845, 4193813, 4239703,
+ 4285516, 4331250, 4376906, 4422482, 4467979, 4513396, 4558734, 4603990,
+ 4649166, 4694260, 4739273, 4784204, 4829052, 4873818, 4918500, 4963099,
+ 5007614, 5052045, 5096391, 5140652, 5184828, 5228918, 5272923, 5316841,
+ 5360672, 5404416, 5448072, 5491641, 5535122, 5578514, 5621818, 5665032,
+ 5708156, 5751191, 5794136, 5836990, 5879753, 5922424, 5965005, 6007493,
+ 6049889, 6092192, 6134403, 6176520, 6218544, 6260474, 6302309, 6344050,
+ 6385696, 6427247, 6468702, 6510061, 6551324, 6592491, 6633560, 6674533,
+ 6715408, 6756185, 6796864, 6837445, 6877927, 6918310, 6958593, 6998777,
+ 7038861, 7078844, 7118727, 7158509, 7198190, 7237770, 7277247, 7316622,
+ 7355895, 7395066, 7434133, 7473097, 7511957, 7550714, 7589366, 7627914,
+ 7666357, 7704695, 7742928, 7781055, 7819077, 7856992, 7894801, 7932502,
+ 7970097, 8007585, 8044965, 8082237, 8119402, 8156457, 8193404, 8230243,
+ 8266972, 8303591, 8340101, 8376501, 8412790, 8448970, 8485038, 8520995,
+ 8556841, 8592576, 8628198, 8663709, 8699107, 8734393, 8769566, 8804626,
+ 8839572, 8874405, 8909125, 8943730, 8978221, 9012597, 9046859, 9081005,
+ 9115037, 9148953, 9182753, 9216437, 9250006, 9283457, 9316792, 9350011,
+ 9383112, 9416096, 9448962, 9481711, 9514341, 9546854, 9579248, 9611523,
+ 9643680, 9675717, 9707636, 9739434, 9771113, 9802672, 9834112, 9865430,
+ 9896628, 9927706, 9958662, 9989498, 10020212, 10050805, 10081275,
+ 10111624, 10141851, 10171956, 10201938, 10231797, 10261533, 10291147,
+ 10320637, 10350004, 10379247, 10408366, 10437361, 10466233, 10494979,
+ 10523602, 10552099, 10580472, 10608720, 10636842, 10664839, 10692711,
+ 10720457, 10748077, 10775571, 10802938, 10830180, 10857295, 10884283,
+ 10911144, 10937878, 10964486, 10990965, 11017318, 11043543, 11069640,
+ 11095609, 11121450, 11147163, 11172747, 11198203, 11223530, 11248729,
+ 11273799, 11298739, 11323551, 11348233, 11372786, 11397209, 11421502,
+ 11445666, 11469699, 11493603, 11517376, 11541019, 11564532, 11587914,
+ 11611165, 11634285, 11657275, 11680133, 11702860, 11725456, 11747921,
+ 11770254, 11792455, 11814525, 11836463, 11858269, 11879943, 11901485,
+ 11922894, 11944172, 11965316, 11986329, 12007209, 12027956, 12048570,
+ 12069051, 12089399, 12109615, 12129697, 12149646, 12169461, 12189144,
+ 12208692, 12228107, 12247389, 12266537, 12285551, 12304431, 12323177,
+ 12341789, 12360267, 12378611, 12396821, 12414896, 12432837, 12450644,
+ 12468316, 12485853, 12503256, 12520525, 12537659, 12554657, 12571522,
+ 12588251, 12604845, 12621304, 12637629, 12653818, 12669872, 12685791,
+ 12701575, 12717223, 12732737, 12748115, 12763357, 12778465, 12793436,
+ 12808273, 12822974, 12837539, 12851969, 12866263, 12880421, 12894444,
+ 12908332, 12922083, 12935699, 12949180, 12962524, 12975733, 12988806,
+ 13001743, 13014544, 13027210, 13039740, 13052134, 13064392, 13076514,
+ 13088501, 13100351, 13112066, 13123645, 13135088, 13146395, 13157566,
+ 13168602, 13179501, 13190265, 13200893, 13211385, 13221742, 13231962,
+ 13242047, 13251996, 13261809, 13271487, 13281029, 13290435, 13299705,
+ 13308840, 13317839, 13326703, 13335431, 13344023, 13352480, 13360802,
+ 13368988, 13377038, 13384954, 13392733, 13400378, 13407887, 13415261,
+ 13422500, 13429604, 13436572, 13443406, 13450104, 13456668, 13463096,
+ 13469390, 13475549, 13481573, 13487463, 13493217, 13498837, 13504323,
+ 13509674, 13514891, 13519973, 13524921, 13529735, 13534414, 13538960,
+ 13543371, 13547648, 13551792, 13555801, 13559677, 13563420, 13567028,
+ 13570503, 13573845, 13577053, 13580128, 13583069, 13585878, 13588553,
+ 13591096, 13593506, 13595782, 13597926, 13599938, 13601817, 13603563,
+ 13605177, 13606659, 13608009, 13609227, 13610313, 13611266, 13612088,
+ 13612779, 13613338, 13613765, 13614061, 13614226, 13614260, 13614163,
+ 13613934, 13613575, 13613086, 13612465, 13611715, 13610834, 13609822,
+ 13608681, 13607410, 13606008, 13604477, 13602817, 13601027, 13599107,
+ 13597058, 13594880, 13592574, 13590138, 13587573, 13584880, 13582059,
+ 13579109, 13576031, 13572825, 13569491, 13566029, 13562440, 13558723,
+ 13554879, 13550907, 13546809, 13542583, 13538231, 13533752, 13529147,
+ 13524415, 13519557, 13514573, 13509464, 13504228, 13498867, 13493381,
+ 13487769, 13482032, 13476171, 13470184, 13464073, 13457838, 13451478,
+ 13444995, 13438387, 13431655, 13424800, 13417822, 13410720, 13403495,
+ 13396147, 13388677, 13381084, 13373368, 13365531, 13357571, 13349489,
+ 13341286, 13332961, 13324515, 13315948, 13307260, 13298451, 13289522,
+ 13280472, 13271302, 13262012, 13252602, 13243073, 13233424, 13223656,
+ 13213769, 13203763, 13193638, 13183395, 13173034, 13162555, 13151957,
+ 13141242, 13130410, 13119461, 13108394, 13097211, 13085911, 13074494,
+ 13062962, 13051313, 13039549, 13027669, 13015673, 13003563, 12991337,
+ 12978997, 12966543, 12953974, 12941291, 12928494, 12915583, 12902560,
+ 12889423, 12876172, 12862810, 12849334, 12835747, 12822047, 12808236,
+ 12794313, 12780278, 12766133, 12751876, 12737509, 12723031, 12708443,
+ 12693745, 12678938, 12664021, 12648994, 12633859, 12618614, 12603262,
+ 12587800, 12572231, 12556554, 12540769, 12524877, 12508878, 12492772,
+ 12476560, 12460241, 12443816, 12427285, 12410648, 12393906, 12377059,
+ 12360107, 12343051, 12325890, 12308625, 12291256, 12273784, 12256208,
+ 12238529, 12220747, 12202863, 12184876, 12166788, 12148598, 12130306,
+ 12111913, 12093418, 12074824, 12056128, 12037333, 12018437, 11999442,
+ 11980348, 11961154, 11941862, 11922471, 11902982, 11883394, 11863709,
+ 11843927, 11824047, 11804070, 11783997, 11763827, 11743561, 11723199,
+ 11702742, 11682190, 11661542, 11640800, 11619963, 11599032, 11578008,
+ 11556890, 11535678, 11514374, 11492976, 11471487, 11449905, 11428231,
+ 11406466, 11384609, 11362661, 11340623, 11318494, 11296276, 11273967,
+ 11251569, 11229081, 11206505, 11183840, 11161086, 11138245, 11115316,
+ 11092299, 11069195, 11046004, 11022727, 10999363, 10975914, 10952378,
+ 10928758, 10905052, 10881261, 10857386, 10833427, 10809384, 10785258,
+ 10761048, 10736755, 10712379, 10687922, 10663382, 10638760, 10614058,
+ 10589274, 10564409, 10539463, 10514438, 10489333, 10464148, 10438884,
+ 10413541, 10388119, 10362619, 10337041, 10311386, 10285653, 10259843,
+ 10233956, 10207993, 10181954, 10155839, 10129648, 10103383, 10077043,
+ 10050628, 10024139, 9997576, 9970940, 9944230, 9917447, 9890592,
+ 9863665, 9836666, 9809595, 9782453, 9755240, 9727956, 9700602, 9673178,
+ 9645685, 9618122, 9590490, 9562790, 9535021, 9507184, 9479279, 9451307,
+ 9423268, 9395162, 9366990, 9338752, 9310449, 9282079, 9253645, 9225146,
+ 9196583, 9167956, 9139265, 9110510, 9081693, 9052812, 9023870, 8994865,
+ 8965799, 8936671, 8907483, 8878233, 8848923, 8819553, 8790124, 8760635,
+ 8731087, 8701480, 8671815, 8642092, 8612312, 8582474, 8552579, 8522627,
+ 8492619, 8462555, 8432436, 8402261, 8372031, 8341747, 8311408, 8281016,
+ 8250569, 8220070, 8189518, 8158913, 8128256, 8097547, 8066786, 8035974,
+ 8005112, 7974199, 7943235, 7912222, 7881160, 7850048, 7818887, 7787679,
+ 7756422, 7725117, 7693765, 7662365, 7630919, 7599427, 7567889, 7536305,
+ 7504675, 7473001, 7441282, 7409519, 7377711, 7345861, 7313966, 7282029,
+ 7250050, 7218028, 7185964, 7153859, 7121713, 7089526, 7057298, 7025030,
+ 6992723, 6960376, 6927990, 6895565, 6863102, 6830601, 6798062, 6765486,
+ 6732872, 6700223, 6667536, 6634814, 6602057, 6569264, 6536436, 6503573,
+ 6470677, 6437746, 6404782, 6371785, 6338755, 6305693, 6272598, 6239472,
+ 6206315, 6173126, 6139906, 6106657, 6073377, 6040067, 6006729, 5973361,
+ 5939965, 5906540, 5873088, 5839607, 5806100, 5772566, 5739005, 5705418,
+ 5671806, 5638168, 5604504, 5570816, 5537104, 5503367, 5469607, 5435823,
+ 5402017, 5368187, 5334336, 5300462, 5266567, 5232650, 5198713, 5164754,
+ 5130776, 5096778, 5062760, 5028723, 4994667, 4960593, 4926500, 4892390,
+ 4858262, 4824117, 4789955, 4755777, 4721583, 4687373, 4653147, 4618907,
+ 4584652, 4550382, 4516099, 4481802, 4447491, 4413168, 4378832, 4344484,
+ 4310123, 4275751, 4241368, 4206974, 4172570, 4138155, 4103730, 4069296,
+ 4034853, 4000401, 3965940, 3931471, 3896994, 3862510, 3828019, 3793521,
+ 3759016, 3724506, 3689989, 3655468, 3620941, 3586409, 3551873, 3517333,
+ 3482789, 3448242, 3413691, 3379138, 3344583, 3310025, 3275466, 3240906,
+ 3206344, 3171782, 3137220, 3102657, 3068095, 3033533, 2998973, 2964413,
+ 2929856, 2895300, 2860747, 2826196, 2791649, 2757104, 2722564, 2688027,
+ 2653495, 2618967, 2584445, 2549927, 2515416, 2480910, 2446411, 2411918,
+ 2377432, 2342954, 2308483, 2274020, 2239566, 2205120, 2170683, 2136255,
+ 2101837, 2067429, 2033031, 1998644, 1964268, 1929902, 1895549, 1861207,
+ 1826877, 1792560, 1758256, 1723965, 1689688, 1655424, 1621174, 1586939,
+ 1552719, 1518514, 1484324, 1450150, 1415992, 1381850, 1347725, 1313617,
+ 1279526, 1245453, 1211398, 1177361, 1143343, 1109344, 1075364, 1041403,
+ 1007462, 973542, 939642, 905762, 871904, 838067, 804252, 770459,
+ 736688, 702940, 669215, 635513, 601834, 568180, 534549, 500944, 467363,
+ 433806, 400276, 366771, 333292, 299839, 266413, 233014, 199643, 166298,
+ 132982, 99693, 66433, 33202, 0, -33173, -66316, -99429, -132513,
+ -165566, -198588, -231579, -264538, -297466, -330362, -363226, -396057,
+ -428855, -461620, -494352, -527050, -559714, -592344, -624940, -657500,
+ -690025, -722515, -754969, -787387, -819769, -852115, -884423, -916694,
+ -948928, -981125, -1013283, -1045403, -1077485, -1109527, -1141531,
+ -1173495, -1205420, -1237305, -1269149, -1300953, -1332717, -1364439,
+ -1396120, -1427760, -1459357, -1490913, -1522426, -1553897, -1585324,
+ -1616709, -1648050, -1679347, -1710601, -1741810, -1772975, -1804095,
+ -1835170, -1866199, -1897183, -1928122, -1959014, -1989860, -2020659,
+ -2051411, -2082117, -2112775, -2143385, -2173948, -2204462, -2234928,
+ -2265345, -2295713, -2326033, -2356303, -2386523, -2416693, -2446813,
+ -2476883, -2506902, -2536870, -2566787, -2596653, -2626467, -2656229,
+ -2685939, -2715597, -2745202, -2774754, -2804253, -2833699, -2863092,
+ -2892430, -2921714, -2950945, -2980120, -3009241, -3038307, -3067318,
+ -3096273, -3125172, -3154016, -3182803, -3211534, -3240209, -3268826,
+ -3297387, -3325890, -3354336, -3382724, -3411054, -3439326, -3467539,
+ -3495694, -3523789, -3551826, -3579804, -3607722, -3635580, -3663378,
+ -3691116, -3718794, -3746411, -3773967, -3801462, -3828896, -3856268,
+ -3883579, -3910828, -3938015, -3965139, -3992201, -4019200, -4046136,
+ -4073009, -4099819, -4126565, -4153248, -4179866, -4206420, -4232910,
+ -4259336, -4285696, -4311992, -4338222, -4364387, -4390487, -4416521,
+ -4442488, -4468390, -4494226, -4519994, -4545696, -4571332, -4596900,
+ -4622401, -4647834, -4673200, -4698497, -4723727, -4748889, -4773982,
+ -4799006, -4823962, -4848849, -4873667, -4898415, -4923094, -4947703,
+ -4972243, -4996712, -5021111, -5045440, -5069698, -5093885, -5118002,
+ -5142047, -5166022, -5189925, -5213756, -5237515, -5261203, -5284818,
+ -5308362, -5331833, -5355231, -5378556, -5401809, -5424989, -5448095,
+ -5471128, -5494087, -5516973, -5539785, -5562523, -5585186, -5607776,
+ -5630291, -5652731, -5675096, -5697387, -5719602, -5741743, -5763807,
+ -5785797, -5807710, -5829548, -5851310, -5872996, -5894605, -5916139,
+ -5937595, -5958975, -5980278, -6001504, -6022653, -6043725, -6064720,
+ -6085636, -6106476, -6127237, -6147921, -6168527, -6189054, -6209503,
+ -6229874, -6250166, -6270380, -6290514, -6310570, -6330547, -6350444,
+ -6370263, -6390002, -6409661, -6429240, -6448740, -6468160, -6487500,
+ -6506760, -6525940, -6545039, -6564057, -6582996, -6601853, -6620630,
+ -6639325, -6657940, -6676473, -6694926, -6713296, -6731586, -6749794,
+ -6767920, -6785964, -6803927, -6821807, -6839606, -6857322, -6874956,
+ -6892508, -6909977, -6927363, -6944667, -6961888, -6979027, -6996082,
+ -7013054, -7029944, -7046750, -7063472, -7080112, -7096667, -7113140,
+ -7129528, -7145833, -7162054, -7178191, -7194244, -7210214, -7226098,
+ -7241899, -7257616, -7273248, -7288795, -7304258, -7319637, -7334931,
+ -7350140, -7365264, -7380303, -7395258, -7410127, -7424911, -7439610,
+ -7454224, -7468752, -7483196, -7497553, -7511826, -7526012, -7540113,
+ -7554129, -7568059, -7581902, -7595660, -7609333, -7622919, -7636419,
+ -7649833, -7663161, -7676403, -7689558, -7702628, -7715611, -7728507,
+ -7741317, -7754041, -7766678, -7779229, -7791693, -7804071, -7816361,
+ -7828565, -7840683, -7852713, -7864657, -7876513, -7888283, -7899966,
+ -7911562, -7923070, -7934492, -7945827, -7957074, -7968235, -7979308,
+ -7990294, -8001193, -8012004, -8022728, -8033365, -8043915, -8054377,
+ -8064751, -8075039, -8085239, -8095351, -8105376, -8115314, -8125164,
+ -8134926, -8144601, -8154188, -8163688, -8173100, -8182425, -8191662,
+ -8200811, -8209873, -8218847, -8227734, -8236533, -8245244, -8253867,
+ -8262403, -8270851, -8279212, -8287485, -8295670, -8303767, -8311777,
+ -8319699, -8327534, -8335281, -8342940, -8350511, -8357995, -8365391,
+ -8372700, -8379921, -8387054, -8394100, -8401058, -8407929, -8414712,
+ -8421407, -8428015, -8434535, -8440968, -8447313, -8453571, -8459742,
+ -8465825, -8471820, -8477728, -8483549, -8489283, -8494929, -8500488,
+ -8505959, -8511343, -8516640, -8521850, -8526973, -8532008, -8536957,
+ -8541818, -8546593, -8551280, -8555880, -8560394, -8564820, -8569160,
+ -8573413, -8577579, -8581658, -8585650, -8589556, -8593375, -8597108,
+ -8600754, -8604313, -8607787, -8611173, -8614474, -8617687, -8620815,
+ -8623857, -8626812, -8629681, -8632464, -8635161, -8637772, -8640297,
+ -8642737, -8645090, -8647358, -8649540, -8651636, -8653647, -8655572,
+ -8657412, -8659167, -8660836, -8662419, -8663918, -8665331, -8666660,
+ -8667903, -8669061, -8670135, -8671123, -8672027, -8672846, -8673581,
+ -8674231, -8674796, -8675277, -8675674, -8675986, -8676215, -8676359,
+ -8676419, -8676395, -8676288, -8676096, -8675821, -8675462, -8675020,
+ -8674494, -8673885, -8673192, -8672416, -8671557, -8670615, -8669590,
+ -8668482, -8667291, -8666018, -8664662, -8663223, -8661702, -8660099,
+ -8658413, -8656645, -8654795, -8652863, -8650849, -8648754, -8646576,
+ -8644317, -8641977, -8639555, -8637052, -8634468, -8631802, -8629056,
+ -8626228, -8623320, -8620331, -8617261, -8614111, -8610881, -8607570,
+ -8604179, -8600708, -8597157, -8593526, -8589816, -8586026, -8582156,
+ -8578207, -8574178, -8570071, -8565884, -8561618, -8557274, -8552851,
+ -8548349, -8543768, -8539109, -8534372, -8529557, -8524664, -8519693,
+ -8514644, -8509517, -8504313, -8499032, -8493673, -8488237, -8482724,
+ -8477134, -8471467, -8465723, -8459903, -8454007, -8448034, -8441985,
+ -8435860, -8429659, -8423383, -8417031, -8410603, -8404100, -8397521,
+ -8390868, -8384139, -8377336, -8370458, -8363505, -8356478, -8349377,
+ -8342202, -8334952, -8327629, -8320232, -8312761, -8305217, -8297600,
+ -8289909, -8282146, -8274309, -8266400, -8258418, -8250364, -8242237,
+ -8234039, -8225768, -8217425, -8209011, -8200525, -8191968, -8183339,
+ -8174640, -8165869, -8157028, -8148116, -8139133, -8130080, -8120957,
+ -8111764, -8102501, -8093168, -8083766, -8074294, -8064753, -8055143,
+ -8045463, -8035716, -8025899, -8016014, -8006061, -7996039, -7985950,
+ -7975793, -7965568, -7955275, -7944916, -7934489, -7923995, -7913434,
+ -7902807, -7892113, -7881352, -7870526, -7859633, -7848675, -7837651,
+ -7826562, -7815407, -7804187, -7792902, -7781552, -7770137, -7758658,
+ -7747115, -7735508, -7723836, -7712101, -7700303, -7688440, -7676515,
+ -7664526, -7652475, -7640361, -7628184, -7615945, -7603644, -7591280,
+ -7578855, -7566368, -7553820, -7541210, -7528539, -7515808, -7503015,
+ -7490162, -7477249, -7464275, -7451241, -7438148, -7424995, -7411782,
+ -7398510, -7385179, -7371789, -7358340, -7344833, -7331267, -7317643,
+ -7303961, -7290222, -7276424, -7262570, -7248658, -7234689, -7220663,
+ -7206581, -7192442, -7178246, -7163995, -7149688, -7135325, -7120906,
+ -7106433, -7091904, -7077320, -7062681, -7047988, -7033241, -7018439,
+ -7003583, -6988674, -6973711, -6958695, -6943625, -6928503, -6913328,
+ -6898100, -6882820, -6867487, -6852103, -6836667, -6821179, -6805640,
+ -6790050, -6774408, -6758716, -6742974, -6727181, -6711337, -6695444,
+ -6679501, -6663509, -6647467, -6631376, -6615236, -6599047, -6582809,
+ -6566524, -6550190, -6533808, -6517379, -6500902, -6484377, -6467806,
+ -6451187, -6434522, -6417811, -6401053, -6384249, -6367399, -6350503,
+ -6333562, -6316576, -6299545, -6282469, -6265348, -6248183, -6230974,
+ -6213721, -6196423, -6179083, -6161699, -6144272, -6126802, -6109289,
+ -6091733, -6074136, -6056496, -6038814, -6021091, -6003326, -5985520,
+ -5967673, -5949786, -5931857, -5913888, -5895879, -5877830, -5859742,
+ -5841614, -5823446, -5805239, -5786994, -5768710, -5750387, -5732026,
+ -5713627, -5695191, -5676717, -5658205, -5639656, -5621070, -5602448,
+ -5583789, -5565094, -5546362, -5527595, -5508792, -5489954, -5471081,
+ -5452172, -5433229, -5414251, -5395239, -5376193, -5357113, -5337999,
+ -5318852, -5299672, -5280458, -5261212, -5241933, -5222622, -5203279,
+ -5183904, -5164497, -5145058, -5125589, -5106088, -5086557, -5066994,
+ -5047402, -5027779, -5008127, -4988445, -4968733, -4948992, -4929222,
+ -4909423, -4889595, -4869740, -4849856, -4829944, -4810004, -4790037,
+ -4770042, -4750021, -4729972, -4709897, -4689796, -4669668, -4649515,
+ -4629336, -4609131, -4588901, -4568646, -4548366, -4528061, -4507732,
+ -4487379, -4467002, -4446602, -4426177, -4405730, -4385259, -4364766,
+ -4344250, -4323711, -4303151, -4282568, -4261964, -4241338, -4220691,
+ -4200023, -4179334, -4158624, -4137895, -4117144, -4096374, -4075585,
+ -4054775, -4033947, -4013099, -3992233, -3971348, -3950444, -3929523,
+ -3908583, -3887626, -3866651, -3845659, -3824650, -3803624, -3782581,
+ -3761523, -3740447, -3719356, -3698250, -3677127, -3655990, -3634837,
+ -3613670, -3592488, -3571291, -3550081, -3528856, -3507618, -3486366,
+ -3465101, -3443823, -3422532, -3401228, -3379912, -3358584, -3337244,
+ -3315892, -3294528, -3273154, -3251768, -3230371, -3208964, -3187546,
+ -3166118, -3144680, -3123233, -3101775, -3080309, -3058833, -3037349,
+ -3015855, -2994354, -2972844, -2951326, -2929800, -2908267, -2886727,
+ -2865179, -2843624, -2822063, -2800495, -2778921, -2757341, -2735755,
+ -2714163, -2692566, -2670964, -2649357, -2627745, -2606128, -2584508,
+ -2562883, -2541254, -2519622, -2497986, -2476347, -2454705, -2433060,
+ -2411412, -2389763, -2368111, -2346457, -2324801, -2303144, -2281485,
+ -2259826, -2238165, -2216504, -2194842, -2173180, -2151518, -2129857,
+ -2108195, -2086535, -2064875, -2043216, -2021558, -1999902, -1978248,
+ -1956595, -1934945, -1913296, -1891651, -1870008, -1848367, -1826731,
+ -1805097, -1783467, -1761841, -1740218, -1718600, -1696986, -1675377,
+ -1653773, -1632173, -1610579, -1588990, -1567407, -1545830, -1524259,
+ -1502694, -1481135, -1459583, -1438038, -1416500, -1394970, -1373446,
+ -1351931, -1330423, -1308924, -1287432, -1265949, -1244475, -1223010,
+ -1201554, -1180107, -1158670, -1137242, -1115824, -1094417, -1073019,
+ -1051632, -1030256, -1008891, -987537, -966194, -944863, -923543,
+ -902235, -880939, -859656, -838385, -817127, -795881, -774649, -753430,
+ -732224, -711032, -689854, -668690, -647540, -626405, -605284, -584178,
+ -563087, -542012, -520951, -499906, -478877, -457864, -436868, -415887,
+ -394923, -373976, -353045, -332132, -311236, -290358, -269497, -248654,
+ -227829, -207023, -186234, -165465, -144714, -123982, -103269, -82576,
+ -61902, -41248, -20614, 0, 20593, 41167, 61720, 82252, 102763, 123253,
+ 143721, 164168, 184594, 204997, 225378, 245737, 266074, 286388, 306680,
+ 326948, 347193, 367415, 387614, 407788, 427939, 448066, 468169, 488247,
+ 508301, 528331, 548335, 568314, 588268, 608197, 628100, 647978, 667829,
+ 687655, 707454, 727227, 746973, 766692, 786385, 806050, 825689, 845300,
+ 864883, 884438, 903966, 923466, 942937, 962380, 981794, 1001180,
+ 1020537, 1039865, 1059163, 1078433, 1097672, 1116882, 1136063, 1155213,
+ 1174333, 1193422, 1212482, 1231510, 1250508, 1269475, 1288411, 1307315,
+ 1326188, 1345030, 1363839, 1382617, 1401363, 1420077, 1438758, 1457407,
+ 1476023, 1494607, 1513157, 1531675, 1550159, 1568610, 1587027, 1605411,
+ 1623761, 1642077, 1660358, 1678606, 1696819, 1714997, 1733141, 1751250,
+ 1769324, 1787363, 1805366, 1823335, 1841267, 1859164, 1877025, 1894850,
+ 1912639, 1930392, 1948108, 1965788, 1983431, 2001037, 2018607, 2036139,
+ 2053634, 2071092, 2088512, 2105895, 2123239, 2140546, 2157815, 2175046,
+ 2192239, 2209393, 2226508, 2243585, 2260623, 2277622, 2294583, 2311504,
+ 2328385, 2345227, 2362030, 2378793, 2395516, 2412199, 2428842, 2445445,
+ 2462007, 2478530, 2495011, 2511452, 2527852, 2544211, 2560529, 2576806,
+ 2593042, 2609236, 2625389, 2641500, 2657569, 2673597, 2689582, 2705526,
+ 2721427, 2737286, 2753102, 2768876, 2784607, 2800296, 2815941, 2831544,
+ 2847103, 2862619, 2878092, 2893521, 2908907, 2924249, 2939548, 2954802,
+ 2970013, 2985179, 3000301, 3015379, 3030413, 3045402, 3060346, 3075246,
+ 3090101, 3104911, 3119676, 3134396, 3149070, 3163700, 3178284, 3192822,
+ 3207315, 3221762, 3236163, 3250519, 3264828, 3279091, 3293308, 3307479,
+ 3321604, 3335682, 3349713, 3363698, 3377636, 3391527, 3405372, 3419169,
+ 3432919, 3446623, 3460278, 3473887, 3487448, 3500961, 3514427, 3527845,
+ 3541216, 3554538, 3567813, 3581039, 3594218, 3607348, 3620430, 3633463,
+ 3646449, 3659385, 3672273, 3685113, 3697903, 3710645, 3723338, 3735982,
+ 3748576, 3761122, 3773619, 3786066, 3798464, 3810812, 3823111, 3835360,
+ 3847560, 3859710, 3871810, 3883861, 3895861, 3907812, 3919712, 3931563,
+ 3943363, 3955113, 3966812, 3978461, 3990060, 4001608, 4013106, 4024553,
+ 4035950, 4047295, 4058590, 4069834, 4081027, 4092169, 4103260, 4114299,
+ 4125288, 4136226, 4147112, 4157946, 4168730, 4179462, 4190142, 4200771,
+ 4211348, 4221874, 4232348, 4242770, 4253140, 4263459, 4273726, 4283940,
+ 4294103, 4304213, 4314272, 4324278, 4334232, 4344134, 4353984, 4363781,
+ 4373526, 4383218, 4392858, 4402446, 4411981, 4421463, 4430893, 4440270,
+ 4449594, 4458866, 4468085, 4477251, 4486364, 4495424, 4504432, 4513386,
+ 4522287, 4531136, 4539931, 4548673, 4557362, 4565998, 4574581, 4583111,
+ 4591587, 4600010, 4608380, 4616696, 4624959, 4633168, 4641324, 4649427,
+ 4657476, 4665472, 4673414, 4681303, 4689138, 4696919, 4704647, 4712322,
+ 4719942, 4727509, 4735022, 4742482, 4749887, 4757239, 4764537, 4771782,
+ 4778972, 4786109, 4793192, 4800221, 4807196, 4814117, 4820985, 4827798,
+ 4834558, 4841263, 4847915, 4854513, 4861056, 4867546, 4873982, 4880364,
+ 4886691, 4892965, 4899185, 4905351, 4911462, 4917520, 4923523, 4929473,
+ 4935368, 4941210, 4946997, 4952730, 4958410, 4964035, 4969606, 4975123,
+ 4980586, 4985995, 4991350, 4996651, 5001897, 5007090, 5012229, 5017313,
+ 5022344, 5027321, 5032243, 5037112, 5041926, 5046687, 5051393, 5056046,
+ 5060644, 5065189, 5069679, 5074116, 5078499, 5082827, 5087102, 5091323,
+ 5095490, 5099604, 5103663, 5107668, 5111620, 5115518, 5119362, 5123152,
+ 5126889, 5130572, 5134201, 5137776, 5141298, 5144766, 5148180, 5151541,
+ 5154848, 5158102, 5161302, 5164448, 5167541, 5170581, 5173567, 5176499,
+ 5179378, 5182204, 5184976, 5187695, 5190361, 5192974, 5195533, 5198039,
+ 5200492, 5202892, 5205238, 5207532, 5209772, 5211959, 5214094, 5216175,
+ 5218204, 5220179, 5222102, 5223972, 5225789, 5227553, 5229265, 5230924,
+ 5232530, 5234084, 5235585, 5237033, 5238430, 5239773, 5241064, 5242303,
+ 5243490, 5244624, 5245706, 5246736, 5247714, 5248639, 5249513, 5250334,
+ 5251104, 5251821, 5252487, 5253101, 5253663, 5254173, 5254632, 5255039,
+ 5255394, 5255698, 5255950, 5256151, 5256300, 5256398, 5256445, 5256441,
+ 5256385, 5256279, 5256121, 5255912, 5255652, 5255341, 5254980, 5254567,
+ 5254104, 5253590, 5253026, 5252411, 5251745, 5251029, 5250263, 5249446,
+ 5248579, 5247661, 5246694, 5245676, 5244609, 5243491, 5242324, 5241106,
+ 5239839, 5238522, 5237156, 5235740, 5234274, 5232759, 5231194, 5229580,
+ 5227917, 5226205, 5224443, 5222633, 5220773, 5218865, 5216908, 5214902,
+ 5212847, 5210743, 5208591, 5206391, 5204142, 5201845, 5199499, 5197105,
+ 5194663, 5192173, 5189635, 5187049, 5184415, 5181734, 5179005, 5176228,
+ 5173403, 5170532, 5167612, 5164646, 5161632, 5158571, 5155463, 5152308,
+ 5149106, 5145858, 5142562, 5139220, 5135831, 5132396, 5128915, 5125387,
+ 5121812, 5118192, 5114526, 5110813, 5107055, 5103250, 5099400, 5095505,
+ 5091563, 5087577, 5083544, 5079467, 5075344, 5071176, 5066963, 5062706,
+ 5058403, 5054055, 5049663, 5045226, 5040745, 5036219, 5031649, 5027034,
+ 5022375, 5017673, 5012926, 5008136, 5003301, 4998423, 4993502, 4988537,
+ 4983528, 4978476, 4973381, 4968243, 4963062, 4957837, 4952570, 4947261,
+ 4941908, 4936513, 4931076, 4925596, 4920074, 4914510, 4908904, 4903255,
+ 4897565, 4891834, 4886060, 4880245, 4874389, 4868491, 4862552, 4856571,
+ 4850550, 4844488, 4838385, 4832241, 4826056, 4819831, 4813566, 4807260,
+ 4800914, 4794528, 4788101, 4781635, 4775129, 4768584, 4761999, 4755374,
+ 4748710, 4742006, 4735264, 4728482, 4721662, 4714802, 4707904, 4700968,
+ 4693992, 4686979, 4679927, 4672837, 4665709, 4658542, 4651338, 4644097,
+ 4636817, 4629500, 4622146, 4614754, 4607325, 4599859, 4592356, 4584817,
+ 4577240, 4569627, 4561978, 4554292, 4546569, 4538811, 4531016, 4523186,
+ 4515320, 4507418, 4499480, 4491507, 4483499, 4475455, 4467376, 4459262,
+ 4451114, 4442930, 4434712, 4426459, 4418172, 4409851, 4401495, 4393106,
+ 4384682, 4376225, 4367733, 4359209, 4350650, 4342059, 4333434, 4324776,
+ 4316085, 4307361, 4298605, 4289816, 4280994, 4272140, 4263254, 4254335,
+ 4245385, 4236402, 4227388, 4218342, 4209265, 4200156, 4191016, 4181845,
+ 4172642, 4163409, 4154145, 4144850, 4135525, 4126170, 4116784, 4107368,
+ 4097922, 4088445, 4078940, 4069404, 4059839, 4050245, 4040621, 4030968,
+ 4021286, 4011575, 4001835, 3992067, 3982270, 3972445, 3962591, 3952710,
+ 3942800, 3932862, 3922897, 3912904, 3902883, 3892835, 3882760, 3872658,
+ 3862528, 3852372, 3842189, 3831980, 3821744, 3811481, 3801193, 3790878,
+ 3780537, 3770171, 3759779, 3749361, 3738918, 3728449, 3717955, 3707436,
+ 3696893, 3686324, 3675731, 3665113, 3654471, 3643805, 3633114, 3622400,
+ 3611661, 3600899, 3590114, 3579304, 3568472, 3557616, 3546737, 3535835,
+ 3524911, 3513963, 3502993, 3492001, 3480986, 3469950, 3458891, 3447810,
+ 3436708, 3425584, 3414438, 3403271, 3392083, 3380874, 3369643, 3358392,
+ 3347121, 3335828, 3324516, 3313183, 3301829, 3290456, 3279063, 3267650,
+ 3256218, 3244766, 3233295, 3221804, 3210294, 3198766, 3187219, 3175652,
+ 3164068, 3152465, 3140843, 3129204, 3117547, 3105871, 3094178, 3082467,
+ 3070739, 3058994, 3047231, 3035451, 3023655, 3011841, 3000011, 2988164,
+ 2976301, 2964422, 2952526, 2940615, 2928687, 2916744, 2904786, 2892812,
+ 2880822, 2868818, 2856798, 2844763, 2832714, 2820650, 2808572, 2796479,
+ 2784372, 2772251, 2760116, 2747967, 2735804, 2723628, 2711438, 2699235,
+ 2687019, 2674790, 2662548, 2650294, 2638026, 2625746, 2613454, 2601150,
+ 2588834, 2576505, 2564165, 2551813, 2539450, 2527075, 2514689, 2502292,
+ 2489884, 2477465, 2465035, 2452595, 2440144, 2427683, 2415212, 2402730,
+ 2390239, 2377738, 2365227, 2352707, 2340177, 2327639, 2315091, 2302534,
+ 2289968, 2277394, 2264811, 2252219, 2239619, 2227011, 2214395, 2201771,
+ 2189140, 2176500, 2163853, 2151199, 2138538, 2125869, 2113194, 2100511,
+ 2087822, 2075126, 2062424, 2049716, 2037001, 2024281, 2011554, 1998822,
+ 1986084, 1973340, 1960591, 1947837, 1935078, 1922314, 1909545, 1896771,
+ 1883993, 1871210, 1858422, 1845631, 1832836, 1820036, 1807233, 1794426,
+ 1781616, 1768802, 1755985, 1743165, 1730341, 1717515, 1704686, 1691855,
+ 1679021, 1666184, 1653346, 1640505, 1627662, 1614818, 1601971, 1589124,
+ 1576274, 1563424, 1550572, 1537719, 1524865, 1512010, 1499155, 1486299,
+ 1473442, 1460586, 1447729, 1434872, 1422015, 1409158, 1396302, 1383446,
+ 1370591, 1357736, 1344882, 1332029, 1319178, 1306327, 1293478, 1280631,
+ 1267784, 1254940, 1242098, 1229257, 1216419, 1203583, 1190749, 1177917,
+ 1165088, 1152262, 1139439, 1126619, 1113802, 1100988, 1088177, 1075370,
+ 1062567, 1049767, 1036971, 1024179, 1011391, 998607, 985827, 973052,
+ 960282, 947516, 934755, 921999, 909248, 896502, 883762, 871027, 858297,
+ 845573, 832855, 820143, 807437, 794737, 782043, 769355, 756674, 744000,
+ 731332, 718672, 706018, 693371, 680732, 668099, 655475, 642857, 630248,
+ 617646, 605052, 592466, 579888, 567319, 554758, 542205, 529661, 517126,
+ 504599, 492082, 479573, 467074, 454584, 442103, 429632, 417171, 404719,
+ 392277, 379845, 367423, 355011, 342610, 330219, 317838, 305469, 293110,
+ 280761, 268424, 256098, 243783, 231479, 219187, 206906, 194637, 182379,
+ 170134, 157900, 145679, 133469, 121272, 109087, 96915, 84755, 72608,
+ 60474, 48353, 36245, 24150, 12068, 0, -12055, -24096, -36124, -48138,
+ -60138, -72124, -84097, -96055, -107998, -119928, -131843, -143743,
+ -155629, -167499, -179355, -191196, -203022, -214833, -226628, -238408,
+ -250173, -261921, -273655, -285372, -297073, -308759, -320428, -332082,
+ -343719, -355339, -366943, -378531, -390102, -401656, -413193, -424713,
+ -436216, -447702, -459171, -470623, -482057, -493473, -504872, -516253,
+ -527616, -538962, -550289, -561599, -572890, -584163, -595417, -606653,
+ -617871, -629069, -640250, -651411, -662553, -673677, -684781, -695866,
+ -706932, -717979, -729006, -740013, -751001, -761969, -772918, -783846,
+ -794755, -805643, -816512, -827360, -838188, -848995, -859782, -870548,
+ -881294, -892019, -902723, -913407, -924069, -934710, -945330, -955929,
+ -966507, -977063, -987597, -998111, -1008602, -1019072, -1029520,
+ -1039946, -1050350, -1060732, -1071092, -1081430, -1091746, -1102039,
+ -1112310, -1122558, -1132784, -1142987, -1153167, -1163325, -1173459,
+ -1183571, -1193660, -1203725, -1213768, -1223787, -1233783, -1243755,
+ -1253704, -1263629, -1273531, -1283409, -1293263, -1303094, -1312900,
+ -1322683, -1332442, -1342176, -1351886, -1361572, -1371234, -1380871,
+ -1390484, -1400072, -1409636, -1419175, -1428690, -1438179, -1447644,
+ -1457083, -1466498, -1475888, -1485252, -1494592, -1503906, -1513194,
+ -1522458, -1531696, -1540908, -1550095, -1559256, -1568392, -1577501,
+ -1586585, -1595643, -1604675, -1613681, -1622661, -1631615, -1640543,
+ -1649444, -1658320, -1667168, -1675991, -1684786, -1693556, -1702298,
+ -1711015, -1719704, -1728367, -1737002, -1745611, -1754193, -1762748,
+ -1771276, -1779777, -1788251, -1796697, -1805116, -1813508, -1821873,
+ -1830210, -1838519, -1846802, -1855056, -1863283, -1871482, -1879654,
+ -1887798, -1895914, -1904002, -1912062, -1920094, -1928098, -1936074,
+ -1944022, -1951942, -1959834, -1967697, -1975532, -1983339, -1991117,
+ -1998867, -2006588, -2014281, -2021945, -2029581, -2037188, -2044766,
+ -2052316, -2059836, -2067328, -2074791, -2082226, -2089631, -2097007,
+ -2104354, -2111672, -2118961, -2126221, -2133451, -2140653, -2147825,
+ -2154968, -2162081, -2169165, -2176220, -2183245, -2190241, -2197207,
+ -2204143, -2211050, -2217927, -2224775, -2231593, -2238381, -2245139,
+ -2251868, -2258567, -2265236, -2271875, -2278484, -2285063, -2291612,
+ -2298131, -2304619, -2311078, -2317507, -2323906, -2330274, -2336612,
+ -2342920, -2349197, -2355445, -2361662, -2367848, -2374005, -2380130,
+ -2386226, -2392291, -2398325, -2404329, -2410303, -2416245, -2422158,
+ -2428039, -2433890, -2439711, -2445500, -2451259, -2456987, -2462685,
+ -2468352, -2473987, -2479593, -2485167, -2490710, -2496223, -2501704,
+ -2507155, -2512575, -2517964, -2523322, -2528648, -2533944, -2539209,
+ -2544443, -2549646, -2554818, -2559958, -2565068, -2570146, -2575193,
+ -2580209, -2585194, -2590148, -2595071, -2599962, -2604822, -2609651,
+ -2614449, -2619215, -2623951, -2628654, -2633327, -2637968, -2642578,
+ -2647157, -2651704, -2656220, -2660705, -2665158, -2669580, -2673971,
+ -2678330, -2682658, -2686954, -2691220, -2695453, -2699655, -2703826,
+ -2707966, -2712073, -2716150, -2720195, -2724209, -2728191, -2732142,
+ -2736061, -2739949, -2743805, -2747630, -2751423, -2755185, -2758916,
+ -2762615, -2766282, -2769918, -2773523, -2777096, -2780638, -2784148,
+ -2787627, -2791074, -2794490, -2797874, -2801227, -2804549, -2807839,
+ -2811097, -2814325, -2817520, -2820684, -2823817, -2826919, -2829989,
+ -2833027, -2836034, -2839010, -2841955, -2844868, -2847749, -2850599,
+ -2853418, -2856206, -2858962, -2861687, -2864380, -2867042, -2869673,
+ -2872273, -2874841, -2877378, -2879884, -2882358, -2884801, -2887213,
+ -2889594, -2891944, -2894262, -2896549, -2898805, -2901030, -2903223,
+ -2905386, -2907517, -2909618, -2911687, -2913725, -2915732, -2917708,
+ -2919653, -2921567, -2923451, -2925303, -2927124, -2928914, -2930673,
+ -2932402, -2934099, -2935766, -2937402, -2939007, -2940581, -2942124,
+ -2943637, -2945119, -2946570, -2947990, -2949380, -2950739, -2952068,
+ -2953366, -2954633, -2955870, -2957076, -2958252, -2959397, -2960511,
+ -2961596, -2962650, -2963673, -2964666, -2965629, -2966561, -2967463,
+ -2968335, -2969177, -2969988, -2970769, -2971520, -2972241, -2972932,
+ -2973593, -2974224, -2974824, -2975395, -2975936, -2976446, -2976927,
+ -2977378, -2977799, -2978191, -2978552, -2978884, -2979186, -2979459,
+ -2979702, -2979915, -2980098, -2980252, -2980377, -2980472, -2980537,
+ -2980574, -2980580, -2980558, -2980506, -2980425, -2980314, -2980175,
+ -2980006, -2979808, -2979581, -2979325, -2979039, -2978725, -2978382,
+ -2978010, -2977609, -2977179, -2976721, -2976234, -2975717, -2975173,
+ -2974599, -2973997, -2973367, -2972708, -2972020, -2971304, -2970560,
+ -2969787, -2968986, -2968156, -2967298, -2966413, -2965499, -2964556,
+ -2963586, -2962588, -2961562, -2960507, -2959425, -2958315, -2957177,
+ -2956012, -2954819, -2953598, -2952349, -2951073, -2949769, -2948438,
+ -2947079, -2945693, -2944280, -2942839, -2941371, -2939875, -2938353,
+ -2936803, -2935227, -2933623, -2931992, -2930335, -2928650, -2926939,
+ -2925201, -2923436, -2921644, -2919826, -2917981, -2916110, -2914212,
+ -2912288, -2910337, -2908360, -2906356, -2904327, -2902271, -2900189,
+ -2898081, -2895947, -2893787, -2891601, -2889390, -2887152, -2884889,
+ -2882599, -2880285, -2877944, -2875578, -2873187, -2870770, -2868328,
+ -2865860, -2863367, -2860849, -2858306, -2855737, -2853144, -2850525,
+ -2847882, -2845214, -2842521, -2839803, -2837060, -2834293, -2831501,
+ -2828684, -2825843, -2822978, -2820088, -2817174, -2814235, -2811273,
+ -2808286, -2805275, -2802240, -2799181, -2796099, -2792992, -2789862,
+ -2786708, -2783530, -2780328, -2777103, -2773855, -2770583, -2767288,
+ -2763969, -2760627, -2757262, -2753874, -2750463, -2747029, -2743572,
+ -2740092, -2736589, -2733063, -2729515, -2725944, -2722350, -2718734,
+ -2715096, -2711435, -2707752, -2704047, -2700319, -2696570, -2692798,
+ -2689004, -2685188, -2681351, -2677492, -2673610, -2669708, -2665783,
+ -2661838, -2657870, -2653881, -2649871, -2645840, -2641787, -2637714,
+ -2633619, -2629503, -2625366, -2621209, -2617030, -2612831, -2608611,
+ -2604371, -2600110, -2595828, -2591526, -2587204, -2582861, -2578499,
+ -2574116, -2569713, -2565290, -2560847, -2556384, -2551902, -2547399,
+ -2542877, -2538336, -2533775, -2529194, -2524594, -2519975, -2515337,
+ -2510679, -2506002, -2501307, -2496592, -2491858, -2487106, -2482335,
+ -2477545, -2472736, -2467909, -2463064, -2458200, -2453318, -2448417,
+ -2443499, -2438562, -2433607, -2428635, -2423644, -2418635, -2413609,
+ -2408565, -2403504, -2398425, -2393328, -2388214, -2383083, -2377934,
+ -2372769, -2367586, -2362386, -2357169, -2351936, -2346685, -2341418,
+ -2336134, -2330834, -2325517, -2320183, -2314833, -2309467, -2304085,
+ -2298686, -2293272, -2287841, -2282395, -2276932, -2271454, -2265960,
+ -2260451, -2254926, -2249385, -2243829, -2238258, -2232671, -2227070,
+ -2221453, -2215821, -2210174, -2204512, -2198836, -2193145, -2187439,
+ -2181718, -2175983, -2170234, -2164470, -2158692, -2152899, -2147093,
+ -2141272, -2135438, -2129589, -2123727, -2117851, -2111961, -2106058,
+ -2100141, -2094211, -2088267, -2082310, -2076340, -2070357, -2064360,
+ -2058351, -2052328, -2046293, -2040245, -2034185, -2028111, -2022026,
+ -2015927, -2009817, -2003694, -1997559, -1991411, -1985252, -1979081,
+ -1972897, -1966702, -1960495, -1954276, -1948046, -1941804, -1935551,
+ -1929286, -1923010, -1916723, -1910425, -1904115, -1897795, -1891464,
+ -1885121, -1878768, -1872405, -1866030, -1859646, -1853250, -1846845,
+ -1840429, -1834002, -1827566, -1821119, -1814663, -1808197, -1801720,
+ -1795234, -1788739, -1782233, -1775719, -1769194, -1762661, -1756118,
+ -1749565, -1743004, -1736434, -1729854, -1723266, -1716669, -1710063,
+ -1703448, -1696825, -1690193, -1683553, -1676904, -1670247, -1663582,
+ -1656909, -1650228, -1643538, -1636841, -1630136, -1623423, -1616703,
+ -1609974, -1603239, -1596496, -1589745, -1582987, -1576222, -1569450,
+ -1562671, -1555885, -1549092, -1542292, -1535485, -1528672, -1521852,
+ -1515025, -1508192, -1501353, -1494507, -1487655, -1480797, -1473933,
+ -1467063, -1460187, -1453306, -1446418, -1439525, -1432626, -1425722,
+ -1418812, -1411897, -1404976, -1398050, -1391119, -1384183, -1377243,
+ -1370297, -1363346, -1356390, -1349430, -1342465, -1335496, -1328522,
+ -1321544, -1314562, -1307575, -1300584, -1293589, -1286590, -1279587,
+ -1272580, -1265570, -1258555, -1251537, -1244516, -1237491, -1230463,
+ -1223431, -1216396, -1209358, -1202317, -1195272, -1188225, -1181175,
+ -1174122, -1167066, -1160008, -1152947, -1145884, -1138818, -1131750,
+ -1124679, -1117606, -1110531, -1103455, -1096376, -1089295, -1082212,
+ -1075128, -1068042, -1060954, -1053864, -1046774, -1039681, -1032588,
+ -1025493, -1018397, -1011300, -1004202, -997103, -990003, -982902,
+ -975801, -968698, -961596, -954492, -947389, -940284, -933180, -926075,
+ -918970, -911865, -904760, -897655, -890550, -883446, -876341, -869237,
+ -862134, -855031, -847928, -840826, -833725, -826624, -819524, -812426,
+ -805328, -798231, -791135, -784041, -776947, -769856, -762765, -755676,
+ -748588, -741502, -734418, -727336, -720255, -713176, -706099, -699024,
+ -691952, -684881, -677813, -670746, -663683, -656621, -649563, -642506,
+ -635453, -628402, -621354, -614308, -607266, -600227, -593190, -586157,
+ -579127, -572100, -565076, -558056, -551040, -544026, -537017, -530011,
+ -523008, -516010, -509015, -502024, -495038, -488055, -481076, -474102,
+ -467132, -460166, -453204, -446247, -439294, -432346, -425403, -418464,
+ -411530, -404600, -397676, -390757, -383842, -376933, -370029, -363130,
+ -356236, -349347, -342464, -335587, -328715, -321848, -314987, -308132,
+ -301283, -294439, -287601, -280770, -273944, -267124, -260310, -253503,
+ -246702, -239907, -233119, -226337, -219561, -212792, -206030, -199274,
+ -192525, -185783, -179048, -172319, -165598, -158884, -152176, -145476,
+ -138783, -132098, -125419, -118748, -112085, -105429, -98781, -92140,
+ -85507, -78881, -72263, -65654, -59052, -52458, -45872, -39294, -32724,
+ -26163, -19609, -13064, -6528, 0, 6519, 13031, 19533, 26027, 32513,
+ 38989, 45457, 51916, 58366, 64808, 71240, 77663, 84077, 90482, 96877,
+ 103264, 109641, 116008, 122367, 128715, 135054, 141384, 147704, 154014,
+ 160315, 166606, 172886, 179157, 185419, 191670, 197911, 204141, 210362,
+ 216573, 222773, 228963, 235143, 241312, 247471, 253619, 259757, 265884,
+ 272001, 278107, 284202, 290286, 296360, 302422, 308474, 314515, 320544,
+ 326563, 332571, 338567, 344552, 350526, 356489, 362440, 368380, 374308,
+ 380225, 386131, 392024, 397907, 403777, 409636, 415483, 421318, 427142,
+ 432954, 438753, 444541, 450317, 456080, 461832, 467571, 473298, 479013,
+ 484716, 490406, 496084, 501750, 507403, 513044, 518672, 524288, 529891,
+ 535481, 541059, 546624, 552176, 557715, 563242, 568756, 574257, 579744,
+ 585219, 590681, 596130, 601565, 606988, 612397, 617793, 623176, 628545,
+ 633902, 639244, 644574, 649890, 655192, 660481, 665756, 671018, 676266,
+ 681501, 686721, 691928, 697122, 702301, 707467, 712618, 717756, 722880,
+ 727990, 733086, 738168, 743236, 748289, 753329, 758354, 763365, 768362,
+ 773345, 778313, 783267, 788207, 793132, 798043, 802939, 807821, 812688,
+ 817541, 822379, 827202, 832011, 836806, 841585, 846350, 851100, 855835,
+ 860555, 865261, 869952, 874627, 879288, 883934, 888565, 893181, 897782,
+ 902368, 906938, 911494, 916034, 920559, 925069, 929564, 934044, 938508,
+ 942957, 947391, 951809, 956212, 960599, 964971, 969328, 973669, 977995,
+ 982305, 986599, 990878, 995142, 999389, 1003622, 1007838, 1012039,
+ 1016224, 1020393, 1024547, 1028685, 1032807, 1036913, 1041003, 1045078,
+ 1049136, 1053179, 1057206, 1061217, 1065212, 1069191, 1073154, 1077101,
+ 1081032, 1084947, 1088845, 1092728, 1096595, 1100445, 1104279, 1108098,
+ 1111900, 1115685, 1119455, 1123208, 1126945, 1130666, 1134371, 1138059,
+ 1141731, 1145387, 1149026, 1152649, 1156255, 1159845, 1163419, 1166977,
+ 1170517, 1174042, 1177550, 1181041, 1184516, 1187975, 1191417, 1194842,
+ 1198251, 1201644, 1205020, 1208379, 1211721, 1215047, 1218357, 1221650,
+ 1224926, 1228185, 1231428, 1234654, 1237864, 1241057, 1244233, 1247392,
+ 1250535, 1253661, 1256770, 1259862, 1262938, 1265997, 1269039, 1272064,
+ 1275073, 1278064, 1281039, 1283997, 1286938, 1289863, 1292770, 1295661,
+ 1298535, 1301392, 1304232, 1307055, 1309862, 1312651, 1315424, 1318179,
+ 1320918, 1323640, 1326345, 1329033, 1331704, 1334358, 1336995, 1339616,
+ 1342219, 1344805, 1347375, 1349927, 1352463, 1354981, 1357483, 1359968,
+ 1362435, 1364886, 1367320, 1369736, 1372136, 1374519, 1376884, 1379233,
+ 1381565, 1383880, 1386178, 1388459, 1390722, 1392969, 1395199, 1397412,
+ 1399608, 1401787, 1403949, 1406094, 1408222, 1410333, 1412427, 1414504,
+ 1416564, 1418607, 1420633, 1422642, 1424634, 1426609, 1428567, 1430508,
+ 1432433, 1434340, 1436230, 1438104, 1439960, 1441800, 1443622, 1445428,
+ 1447217, 1448988, 1450743, 1452481, 1454202, 1455906, 1457593, 1459264,
+ 1460917, 1462554, 1464173, 1465776, 1467362, 1468931, 1470483, 1472019,
+ 1473537, 1475039, 1476524, 1477992, 1479443, 1480878, 1482295, 1483696,
+ 1485080, 1486448, 1487798, 1489132, 1490449, 1491750, 1493033, 1494300,
+ 1495551, 1496784, 1498001, 1499201, 1500385, 1501552, 1502702, 1503836,
+ 1504953, 1506053, 1507137, 1508204, 1509255, 1510289, 1511306, 1512307,
+ 1513292, 1514260, 1515211, 1516146, 1517065, 1517967, 1518852, 1519721,
+ 1520574, 1521411, 1522230, 1523034, 1523821, 1524592, 1525347, 1526085,
+ 1526807, 1527512, 1528202, 1528875, 1529531, 1530172, 1530796, 1531405,
+ 1531997, 1532572, 1533132, 1533676, 1534203, 1534714, 1535209, 1535689,
+ 1536152, 1536599, 1537030, 1537445, 1537844, 1538227, 1538594, 1538945,
+ 1539281, 1539600, 1539904, 1540191, 1540463, 1540719, 1540959, 1541184,
+ 1541393, 1541586, 1541763, 1541924, 1542070, 1542200, 1542315, 1542414,
+ 1542497, 1542565, 1542617, 1542654, 1542675, 1542681, 1542671, 1542646,
+ 1542605, 1542549, 1542477, 1542390, 1542288, 1542171, 1542038, 1541890,
+ 1541726, 1541548, 1541354, 1541145, 1540921, 1540682, 1540427, 1540158,
+ 1539873, 1539574, 1539259, 1538929, 1538585, 1538225, 1537851, 1537461,
+ 1537057, 1536638, 1536204, 1535755, 1535292, 1534814, 1534321, 1533813,
+ 1533291, 1532754, 1532202, 1531636, 1531055, 1530460, 1529850, 1529225,
+ 1528587, 1527933, 1527266, 1526584, 1525887, 1525177, 1524451, 1523712,
+ 1522959, 1522191, 1521409, 1520613, 1519802, 1518978, 1518139, 1517287,
+ 1516420, 1515540, 1514645, 1513737, 1512814, 1511878, 1510928, 1509964,
+ 1508986, 1507995, 1506989, 1505970, 1504938, 1503891, 1502831, 1501758,
+ 1500671, 1499570, 1498456, 1497328, 1496187, 1495033, 1493865, 1492684,
+ 1491490, 1490282, 1489061, 1487827, 1486579, 1485319, 1484045, 1482758,
+ 1481458, 1480145, 1478819, 1477480, 1476129, 1474764, 1473386, 1471996,
+ 1470593, 1469177, 1467748, 1466306, 1464852, 1463385, 1461906, 1460414,
+ 1458909, 1457392, 1455862, 1454320, 1452766, 1451199, 1449620, 1448028,
+ 1446425, 1444809, 1443180, 1441540, 1439887, 1438223, 1436546, 1434857,
+ 1433156, 1431443, 1429719, 1427982, 1426233, 1424473, 1422701, 1420917,
+ 1419121, 1417314, 1415495, 1413664, 1411822, 1409968, 1408103, 1406226,
+ 1404338, 1402438, 1400527, 1398604, 1396671, 1394726, 1392770, 1390802,
+ 1388823, 1386834, 1384833, 1382821, 1380798, 1378764, 1376719, 1374664,
+ 1372597, 1370520, 1368431, 1366332, 1364223, 1362102, 1359971, 1357829,
+ 1355677, 1353514, 1351341, 1349157, 1346963, 1344758, 1342544, 1340318,
+ 1338083, 1335837, 1333581, 1331315, 1329038, 1326752, 1324456, 1322149,
+ 1319833, 1317506, 1315170, 1312824, 1310468, 1308102, 1305727, 1303342,
+ 1300947, 1298542, 1296128, 1293704, 1291271, 1288829, 1286377, 1283915,
+ 1281444, 1278964, 1276475, 1273976, 1271468, 1268951, 1266425, 1263889,
+ 1261345, 1258792, 1256229, 1253658, 1251078, 1248489, 1245891, 1243284,
+ 1240669, 1238045, 1235412, 1232771, 1230121, 1227463, 1224796, 1222121,
+ 1219437, 1216745, 1214044, 1211335, 1208618, 1205893, 1203159, 1200418,
+ 1197668, 1194910, 1192145, 1189371, 1186589, 1183800, 1181002, 1178197,
+ 1175384, 1172563, 1169735, 1166898, 1164055, 1161203, 1158344, 1155478,
+ 1152604, 1149723, 1146834, 1143938, 1141035, 1138125, 1135207, 1132282,
+ 1129350, 1126411, 1123465, 1120511, 1117551, 1114584, 1111610, 1108629,
+ 1105642, 1102647, 1099646, 1096639, 1093624, 1090603, 1087576, 1084541,
+ 1081501, 1078454, 1075400, 1072341, 1069274, 1066202, 1063123, 1060039,
+ 1056948, 1053851, 1050747, 1047638, 1044523, 1041402, 1038275, 1035142,
+ 1032003, 1028859, 1025708, 1022552, 1019391, 1016224, 1013051, 1009872,
+ 1006689, 1003499, 1000304, 997104, 993899, 990688, 987472, 984251,
+ 981025, 977793, 974556, 971315, 968068, 964816, 961560, 958299, 955032,
+ 951761, 948485, 945205, 941920, 938630, 935335, 932036, 928733, 925425,
+ 922112, 918795, 915474, 912148, 908819, 905485, 902146, 898804, 895458,
+ 892107, 888752, 885394, 882031, 878665, 875295, 871921, 868543, 865161,
+ 861776, 858387, 854994, 851598, 848198, 844795, 841388, 837978, 834565,
+ 831148, 827728, 824304, 820878, 817448, 814015, 810579, 807140, 803698,
+ 800253, 796805, 793354, 789900, 786444, 782984, 779522, 776058, 772590,
+ 769120, 765648, 762172, 758695, 755215, 751732, 748247, 744760, 741271,
+ 737779, 734285, 730789, 727290, 723790, 720287, 716783, 713276, 709768,
+ 706258, 702746, 699232, 695716, 692198, 688679, 685158, 681636, 678111,
+ 674586, 671059, 667530, 664000, 660468, 656936, 653401, 649866, 646329,
+ 642791, 639252, 635712, 632171, 628629, 625085, 621541, 617996, 614450,
+ 610903, 607355, 603807, 600257, 596707, 593157, 589605, 586054, 582501,
+ 578948, 575395, 571841, 568287, 564732, 561177, 557622, 554067, 550511,
+ 546955, 543399, 539843, 536287, 532731, 529175, 525618, 522062, 518507,
+ 514951, 511395, 507840, 504285, 500730, 497176, 493622, 490068, 486515,
+ 482962, 479410, 475859, 472308, 468757, 465208, 461659, 458110, 454563,
+ 451016, 447470, 443926, 440382, 436839, 433296, 429755, 426216, 422677,
+ 419139, 415602, 412067, 408533, 405000, 401469, 397938, 394410, 390882,
+ 387356, 383832, 380309, 376787, 373268, 369749, 366233, 362718, 359205,
+ 355693, 352184, 348676, 345170, 341666, 338164, 334664, 331166, 327670,
+ 324176, 320684, 317194, 313706, 310221, 306738, 303257, 299778, 296302,
+ 292828, 289356, 285887, 282420, 278956, 275494, 272035, 268578, 265124,
+ 261673, 258224, 254779, 251335, 247895, 244457, 241023, 237591, 234162,
+ 230736, 227313, 223893, 220476, 217062, 213651, 210243, 206839, 203437,
+ 200039, 196644, 193252, 189864, 186479, 183097, 179719, 176344, 172973,
+ 169605, 166241, 162880, 159522, 156169, 152819, 149473, 146130, 142791,
+ 139456, 136125, 132797, 129473, 126153, 122838, 119526, 116218, 112913,
+ 109613, 106317, 103026, 99738, 96454, 93174, 89899, 86628, 83361,
+ 80098, 76840, 73586, 70336, 67091, 63850, 60614, 57382, 54154, 50931,
+ 47713, 44499, 41290, 38085, 34885, 31690, 28499, 25313, 22132, 18956,
+ 15784, 12618, 9456, 6299, 3147, 0, -3142, -6279, -9411, -12538, -15660,
+ -18777, -21889, -24996, -28098, -31194, -34285, -37371, -40452, -43527,
+ -46598, -49662, -52722, -55776, -58825, -61868, -64906, -67938, -70965,
+ -73986, -77002, -80012, -83017, -86016, -89009, -91997, -94979, -97955,
+ -100926, -103891, -106850, -109803, -112751, -115692, -118628, -121558,
+ -124482, -127400, -130312, -133219, -136119, -139013, -141901, -144783,
+ -147659, -150529, -153393, -156251, -159102, -161948, -164787, -167620,
+ -170447, -173267, -176081, -178889, -181691, -184486, -187275, -190058,
+ -192834, -195604, -198367, -201124, -203874, -206618, -209355, -212086,
+ -214811, -217528, -220240, -222944, -225642, -228333, -231018, -233696,
+ -236368, -239032, -241690, -244341, -246986, -249623, -252254, -254878,
+ -257495, -260106, -262709, -265306, -267895, -270478, -273054, -275623,
+ -278185, -280740, -283288, -285829, -288363, -290890, -293410, -295922,
+ -298428, -300927, -303418, -305903, -308380, -310850, -313313, -315768,
+ -318217, -320658, -323092, -325519, -327939, -330351, -332756, -335153,
+ -337544, -339927, -342302, -344671, -347032, -349385, -351731, -354070,
+ -356401, -358725, -361041, -363350, -365652, -367946, -370232, -372511,
+ -374783, -377047, -379303, -381552, -383793, -386027, -388253, -390471,
+ -392682, -394885, -397081, -399268, -401449, -403621, -405786, -407943,
+ -410093, -412234, -414368, -416495, -418613, -420724, -422827, -424922,
+ -427010, -429089, -431161, -433225, -435281, -437330, -439370, -441403,
+ -443427, -445444, -447453, -449454, -451448, -453433, -455410, -457380,
+ -459342, -461295, -463241, -465179, -467108, -469030, -470944, -472850,
+ -474747, -476637, -478519, -480393, -482259, -484116, -485966, -487808,
+ -489641, -491467, -493284, -495094, -496895, -498689, -500474, -502251,
+ -504020, -505781, -507533, -509278, -511015, -512743, -514463, -516175,
+ -517879, -519575, -521263, -522943, -524614, -526277, -527932, -529579,
+ -531218, -532848, -534471, -536085, -537691, -539288, -540878, -542459,
+ -544032, -545597, -547154, -548702, -550243, -551775, -553298, -554814,
+ -556321, -557820, -559311, -560794, -562268, -563734, -565192, -566641,
+ -568083, -569516, -570941, -572357, -573766, -575166, -576557, -577941,
+ -579316, -580683, -582042, -583392, -584734, -586068, -587394, -588711,
+ -590020, -591321, -592613, -593898, -595174, -596441, -597701, -598952,
+ -600195, -601429, -602655, -603873, -605083, -606285, -607478, -608663,
+ -609839, -611008, -612168, -613320, -614463, -615599, -616726, -617844,
+ -618955, -620057, -621151, -622237, -623314, -624384, -625445, -626497,
+ -627542, -628578, -629606, -630626, -631637, -632641, -633636, -634623,
+ -635601, -636572, -637534, -638488, -639434, -640371, -641301, -642222,
+ -643135, -644039, -644936, -645824, -646705, -647577, -648440, -649296,
+ -650144, -650983, -651814, -652637, -653452, -654259, -655057, -655848,
+ -656630, -657404, -658171, -658929, -659678, -660420, -661154, -661880,
+ -662597, -663307, -664008, -664701, -665386, -666064, -666733, -667394,
+ -668047, -668692, -669329, -669958, -670579, -671192, -671797, -672394,
+ -672983, -673564, -674137, -674702, -675259, -675808, -676349, -676883,
+ -677408, -677926, -678435, -678937, -679430, -679916, -680394, -680864,
+ -681327, -681781, -682228, -682666, -683097, -683520, -683935, -684343,
+ -684742, -685134, -685518, -685895, -686263, -686624, -686977, -687322,
+ -687660, -687990, -688312, -688626, -688933, -689232, -689523, -689807,
+ -690083, -690352, -690613, -690866, -691111, -691349, -691580, -691803,
+ -692018, -692226, -692426, -692619, -692804, -692981, -693151, -693314,
+ -693469, -693617, -693757, -693890, -694015, -694133, -694243, -694346,
+ -694442, -694530, -694611, -694685, -694751, -694810, -694861, -694906,
+ -694942, -694972, -694994, -695010, -695017, -695018, -695011, -694997,
+ -694976, -694948, -694913, -694870, -694820, -694764, -694700, -694628,
+ -694550, -694465, -694373, -694273, -694167, -694053, -693932, -693805,
+ -693670, -693529, -693380, -693225, -693062, -692893, -692717, -692533,
+ -692343, -692146, -691943, -691732, -691515, -691290, -691059, -690821,
+ -690577, -690325, -690067, -689802, -689530, -689252, -688967, -688675,
+ -688377, -688072, -687760, -687442, -687117, -686785, -686447, -686103,
+ -685752, -685394, -685030, -684659, -684282, -683898, -683508, -683111,
+ -682708, -682299, -681883, -681461, -681033, -680598, -680157, -679709,
+ -679255, -678795, -678329, -677856, -677377, -676892, -676401, -675904,
+ -675400, -674890, -674374, -673852, -673324, -672790, -672250, -671703,
+ -671151, -670592, -670028, -669457, -668881, -668299, -667710, -667116,
+ -666516, -665910, -665298, -664680, -664057, -663427, -662792, -662151,
+ -661504, -660851, -660193, -659529, -658859, -658184, -657503, -656816,
+ -656124, -655426, -654722, -654013, -653298, -652578, -651852, -651120,
+ -650383, -649641, -648893, -648140, -647381, -646617, -645848, -645073,
+ -644293, -643507, -642716, -641920, -641118, -640312, -639500, -638682,
+ -637860, -637032, -636200, -635362, -634519, -633670, -632817, -631959,
+ -631095, -630226, -629353, -628474, -627591, -626702, -625809, -624910,
+ -624007, -623099, -622185, -621267, -620344, -619417, -618484, -617547,
+ -616605, -615658, -614706, -613750, -612789, -611823, -610853, -609878,
+ -608899, -607914, -606926, -605932, -604934, -603932, -602925, -601913,
+ -600898, -599877, -598852, -597823, -596790, -595752, -594709, -593663,
+ -592612, -591556, -590497, -589433, -588365, -587293, -586216, -585135,
+ -584050, -582961, -581868, -580771, -579670, -578564, -577455, -576341,
+ -575224, -574102, -572977, -571848, -570714, -569577, -568436, -567291,
+ -566142, -564989, -563833, -562672, -561508, -560340, -559169, -557993,
+ -556814, -555631, -554445, -553255, -552061, -550864, -549663, -548459,
+ -547251, -546039, -544824, -543606, -542384, -541158, -539930, -538697,
+ -537462, -536223, -534980, -533735, -532486, -531234, -529978, -528719,
+ -527457, -526192, -524924, -523652, -522377, -521099, -519818, -518534,
+ -517247, -515957, -514664, -513367, -512068, -510766, -509461, -508153,
+ -506842, -505528, -504211, -502891, -501569, -500243, -498915, -497584,
+ -496251, -494914, -493575, -492233, -490889, -489542, -488192, -486839,
+ -485484, -484127, -482766, -481404, -480038, -478671, -477300, -475928,
+ -474553, -473175, -471795, -470413, -469028, -467641, -466251, -464860,
+ -463466, -462069, -460671, -459270, -457867, -456462, -455055, -453645,
+ -452234, -450820, -449404, -447986, -446566, -445144, -443720, -442294,
+ -440866, -439436, -438004, -436570, -435135, -433697, -432258, -430816,
+ -429373, -427928, -426482, -425033, -423583, -422131, -420677, -419222,
+ -417765, -416306, -414846, -413384, -411921, -410456, -408989, -407521,
+ -406051, -404580, -403107, -401633, -400158, -398681, -397203, -395723,
+ -394242, -392759, -391275, -389790, -388304, -386816, -385327, -383837,
+ -382346, -380853, -379360, -377865, -376369, -374872, -373373, -371874,
+ -370374, -368872, -367370, -365866, -364362, -362856, -361350, -359843,
+ -358334, -356825, -355315, -353804, -352293, -350780, -349267, -347753,
+ -346238, -344722, -343206, -341689, -340171, -338652, -337133, -335614,
+ -334093, -332572, -331051, -329528, -328006, -326483, -324959, -323435,
+ -321910, -320385, -318859, -317333, -315806, -314280, -312752, -311225,
+ -309697, -308169, -306640, -305111, -303582, -302053, -300523, -298993,
+ -297463, -295933, -294403, -292872, -291342, -289811, -288280, -286749,
+ -285218, -283688, -282157, -280625, -279094, -277564, -276033, -274502,
+ -272971, -271440, -269910, -268379, -266849, -265319, -263789, -262259,
+ -260729, -259200, -257671, -256142, -254614, -253085, -251557, -250030,
+ -248503, -246976, -245449, -243923, -242397, -240872, -239347, -237823,
+ -236299, -234776, -233253, -231730, -230208, -228687, -227166, -225646,
+ -224127, -222608, -221090, -219572, -218055, -216539, -215023, -213508,
+ -211994, -210481, -208968, -207456, -205945, -204435, -202926, -201417,
+ -199910, -198403, -196897, -195392, -193888, -192384, -190882, -189381,
+ -187880, -186381, -184883, -183385, -181889, -180394, -178900, -177407,
+ -175915, -174424, -172934, -171445, -169958, -168472, -166986, -165503,
+ -164020, -162538, -161058, -159579, -158101, -156625, -155150, -153676,
+ -152203, -150732, -149262, -147794, -146327, -144861, -143397, -141934,
+ -140473, -139013, -137554, -136097, -134642, -133188, -131735, -130284,
+ -128835, -127387, -125940, -124496, -123053, -121611, -120171, -118733,
+ -117296, -115861, -114428, -112997, -111567, -110138, -108712, -107287,
+ -105864, -104443, -103024, -101606, -100190, -98776, -97364, -95954,
+ -94545, -93139, -91734, -90331, -88930, -87531, -86134, -84739, -83346,
+ -81955, -80565, -79178, -77793, -76410, -75028, -73649, -72272, -70897,
+ -69524, -68153, -66784, -65417, -64053, -62690, -61330, -59971, -58615,
+ -57261, -55910, -54560, -53213, -51868, -50525, -49184, -47846, -46510,
+ -45176, -43844, -42515, -41188, -39863, -38541, -37221, -35903, -34588,
+ -33275, -31964, -30656, -29350, -28047, -26746, -25447, -24151, -22857,
+ -21566, -20277, -18991, -17707, -16426, -15147, -13870, -12597, -11325,
+ -10057, -8790, -7527, -6266, -5007, -3752, -2498, -1248, 0
+};
diff --git a/kernel/framework/audio/grc3code.inc b/kernel/framework/audio/grc3code.inc
new file mode 100644
index 0000000..a44d037
--- /dev/null
+++ b/kernel/framework/audio/grc3code.inc
@@ -0,0 +1,384 @@
+/*
+ * Purpose: Low level macros for GRC3
+ *
+ * GRC library version 3.1
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+__inline__ signed short
+clamp16 (int sample)
+{
+ if (sample > 32767)
+ return 32767;
+ else if (sample < -32768)
+ return -32768;
+ else
+ return sample;
+}
+
+__inline__ signed char
+clamp8 (int sample)
+{
+ if (sample > 127)
+ return 127;
+ else if (sample < -128)
+ return -128;
+ else
+ return sample;
+}
+
+
+#define IN8(a) ((a^0x80)<<15)
+#define OUT8(d,a) d=((clamp8(a>>15))^0x80)
+
+#define IN16(a) (a<<7)
+#define OUT16(d,a) d=clamp16(a>>7)
+
+#define INv16(a) (_swap16(a)<<7)
+#define OUTv16(d,a) d=_swap16(clamp16(a>>7))
+
+#define IN32(a) (a)
+#define OUT32(d,a) d=(a)
+
+#define INv32(a) _swap32(a)
+#define OUTv32(d,a) d=_swap32(a)
+
+#define DOCLAMP(a) (a) /* do not clip overflows */
+
+#undef QSUFFIX
+
+/***********************************************************************/
+
+#ifdef GRC3_COMPILE_L
+
+#define QSUFFIX(a) a##L
+
+#if 0
+#define SUFFIX(a) a##L
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+#endif
+
+#define SUFFIX(a) a##L8_8
+#define TYPEIN uint8_t
+#define TYPEOUT uint8_t
+#define IN IN8
+#define OUT OUT8
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##L16_16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##Lv16_v16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN INv16
+#define OUT OUTv16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##L32_32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN IN32
+#define OUT OUT32
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##Lv32_v32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN INv32
+#define OUT OUTv32
+#include "grc3inc.inc"
+
+#undef QSUFFIX
+
+#endif
+
+/***********************************************************************/
+
+#ifdef GRC3_COMPILE_M
+
+#define QSUFFIX(a) a##M
+
+#if 0
+#define SUFFIX(a) a##M
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+#endif
+
+#define SUFFIX(a) a##M8_8
+#define TYPEIN uint8_t
+#define TYPEOUT uint8_t
+#define IN IN8
+#define OUT OUT8
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##M16_16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##Mv16_v16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN INv16
+#define OUT OUTv16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##M32_32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN IN32
+#define OUT OUT32
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##Mv32_v32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN INv32
+#define OUT OUTv32
+#include "grc3inc.inc"
+
+#undef QSUFFIX
+
+#endif
+
+/***********************************************************************/
+
+#ifdef GRC3_COMPILE_H
+
+#define QSUFFIX(a) a##H
+
+#if 0
+#define SUFFIX(a) a##H
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+#endif
+
+#define SUFFIX(a) a##H8_8
+#define TYPEIN uint8_t
+#define TYPEOUT uint8_t
+#define IN IN8
+#define OUT OUT8
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##H16_16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##Hv16_v16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN INv16
+#define OUT OUTv16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##H32_32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN IN32
+#define OUT OUT32
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##Hv32_v32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN INv32
+#define OUT OUTv32
+#include "grc3inc.inc"
+
+#undef QSUFFIX
+
+#endif
+
+/***********************************************************************/
+
+#ifdef GRC3_COMPILE_H
+
+#define QSUFFIX(a) a##HX
+
+#if 0
+#define SUFFIX(a) a##HX
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+#endif
+
+#define SUFFIX(a) a##HX8_8
+#define TYPEIN uint8_t
+#define TYPEOUT uint8_t
+#define IN IN8
+#define OUT OUT8
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##HX16_16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##HXv16_v16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN INv16
+#define OUT OUTv16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##HX32_32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN IN32
+#define OUT OUT32
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##HXv32_v32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN INv32
+#define OUT OUTv32
+#include "grc3inc.inc"
+
+#undef QSUFFIX
+
+#endif
+
+/***********************************************************************/
+
+#ifdef GRC3_COMPILE_P
+
+#define QSUFFIX(a) a##P
+
+#if 0
+#define SUFFIX(a) a##P
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+#endif
+
+#define SUFFIX(a) a##P8_8
+#define TYPEIN uint8_t
+#define TYPEOUT uint8_t
+#define IN IN8
+#define OUT OUT8
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##P16_16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##Pv16_v16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN INv16
+#define OUT OUTv16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##P32_32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN IN32
+#define OUT OUT32
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##Pv32_v32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN INv32
+#define OUT OUTv32
+#include "grc3inc.inc"
+
+#undef QSUFFIX
+
+#endif
+
+/***********************************************************************/
+
+#ifdef GRC3_COMPILE_P
+
+#define QSUFFIX(a) a##PX
+
+#if 0
+#define SUFFIX(a) a##PX
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+#endif
+
+#define SUFFIX(a) a##PX8_8
+#define TYPEIN uint8_t
+#define TYPEOUT uint8_t
+#define IN IN8
+#define OUT OUT8
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##PX16_16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN IN16
+#define OUT OUT16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##PXv16_v16
+#define TYPEIN int16_t
+#define TYPEOUT int16_t
+#define IN INv16
+#define OUT OUTv16
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##PX32_32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN IN32
+#define OUT OUT32
+#include "grc3inc.inc"
+
+#define SUFFIX(a) a##PXv32_v32
+#define TYPEIN int32_t
+#define TYPEOUT int32_t
+#define IN INv32
+#define OUT OUTv32
+#include "grc3inc.inc"
+
+#undef QSUFFIX
+
+#endif
+
+/***********************************************************************/
diff --git a/kernel/framework/audio/grc3inc.inc b/kernel/framework/audio/grc3inc.inc
new file mode 100644
index 0000000..98c9205
--- /dev/null
+++ b/kernel/framework/audio/grc3inc.inc
@@ -0,0 +1,165 @@
+/*
+ * Purpose: Resampling routines for GRC3
+ *
+ * GRC library version 3.1
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+static __inline__ int32_t SUFFIX (grc3_upsample_) (grc3state_t * grc,
+ TYPEIN * src,
+ TYPEOUT * dst, uint32_t sz,
+ uint32_t bufsz,
+ int32_t inc,
+ int32_t offset)
+{
+ GRCvreg uint32_t ptr = grc->ptr;
+ uint32_t srcrate = grc->srcrate;
+ uint32_t dstrate = grc->dstrate;
+ GRCvreg int32_t *history = grc->historyptr;
+ uint32_t filtfactor = grc->filtfactor;
+ uint32_t dstsz = 0;
+
+ grc->insz = sz;
+
+ src += offset;
+ dst += offset;
+
+ while (sz > 0)
+ {
+ while (ptr < dstrate)
+ {
+ if (dstsz >= bufsz)
+ goto endloop;
+ OUT (dst[0],
+ DOCLAMP (QSUFFIX (_conv31_)
+ (history, _grc_sat6 (ptr, filtfactor))));
+ ptr += srcrate;
+#ifndef INCOUT
+ dst += inc;
+#else
+ INCOUT
+#endif
+ dstsz++;
+ }
+
+ history++;
+ if (history >= (grc->history + GRC3_MAXHISTORY * 2))
+ history -= GRC3_MAXHISTORY;
+
+ history[0] = history[-GRC3_MAXHISTORY] = IN (((*src)));
+
+ ptr -= dstrate;
+
+ sz--;
+#ifndef INCIN
+ src += inc;
+#else
+ INCIN
+#endif
+ }
+endloop:
+
+ grc->ptr = ptr;
+ grc->historyptr = history;
+ grc->outsz = dstsz;
+ grc->insz -= sz;
+
+ return (int32_t) dstsz;
+}
+
+__inline__ int32_t SUFFIX (grc3_dnsample_) (grc3state_t * grc, TYPEIN * src,
+ TYPEOUT * dst, uint32_t sz,
+ uint32_t bufsz, int32_t inc,
+ int32_t offset)
+{
+ GRCvreg uint32_t ptr = grc->ptr;
+ uint32_t srcrate = grc->srcrate;
+ uint32_t dstrate = grc->dstrate;
+ uint32_t sat = grc->sat;
+ GRCvreg int32_t *history = grc->historyptr;
+ uint32_t filtfactor = grc->filtfactor;
+ uint32_t dstsz = 0;
+
+ grc->insz = sz;
+
+ src += offset;
+ dst += offset;
+
+ while (sz > 0)
+ {
+ while (ptr >= srcrate)
+ {
+ if (dstsz >= bufsz)
+ goto endloop;
+ ptr -= srcrate;
+ OUT (dst[0],
+ DOCLAMP (QSUFFIX (_conv31d_)
+ (history, _grc_sat6 (ptr, filtfactor),
+ grc->ptr_incv)));
+#ifndef INCOUT
+ dst += inc;
+#else
+ INCOUT
+#endif
+ dstsz++;
+ }
+
+ history++;
+ if (history >= (grc->history + GRC3_MAXHISTORY * 2))
+ history -= GRC3_MAXHISTORY;
+
+ /* TODO: for better quality multiplier is worth moving to output cascade */
+ history[0] = history[-GRC3_MAXHISTORY] =
+ _grc_sat31 (IN (((*src))), sat);
+
+ ptr += dstrate;
+
+ sz--;
+#ifndef INCIN
+ src += inc;
+#else
+ INCIN
+#endif
+ }
+endloop:
+
+ grc->ptr = ptr;
+ grc->historyptr = history;
+ grc->outsz = dstsz;
+ grc->insz -= sz;
+
+ return (int32_t) dstsz;
+}
+
+static __inline__ int32_t SUFFIX (grc3_resample_) (grc3state_t * grc,
+ void *src, void *dst,
+ uint32_t sz,
+ uint32_t bufsz,
+ int32_t inc,
+ int32_t offset)
+{
+ if (grc->srcrate <= grc->dstrate)
+ return SUFFIX (grc3_upsample_) (grc, (TYPEIN *) src, (TYPEOUT *) dst, sz,
+ bufsz, inc, offset);
+ else
+ return SUFFIX (grc3_dnsample_) (grc, (TYPEIN *) src, (TYPEOUT *) dst, sz,
+ bufsz, inc, offset);
+}
+
+#undef TYPEIN
+#undef TYPEOUT
+#undef INCIN
+#undef INCOUT
+#undef SUFFIX
+#undef IN
+#undef OUT
diff --git a/kernel/framework/audio/oss_audio_core.c b/kernel/framework/audio/oss_audio_core.c
new file mode 100644
index 0000000..4eeba4a
--- /dev/null
+++ b/kernel/framework/audio/oss_audio_core.c
@@ -0,0 +1,6639 @@
+/*
+ * Purpose: Audio core functionality of OSS
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#undef NO_COOKED_MODE
+#define AUDIO_C
+
+#define GRC 3
+
+/* Some debugging macros (for future use) */
+#define UP_STATUS(x)
+#define DOWN_STATUS(x)
+
+#include <oss_config.h>
+
+extern int src_quality;
+extern int vmix_disabled;
+extern int excl_policy;
+
+oss_mutex_t audio_global_mutex;
+
+/*
+ * Resizeable audio device tables
+ */
+static oss_memblk_t *audio_global_memblk=NULL;
+int oss_max_audio_devfiles=4;
+int oss_max_audio_engines=8;
+#define AUDIO_MALLOC(osdev, size) oss_memblk_malloc(&audio_global_memblk, size)
+#define AUDIO_FREE(osdev, addr) oss_memblk_free(&audio_global_memblk, addr)
+#define AUDIO_ENGINE_INCREMENT (oss_max_audio_engines/2)
+#define AUDIO_DEVFILE_INCREMENT (oss_max_audio_devfiles/2)
+
+/*
+ * List of audio devices in the system
+ */
+adev_t **audio_engines = NULL;
+int num_audio_engines = 0;
+
+adev_t **audio_devfiles = NULL;
+int num_audio_devfiles = 0;
+extern int flat_device_model;
+
+#if 0
+/*
+ * Device lists (input, output, duplex) for /dev/dsp.
+ */
+
+oss_devlist_t dspinlist = { 0 };
+oss_devlist_t dspoutlist = { 0 };
+oss_devlist_t dspinoutlist = { 0 };
+oss_devlist_t dspoutlist2 = { 0 }; /* 2nd priority output devices */
+#endif
+
+/*
+ * Applications known to require special handling (mmap, etc.). These
+ * applications are listed here because they use the OSS API incorrectly and
+ * some workarounds by OSS are required to make them to work.
+ */
+typedef struct
+{
+ char *name;
+ int open_flags;
+} oss_specialapp_t;
+
+oss_specialapp_t special_apps[] = {
+ {"quake", OF_MMAP},
+ {"quake2", OF_MMAP},
+ {"q3demo.x86", OF_MMAP},
+ {"wolfsp.x86", OF_MMAP},
+ {"wolfmp.x86", OF_MMAP},
+ {"quake3", OF_MMAP},
+ {"wolf3d", OF_MMAP},
+ {"rtcw", OF_MMAP},
+ {"artsd", OF_BLOCK | OF_NOCONV},
+ {"realplay.bin", OF_SMALLFRAGS},
+ {"hxplay.bin", OF_SMALLFRAGS},
+#if 1
+ {"auserver", OF_NOCONV}, /* Win4lin */
+#endif
+ {"quake3.x86", OF_MMAP},
+ {"wolf.x86", OF_MMAP},
+ {"et.x86", OF_MMAP},
+ {"doom.x86", OF_MMAP},
+ // {"mozilla-bin", OF_MEDIUMBUF}, /* For the flash plugin */
+ {NULL, 0}
+};
+
+#ifdef APPLIST_SUPPORT
+/*
+ * Lookup tables for applications. Use these lists to assign
+ * fixed target devices for given applications.
+ */
+
+app_routing_t oss_applist[APPLIST_SIZE];
+int oss_applist_size = 0;
+
+static int
+app_lookup (int mode, const char *appname, int *open_flags)
+{
+ int i, dev;
+
+ if (appname == NULL)
+ return -2;
+
+ for (i = 0; i < oss_applist_size; i++)
+ {
+ if (oss_applist[i].mode == mode)
+ if (strncmp (appname, oss_applist[i].name, 32) == 0)
+ {
+ dev = oss_applist[i].dev;
+
+ if (dev < -1 || dev >= num_audio_devfiles)
+ return -1;
+ *open_flags |= oss_applist[i].open_flags;
+ return dev;
+ }
+ }
+
+ return -2;
+}
+#endif
+
+/*ARGSUSED*/
+static int
+get_open_flags (int mode, int open_flags, struct fileinfo *file)
+{
+ char *name;
+ int i;
+
+ if ((name = GET_PROCESS_NAME (file)) != NULL)
+ {
+#ifdef APPLIST_SUPPORT
+ if (app_lookup (mode, name, &open_flags) >= -1)
+ return open_flags;
+#endif
+
+ for (i = 0; special_apps[i].name != NULL; i++)
+ if (strcmp (special_apps[i].name, name) == 0)
+ {
+ open_flags |= special_apps[i].open_flags;
+ return open_flags;
+ }
+ }
+
+ return open_flags;
+}
+
+#define BIGWRITE_SIZE 1024
+
+#define NEUTRAL8 0x80
+#define NEUTRAL16 0x00
+#define OSS_PLUGIN_VERSION (0x100|oss_sample_bits)
+
+int always_cooked = 0;
+static unsigned long sync_seed = 0;
+
+#define COOKED_BLOCK_SIZE 4096
+
+extern oss_uint64_t oss_tmp_timer;
+
+/*
+ * Structure used by oss_audio_register_client()
+ */
+typedef struct
+{
+ oss_audio_startup_func func;
+ void *devc;
+ oss_device_t *osdev;
+} audio_startup_t;
+
+#define MAX_STARTUPS 5
+static audio_startup_t audio_startups[MAX_STARTUPS];
+static int num_audio_startups = 0;
+
+int
+dmap_get_qlen (dmap_p dmap)
+{
+ int len;
+
+ if (dmap->dma_mode == PCM_ENABLE_OUTPUT)
+ {
+ if (dmap->fragment_size == 0)
+ {
+ cmn_err (CE_WARN, "dmap (out) fragment_size=0, dev=%s\n",
+ dmap->adev->name);
+ return 0;
+ }
+
+ len =
+ (int) ((dmap->user_counter -
+ dmap->byte_counter) / dmap->fragment_size);
+ if (len < 0)
+ len = 0;
+ return len;
+ }
+
+ if (dmap->dma_mode == PCM_ENABLE_INPUT)
+ {
+ if (dmap->fragment_size == 0)
+ {
+ cmn_err (CE_WARN, "dmap (in) fragment_size=0, dev=%s\n",
+ dmap->adev->name);
+ return 0;
+ }
+
+ len =
+ (int) ((dmap->byte_counter -
+ dmap->user_counter) / dmap->fragment_size);
+ if (len < 0)
+ len = 0;
+ return len;
+ }
+
+ return 0;
+}
+
+int
+dmap_get_qhead (dmap_p dmap)
+{
+ unsigned int ptr;
+
+ if (dmap->fragment_size == 0)
+ return 0;
+
+ if (dmap->dma_mode == PCM_ENABLE_OUTPUT)
+ {
+ ptr = (int) (dmap->byte_counter % dmap->bytes_in_use);
+ return ptr / dmap->fragment_size;
+ }
+
+ if (dmap->dma_mode == PCM_ENABLE_INPUT)
+ {
+ ptr = (int) (dmap->user_counter % dmap->bytes_in_use);
+ return ptr / dmap->fragment_size;
+ }
+
+ return 0;
+}
+
+int
+dmap_get_qtail (dmap_p dmap)
+{
+ unsigned int ptr;
+
+ if (dmap->fragment_size == 0)
+ return 0;
+
+ if (dmap->dma_mode == PCM_ENABLE_INPUT)
+ {
+ ptr = (int) (dmap->byte_counter % dmap->bytes_in_use);
+ return ptr / dmap->fragment_size;
+ }
+
+ if (dmap->dma_mode == PCM_ENABLE_OUTPUT)
+ {
+ ptr = (int) (dmap->user_counter % dmap->bytes_in_use);
+ return ptr / dmap->fragment_size;
+ }
+
+ return 0;
+}
+
+int
+oss_audio_set_format (int dev, int fmt, int format_mask)
+{
+ adev_p adev;
+ int ret, newfmt;
+ unsigned char neutral_byte;
+ audio_format_info_p fmt_info;
+
+ sync_seed++;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ adev = audio_engines[dev];
+ if (!adev->enabled)
+ return OSS_ENXIO;
+
+ if (fmt == 0)
+ return adev->user_parms.fmt;
+
+ if (fmt == AFMT_AC3)
+ {
+ /*
+ * AC3 cannot tolerate any format/rate conversions so disable them.
+ */
+ adev->cooked_enable = 0;
+
+ /*
+ * Report EIO error if the application tries to do something stupid.
+ * Otherwise buggy applications may produce loud helicopter sound.
+ */
+
+ if (adev->flags & ADEV_VMIX)
+ {
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1018,
+ "AFMT_AC3 used with virtual mixing device."),
+ 0);
+ /*
+ * Errordesc:
+ * Devices that support virtual or hardware mixing are
+ * probably not capable to play AC3 streams properly.
+ *
+ * Virtual mixing is enabled on the audio device. The virtual
+ * mixer driver will do voolume control that corrupts the AC3
+ * bitstream. Applications using AC3 should
+ * open the audio device with O_EXCL to make sure that virtual
+ * mixing is properly bypassed.
+ */
+ return OSS_EIO;
+ }
+
+ if (adev->flags & ADEV_HWMIX)
+ {
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1019,
+ "AFMT_AC3 used with hardware mixing device."),
+ 0);
+ /*
+ * Errordesc:
+ * Devices that support virtual or hardware mixing are
+ * probably not capable to play AC3 streams properly.
+ *
+ * This error may be caused by user who selected a wrong audio
+ * device.
+ */
+ return OSS_EIO;
+ }
+
+ if (adev->dmask & DMASK_OUT)
+ if (adev->dmap_out->flags & DMAP_COOKED)
+ {
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1020,
+ "AFMT_AC3 used with format conversions enabled."),
+ 0);
+ /*
+ * Errordesc:
+ * AC3 audio format (AFMT_AC3) bitstreams don't tolerate any
+ * kind of sample rate or format conversions. However it looks
+ * like conversions would be needed. The reason may be that the
+ * application had earlier requested some sample rate that is
+ * not supported by the device.
+ *
+ * Applications using AC3 should call SNDCTL_DSP_COOKEDMODE to
+ * disable format conversions.
+ */
+ return OSS_EIO;
+ }
+ }
+
+ ret = adev->d->adrv_set_format (dev, fmt);
+
+ adev->user_parms.fmt = ret;
+ adev->hw_parms.fmt = ret;
+
+ if ((fmt_info = oss_find_format (ret)) == NULL)
+ neutral_byte = 0;
+ else
+ {
+ neutral_byte = fmt_info->neutral_byte;
+ }
+
+ if (adev->dmask & DMASK_OUT)
+ adev->dmap_out->neutral_byte = neutral_byte;
+ if (adev->dmask & DMASK_IN)
+ adev->dmap_in->neutral_byte = neutral_byte;
+
+ /* Disable format conversions if mmap() */
+ if ((adev->dmap_out->mapping_flags & DMA_MAP_MAPPED) ||
+ (adev->dmap_in->mapping_flags & DMA_MAP_MAPPED) ||
+ (adev->open_flags & OF_MMAP))
+ return ret;
+
+#ifdef NO_COOKED_MODE
+ return ret;
+#else
+
+ if (ret == fmt)
+ return ret;
+
+ if (!adev->cooked_enable)
+ return ret;
+
+/*
+ * We need to perform format conversions because the device
+ * doesn't support the requested format.
+ */
+
+ /* Convertable format? */
+ if (!(fmt & CONVERTABLE_FORMATS))
+ {
+ return ret;
+ }
+
+ adev->user_parms.fmt = fmt;
+ if (adev->dmask & DMASK_OUT)
+ {
+ adev->dmap_out->flags |= DMAP_COOKED;
+ }
+
+ if (adev->dmask & DMASK_IN)
+ {
+ adev->dmap_in->flags |= DMAP_COOKED;
+ }
+
+ /* If the device is in 16 bit format then just return */
+ if (ret & (AFMT_S16_LE | AFMT_S16_BE))
+ return fmt;
+
+ /* Try to find a suitable format */
+
+ if (fmt == AFMT_MU_LAW && ret == AFMT_U8) /* mu-Law <-> 8 bit linear */
+ return fmt;
+
+ if (format_mask & AFMT_S16_LE)
+ {
+ newfmt = AFMT_S16_LE;
+ goto got_it;
+ }
+
+ if (format_mask & AFMT_S16_BE)
+ {
+ newfmt = AFMT_S16_BE;
+ goto got_it;
+ }
+
+ return fmt; /* Nothing better than the one suggested by the device */
+got_it:
+
+ ret = adev->d->adrv_set_format (dev, newfmt);
+
+ adev->hw_parms.fmt = ret;
+
+ return fmt;
+#endif
+}
+
+int
+oss_audio_set_channels (int dev, int ch)
+{
+ adev_p adev;
+ int ret;
+
+ sync_seed++;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ adev = audio_engines[dev];
+ if (!adev->enabled)
+ return OSS_ENXIO;
+
+ if (ch == 0)
+ return adev->user_parms.channels;
+
+ ret = adev->d->adrv_set_channels (dev, ch);
+
+ if (ret < 1)
+ {
+ cmn_err (CE_WARN,
+ "Audio engine %d: Internal error in channel setup, err=%d, ch=%d\n",
+ dev, ret, ch);
+ return OSS_EIO;
+ }
+
+ if (ch > 2 && ch > ret) /* Requested multi channel mode not possible */
+ ch = ret;
+
+ adev->user_parms.channels = ret;
+ adev->hw_parms.channels = ret;
+
+ /* Disable format conversions if mmap() */
+ if ((adev->dmap_out->mapping_flags & DMA_MAP_MAPPED) ||
+ (adev->dmap_in->mapping_flags & DMA_MAP_MAPPED) ||
+ (adev->open_flags & OF_MMAP))
+ return ret;
+
+ if (ret > 1 && (adev->flags & ADEV_NONINTERLEAVED))
+ {
+ if (adev->dmask & DMASK_OUT)
+ adev->dmap_out->flags |= DMAP_COOKED;
+
+ if (adev->dmask & DMASK_IN)
+ adev->dmap_in->flags |= DMAP_COOKED;
+ }
+
+
+#ifdef NO_COOKED_MODE
+ return ret;
+#else
+
+ if (!adev->cooked_enable)
+ return ret;
+
+ if (ret == ch)
+ return ret;
+
+ /* For the time being only stereo <->mono is possible */
+ if (ch != ret)
+ if (!((ch == 1 && ret == 2) || (ch == 2 && ret == 1)))
+ return ret;
+
+/*
+ * Needs to perform format conversions
+ */
+
+ adev->user_parms.channels = ch;
+ if (adev->dmask & DMASK_OUT)
+ {
+ adev->dmap_out->flags |= DMAP_COOKED;
+ }
+
+ if (adev->dmask & DMASK_IN)
+ {
+ adev->dmap_in->flags |= DMAP_COOKED;
+ }
+
+ return ch;
+#endif
+}
+
+int
+oss_audio_set_rate (int dev, int rate)
+{
+ adev_p adev;
+ int ret;
+
+ sync_seed++;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ adev = audio_engines[dev];
+ if (!adev->enabled)
+ return OSS_ENXIO;
+
+ if (rate == 0)
+ return adev->user_parms.rate;
+
+ ret = adev->d->adrv_set_rate (dev, rate);
+ if (ret < 0)
+ return ret;
+
+ adev->user_parms.rate = ret;
+ adev->hw_parms.rate = ret;
+
+ /* Disable format conversions if mmap() */
+ if ((adev->dmap_out->mapping_flags & DMA_MAP_MAPPED) ||
+ (adev->dmap_in->mapping_flags & DMA_MAP_MAPPED) ||
+ (adev->flags & ADEV_NOSRC) || (adev->open_flags & OF_MMAP))
+ return ret;
+
+ if (!adev->cooked_enable)
+ return ret;
+
+#if defined(NO_COOKED_MODE) || GRC == 0
+ return ret;
+#else
+
+ if (ret == rate) /* No SRC needed */
+ return ret;
+
+/*
+ * Needs to perform format conversions
+ */
+
+ adev->user_parms.rate = rate;
+ if (adev->dmask & DMASK_OUT)
+ {
+ adev->dmap_out->flags |= DMAP_COOKED;
+ }
+
+ if (adev->dmask & DMASK_IN)
+ {
+ adev->dmap_in->flags |= DMAP_COOKED;
+ }
+
+ return rate;
+#endif
+}
+
+static void
+reset_dmap (dmap_p dmap)
+{
+#ifdef DO_TIMINGS
+ oss_do_timing ("Reset dmap");
+#endif
+ dmap->dma_mode = 0;
+ dmap->flags &= (DMAP_FRAGFIXED | DMAP_COOKED);
+ dmap->byte_counter = dmap->user_counter = 0;
+ dmap->fragment_counter = 0;
+ dmap->interrupt_count = 0;
+ dmap->expand_factor = UNIT_EXPAND; /* 1:1 */
+ dmap->play_underruns = dmap->rec_overruns = 0;
+ dmap->num_errors = 0;
+ dmap->leftover_bytes = 0;
+ dmap->leftover_buf = NULL;
+}
+
+int
+oss_alloc_dmabuf (int dev, dmap_p dmap, int direction)
+{
+ adev_t *adev = dmap->adev;
+
+ if (adev == NULL)
+ {
+ cmn_err (CE_WARN, "oss_alloc_dmabuf: adev==NULL\n");
+ return OSS_EIO;
+ }
+
+ return __oss_alloc_dmabuf (dev, dmap, adev->dmabuf_alloc_flags,
+ adev->dmabuf_maxaddr, direction);
+}
+
+static int
+default_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ int err;
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+ if ((err = oss_alloc_dmabuf (dev, dmap, direction)) < 0)
+ return err;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+default_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ if (dmap->dmabuf == NULL)
+ return 0;
+
+ oss_free_dmabuf (dev, dmap);
+
+ dmap->dmabuf = NULL;
+ dmap->dmabuf_phys = 0;
+ return 0;
+}
+
+static int
+init_dmap (adev_p adev, dmap_p dmap, int direction)
+{
+ int retval;
+ int l, static_len;
+ char *p;
+ oss_native_word flags;
+
+ if (dmap->osdev == NULL)
+ {
+ cmn_err (CE_WARN, "dmap->osdev==NULL\n");
+ return OSS_EIO;
+ }
+
+ if (dmap->dmabuf == NULL)
+ {
+ if (adev->d->adrv_alloc_buffer != NULL)
+ {
+ retval =
+ adev->d->adrv_alloc_buffer (adev->engine_num, dmap, direction);
+ }
+ else
+ {
+ retval = default_alloc_buffer (adev->engine_num, dmap, direction);
+ }
+ if (retval < 0)
+ {
+ cmn_err (CE_WARN,
+ "Failed to allocate DMA buffer for audio engine %d/%s\n",
+ adev->engine_num, adev->name);
+ return retval;
+ }
+
+ if (dmap->dmabuf_phys == 0) /* Cannot do mmap */
+ adev->flags |= ADEV_NOMMAP;
+ }
+
+#ifdef linux
+ if (dmap->dmabuf_phys == 0)
+ adev->flags |= ADEV_NOMMAP;
+#endif
+ dmap->flags &= ~DMAP_FRAGFIXED;
+
+ l = sizeof (dmap_t);
+ static_len = (oss_native_word) & dmap->flags - (oss_native_word) dmap;
+
+ p = (char *) &dmap->flags;
+ l -= static_len;
+ if (p != NULL)
+ memset (p, 0, l); /* Clear all */
+
+ if (!dmap->buffer_protected && dmap->dmabuf != NULL)
+ memset (dmap->dmabuf, dmap->neutral_byte, dmap->buffsize);
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ reset_dmap (dmap);
+ dmap->bytes_in_use = dmap->buffsize;
+ dmap->frame_size = 1;
+ dmap->user_frame_size = 1;
+ dmap->flags = 0;
+ dmap->audio_callback = NULL;
+
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ return 0;
+}
+
+void
+audio_reset_adev (adev_p adev)
+{
+ oss_native_word flags, dflags;
+#ifdef DO_TIMINGS
+ oss_do_timing ("Reset input & output\n");
+#endif
+ sync_seed++;
+ if (!adev->enabled)
+ return;
+
+ dflags = 0;
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ adev->go = 1;
+ adev->enable_bits = adev->open_mode;
+ if (adev->open_mode & OPEN_WRITE)
+ {
+ dmap_p dmap = adev->dmap_out;
+ dmap->flags &= ~DMAP_PREPARED;
+ memset (dmap->dmabuf, 0, dmap->buffsize);
+ }
+
+ if (adev->d->adrv_halt_input && adev->d->adrv_halt_output)
+ {
+ if (adev->open_mode & OPEN_READ)
+ {
+ dmap_p dmap = adev->dmap_in;
+ MUTEX_ENTER (dmap->mutex, dflags);
+ dmap->flags &= ~DMAP_PREPARED;
+ if ((dmap->dma_mode == PCM_ENABLE_INPUT)
+ && (dmap->flags & DMAP_STARTED))
+ {
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_RESET_INPUT);
+#endif
+ MUTEX_EXIT (dmap->mutex, dflags);
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+ adev->d->adrv_halt_input (adev->engine_num);
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ MUTEX_ENTER (dmap->mutex, dflags);
+ reset_dmap (dmap);
+ }
+ MUTEX_EXIT (dmap->mutex, dflags);
+ }
+ if (adev->open_mode & OPEN_WRITE)
+ {
+ dmap_p dmap = adev->dmap_out;
+ MUTEX_ENTER (dmap->mutex, dflags);
+ if ((dmap->dma_mode == PCM_ENABLE_OUTPUT) &&
+ (dmap->flags & DMAP_STARTED))
+ {
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_RESET_OUTPUT);
+#endif
+ MUTEX_EXIT (dmap->mutex, dflags);
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+ adev->d->adrv_halt_output (adev->engine_num);
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ MUTEX_ENTER (dmap->mutex, dflags);
+ reset_dmap (dmap);
+ }
+ MUTEX_EXIT (dmap->mutex, dflags);
+ }
+
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+ return;
+ }
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_RESET_OUTPUT);
+ ossd_event (adev->engine_num, OSSD_EV_RESET_INPUT);
+#endif
+ adev->d->adrv_halt_io (adev->engine_num);
+
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ reset_dmap (adev->dmap_out);
+ reset_dmap (adev->dmap_in);
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+}
+
+static void
+audio_reset_input (adev_p adev)
+{
+ dmap_p dmap = adev->dmap_in;
+ oss_native_word flags, dflags;
+
+ dflags = 0;
+ if (!(adev->open_mode & OPEN_READ))
+ return;
+
+ if (dmap->dma_mode != PCM_ENABLE_INPUT)
+ return;
+
+ if (!(dmap->flags & DMAP_STARTED))
+ return;
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Reset input\n");
+#endif
+ dmap->flags &= ~DMAP_PREPARED;
+
+ if (adev->d->adrv_halt_input)
+ {
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_RESET_INPUT);
+#endif
+ adev->d->adrv_halt_input (adev->engine_num);
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ reset_dmap (dmap);
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return;
+ }
+
+ adev->d->adrv_halt_io (adev->engine_num);
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ MUTEX_ENTER (dmap->mutex, dflags);
+ reset_dmap (dmap);
+ MUTEX_EXIT (dmap->mutex, dflags);
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+}
+
+static void
+audio_reset_output (adev_p adev)
+{
+ dmap_p dmap = adev->dmap_out;
+ oss_native_word flags, dflags;
+ dflags = 0;
+
+ sync_seed++;
+
+ if (!(adev->open_mode & OPEN_WRITE))
+ return;
+
+ if (dmap->dma_mode != PCM_ENABLE_OUTPUT)
+ return;
+
+ if (!(dmap->flags & DMAP_STARTED))
+ return;
+
+ dmap->flags &= ~DMAP_PREPARED;
+#ifdef DO_TIMINGS
+ oss_do_timing ("Reset output\n");
+#endif
+
+ if (adev->d->adrv_halt_output)
+ {
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_RESET_OUTPUT);
+#endif
+ adev->d->adrv_halt_output (adev->engine_num);
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ reset_dmap (dmap);
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return;
+ }
+
+ adev->d->adrv_halt_io (adev->engine_num);
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ MUTEX_ENTER (dmap->mutex, dflags);
+ reset_dmap (dmap);
+ MUTEX_EXIT (dmap->mutex, dflags);
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+}
+
+static int launch_output (adev_p adev, dmap_p dmap);
+static int launch_input (adev_p adev, dmap_p dmap);
+
+static void
+oss_audio_post (adev_p adev)
+{
+ int i, n, p;
+ oss_uint64_t limit;
+ dmap_p dmap = adev->dmap_out;
+
+ if (!(adev->open_mode & OPEN_WRITE))
+ return;
+ if (dmap->user_counter == 0)
+ return;
+
+ if (dmap->flags & DMAP_STARTED)
+ return;
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Post output\n");
+#endif
+
+ /* Clean the unused buffer space (in slow way) */
+ limit = dmap->byte_counter + dmap->bytes_in_use;
+ if (limit > dmap->user_counter + dmap->bytes_in_use)
+ limit = dmap->user_counter + dmap->bytes_in_use;
+ n = (int) (limit - dmap->user_counter) + 1;
+ p = (int) (dmap->user_counter % dmap->bytes_in_use); /* Current ptr */
+ for (i = 0; i < n; i++)
+ {
+ dmap->dmabuf[p] = dmap->neutral_byte;
+ p = (p + 1) % dmap->bytes_in_use;
+ }
+
+ launch_output (adev, dmap);
+}
+
+static void
+oss_audio_sync (adev_p adev)
+{
+ dmap_p dmap = adev->dmap_out;
+ oss_uint64_t uc, limit;
+ oss_native_word flags;
+ unsigned int status;
+
+ int n = 0, loops = 0, tmout = OSS_HZ, i;
+ int prev_underruns;
+
+ if (dmap->dma_mode != PCM_ENABLE_OUTPUT)
+ return;
+ if (adev->dmap_out->mapping_flags & DMA_MAP_MAPPED)
+ return;
+
+ if (!(dmap->flags & DMAP_STARTED))
+ oss_audio_post (adev);
+
+ if (!(dmap->flags & DMAP_STARTED))
+ return;
+
+ /* Don't wait if output is untriggered */
+ if (adev->go == 0 || !(adev->enable_bits & PCM_ENABLE_OUTPUT))
+ return;
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Sync output\n");
+#endif
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ dmap->flags |= DMAP_POST;
+
+ uc = dmap->user_counter;
+ prev_underruns = dmap->play_underruns;
+ dmap->play_underruns = 0;
+
+ while (dmap->play_underruns == 0 && loops++ < dmap->nfrags
+ && dmap->byte_counter < uc)
+ {
+ int p;
+ adev->dmap_out->error = 0;
+ /* Clean the unused buffer space (in a slow but precise way) */
+ limit = dmap->byte_counter + dmap->bytes_in_use;
+ if (limit > dmap->user_counter + dmap->bytes_in_use)
+ limit = dmap->user_counter + dmap->bytes_in_use;
+
+ p = (int) (dmap->user_counter % dmap->bytes_in_use); /* Current ptr */
+ n = (int) (limit - dmap->user_counter) + 1;
+ for (i = 0; i < n; i++)
+ {
+ dmap->dmabuf[p] = dmap->neutral_byte;
+ p = (p + 1) % dmap->bytes_in_use;
+ }
+
+ tmout = (dmap->fragment_size * OSS_HZ) / dmap->data_rate;
+ tmout += OSS_HZ / 10;
+
+ if (!oss_sleep (adev->out_wq, &dmap->mutex, tmout, &flags, &status))
+ {
+#ifndef __FreeBSD__
+ cmn_err (CE_WARN, "Output timed out (sync) on audio engine %d\n",
+ adev->engine_num);
+#endif
+ adev->timeout_count++;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ FMA_EREPORT(adev->osdev, DDI_FM_DEVICE_STALL, NULL, NULL, NULL);
+ FMA_IMPACT(adev->osdev, DDI_SERVICE_LOST);
+ return;
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ n = 0;
+ if (adev->d->adrv_local_qlen) /* Drain the internal queue too */
+ while (n++ <=
+ adev->d->adrv_local_qlen (adev->engine_num) / dmap->fragment_size)
+ {
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ audio_engines[adev->engine_num]->dmap_out->error = 0;
+ tmout = (dmap->fragment_size * OSS_HZ) / dmap->data_rate;
+ tmout += OSS_HZ / 10;
+ oss_sleep (adev->out_wq, &dmap->mutex, tmout, &flags, &status);
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ }
+ dmap->play_underruns = prev_underruns;
+}
+
+static int prepare_output (adev_p adev, dmap_p dmap);
+static int prepare_input (adev_p adev, dmap_p dmap);
+
+void
+oss_audio_set_error (int dev, int mode, int err, int parm)
+{
+ int i, n;
+
+ dmap_t *dmap;
+
+#ifdef DO_TIMINGS
+ {
+ if (mode == E_REC)
+ oss_timing_printf ("Audio rec error code %05d/%d, engine=%d", err, parm,
+ mode);
+ else
+ oss_timing_printf ("Audio play error code %05d/%d, engine=%d", err, parm,
+ mode);
+ }
+#endif
+
+#if 0
+ if (mode == E_REC)
+ cmn_err (CE_CONT, "Audio rec error code %05d/%d, engine=%d\n", err, parm,
+ mode);
+ else
+ cmn_err (CE_CONT, "Audio play error code %05d/%d, engine=%d\n", err, parm,
+ mode);
+#endif
+
+ switch (mode)
+ {
+ case E_PLAY:
+ dmap = audio_engines[dev]->dmap_out;
+ break;
+ case E_REC:
+ dmap = audio_engines[dev]->dmap_in;
+ break;
+
+ default:
+ dmap = audio_engines[dev]->dmap_out; /* Actually this would be an error */
+ }
+
+ n = dmap->num_errors++;
+ if (n > MAX_AUDIO_ERRORS)
+ n = MAX_AUDIO_ERRORS;
+
+ if (n > 0)
+ {
+
+/*
+ * Move previous errors (if any) upwards in the list.
+ */
+ for (i = n; i > 0; i--)
+ {
+ dmap->errors[i] = dmap->errors[i - 1];
+ dmap->error_parms[i] = dmap->error_parms[i - 1];
+ }
+ }
+
+ dmap->errors[0] = err;
+ dmap->error_parms[0] = parm;
+
+}
+
+/*ARGSUSED*/
+static void
+report_errors (char *s, const char *hdr, adev_t * adev, dmap_t * dmap,
+ int bufsize)
+{
+ int i, l, j;
+
+ if (bufsize < 30) /* No space left */
+ return;
+
+ strcpy (s, hdr);
+ s += l = strlen (s);
+ bufsize -= l;
+
+ for (i = 0; i < dmap->num_errors && i < MAX_AUDIO_ERRORS; i++)
+ {
+ int dupe = 0;
+
+ if (bufsize < 30)
+ return;
+ for (j = 0; !dupe && j < i; j++)
+ if (dmap->errors[i] == dmap->errors[j])
+ dupe = 1;
+
+ if (dupe)
+ continue;
+
+ sprintf (s, " %05d:%d", dmap->errors[i], dmap->error_parms[i]);
+ s += l = strlen (s);
+ bufsize -= l;
+ }
+}
+
+static void
+store_history (int dev)
+{
+ int p;
+ char *tmp, *s;
+
+ adev_p adev = audio_engines[dev];
+
+ if (adev->pid == 0) /* Virtual mixer */
+ return;
+
+ if (*adev->cmd && strcmp (adev->cmd, "sndconf") == 0)
+ return;
+
+ p = oss_history_p;
+ oss_history_p = (oss_history_p + 1) % OSS_HISTORY_SIZE;
+
+ tmp = oss_history[p];
+ memset (tmp, 0, OSS_HISTORY_STRSIZE);
+ s = tmp;
+
+ sprintf (s, "%s.%02d: ", adev->devnode, adev->engine_num);
+ s += strlen (s);
+
+ if (adev->pid != -1)
+ {
+ sprintf (s, "pid %d ", adev->pid);
+ s += strlen (s);
+ }
+
+ if (*adev->cmd != 0)
+ {
+ sprintf (s, "cmd '%s' ", adev->cmd);
+ s += strlen (s);
+ }
+ else
+ {
+ strcpy (s, "cmd: Unknown ");
+ s += strlen (s);
+ }
+
+ if (adev->open_mode & OPEN_READ)
+ {
+ sprintf (s, "IN ");
+ s += strlen (s);
+ }
+
+ if (adev->open_mode & OPEN_WRITE)
+ {
+ sprintf (s, "OUT ");
+ s += strlen (s);
+ }
+
+ if (adev->timeout_count > 0)
+ {
+ sprintf (s, "%d timeouts ", adev->timeout_count);
+ s += strlen (s);
+ }
+
+ if (adev->dmap_out->play_underruns > 0)
+ {
+ sprintf (s, "%d underruns ", adev->dmap_out->play_underruns);
+ s += strlen (s);
+ }
+
+ if (adev->dmap_in->rec_overruns > 0)
+ {
+ sprintf (s, "%d overruns ", adev->dmap_in->rec_overruns);
+ s += strlen (s);
+ }
+
+ if (adev->dmap_out->num_errors > 0)
+ {
+ report_errors (s, "Play events:", adev, adev->dmap_out,
+ OSS_HISTORY_STRSIZE - strlen (tmp) - 1);
+ s += strlen (s);
+ *s++ = ' ';
+ }
+
+ if (adev->dmap_in->num_errors > 0)
+ {
+ report_errors (s, "Rec events:", adev, adev->dmap_in,
+ OSS_HISTORY_STRSIZE - strlen (tmp) - 1);
+ s += strlen (s);
+ *s++ = ' ';
+ }
+}
+
+char *
+audio_show_latency (int dev)
+{
+ static char str[32];
+ adev_p adev = audio_engines[dev];
+ dmap_p dmap;
+ int dr, fs;
+
+ *str = 0;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return "Bad device";
+
+ if (adev->open_mode == 0)
+ return "Not opened";
+
+ if (adev->open_mode == OPEN_READ)
+ dmap = adev->dmap_in;
+ else
+ dmap = adev->dmap_out;
+
+ if (dmap == NULL)
+ return "Unknown";
+
+ if (!(dmap->flags & DMAP_STARTED))
+ return "Not started";
+
+ dr = dmap->data_rate;
+ fs = dmap->fragment_size;
+
+ if (dr <= 0)
+ sprintf (str, "%d", dmap->fragment_size);
+ else
+ {
+ int r = (fs * 10000) / dr;
+
+ sprintf (str, "%d/%d (%d.%d msec)", dmap->fragment_size, dr, r / 10,
+ r % 10);
+ }
+
+
+ return str;
+}
+
+void
+oss_audio_release (int dev, struct fileinfo *file)
+{
+ adev_p adev;
+ int mode;
+ oss_native_word flags;
+
+ sync_seed++;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return;
+ if (file)
+ mode = file->mode & O_ACCMODE;
+ else
+ mode = OPEN_READ | OPEN_WRITE;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("=-=-=- Closing audio engine %d -=-=-=", dev);
+#endif
+
+ adev = audio_engines[dev];
+
+ if (adev->unloaded || !adev->enabled)
+ {
+ cmn_err (CE_CONT, "Audio device %s not available - close aborted\n",
+ adev->name);
+ return;
+ }
+
+ oss_audio_post (adev);
+ oss_audio_sync (adev);
+
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_CLOSE);
+#endif
+ adev->d->adrv_halt_io (dev);
+ adev->d->adrv_close (dev, mode);
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ if (adev->dmask & DMASK_OUT)
+ {
+ adev->dmap_out->audio_callback = NULL;
+ if (!adev->dmap_out->buffer_protected)
+ if (adev->dmap_out->dmabuf != NULL)
+ memset (adev->dmap_out->dmabuf, adev->dmap_out->neutral_byte,
+ adev->dmap_out->buffsize);
+ }
+
+ if (adev->dmask & DMASK_IN)
+ {
+ adev->dmap_in->audio_callback = NULL;
+ }
+
+ store_history (dev);
+
+ memset (audio_engines[dev]->cmd, 0, sizeof (audio_engines[dev]->cmd));
+ memset (audio_engines[dev]->label, 0, sizeof (audio_engines[dev]->label));
+ memset (audio_engines[dev]->song_name, 0,
+ sizeof (audio_engines[dev]->song_name));
+ audio_engines[dev]->pid = -1;
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+
+ /*
+ * Free the DMA buffer(s)
+ */
+ if (adev->dmask & DMASK_OUT)
+ if (adev->dmap_out->dmabuf != NULL)
+ {
+ if (adev->d->adrv_free_buffer != NULL)
+ {
+ adev->d->adrv_free_buffer (dev, adev->dmap_out, OPEN_WRITE);
+ }
+ else
+ default_free_buffer (dev, adev->dmap_out, OPEN_WRITE);
+ adev->dmap_out->dmabuf = NULL;
+ }
+
+ if (adev->dmask & DMASK_IN)
+ if (adev->dmap_in != adev->dmap_out && adev->dmap_in->dmabuf != NULL)
+ {
+ if (adev->d->adrv_free_buffer != NULL)
+ {
+ adev->d->adrv_free_buffer (dev, adev->dmap_in, OPEN_READ);
+ }
+ else
+ default_free_buffer (dev, adev->dmap_in, OPEN_READ);
+ adev->dmap_in->dmabuf = NULL;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ adev->open_mode = 0;
+ adev->flags &= ~ADEV_OPENED;
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+}
+
+static void audio_outputintr (int dev, int intr_flags);
+static void audio_inputintr (int dev, int intr_flags);
+
+/*ARGSUSED*/
+int
+oss_audio_open_engine (int dev, int no_worries, struct fileinfo *file,
+ int recursive, int open_flags, int *newdev)
+{
+/*
+ * Open audio engine
+ */
+ adev_p adev;
+ int retval = 0, fmt;
+ int mode;
+ int saved_cooked;
+ int channels, rate;
+ oss_native_word flags;
+ extern int cooked_enable; /* Config option */
+
+ DOWN_STATUS (0xff);
+
+ if (file)
+ {
+ mode = file->mode & O_ACCMODE;
+ }
+ else
+ mode = OPEN_READ | OPEN_WRITE;
+
+ sync_seed++;
+
+ DDB (cmn_err
+ (CE_CONT, "oss_audio_open_engine(%d, mode=0x%x)\n", dev, mode));
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("-----> oss_audio_open_engine(%d, mode=0x%x)", dev, mode);
+#endif
+
+ if (dev < 0 || dev >= num_audio_engines || audio_engines == NULL)
+ return OSS_ENXIO;
+
+ adev = audio_engines[dev];
+ if (adev->unloaded)
+ return OSS_ENODEV;
+ if (!adev->enabled)
+ return OSS_ENXIO;
+
+ if (adev->osdev == NULL)
+ {
+ cmn_err (CE_WARN, "adev->osdev==NULL\n");
+ return OSS_EIO;
+ }
+
+ open_flags = get_open_flags (mode, open_flags, file);
+
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ if (adev->open_mode != 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+ return OSS_EBUSY;
+ }
+ adev->open_mode = mode;
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+
+ adev->cooked_enable = cooked_enable; /* This must be done before drv->open() */
+#ifdef DO_TIMINGS
+ if (adev->cooked_enable)
+ oss_do_timing ("Initial cooked mode ON");
+ else
+ oss_do_timing ("Initial cooked mode OFF");
+#endif
+
+ adev->src_quality = src_quality;
+ if ((retval = adev->d->adrv_open (dev, mode, open_flags)) < 0)
+ {
+ adev->open_mode = 0;
+
+ return retval;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ adev->outputintr = audio_outputintr;
+ adev->inputintr = audio_inputintr;
+ adev->forced_nonblock = 0;
+ adev->setfragment_warned = 0;
+ adev->getispace_error_count = 0;
+ adev->sync_next = NULL;
+ adev->sync_group = 0;
+ adev->sync_flags = 0;
+ adev->open_flags = open_flags;
+ adev->flags |= ADEV_OPENED;
+ adev->timeout_count = 0;
+ adev->policy = -1;
+ adev->song_name[0] = 0;
+ adev->label[0] = 0;
+
+ if (open_flags & (OF_NOCONV | OF_MMAP))
+ {
+ adev->cooked_enable = 0;
+#ifdef DO_TIMINGS
+ oss_do_timing ("Forcing cooked mode OFF");
+#endif
+ }
+
+ memset (audio_engines[dev]->cmd, 0, sizeof (audio_engines[dev]->cmd));
+
+ if (recursive)
+ {
+ strcpy (audio_engines[dev]->cmd, "OSS internal");
+ audio_engines[dev]->pid = 0;
+ }
+ else
+ {
+ char *cmd;
+
+ if ((cmd = GET_PROCESS_NAME (file)) != NULL)
+ {
+ strncpy (audio_engines[dev]->cmd, cmd, 16);
+ strncpy (audio_engines[dev]->label, cmd, 16);
+ audio_engines[dev]->cmd[15] = '\0';
+ audio_engines[dev]->label[15] = '\0';
+ }
+ audio_engines[dev]->pid = GET_PROCESS_PID (file);
+ }
+
+ adev->dmask = 0;
+/*
+ * Find out which dmap structures are required.
+ */
+
+ if (mode == OPEN_WRITE)
+ adev->dmask = DMASK_OUT;
+ else if (mode == OPEN_READ)
+ adev->dmask = DMASK_IN;
+ else
+ {
+ if (mode != (OPEN_WRITE | OPEN_READ))
+ cmn_err (CE_NOTE, "Unrecognized open mode %x\n", mode);
+ adev->dmask = DMASK_OUT;
+
+ if ((adev->flags & ADEV_DUPLEX) && adev->dmap_out != adev->dmap_in)
+ adev->dmask = DMASK_OUT | DMASK_IN;
+ }
+
+#if 0
+/*
+ * Handling of non-blocking doesn't belong here. It will be handled
+ * by read/write.
+ */
+ if (file != NULL && !(open_flags & OF_BLOCK))
+ if (ISSET_FILE_FLAG (file, O_NONBLOCK) || adev->forced_nonblock)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("*** Non-blocking open ***");
+#endif
+ adev->nonblock = 1;
+ }
+#endif
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+
+ if (adev->dmask & DMASK_OUT)
+ {
+
+ /*
+ * Use small DMA buffer if requested and if the device supports it.
+ */
+ if (SMALL_DMABUF_SIZE >= (adev->min_block * 2) &&
+ (open_flags & OF_SMALLBUF))
+ adev->dmap_out->flags |= DMAP_SMALLBUF;
+ else
+ if (MEDIUM_DMABUF_SIZE >= (adev->min_block * 2) &&
+ (open_flags & OF_MEDIUMBUF))
+ adev->dmap_out->flags |= DMAP_MEDIUMBUF;
+ else
+ adev->dmap_out->flags &= ~(DMAP_SMALLBUF | DMAP_MEDIUMBUF);
+
+ if ((retval = init_dmap (adev, adev->dmap_out, OPEN_WRITE)) < 0)
+ {
+ oss_audio_release (dev, file);
+ return retval;
+ }
+ }
+
+ if (adev->dmask & DMASK_IN)
+ {
+ /*
+ * Use small DMA buffer if requested and if the device supports it.
+ */
+ if (SMALL_DMABUF_SIZE >= (adev->min_block * 2) &&
+ (open_flags & OF_SMALLBUF))
+ adev->dmap_in->flags |= DMAP_SMALLBUF;
+ else
+ adev->dmap_in->flags &= ~DMAP_SMALLBUF;
+
+ if ((retval = init_dmap (adev, adev->dmap_in, OPEN_READ)) < 0)
+ {
+ oss_audio_release (dev, file);
+ return retval;
+ }
+ }
+
+ adev->dmap_out->num_errors = 0;
+ adev->dmap_in->num_errors = 0;
+
+ if ((mode & OPEN_WRITE) && !(adev->flags & ADEV_NOOUTPUT))
+ {
+ oss_reset_wait_queue (adev->out_wq);
+ }
+ if ((mode & OPEN_READ) && !(adev->flags & ADEV_NOINPUT))
+ {
+ oss_reset_wait_queue (adev->in_wq);
+ }
+
+ adev->xformat_mask = 0;
+
+ switch (adev->dmask)
+ {
+ case DMASK_OUT:
+ adev->xformat_mask = adev->oformat_mask;
+ break;
+
+ case DMASK_IN:
+ adev->xformat_mask = adev->iformat_mask;
+ break;
+
+ case DMASK_OUT | DMASK_IN:
+ adev->xformat_mask = adev->oformat_mask & adev->iformat_mask;
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Internal error A during open\n");
+ }
+
+ fmt = DSP_DEFAULT_FMT;
+ rate = DSP_DEFAULT_SPEED;
+
+ if (adev->flags & ADEV_FIXEDRATE && adev->fixed_rate != 0)
+ rate = adev->fixed_rate;
+
+ if (adev->flags & ADEV_16BITONLY)
+ fmt = AFMT_S16_LE;
+
+ adev->go = 1;
+ adev->enable_bits = adev->open_mode;
+
+ channels = 1;
+ if (adev->flags & ADEV_STEREOONLY)
+ channels = 2;
+
+ saved_cooked = adev->cooked_enable;
+ adev->cooked_enable = 0;
+ oss_audio_set_format (dev, fmt, adev->xformat_mask);
+ oss_audio_set_channels (dev, channels);
+ oss_audio_set_rate (dev, rate);
+ adev->cooked_enable = saved_cooked;
+
+/* Clear the Cooked mode to permit mmap() */
+ if (adev->dmask & DMASK_OUT)
+ adev->dmap_out->flags &= ~DMAP_COOKED;
+ if (adev->dmask & DMASK_IN)
+ adev->dmap_in->flags &= ~DMAP_COOKED;
+
+#ifdef DO_TIMINGS
+ {
+ char *p_name;
+ pid_t proc_pid;
+ oss_timing_printf ("=-=-=- Audio device %d (%s) opened, mode %x -=-=-=",
+ adev->engine_num, adev->name, mode);
+
+ if ((proc_pid = GET_PROCESS_PID (file)) != -1)
+ oss_timing_printf ("Opened by PID: %d", proc_pid);
+
+ if ((p_name = GET_PROCESS_NAME (file)) != NULL)
+ oss_timing_printf ("Opening process name: %s", p_name);
+ }
+#endif
+
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_OPEN);
+#endif
+
+ return adev->engine_num;
+}
+
+#ifdef VDEV_SUPPORT
+int
+oss_audio_open_devfile (int dev, int dev_class, struct fileinfo *file,
+ int recursive, int open_flags, int *newdev)
+{
+/*
+ * Open audio device file (by calling oss_audio_open_engine).
+ */
+ int err, d, n;
+ int open_excl = 0;
+ adev_p adev;
+ int mode = OPEN_READ | OPEN_WRITE;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("-----> oss_audio_open_devfile(%d, mode=0x%x)", dev, mode);
+#endif
+
+ if (file)
+ {
+ mode = file->mode & O_ACCMODE;
+ open_flags = get_open_flags (mode, open_flags, file);
+ if (file->acc_flags & O_EXCL)
+ {
+ if (excl_policy == 0) open_excl = 1;
+#ifdef GET_PROCESS_UID
+ else if ((excl_policy == 1) && (GET_PROCESS_UID () == 0)) open_excl = 1;
+#endif
+ }
+ }
+
+ DDB (cmn_err
+ (CE_CONT, "oss_audio_open_devfile(%d, mode=0x%x, excl=%d)\n", dev,
+ mode, open_excl));
+
+ if (dev < 0 || dev >= num_audio_devfiles)
+ {
+ return OSS_ENODEV;
+ }
+ adev = audio_devfiles[dev];
+ dev = adev->engine_num;
+
+ n=0;
+ while (adev->d->adrv_redirect != NULL)
+ {
+ int next_dev = dev;
+
+ if (n++ > num_audio_engines)
+ {
+ cmn_err(CE_CONT, "Recursive audio device redirection\n");
+ return OSS_ELOOP;
+ }
+
+ next_dev = adev->d->adrv_redirect (dev, mode, open_flags);
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Engine redirect %d -> %d\n", dev, next_dev);
+#endif
+
+ if (next_dev == dev) /* No change */
+ break;
+
+ if (next_dev < 0 || next_dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ dev = next_dev;
+ adev = audio_engines[dev];
+ }
+
+/*
+ * Check Exclusive mode open - do not do any kind of device
+ * sharing. For the time being this mode is not supported with devices
+ * that do hardware mixing.
+ */
+ if (open_excl && !(adev->flags & ADEV_HWMIX))
+ {
+ DDB (cmn_err
+ (CE_CONT, "Exclusive open, engine=%d\n", adev->engine_num));
+ if ((dev = oss_audio_open_engine (adev->engine_num, dev_class, file,
+ recursive, open_flags, newdev)) < 0)
+ {
+ return dev;
+ }
+
+ goto done;
+ }
+
+#ifdef CONFIG_OSS_VMIX
+/*
+ * Get a vmix engine if the device has vmix support enabled.
+ */
+ if (!vmix_disabled)
+ if (adev->vmix_mixer != NULL) // Virtual mixer attached
+ {
+ int vmix_dev;
+
+ /*
+ * Create a new vmix client instance.
+ */
+
+ if ((vmix_dev=vmix_create_client(adev->vmix_mixer))>=0)
+ {
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Vmix redirect %d -> %d\n", dev, vmix_dev);
+#endif
+ if ((dev = oss_audio_open_engine (vmix_dev, dev_class, file,
+ recursive, open_flags, newdev)) < 0)
+ {
+ //cmn_err(CE_WARN, "Failed to open vmix engine %d, err=%d\n", vmix_dev, dev);
+ return dev;
+ }
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Vmix engine opened %d -> %d\n", vmix_dev, dev);
+#endif
+
+ goto done;
+ }
+ }
+#endif
+
+#if 0
+/*
+ * Follow redirection chain for the device.
+ *
+ * (TODO: This feature was for earlier versions of vmix/softoss and not in use for the time being. However
+ * it is possible that some other driver finds use for it in the future).
+ */
+
+ if (!open_excl)
+ {
+ if (mode == OPEN_WRITE)
+ {
+ redirect = adev->redirect_out;
+ }
+ else if (mode == OPEN_READ)
+ {
+ redirect = adev->redirect_in;
+ }
+ else
+ {
+ /*
+ * Read-write open. Check that redirection for both directions are
+ * identical.
+ */
+ if (adev->redirect_out == adev->redirect_in)
+ redirect = adev->redirect_out;
+ }
+ }
+ DDB (cmn_err
+ (CE_CONT, "Redirect=%d (%d, %d)\n", redirect, adev->redirect_out,
+ adev->redirect_in));
+
+ if (redirect >= 0 && redirect < num_audio_engines)
+ {
+ adev = audio_engines[redirect];
+ DDB (cmn_err
+ (CE_CONT, "Redirect devfile %d -> engine=%d\n", dev,
+ adev->engine_num));
+ dev = redirect;
+ }
+#endif
+
+ while (adev != NULL)
+ {
+ DDB (cmn_err (CE_CONT, "Trying engine=%d\n", adev->engine_num));
+ if (!adev->enabled)
+ return OSS_EAGAIN;
+
+ if (adev->unloaded)
+ return OSS_EAGAIN;
+
+ *newdev = adev->engine_num;
+ if ((err =
+ oss_audio_open_engine (adev->engine_num, dev_class, file,
+ recursive, open_flags, newdev)) < 0)
+ {
+ /*
+ * Check if the device was busy and if it has a
+ * shadow device.
+ */
+ if (err != OSS_EBUSY || adev->next_out == NULL)
+ return err;
+ adev = adev->next_out;
+ }
+ else
+ {
+ dev = adev->engine_num;
+ DDB (cmn_err (CE_CONT, "Engine %d opened\n", adev->engine_num));
+ goto done;
+ }
+ }
+
+ return OSS_EBUSY;
+
+done:
+/*
+ * Try to find which minor number matches this /dev/dsp# device.
+ */
+
+ if ((d = oss_find_minor (OSS_DEV_DSP_ENGINE, dev)) < 0)
+ {
+ oss_audio_release (dev, file);
+ return d;
+ }
+
+ *newdev = d;
+ return dev;
+}
+#endif
+
+static struct
+{
+ int sz, nfrags;
+} policies[] =
+{
+ {
+ 8, 2}, /* 0 */
+ {
+ 16, 2}, /* 1 */
+ {
+ 128, 2}, /* 2 */
+ {
+ 256, 4}, /* 3 */
+ {
+ 512, 4}, /* 4 */
+ {
+ 1024, 0}, /* 5 */
+ {
+ 2048, 0}, /* 6 */
+ {
+ 4096, 0}, /* 7 */
+ {
+ 16384, 0}, /* 8 */
+ {
+ 32768, 0}, /* 9 */
+ {
+ 256 *1024, 0}, /* 10 */
+};
+
+static void
+setup_fragments (adev_p adev, dmap_p dmap, int direction)
+{
+ int sz, maxfrags = 100000;
+ int min;
+ extern int max_intrate;
+
+ if (adev->max_intrate == 0 || adev->max_intrate > max_intrate)
+ adev->max_intrate = max_intrate;
+
+ if (dmap->flags & DMAP_FRAGFIXED)
+ return;
+ dmap->flags |= DMAP_FRAGFIXED;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("setup_fragments(%d, dir=%d)", adev->engine_num, direction);
+#endif
+
+ sz = 1024;
+
+ dmap->low_water_rq = 0;
+ dmap->low_water = -1;
+
+ if (dmap->fragsize_rq != 0) /* SNDCTL_DSP_SETFRAGMENT was called */
+ {
+ int v;
+ v = dmap->fragsize_rq & 0xffff;
+
+ sz = (1 << v);
+
+ if (dmap->expand_factor != UNIT_EXPAND)
+ {
+ int sz2;
+
+ sz2 = (sz * dmap->expand_factor) / UNIT_EXPAND;
+
+ if (sz < sz2)
+ {
+ while (sz < sz2)
+ sz *= 2;
+ }
+ else if (sz > sz2)
+ {
+ while (sz > sz2)
+ sz /= 2;
+ }
+
+ }
+
+ if (sz < 8)
+ sz = 8;
+ if (sz > dmap->buffsize / 2)
+ sz = dmap->buffsize / 2;
+
+ maxfrags = (dmap->fragsize_rq >> 16) & 0x7fff;
+
+ if (maxfrags == 0)
+ maxfrags = 0x7fff;
+ else if (maxfrags < 2)
+ maxfrags = 2;
+
+ if (maxfrags < adev->min_fragments)
+ maxfrags = adev->min_fragments;
+ else if (adev->max_fragments >= 2 && maxfrags > adev->max_fragments)
+ maxfrags = adev->max_fragments;
+
+#if 1
+ /*
+ * Workaround for realplay
+ */
+ if (adev->open_flags & OF_SMALLFRAGS)
+ while (sz > dmap->buffsize / 8)
+ {
+ maxfrags *= 2;
+ sz /= 2;
+ }
+#endif
+ }
+
+ if (adev->policy >= 0 && adev->policy <= 10)
+ {
+ sz = policies[adev->policy].sz;
+ maxfrags = policies[adev->policy].nfrags;
+ if (maxfrags == 0) /* Unlimited */
+ maxfrags = 0xffff;
+ }
+
+#if 1
+ /* Use short fragments if ossd has registered this device */
+ if (adev->ossd_registered)
+ sz = 256;
+#endif
+
+ /* Sanity check */
+ if (adev->min_block && adev->max_block)
+ if (adev->min_block > adev->max_block)
+ adev->min_block = adev->max_block = 0;
+
+ if (adev->max_block > 0 && sz > adev->max_block)
+ sz = adev->max_block;
+ if (adev->min_block > 0 && sz < adev->min_block)
+ sz = adev->min_block;
+
+ if (sz < 8)
+ sz = 8;
+
+ /* Ensure that the interrupt rate is within the limits */
+
+ min = 0;
+
+ if (adev->max_intrate > 0)
+ {
+ int data_rate;
+
+ data_rate = dmap->data_rate;
+ if (data_rate < 8000)
+ data_rate = adev->hw_parms.rate * 4;
+
+ min = data_rate / adev->max_intrate;
+
+ if (min > dmap->buffsize / 2)
+ min = dmap->buffsize / 2;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Max intrate %d -> min buffer %d", adev->max_intrate,
+ min);
+#endif
+ }
+
+#if 1
+ if (dmap->flags & DMAP_COOKED)
+ if (min < 256)
+ min = 256;
+#endif
+
+ if (adev->max_block && min > adev->max_block)
+ min = adev->max_block;
+
+ if (sz < min)
+ {
+ while (sz < min)
+ sz *= 2;
+ if (adev->max_block > 0 && sz > adev->max_block)
+ sz = adev->max_block;
+ }
+
+ dmap->fragment_size = sz;
+ dmap->nfrags = dmap->buffsize / sz;
+
+ if (dmap == adev->dmap_out)
+ {
+ if (direction == OPEN_WRITE)
+ {
+ if (dmap->nfrags > maxfrags)
+ dmap->nfrags = maxfrags;
+ }
+ }
+
+ if (adev->d->adrv_setup_fragments)
+ {
+ adev->d->adrv_setup_fragments (adev->engine_num, dmap, direction);
+ }
+
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+
+ if (dmap->nfrags < 2)
+ {
+ dmap->nfrags = 2;
+ dmap->fragment_size = dmap->bytes_in_use / 2;
+ }
+
+ while (dmap->nfrags < adev->min_fragments)
+ {
+ dmap->nfrags *= 2;
+ dmap->fragment_size /= 2;
+ }
+
+ if (adev->max_fragments >= 2)
+ while (dmap->nfrags > adev->max_fragments)
+ {
+ dmap->nfrags /= 2;
+ dmap->fragment_size *= 2;
+ }
+ while (dmap->nfrags < adev->min_fragments)
+ {
+ dmap->nfrags *= 2;
+ dmap->fragment_size /= 2;
+ }
+
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+
+ dmap->bytes_in_use = dmap->nfrags * dmap->fragment_size;
+ dmap->low_water_rq = dmap->fragment_size;
+
+#if 1
+ if (dmap->nfrags < 4)
+#endif
+ if (dmap->low_water_rq < dmap->bytes_in_use / 4)
+ dmap->low_water_rq = dmap->bytes_in_use / 4;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("fragsz=%d, nfrags=%d", dmap->fragment_size, dmap->nfrags);
+#endif
+}
+
+static int
+getblksize (adev_p adev)
+{
+ int size = 4096;
+ dmap_p dmap;
+ oss_native_word flags, dflags;
+ dflags = 0;
+
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ if (adev->dmask & DMASK_IN)
+ {
+ dmap = adev->dmap_in;
+
+ if (!(dmap->flags & DMAP_FRAGFIXED))
+ {
+ MUTEX_ENTER (dmap->mutex, dflags);
+ setup_fragments (adev, dmap, OPEN_READ);
+ size = dmap->fragment_size;
+ MUTEX_EXIT (dmap->mutex, dflags);
+ }
+ }
+
+ if (adev->dmask & DMASK_OUT)
+ {
+ dmap = adev->dmap_out;
+
+ if (!(dmap->flags & DMAP_FRAGFIXED))
+ {
+ MUTEX_ENTER (dmap->mutex, dflags);
+ setup_fragments (adev, dmap, OPEN_WRITE);
+ size = dmap->fragment_size;
+ MUTEX_EXIT (dmap->mutex, dflags);
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+
+ return size;
+}
+
+/*ARGSUSED*/
+static oss_uint64_t
+get_output_pointer (adev_p adev, dmap_p dmap, int do_adjust)
+{
+ oss_uint64_t ptr;
+
+ if (adev->d->adrv_get_output_pointer == NULL)
+ {
+ return dmap->fragment_counter * dmap->fragment_size;
+ }
+
+ UP_STATUS (STS_PTR);
+ ptr =
+ adev->d->adrv_get_output_pointer (adev->engine_num, dmap,
+ PCM_ENABLE_OUTPUT) & ~7;
+ DOWN_STATUS (STS_PTR);
+
+ return ptr;
+}
+
+static oss_uint64_t
+get_input_pointer (adev_p adev, dmap_p dmap, int do_adjust)
+{
+ oss_uint64_t ptr;
+
+ if (adev->d->adrv_get_input_pointer == NULL)
+ return dmap->fragment_counter * dmap->fragment_size;
+
+ ptr =
+ adev->d->adrv_get_input_pointer (adev->engine_num, dmap,
+ PCM_ENABLE_INPUT) & ~7;
+ if (ptr < dmap->byte_counter)
+ ptr += dmap->bytes_in_use;
+ ptr %= dmap->bytes_in_use;
+
+ if (do_adjust)
+ {
+ oss_uint64_t tmp = dmap->byte_counter;
+
+ tmp = (tmp / dmap->bytes_in_use) * dmap->bytes_in_use;
+ dmap->byte_counter = tmp + ptr;
+ }
+
+ return ptr;
+}
+
+static int
+get_optr (adev_p adev, dmap_p dmap, ioctl_arg arg)
+{
+ count_info *info = (count_info *) arg;
+ oss_native_word flags;
+ oss_uint64_t bytes;
+
+ memset ((char *) info, 0, sizeof (count_info));
+
+ if (dmap->dma_mode != PCM_ENABLE_OUTPUT || !(dmap->flags & DMAP_STARTED))
+ return 0;
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+
+ info->ptr = get_output_pointer (adev, dmap, 1);
+ info->blocks = dmap->interrupt_count;
+ dmap->interrupt_count = 0;
+
+ bytes = (dmap->byte_counter / dmap->bytes_in_use) * dmap->bytes_in_use;
+ bytes += info->ptr;
+ if (bytes < dmap->byte_counter)
+ bytes += dmap->bytes_in_use;
+ info->bytes = (unsigned int) bytes;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ /* Adjust for format conversions */
+ info->ptr = (info->ptr * UNIT_EXPAND) / dmap->expand_factor;
+ info->bytes = (info->bytes / dmap->expand_factor) * UNIT_EXPAND;
+ info->bytes &= 0x3fffffff;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("GETOPTR(%d,%d,%d)", info->bytes, info->ptr, info->blocks);
+#endif
+ return 0;
+}
+
+static int
+get_iptr (adev_p adev, dmap_p dmap, ioctl_arg arg)
+{
+ count_info *info = (count_info *) arg;
+ oss_native_word flags;
+ oss_uint64_t bytes;
+
+ memset ((char *) info, 0, sizeof (count_info));
+
+ if (dmap->dma_mode != PCM_ENABLE_INPUT || !(dmap->flags & DMAP_STARTED))
+ return 0;
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ info->ptr = get_input_pointer (adev, dmap, 1);
+ info->blocks = dmap->interrupt_count;
+ dmap->interrupt_count = 0;
+
+ bytes = (dmap->byte_counter / dmap->bytes_in_use) * dmap->bytes_in_use;
+ bytes += info->ptr;
+ if (bytes < dmap->byte_counter)
+ bytes += dmap->bytes_in_use;
+ info->bytes = (unsigned int) bytes;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ /* Adjust for format conversions */
+ info->ptr = (info->ptr * UNIT_EXPAND) / dmap->expand_factor;
+ info->bytes = (info->bytes / dmap->expand_factor) * UNIT_EXPAND;
+ info->bytes &= 0x3fffffff;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("GETIPTR(%d,%d,%d)", info->bytes, info->ptr, info->blocks);
+#endif
+ return 0;
+}
+
+#ifndef OSS_NO_LONG_LONG
+static int
+get_long_optr (adev_p adev, dmap_p dmap, ioctl_arg arg)
+{
+ oss_count_t *ptr = (oss_count_t *) arg;
+ oss_native_word flags;
+ oss_uint64_t pos, bytes;
+
+ memset ((char *) ptr, 0, sizeof (*ptr));
+
+ if (dmap->dma_mode != PCM_ENABLE_OUTPUT || !(dmap->flags & DMAP_STARTED))
+ return 0;
+
+ ptr->fifo_samples = 0;
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ if (dmap->frame_size < 1)
+ dmap->frame_size = 1;
+ if (dmap->user_frame_size < 1)
+ dmap->user_frame_size = 1;
+ pos = get_output_pointer (adev, dmap, 1);
+ bytes = (dmap->byte_counter / dmap->bytes_in_use) * dmap->bytes_in_use;
+ bytes += pos;
+ ptr->samples = (unsigned int) (bytes / dmap->frame_size);
+
+ /* Adjust for format conversions */
+ ptr->samples = (ptr->samples * UNIT_EXPAND) / dmap->expand_factor;
+
+ if (adev->d->adrv_local_qlen)
+ {
+ ptr->fifo_samples =
+ adev->d->adrv_local_qlen (adev->engine_num) / dmap->frame_size;
+ ptr->fifo_samples =
+ (ptr->fifo_samples * UNIT_EXPAND) / dmap->expand_factor;
+ }
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ return 0;
+}
+
+static int
+get_long_iptr (adev_p adev, dmap_p dmap, ioctl_arg arg)
+{
+ oss_count_t *ptr = (oss_count_t *) arg;
+ oss_native_word flags;
+ oss_uint64_t pos, bytes;
+
+ memset ((char *) ptr, 0, sizeof (*ptr));
+
+ if (dmap->dma_mode != PCM_ENABLE_INPUT || !(dmap->flags & DMAP_STARTED))
+ return 0;
+
+ ptr->fifo_samples = 0;
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ if (dmap->frame_size < 1)
+ dmap->frame_size = 1;
+ if (dmap->user_frame_size < 1)
+ dmap->user_frame_size = 1;
+ pos = get_input_pointer (adev, dmap, 1);
+ bytes = (dmap->byte_counter / dmap->bytes_in_use) * dmap->bytes_in_use;
+ bytes += pos;
+ ptr->samples = (unsigned int) (bytes / dmap->frame_size);
+
+ /* Adjust for format conversions */
+ ptr->samples = (ptr->samples / dmap->expand_factor) * UNIT_EXPAND;
+
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ return 0;
+}
+#endif
+
+static int
+get_odelay (adev_p adev, dmap_p dmap, ioctl_arg arg)
+{
+ oss_int64_t val, pos;
+ oss_native_word flags;
+ if (dmap->dma_mode != PCM_ENABLE_OUTPUT ||
+ (dmap->mapping_flags & DMA_MAP_MAPPED))
+ return *arg = (0);
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ pos = get_output_pointer (adev, dmap, 1);
+ val = (dmap->byte_counter / dmap->bytes_in_use) * dmap->bytes_in_use;
+ val += pos;
+ val = dmap->user_counter - val;
+ if (val < 0)
+ val = 0;
+ if (val > dmap->bytes_in_use)
+ val = dmap->bytes_in_use;
+
+ if (adev->d->adrv_local_qlen)
+ {
+ val += adev->d->adrv_local_qlen (adev->engine_num);
+ }
+
+ val += dmap->leftover_bytes;
+ val = (val * UNIT_EXPAND) / dmap->expand_factor;
+
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+#ifdef DO_TIMINGS
+ oss_timing_printf ("GETODELAY(%d, %d)", adev->engine_num, val);
+#endif
+ return *arg = (val);
+}
+
+static int audio_space_in_queue (adev_p adev, dmap_p dmap, int count);
+
+static int
+get_ospace (adev_p adev, dmap_p dmap, ioctl_arg arg)
+{
+ audio_buf_info *info = (audio_buf_info *) arg;
+ oss_native_word flags;
+
+ memset ((char *) info, 0, sizeof (audio_buf_info));
+
+ if (!(dmap->flags & DMAP_PREPARED))
+ {
+ setup_fragments (adev, dmap, OPEN_WRITE);
+ prepare_output (adev, dmap);
+ }
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ info->fragstotal = dmap->nfrags;
+
+ info->fragsize = (dmap->fragment_size * UNIT_EXPAND) / dmap->expand_factor;
+
+ /* Make sure we report full samples */
+ info->fragsize =
+ ((info->fragsize + dmap->user_frame_size -
+ 1) / dmap->user_frame_size) * dmap->user_frame_size;
+
+ if (!(adev->open_mode & OPEN_WRITE))
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ cmn_err (CE_WARN,
+ "SNDCTL_DSP_GETOSPACE cannot be called in read-only mode.\n");
+#ifdef DO_TIMINGS
+ oss_do_timing ("GETOSPACE: Bad access mode - return EACCES");
+#endif
+ return OSS_EACCES;
+ }
+
+ if (dmap->mapping_flags & DMA_MAP_MAPPED)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ cmn_err (CE_WARN,
+ "SNDCTL_DSP_GETOSPACE cannot be called in mmap mode.\n");
+#ifdef DO_TIMINGS
+ oss_do_timing ("GETOSPACE: mmap access mode - return EPERM");
+#endif
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1000, "GETOSPACE called in mmap mode"), 0);
+ /* Errordesc:
+ * Do not call SNDCTL_DSP_GETOSPACE in mmap mode. Use SNDCTL_DSP_GETOPTR
+ * instead. SNDCTL_DSP_GETOSPACE is defined only for applications that
+ * use the normal write() method.
+ * Applications that use mmap can call SNDCTL_DSP_GETOSPACE before calling
+ * mmap to get the actual buffer size.
+ */
+ return OSS_EPERM;
+ }
+
+ if (!(dmap->flags & DMAP_STARTED))
+ {
+ int bytes;
+ bytes = (int) ((long long) dmap->bytes_in_use - dmap->user_counter);
+#ifdef DO_TIMINGS
+ {
+ oss_do_timing ("GETOSPACE: Not started - ignore device count");
+ oss_timing_printf ("bytes_in_use=%d", dmap->bytes_in_use);
+ oss_timing_printf ("user_counter=%lld", dmap->user_counter);
+ oss_timing_printf ("raw bytes=%d", bytes);
+ }
+#endif
+ bytes = (bytes / dmap->expand_factor) * UNIT_EXPAND; /* Round downwards */
+ bytes = (bytes / dmap->user_frame_size) * dmap->user_frame_size; /* Truncate to frame size */
+ info->bytes = bytes;
+ info->fragments = info->fragstotal = dmap->nfrags;
+ if (info->bytes > info->fragsize * info->fragstotal)
+ info->bytes = info->fragsize * info->fragstotal;
+
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return 0;
+ }
+
+ info->bytes = audio_space_in_queue (adev, dmap, 0);
+#ifdef DO_TIMINGS
+ oss_timing_printf ("audio_space_in_queue returned %d", info->bytes);
+#endif
+
+ if (info->bytes < dmap->low_water)
+ info->bytes = 0;
+
+ if (adev->dmap_out->flags & DMAP_COOKED)
+ {
+
+ if (dmap->tmpbuf_ptr > 0)
+ info->bytes -= dmap->tmpbuf_ptr;
+ }
+
+ if ((adev->dmap_out->flags & DMAP_COOKED) && info->bytes <
+ dmap->fragment_size / 2)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("GETOSPACE: Buffer full");
+#endif
+ info->bytes = 0;
+ }
+
+ if (info->bytes < 0)
+ info->bytes = 0;
+
+ info->bytes = (info->bytes * UNIT_EXPAND) / dmap->expand_factor;
+ info->bytes = (info->bytes / dmap->user_frame_size) * dmap->user_frame_size; /* Truncate to frame size */
+ if (dmap->flags & DMAP_COOKED)
+ {
+ /*
+ * Reserve some space for format conversions. Sample rate conversions
+ * may not always be able to take the "last" sample with fractional conversion
+ * ratios.
+ */
+ if (info->bytes >= dmap->frame_size)
+ info->bytes -= dmap->frame_size; /* Substract one sample. */
+ }
+ info->fragments = info->bytes / info->fragsize;
+
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ if (info->bytes > info->fragsize * info->fragstotal)
+ info->bytes = info->fragsize * info->fragstotal;
+
+ return 0;
+}
+
+static int
+get_ispace (adev_p adev, dmap_p dmap, ioctl_arg arg)
+{
+ audio_buf_info *info = (audio_buf_info *) arg;
+ oss_native_word flags;
+
+ memset ((char *) info, 0, sizeof (audio_buf_info));
+
+ setup_fragments (adev, dmap, OPEN_READ);
+ prepare_input (adev, dmap);
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ info->fragstotal = dmap->nfrags;
+ info->fragsize = (dmap->fragment_size * UNIT_EXPAND) / dmap->expand_factor;
+
+ /* Make sure we report full samples */
+ info->fragsize =
+ ((info->fragsize + dmap->user_frame_size -
+ 1) / dmap->user_frame_size) * dmap->user_frame_size;
+
+ if (!(adev->open_mode & OPEN_READ))
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ cmn_err (CE_WARN,
+ "SNDCTL_DSP_GETISPACE cannot be called in write-only mode.\n");
+ return OSS_EACCES;
+ }
+
+ if (dmap->mapping_flags & DMA_MAP_MAPPED)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ cmn_err (CE_WARN,
+ "SNDCTL_DSP_GETISPACE cannot be called in mmap mode.\n");
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1003, "GETISPACE called in mmap mode"), 0);
+ /* Errordesc:
+ * Do not call SNDCTL_DSP_GETISPACE in mmap mode.
+ * SNDCTL_DSP_GETISPACE is defined only for applications that
+ * use the normal write() method.
+ * Applications that use mmap can call SNDCTL_DSP_GETISPACE before calling
+ * mmap to get the actual buffer size.
+ */
+ return OSS_EPERM;
+ }
+
+ if (!(dmap->flags & DMAP_STARTED))
+ {
+/*
+ * A stupid application has called GETISPACE before recording has started.
+ * The right behaviour would definitely be returning bytes=0. However
+ * reporting one ready fragment will keep poor programmers happy.
+ * After all this is a minor error because no properly written application
+ * should ever call GETISPACE before starting recording.
+ */
+ info->bytes = info->fragsize;
+ info->fragments = 1;
+
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ if (info->bytes > info->fragsize * info->fragstotal)
+ info->bytes = info->fragsize * info->fragstotal;
+ if (adev->getispace_error_count++ == 1) /* Second time this happens */
+ {
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1004,
+ "GETISPACE called before recording has been started"),
+ 0);
+ /*
+ * Errordesc:
+ * There is no recoded data available before recording has been started.
+ * This would result in situation where the application waits infinitely
+ * for recorded data that never arrives. As a workaround
+ * SNDCTL_DSP_GETISPACE will fake that one fragment is already available
+ * to read. This in turn makes the application to block incorrectly.
+ *
+ * Applications must start recording before calling SNDCTL_DSP_GETISPACE
+ * if they are trying to avoid blocking. This can be done by calling
+ * SNDCTL_DSP_SETTRIGGER.
+ *
+ * However applications going to use mmap can/should call
+ * SNDCTL_DSP_GETISPACE in the beginning to find out how large buffer to
+ * map. In such case this event is a false alarm.
+ */
+ }
+ return 0;
+ }
+
+ info->bytes = (unsigned int) (dmap->byte_counter - dmap->user_counter);
+
+ if (dmap->flags & DMAP_COOKED)
+ {
+ /* Count the already converted bytes in the tmp buffer */
+ int nn = dmap->tmpbuf_len - dmap->tmpbuf_ptr;
+
+ if (nn > 0)
+ info->bytes += nn;
+ }
+
+ if (info->bytes > dmap->bytes_in_use)
+ info->bytes = dmap->bytes_in_use;
+
+ info->bytes = (info->bytes * UNIT_EXPAND) / dmap->expand_factor;
+ info->bytes = (info->bytes / dmap->user_frame_size) * dmap->user_frame_size;
+ info->fragments = info->bytes / info->fragsize;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ if (info->bytes > info->fragsize * info->fragstotal)
+ info->bytes = info->fragsize * info->fragstotal;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("GETISPACE(%d,%d,%d,%d)", info->bytes, info->fragments,
+ info->fragsize, info->fragstotal);
+#endif
+ return 0;
+}
+
+#define xrand(seed) (seed=1664525*seed+1013904223)
+
+static void
+setfragment_error (int dev)
+{
+ if (audio_engines[dev]->setfragment_warned)
+ return;
+
+ oss_audio_set_error (dev, E_PLAY,
+ OSSERR (1011,
+ "SNDCTL_DSP_SETFRAGMENT was called too late."),
+ 0);
+ /*
+ * Errordesc: The SNDCTL_DSP_SETFRAGMENT call is only valid immediately after
+ * opening the device. It can only be called once without reopening
+ * the audio device.
+ *
+ * Calling read/write or certain ioctl calls will lock the fragment size/count
+ * to some values which makes changing it impossible.
+ */
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Setfragment called twice");
+#endif
+
+ audio_engines[dev]->setfragment_warned = 1;
+}
+
+static int
+handle_syncgroup (adev_p adev, oss_syncgroup * group)
+{
+ int id, sync_dev;
+ adev_p sync_adev;
+
+ if (adev->sync_group != 0)
+ {
+ return OSS_EBUSY;
+ }
+
+ if (group->id == 0)
+ {
+ if (adev->engine_num > SYNC_DEVICE_MASK)
+ {
+ cmn_err (CE_WARN, "Bad device number %d\n", adev->engine_num);
+ return OSS_EIO;
+ }
+
+ id = xrand (sync_seed) & ~SYNC_DEVICE_MASK; /* Clear the engine number field */
+ id |= adev->engine_num;
+
+ group->id = id;
+ sync_dev = adev->engine_num;
+ adev->sync_next = NULL;
+ }
+ else
+ {
+ id = group->id;
+ sync_dev = id & SYNC_DEVICE_MASK;
+ }
+
+ if (sync_dev < 0 || sync_dev >= num_audio_engines)
+ {
+ group->id = 0;
+ return OSS_EINVAL;
+ }
+
+ sync_adev = audio_engines[sync_dev];
+
+ if (sync_dev == adev->engine_num)
+ adev->sync_flags |= SYNC_MASTER;
+ else
+ {
+ if (!(sync_adev->sync_flags & SYNC_MASTER))
+ {
+ return OSS_EINVAL;
+ }
+
+ if (sync_adev->sync_group != id)
+ {
+ return OSS_EINVAL;
+ }
+
+ adev->sync_flags |= SYNC_SLAVE;
+ }
+
+ group->mode &= (PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT);
+ group->mode &= adev->open_mode;
+ if (group->mode == 0)
+ {
+ adev->sync_flags = 0;
+ return OSS_EINVAL;
+ }
+
+ adev->sync_mode = group->mode;
+ adev->sync_group = id;
+ if (adev->d->adrv_sync_control != NULL)
+ adev->d->adrv_sync_control (adev->engine_num, SYNC_ATTACH,
+ adev->sync_mode);
+
+ if (adev != sync_adev)
+ {
+ adev->sync_next = sync_adev->sync_next;
+ sync_adev->sync_next = adev;
+ }
+
+ adev->go = 0;
+
+ return 0;
+}
+
+static int
+handle_syncstart (int orig_dev, int group)
+{
+ int master_dev, arg;
+ adev_p adev, next;
+
+ master_dev = group & SYNC_DEVICE_MASK;
+ if (master_dev < 0 || master_dev >= num_audio_engines)
+ return OSS_EINVAL;
+
+ adev = audio_engines[master_dev];
+
+ if (!(adev->sync_flags & SYNC_MASTER) ||
+ master_dev != orig_dev)
+ {
+ /*
+ * Potential attack. SYNCSTART was called on wrong file descriptor.
+ */
+ return OSS_EPERM;
+ }
+
+ if (adev->sync_group != group)
+ return OSS_EINVAL;
+
+/*
+ * Pass 1: Inform all devices about the actual start command to come soon.
+ */
+
+ while (adev != NULL)
+ {
+
+ if (adev->sync_group == group)
+ {
+ adev->go = 0;
+
+ if (adev->d->adrv_sync_control)
+ {
+ if (adev->sync_mode & PCM_ENABLE_INPUT)
+ {
+ if (!(adev->dmap_in->flags & DMAP_PREPARED))
+ {
+ adev->dmap_in->dma_mode = PCM_ENABLE_INPUT;
+ prepare_input (adev, adev->dmap_in);
+ }
+ launch_input (adev, adev->dmap_in);
+ }
+ if (adev->sync_mode & PCM_ENABLE_OUTPUT)
+ {
+ dmap_p dmap = adev->dmap_out;
+ int err;
+
+ if (adev->dmap_out->mapping_flags & DMA_MAP_MAPPED)
+ dmap->dma_mode = PCM_ENABLE_OUTPUT;
+ if ((err = prepare_output (adev, adev->dmap_out)) < 0)
+ return err;
+ launch_output (adev, adev->dmap_out);
+ }
+ adev->d->adrv_sync_control (adev->engine_num, SYNC_PREPARE,
+ adev->sync_mode);
+ }
+ else
+ {
+ arg = 0;
+ oss_audio_ioctl (adev->engine_num, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & arg);
+ }
+ }
+ else
+ {
+ cmn_err (CE_NOTE, "Broken sync chain\n");
+ }
+
+ adev = adev->sync_next;
+ }
+
+/*
+ * Pass 2: Deliver the actual start commands.
+ */
+
+ adev = audio_engines[master_dev];
+
+ while (adev != NULL)
+ {
+
+ if (adev->sync_group == group)
+ {
+ adev->go = 1;
+
+ if (adev->d->adrv_sync_control)
+ adev->d->adrv_sync_control (adev->engine_num, SYNC_TRIGGER,
+ adev->sync_mode);
+ else
+ {
+ arg = adev->sync_mode;
+ oss_audio_ioctl (adev->engine_num, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & arg);
+ }
+ }
+ else
+ {
+ /* Skip this one */
+ adev = adev->sync_next;
+ continue;
+ }
+
+ next = adev->sync_next;
+ adev->sync_next = NULL;
+ adev->sync_flags = 0;
+ adev->sync_group = 0;
+
+ adev = next;
+ }
+ return 0;
+}
+
+#ifdef DO_TIMINGS
+static char *
+find_ioctl_name (unsigned int cmd, ioctl_arg val)
+{
+ static char tmp[32];
+
+ typedef struct
+ {
+ unsigned int code;
+ char *name;
+ int flags;
+#define IOF_DEC 0x00000001
+#define IOF_HEX 0x00000002
+ } ioctl_def_t;
+
+ static ioctl_def_t call_names[] = {
+ {SNDCTL_DSP_HALT, "SNDCTL_DSP_HALT"},
+ {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+ {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED", IOF_DEC},
+ {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO", IOF_DEC},
+ {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+ {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS", IOF_DEC},
+ {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+ {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+ {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT", IOF_HEX},
+ {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+ {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT", IOF_HEX},
+ {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+ {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+ {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+ {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+ {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER", IOF_HEX},
+ {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+ {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+ {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO", IOF_HEX},
+ {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+ {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+ {SNDCTL_DSP_GETPLAYVOL, "SNDCTL_DSP_GETPLAYVOL"},
+ {SNDCTL_DSP_SETPLAYVOL, "SNDCTL_DSP_SETPLAYVOL", IOF_HEX},
+ {SNDCTL_DSP_GETRECVOL, "SNDCTL_DSP_GETRECVOL"},
+ {SNDCTL_DSP_SETRECVOL, "SNDCTL_DSP_SETRECVOL", IOF_HEX},
+ {SNDCTL_DSP_GETERROR, "SNDCTL_DSP_GETERROR"},
+ {SNDCTL_DSP_READCTL, "SNDCTL_DSP_READCTL"},
+ {SNDCTL_DSP_WRITECTL, "SNDCTL_DSP_WRITECTL"},
+ {SNDCTL_DSP_SYNCGROUP, "SNDCTL_DSP_SYNCGROUP"},
+ {SNDCTL_DSP_SYNCSTART, "SNDCTL_DSP_SYNCSTART"},
+ {SNDCTL_DSP_COOKEDMODE, "SNDCTL_DSP_COOKEDMODE", IOF_DEC},
+ {SNDCTL_DSP_SILENCE, "SNDCTL_DSP_SILENCE"},
+ {SNDCTL_DSP_SKIP, "SNDCTL_DSP_SKIP"},
+ {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+ {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+ {SNDCTL_DSP_HALT_INPUT, "SNDCTL_DSP_HALT_INPUT"},
+ {SNDCTL_DSP_HALT_OUTPUT, "SNDCTL_DSP_HALT_OUTPUT"},
+ {SNDCTL_DSP_LOW_WATER, "SNDCTL_DSP_LOW_WATER"},
+#ifndef OSS_NO_LONG_LONG
+ {SNDCTL_DSP_CURRENT_IPTR, "SNDCTL_DSP_CURRENT_IPTR"},
+ {SNDCTL_DSP_CURRENT_OPTR, "SNDCTL_DSP_CURRENT_OPTR"},
+#endif
+ {SNDCTL_DSP_GET_RECSRC, "SNDCTL_DSP_GET_RECSRC"},
+ {SNDCTL_DSP_SET_RECSRC, "SNDCTL_DSP_SET_RECSRC"},
+ {SNDCTL_DSP_GET_RECSRC_NAMES, "SNDCTL_DSP_GET_RECSRC_NAMES"},
+ {SNDCTL_DSP_GET_PLAYTGT, "SNDCTL_DSP_GET_PLAYTGT"},
+ {SNDCTL_DSP_SET_PLAYTGT, "SNDCTL_DSP_SET_PLAYTGT"},
+ {SNDCTL_DSP_GET_PLAYTGT_NAMES, "SNDCTL_DSP_GET_PLAYTGT_NAMES"},
+ {0, NULL}
+ };
+
+ int i;
+ for (i = 0; call_names[i].code != 0; i++)
+ if (call_names[i].code == cmd)
+ {
+ int flags = call_names[i].flags;
+
+ if (flags & IOF_DEC)
+ {
+ sprintf (tmp, "%s, *%d", call_names[i].name, *val);
+ return tmp;
+ }
+
+ if (flags & IOF_HEX)
+ {
+ sprintf (tmp, "%s, *0x%08x", call_names[i].name, *val);
+ return tmp;
+ }
+
+ return call_names[i].name;
+ }
+
+ sprintf (tmp, "Unknown %08x", cmd);
+ return tmp;
+}
+#endif
+
+/*ARGSUSED*/
+int
+oss_encode_enum (oss_mixer_enuminfo * ei, const char *s, int version)
+{
+ int n = 1, l;
+ int i;
+
+ memset (ei, 0, sizeof (*ei)); /* Wipe out everything */
+
+ strncpy (ei->strings, s, sizeof (ei->strings) - 1);
+ ei->strings[sizeof (ei->strings) - 1] = 0;
+
+ ei->strindex[0] = 0;
+
+ l = strlen (ei->strings);
+ for (i = 0; i < l; i++)
+ {
+ if (ei->strings[i] == ' ')
+ {
+ ei->strindex[n++] = i + 1;
+ ei->strings[i] = 0;
+ }
+ }
+
+ ei->nvalues = n;
+
+ return 0;
+}
+
+static int
+get_legacy_recsrc_names (int dev, oss_mixer_enuminfo * ei)
+{
+ static const char *labels[] = SOUND_DEVICE_NAMES;
+
+ int i, mixer_dev, recmask, devmask, caps, n;
+ char *s;
+
+ if (audio_engines[dev]->mixer_dev < 0) /* No mixer */
+ return 0;
+
+ mixer_dev = audio_engines[dev]->mixer_dev;
+
+
+ if (oss_legacy_mixer_ioctl
+ (mixer_dev, -1, SOUND_MIXER_READ_CAPS, (ioctl_arg) & caps) < 0)
+ caps = 0; /* Error */
+
+ if (caps & SOUND_CAP_NORECSRC)
+ return 0;
+
+ if (oss_legacy_mixer_ioctl
+ (mixer_dev, -1, SOUND_MIXER_READ_DEVMASK, (ioctl_arg) & devmask) < 0)
+ return 0; /* Error */
+
+ if (oss_legacy_mixer_ioctl
+ (mixer_dev, -1, SOUND_MIXER_READ_RECMASK, (ioctl_arg) & recmask) < 0)
+ return 0; /* Error */
+
+ recmask &= devmask;
+ if (recmask == 0)
+ return 0;
+
+ n = 0;
+ s = ei->strings;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if (recmask & (1 << i)) /* This control is also recording device */
+ {
+ /*LINTED*/ ei->strindex[n] = s - ei->strings;
+
+ strcpy (s, labels[i]);
+ s += strlen (s);
+ *s++ = 0;
+ n++;
+ }
+
+ ei->nvalues = n;
+
+ return (n > 0);
+}
+
+static int
+get_legacy_recsrc (int dev)
+{
+ int i, mixer_dev, recmask, recsrc, caps, n;
+
+ if (audio_engines[dev]->mixer_dev < 0) /* No mixer */
+ return 0;
+
+ mixer_dev = audio_engines[dev]->mixer_dev;
+
+
+ if (oss_legacy_mixer_ioctl
+ (mixer_dev, -1, SOUND_MIXER_READ_CAPS, (ioctl_arg) & caps) < 0)
+ caps = 0; /* Error */
+
+ if (caps & SOUND_CAP_NORECSRC)
+ return 0;
+
+ if (oss_legacy_mixer_ioctl
+ (mixer_dev, -1, SOUND_MIXER_READ_RECSRC, (ioctl_arg) & recsrc) < 0)
+ return 0; /* Error */
+
+ if (oss_legacy_mixer_ioctl
+ (mixer_dev, -1, SOUND_MIXER_READ_RECMASK, (ioctl_arg) & recmask) < 0)
+ return 0; /* Error */
+
+ if (recmask == 0 || recsrc == 0)
+ return 0;
+
+ n = 0;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if (recmask & (1 << i)) /* This control is also recording device */
+ {
+ if (recsrc & (1 << i)) /* It was this one */
+ return n;
+ n++;
+ }
+
+
+ return 0;
+}
+
+static int
+set_legacy_recsrc (int dev, int val)
+{
+ int i, mixer_dev, recmask, recsrc, caps, n;
+
+ if (audio_engines[dev]->mixer_dev < 0) /* No mixer */
+ return 0;
+
+ mixer_dev = audio_engines[dev]->mixer_dev;
+
+
+ if (oss_legacy_mixer_ioctl
+ (mixer_dev, -1, SOUND_MIXER_READ_CAPS, (ioctl_arg) & caps) < 0)
+ caps = 0; /* Error */
+
+ if (caps & SOUND_CAP_NORECSRC)
+ return 0;
+
+ if (oss_legacy_mixer_ioctl
+ (mixer_dev, -1, SOUND_MIXER_READ_RECMASK, (ioctl_arg) & recmask) < 0)
+ return 0; /* Error */
+
+ if (recmask == 0)
+ return 0;
+
+ n = 0;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if (recmask & (1 << i)) /* This control is also recording device */
+ {
+ if (n == val)
+ {
+ recsrc = (1 << i);
+
+ if (oss_legacy_mixer_ioctl
+ (mixer_dev, -1, SOUND_MIXER_WRITE_RECSRC,
+ (ioctl_arg) & recsrc) < 0)
+ return 0; /* Error */
+
+ return 1;
+ }
+ n++;
+ }
+
+
+ return 0;
+}
+
+/*ARGSUSED*/
+int
+oss_audio_ioctl (int dev, struct fileinfo *bogus,
+ unsigned int cmd, ioctl_arg arg)
+{
+ int val, err;
+ int mixdev;
+ int ret;
+ adev_p adev;
+ dmap_p dmapin, dmapout;
+ oss_native_word flags;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("oss_audio_ioctl(%d, %s)", dev, find_ioctl_name (cmd, arg));
+#endif
+
+ if (cmd == OSS_GETVERSION)
+ return *arg = OSS_VERSION;
+
+ UP_STATUS (STS_IOCTL);
+ DOWN_STATUS (STS_IOCTL);
+ sync_seed++;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ adev = audio_engines[dev];
+ if (adev->unloaded)
+ return OSS_ENODEV;
+ if (!adev->enabled)
+ return OSS_ENXIO;
+
+ if (adev->d->adrv_ioctl_override != NULL)
+ {
+ /*
+ * Use the ioctl override function if available. However process the request
+ * in the usual way if the override function returned OSS_EAGAIN. It may
+ * be possible that the override function has modified the parameters
+ * before returning.
+ */
+ if ((err = adev->d->adrv_ioctl_override(dev, cmd, arg)) != OSS_EAGAIN)
+ return err;
+ }
+
+ dmapout = adev->dmap_out;
+ dmapin = adev->dmap_in;
+
+/*
+ * Handle mixer ioctl calls on audio fd.
+ */
+
+ if (cmd == SOUND_MIXER_WRITE_PCM) cmd = SNDCTL_DSP_SETPLAYVOL;
+ if (cmd == SOUND_MIXER_WRITE_RECLEV) cmd = SNDCTL_DSP_SETRECVOL;
+ if (cmd == SOUND_MIXER_READ_PCM) cmd = SNDCTL_DSP_GETPLAYVOL;
+ if (cmd == SOUND_MIXER_READ_RECLEV) cmd = SNDCTL_DSP_GETRECVOL;
+
+ if ((mixdev = adev->mixer_dev) != -1)
+ {
+ if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0) /* Mixer ioctl */
+ if ((ret = oss_legacy_mixer_ioctl (mixdev, dev, cmd, arg)) != OSS_EINVAL)
+ return ret;
+ }
+
+ if (((cmd >> 8) & 0xff) == 'X') /* Mixer extension API */
+ return oss_mixer_ext (adev->engine_num, OSS_DEV_DSP, cmd, arg);
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_SYNC:
+ oss_audio_sync (adev);
+ return 0;
+ break;
+
+ case SNDCTL_DSP_POST:
+ oss_audio_post (adev);
+ return 0;
+ break;
+
+ case SNDCTL_DSP_HALT:
+ audio_reset_adev (adev);
+ return 0;
+ break;
+
+ case SNDCTL_DSP_HALT_INPUT:
+ audio_reset_input (adev);
+ return 0;
+ break;
+
+ case SNDCTL_DSP_LOW_WATER:
+ val = *arg;
+ if (adev->open_mode & OPEN_READ)
+ adev->dmap_in->low_water = val;
+ if (adev->open_mode & OPEN_WRITE)
+ adev->dmap_out->low_water = val;
+ return 0;
+ break;
+
+ case SNDCTL_DSP_HALT_OUTPUT:
+ audio_reset_output (adev);
+ return 0;
+ break;
+
+ case SNDCTL_DSP_GETFMTS:
+ switch (adev->open_mode & (OPEN_READ | OPEN_WRITE))
+ {
+ case OPEN_WRITE:
+ return *arg = (adev->oformat_mask);
+ break;
+
+ case OPEN_READ:
+ return *arg = (adev->oformat_mask);
+ break;
+
+ default:
+ return *arg = (adev->xformat_mask);
+ break;
+ }
+ break;
+
+ case SNDCTL_DSP_SETFMT:
+ val = *arg;
+ switch (adev->open_mode & (OPEN_READ | OPEN_WRITE))
+ {
+ case OPEN_WRITE:
+ return *arg = (oss_audio_set_format (dev, val,
+ audio_engines
+ [dev]->oformat_mask));
+ break;
+
+ case OPEN_READ:
+ return *arg = (oss_audio_set_format (dev, val,
+ audio_engines
+ [dev]->iformat_mask));
+ break;
+
+ default:
+ return *arg = (oss_audio_set_format (dev, val,
+ audio_engines
+ [dev]->oformat_mask &
+ audio_engines
+ [dev]->iformat_mask));
+ break;
+ }
+
+ case SNDCTL_DSP_GETOSPACE:
+ if (!(adev->dmask & DMASK_OUT))
+ {
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1001,
+ "GETOSPACE called in read-only mode"),
+ 0);
+ /* Errordesc: SNDCTL_DSP_GETOSPACE is not defined in read-only access mode */
+ return OSS_ENOTSUP;
+ }
+ ret = get_ospace (adev, dmapout, arg);
+#ifdef DO_TIMINGS
+ {
+ audio_buf_info *info = (audio_buf_info *) arg;
+ oss_timing_printf ("GETOSPACE(b=%d,f=%d,fsz=%d,ft=%d)=%d", info->bytes,
+ info->fragments, info->fragsize, info->fragstotal, ret);
+ oss_timing_printf ("Low water %d, ap flags=%x, tmpbuf=%d/%d",
+ dmapout->low_water, adev->open_flags, dmapout->tmpbuf_ptr,
+ dmapout->tmpbuf_len);
+ }
+#endif
+ return ret;
+ break;
+
+ case SNDCTL_DSP_GETISPACE:
+ if (!(adev->dmask & DMASK_IN))
+ {
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1002,
+ "GETISPACE called in write-only mode"),
+ 0);
+ /*
+ * Errordesc: SNDCTL_DSP_GETISPACE has no defined meaning when the audio
+ * device is opened in write-only mode.
+ */
+ return OSS_ENOTSUP;
+ }
+
+ return get_ispace (adev, dmapin, arg);
+ break;
+
+ case SNDCTL_DSP_GETODELAY:
+ if (!(adev->dmask & DMASK_OUT))
+ {
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1005,
+ "GETODELAY called in read-only mode"),
+ 0);
+ return OSS_ENOTSUP;
+ }
+ return get_odelay (adev, dmapout, arg);
+ break;
+
+ case SNDCTL_DSP_SETDUPLEX:
+ /*
+ * Note! SNDCTL_DSP_SETDUPLEX has not been implemented by any driver for years.
+ * The call is still implemented in audio core but it may get removed in the
+ * future.
+ */
+ if (adev->open_mode != OPEN_READWRITE)
+ {
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1006,
+ "SETDUPLEX called in non-read/write mode"),
+ 0);
+ return OSS_ENOTSUP;
+ }
+ if (adev->flags & ADEV_DUPLEX)
+ {
+ if (adev->d->adrv_ioctl == NULL)
+ return 0;
+ val = adev->d->adrv_ioctl (dev, cmd, arg);
+ if (val == OSS_EINVAL)
+ return 0;
+ else
+ return val;
+ }
+ else
+ {
+ return OSS_ENOTSUP;
+ }
+ break;
+
+ case SNDCTL_DSP_COOKEDMODE:
+ val = *arg;
+
+ if (adev->flags & ADEV_NONINTERLEAVED)
+ val=1;
+
+ adev->cooked_enable = !!val;
+ if (adev->d->adrv_ioctl != NULL)
+ adev->d->adrv_ioctl (dev, cmd, arg);
+#ifdef DO_TIMINGS
+ if (adev->cooked_enable)
+ oss_do_timing ("Setting cooked mode ON");
+ else
+ oss_do_timing ("Setting cooked mode OFF");
+#endif
+ return 0;
+ break;
+
+ case SNDCTL_DSP_GETCAPS:
+ {
+ int info;
+ info = audio_engines[dev]->caps;
+ info |= 2; /* Revision level of this ioctl() */
+
+#if 0
+ if (!(adev->flags & ADEV_VIRTUAL) && !adev->d->adrv_local_qlen)
+#endif
+ info |= PCM_CAP_REALTIME;
+
+
+ if (!(adev->flags & ADEV_NOINPUT))
+ info |= PCM_CAP_INPUT;
+
+ if (!(adev->flags & ADEV_NOOUTPUT))
+ info |= PCM_CAP_OUTPUT;
+
+ if ((adev->flags & ADEV_VIRTUAL))
+ info |= PCM_CAP_VIRTUAL;
+
+ if (!(adev->flags & ADEV_NOINPUT) && !(adev->flags & ADEV_NOOUTPUT))
+ if (adev->flags & ADEV_DUPLEX && adev->open_mode == OPEN_READWRITE)
+ info |= PCM_CAP_DUPLEX;
+
+ if (dev > 0)
+ if (adev->flags & ADEV_SPECIAL)
+ info |= PCM_CAP_SPECIAL;
+
+ if (dev < num_audio_engines - 1)
+ {
+ if (audio_engines[dev + 1]->flags & ADEV_SHADOW)
+ info |= PCM_CAP_MULTI;
+ }
+
+ if (adev->d->adrv_local_qlen) /* Device has hidden buffers */
+ info |= PCM_CAP_BATCH;
+
+ if (adev->d->adrv_trigger) /* Supports SETTRIGGER */
+ info |= PCM_CAP_TRIGGER;
+
+#ifdef ALLOW_BUFFER_MAPPING
+ info |= PCM_CAP_MMAP;
+#endif
+ if (!(adev->flags & ADEV_NOINPUT))
+ info |= PCM_CAP_INPUT;
+
+ if (!(adev->flags & ADEV_NOOUTPUT))
+ info |= PCM_CAP_OUTPUT;
+
+ if (adev->d->adrv_bind != NULL)
+ info |= PCM_CAP_BIND;
+ /*
+ * TODO: ADEV_DEFAULT is not the right way to find out
+ * PCM_CAP_DEFAULT devices. A new ADEV_ flag should be defined
+ * for this purpose.
+ */
+ if (adev->flags & ADEV_DEFAULT)
+ info |= PCM_CAP_DEFAULT;
+
+ return *arg = (info);
+ }
+ break;
+
+ case SNDCTL_DSP_NONBLOCK:
+ adev->forced_nonblock = 1;
+ return 0;
+ break;
+
+ case SNDCTL_DSP_GETCHANNELMASK:
+ case SNDCTL_DSP_BIND_CHANNEL:
+ if (adev->d->adrv_bind == NULL)
+ return OSS_EINVAL;
+ return adev->d->adrv_bind (adev->engine_num, cmd, arg);
+ break;
+
+ case SNDCTL_DSP_SETTRIGGER:
+ {
+ int val;
+
+ if (!adev->d->adrv_trigger)
+ {
+ cmn_err (CE_NOTE, "Device %d doesn't have trigger capability\n",
+ adev->engine_num);
+ return OSS_EIO;
+ }
+
+ val = *arg;
+ val &= PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
+ val &= adev->open_mode;
+
+ if ((val & adev->open_mode) != (adev->enable_bits & adev->open_mode))
+ {
+ if ((val & PCM_ENABLE_OUTPUT)
+ && !(adev->enable_bits & PCM_ENABLE_OUTPUT))
+ {
+ dmap_p dmap = adev->dmap_out;
+ oss_native_word flags;
+ if (adev->dmap_out->mapping_flags & DMA_MAP_MAPPED)
+ dmap->dma_mode = PCM_ENABLE_OUTPUT;
+ if ((err = prepare_output (adev, adev->dmap_out)) < 0)
+ return err;
+ launch_output (adev, adev->dmap_out);
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ adev->enable_bits &= PCM_ENABLE_OUTPUT;
+ adev->enable_bits |= val & PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ }
+
+ if ((val & PCM_ENABLE_INPUT)
+ && !(adev->enable_bits & PCM_ENABLE_INPUT))
+ {
+ dmap_p dmap = adev->dmap_in;
+ oss_native_word flags;
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ dmap->dma_mode = PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ if ((err = prepare_input (adev, adev->dmap_in)) < 0)
+ return err;
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ launch_input (adev, adev->dmap_in);
+ adev->enable_bits &= PCM_ENABLE_INPUT;
+ adev->enable_bits |= val & PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ }
+
+ adev->enable_bits = val;
+ if (adev->enable_bits == 0 || adev->go) /* Device is enabled */
+ {
+ adev->d->adrv_trigger (adev->engine_num, adev->enable_bits);
+ }
+ }
+ *arg = val;
+ return 0;
+ }
+ break;
+
+ case SNDCTL_DSP_GETTRIGGER:
+ if (!adev->d->adrv_trigger)
+ {
+ cmn_err (CE_NOTE, "Device %d doesn't have trigger capability\n",
+ adev->engine_num);
+ return OSS_EIO;
+ }
+ return *arg = (adev->enable_bits & adev->open_mode);
+ break;
+
+ case SNDCTL_DSP_SETSYNCRO:
+ adev->go = 0;
+ break;
+
+ case SNDCTL_DSP_SYNCGROUP:
+ return handle_syncgroup (adev, (oss_syncgroup *) arg);
+ break;
+
+ case SNDCTL_DSP_SYNCSTART:
+ val = *arg;
+
+ MUTEX_ENTER_IRQDISABLE (audio_global_mutex, flags);
+ ret = handle_syncstart (adev->engine_num, val);
+ MUTEX_EXIT_IRQRESTORE (audio_global_mutex, flags);
+
+ return ret;
+ break;
+
+ case SNDCTL_DSP_GETERROR:
+ {
+ audio_errinfo *info = (audio_errinfo *) arg;
+
+ memset ((void *) info, 0, sizeof (*info));
+
+ //if (audio_engines[dev]->open_mode & OPEN_READ)
+ {
+ dmap_t *dmap = audio_engines[dev]->dmap_in;
+
+ info->rec_overruns = dmap->rec_overruns;
+ dmap->rec_overruns = 0;
+ info->rec_ptradjust = 0;
+ info->rec_errorcount = dmap->num_errors;
+ info->rec_lasterror = dmap->errors[0];
+ info->rec_errorparm = dmap->error_parms[0];
+ }
+
+ //if (audio_engines[dev]->open_mode & OPEN_WRITE)
+ {
+ dmap_t *dmap = audio_engines[dev]->dmap_out;
+
+ info->play_underruns = dmap->play_underruns;
+ dmap->play_underruns = 0;
+ info->play_ptradjust = 0;
+ info->play_errorcount = dmap->num_errors;
+ info->play_lasterror = dmap->errors[0];
+ info->play_errorparm = dmap->error_parms[0];
+ }
+
+ return 0;
+ }
+ break;
+
+ case SNDCTL_DSP_GETPLAYVOL:
+ case SNDCTL_DSP_SETPLAYVOL:
+ {
+ int err, mixdev;
+
+ mixdev = adev->mixer_dev;
+ if (cmd == SNDCTL_DSP_SETPLAYVOL && mixdev >= 0
+ && mixdev < num_mixers)
+ mixer_devs[mixdev]->modify_counter++;
+
+ if (adev->d->adrv_ioctl == NULL
+ || (err = adev->d->adrv_ioctl (dev, cmd, arg)) == OSS_EINVAL)
+ {
+ /* Emulate these calls using mixer API */
+
+ if (mixdev < 0 || mixdev >= num_mixers)
+ return OSS_EINVAL;
+
+ if (cmd == SNDCTL_DSP_GETPLAYVOL)
+ cmd = SOUND_MIXER_READ_PCM;
+ else
+ cmd = SOUND_MIXER_WRITE_PCM;
+ return mixer_devs[mixdev]->d->ioctl (mixdev, dev, cmd, arg);
+ }
+ return err;
+ }
+ break;
+
+ case SNDCTL_DSP_GETRECVOL:
+ case SNDCTL_DSP_SETRECVOL:
+ {
+ int err, mixdev;
+
+ mixdev = adev->mixer_dev;
+ if (cmd == SNDCTL_DSP_SETRECVOL && mixdev >= 0 && mixdev < num_mixers)
+ mixer_devs[mixdev]->modify_counter++;
+
+ if (adev->d->adrv_ioctl == NULL
+ || (err = adev->d->adrv_ioctl (dev, cmd, arg)) == OSS_EINVAL)
+ {
+ /* Emulate these calls using mixer API */
+
+ if (mixdev < 0 || mixdev >= num_mixers)
+ return OSS_EINVAL;
+
+ /* Try with RECGAIN */
+ if (cmd == SNDCTL_DSP_GETRECVOL)
+ cmd = SOUND_MIXER_READ_RECGAIN;
+ else
+ cmd = SOUND_MIXER_WRITE_RECGAIN;
+ err = mixer_devs[mixdev]->d->ioctl (mixdev, dev, cmd, arg);
+
+ /* Try with RECLEV */
+ if (cmd == SNDCTL_DSP_GETRECVOL)
+ cmd = SOUND_MIXER_READ_RECLEV;
+ else
+ cmd = SOUND_MIXER_WRITE_RECLEV;
+ err = mixer_devs[mixdev]->d->ioctl (mixdev, dev, cmd, arg);
+
+ if (err >= 0) /* Was OK */
+ return err;
+
+ /* Try with IGAIN */
+ if (cmd == SNDCTL_DSP_GETRECVOL)
+ cmd = SOUND_MIXER_READ_IGAIN;
+ else
+ cmd = SOUND_MIXER_WRITE_IGAIN;
+ return mixer_devs[mixdev]->d->ioctl (mixdev, dev, cmd, arg);
+ }
+ return err;
+ }
+ break;
+
+ case SNDCTL_DSP_GETOPTR:
+ if (!(adev->dmask & DMASK_OUT))
+ {
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1007,
+ "GETOPTR called in read-only mode"),
+ 0);
+ return OSS_ENOTSUP;
+ }
+ return get_optr (adev, dmapout, arg);
+ break;
+
+ case SNDCTL_DSP_GETIPTR:
+ if (!(adev->dmask & DMASK_IN))
+ {
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1008,
+ "GETIPTR called in write-only mode"),
+ 0);
+ return OSS_ENOTSUP;
+ }
+ return get_iptr (adev, dmapin, arg);
+ break;
+
+#ifndef OSS_NO_LONG_LONG
+ case SNDCTL_DSP_CURRENT_OPTR:
+ if (!(adev->dmask & DMASK_OUT))
+ return OSS_ENOTSUP;
+ return get_long_optr (adev, dmapout, arg);
+ break;
+
+ case SNDCTL_DSP_CURRENT_IPTR:
+ if (!(adev->dmask & DMASK_IN))
+ return OSS_ENOTSUP;
+ return get_long_iptr (adev, dmapin, arg);
+ break;
+#endif
+
+ case SNDCTL_DSP_POLICY:
+ val = *arg;
+ if (val < 0 || val > 10)
+ return OSS_EIO;
+ adev->policy = val;
+ return 0;
+ break;
+
+ case SNDCTL_DSP_SETFRAGMENT:
+ case SNDCTL_DSP_SUBDIVIDE:
+ if (cmd == SNDCTL_DSP_SUBDIVIDE)
+ {
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1010,
+ "SNDCTL_DSP_SUBDIVIDE is obsolete"),
+ 0);
+ /*
+ * Errordesc:
+ * SNDCTL_DSP_SUBDIVIDE is obsolete. It's still emulated by OSS but
+ * the result is not precise. You need to use SNDCTL_DSP_SETFRAGMENT
+ * instead.
+ */
+ *arg = 0x00040008; /* Default to 4 fragments of 256 bytes */
+ }
+
+ val = *arg;
+ if (adev->dmask & DMASK_OUT)
+ {
+ if (dmapout->flags & DMAP_FRAGFIXED)
+ setfragment_error (dev);
+ dmapout->fragsize_rq = val;
+ }
+ if (adev->dmask & DMASK_IN)
+ {
+ if (dmapin->flags & DMAP_FRAGFIXED)
+ setfragment_error (dev);
+ dmapin->fragsize_rq = val;
+ }
+ return 0;
+
+#ifdef __FreeBSD__
+ case FREEBSD_GETBLKSIZE:
+#endif
+ case SNDCTL_DSP_GETBLKSIZE:
+ return *arg = getblksize (adev);
+
+ case SNDCTL_DSP_SPEED:
+ val = *arg;
+ if (val<0)
+ return OSS_EINVAL;
+ return *arg = (oss_audio_set_rate (dev, val));
+
+ case SNDCTL_DSP_STEREO:
+ {
+ int n, v;
+
+ n = *arg;
+ if (n > 1)
+ {
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1009,
+ "SNDCTL_DSP_STEREO called with bad agrument value"),
+ n);
+ /*
+ * Errordesc: SNDCTL_DSP_STEREO is an obsolete ioctl call that
+ * supports only mono (0) or stereo (1). For larger number of channels
+ * you need to use SNDCTL_DSP_CHANNELS instead.
+ */
+ return OSS_EINVAL;
+ }
+
+ if (n < 0)
+ return OSS_EINVAL;
+
+ v = oss_audio_set_channels (dev, n + 1);
+ return *arg = (v - 1);
+ }
+
+ case SNDCTL_DSP_CHANNELS:
+ {
+ int v;
+ val = *arg;
+#ifdef DO_TIMINGS
+ {
+ char tmp[128];
+
+ sprintf (tmp, "Set channels %d", (int) val);
+ oss_do_timing2 (DFLAG_PROFILE, tmp);
+ }
+#endif
+ if (val<0)
+ {
+ return OSS_EINVAL;
+ }
+ v = oss_audio_set_channels (dev, val);
+ return *arg = v;
+ }
+
+ case SNDCTL_DSP_PROFILE: /* Obsolete */
+ return 0;
+ break;
+
+ case SNDCTL_DSP_SILENCE:
+ memset (dmapout->dmabuf, dmapout->neutral_byte, dmapout->buffsize);
+ return 0;
+ break;
+
+ case SNDCTL_DSP_SKIP:
+ return 0;
+ break;
+
+ case SNDCTL_DSP_GET_RECSRC_NAMES:
+ if (adev->d->adrv_ioctl == NULL || (err = adev->d->adrv_ioctl (dev, cmd, arg)) == OSS_EINVAL) /* Not handled */
+ {
+ oss_mixer_enuminfo *ei = (oss_mixer_enuminfo *) arg;
+
+ memset (ei, 0, sizeof (*ei)); /* Wipe out everything */
+
+ if (get_legacy_recsrc_names (dev, ei))
+ return 0;
+ ei->nvalues = 1;
+ strcpy (ei->strings, "default");
+ return 0;
+ }
+ return err;
+ break;
+
+ case SNDCTL_DSP_GET_RECSRC:
+ if (adev->d->adrv_ioctl == NULL || (err = adev->d->adrv_ioctl (dev, cmd, arg)) == OSS_EINVAL) /* Not handled */
+ {
+ return *arg = (get_legacy_recsrc (dev));
+ }
+ return err;
+ break;
+
+ case SNDCTL_DSP_SET_RECSRC:
+ if (adev->d->adrv_ioctl == NULL || (err = adev->d->adrv_ioctl (dev, cmd, arg)) == OSS_EINVAL) /* Not handled */
+ {
+ val = *arg;
+ set_legacy_recsrc (dev, val);
+ return *arg = (get_legacy_recsrc (dev));
+ }
+ return err;
+ break;
+
+ case SNDCTL_DSP_GET_PLAYTGT_NAMES:
+ if (adev->d->adrv_ioctl == NULL || (err = adev->d->adrv_ioctl (dev, cmd, arg)) == OSS_EINVAL) /* Not handled */
+ {
+ oss_mixer_enuminfo *ei = (oss_mixer_enuminfo *) arg;
+ memset (ei, 0, sizeof (*ei));
+ ei->nvalues = 1;
+ strcpy (ei->strings, "default");
+ return 0;
+ }
+ return err;
+ break;
+
+ case SNDCTL_DSP_GET_PLAYTGT:
+ if (adev->d->adrv_ioctl == NULL || (err = adev->d->adrv_ioctl (dev, cmd, arg)) == OSS_EINVAL) /* Not handled */
+ {
+ return *arg = (0);
+ }
+ return err;
+ break;
+
+ case SNDCTL_DSP_SET_PLAYTGT:
+ if (adev->d->adrv_ioctl == NULL || (err = adev->d->adrv_ioctl (dev, cmd, arg)) == OSS_EINVAL) /* Not handled */
+ {
+ return *arg = (0);
+ }
+ return err;
+ break;
+
+ case SNDCTL_SETSONG:
+ if (adev->d->adrv_ioctl != NULL
+ && adev->d->adrv_ioctl (dev, cmd, arg) >= 0)
+ return 0;
+ strncpy (adev->song_name, (char *) arg, sizeof (adev->song_name));
+ adev->song_name[sizeof (adev->song_name) - 1] = 0;
+ return 0;
+ break;
+
+ case SNDCTL_SETLABEL:
+ if (adev->d->adrv_ioctl != NULL
+ && adev->d->adrv_ioctl (dev, cmd, arg) >= 0)
+ return 0;
+ strncpy (adev->label, (char *) arg, sizeof (adev->label));
+ adev->label[sizeof (adev->label) - 1] = 0;
+ if (*adev->cmd == 0) /* Command name not known */
+ strcpy (adev->cmd, adev->label);
+ return 0;
+ break;
+ default:
+ if (adev->d->adrv_ioctl == NULL)
+ return OSS_EINVAL;
+ return adev->d->adrv_ioctl (dev, cmd, arg);
+ }
+ return OSS_EINVAL;
+}
+
+
+static int
+prepare_output (adev_p adev, dmap_p dmap)
+{
+ int ret, data_rate = 0;
+ audio_format_info_p fmt_info;
+
+ if (dmap->flags & DMAP_PREPARED)
+ return 0;
+
+ data_rate = 8;
+
+ dmap->flags &= ~DMAP_COOKED;
+ adev->user_parms.convert = 0;
+ adev->hw_parms.convert = 0;
+ dmap->convert_func = NULL;
+ dmap->convert_mode = 0;
+ dmap->expand_factor = UNIT_EXPAND;
+
+ if (adev->user_parms.rate != adev->hw_parms.rate)
+ dmap->flags |= DMAP_COOKED;
+ if (adev->user_parms.fmt != adev->hw_parms.fmt)
+ dmap->flags |= DMAP_COOKED;
+ if (adev->user_parms.channels != adev->hw_parms.channels)
+ dmap->flags |= DMAP_COOKED;
+ if ((adev->flags & ADEV_NONINTERLEAVED) && adev->hw_parms.channels > 1)
+ dmap->flags |= DMAP_COOKED;
+
+#if 1
+ if (always_cooked && !(dmap->mapping_flags & DMA_MAP_MAPPED))
+ dmap->flags |= DMAP_COOKED;
+#endif
+
+ if ((dmap->mapping_flags & DMA_MAP_MAPPED) && (dmap->flags & DMAP_COOKED))
+ {
+ cmn_err (CE_WARN, "Internal error in mmap() support\n");
+ dmap->flags &= ~DMAP_COOKED;
+ }
+
+ if (dmap->flags & DMAP_COOKED)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Cooked mode - Setting up conversions");
+#endif
+ if ((ret =
+ setup_format_conversions (adev, dmap, &adev->user_parms,
+ &adev->hw_parms,
+ &adev->user_parms,
+ &adev->hw_parms,
+ adev->oformat_mask)) < 0)
+ {
+ return ret;
+ }
+ }
+ else
+ {
+ DDB (cmn_err (CE_CONT, "No format conversions needed\n"));
+#ifdef DO_TIMINGS
+ oss_do_timing ("No format conversions needed");
+#endif
+ }
+
+/*
+ * Compute device data rate and frame size
+ */
+ if ((fmt_info = oss_find_format (adev->hw_parms.fmt)) != NULL)
+ data_rate = fmt_info->bits;
+
+ data_rate /= 8;
+ if (data_rate < 1)
+ data_rate = 1;
+ data_rate *= adev->hw_parms.channels;
+ dmap->frame_size = data_rate;
+ data_rate *= adev->hw_parms.rate;
+ if (data_rate < 1)
+ data_rate = 8000;
+ dmap->data_rate = data_rate;
+
+/*
+ * Compute application/user frame_size
+ */
+ data_rate = 8;
+ if ((fmt_info = oss_find_format (adev->user_parms.fmt)) != NULL)
+ data_rate = fmt_info->bits;
+
+ data_rate /= 8;
+ if (data_rate < 1)
+ data_rate = 1;
+ data_rate *= adev->user_parms.channels;
+ dmap->user_frame_size = data_rate;
+
+ setup_fragments (adev, dmap, OPEN_WRITE);
+ if (dmap->expand_factor == 0)
+ {
+ dmap->expand_factor = UNIT_EXPAND;
+ cmn_err (CE_WARN, "Bad expand factor for device %d\n",
+ adev->engine_num);
+ }
+ if (dmap->low_water == -1)
+ {
+ dmap->low_water =
+ (dmap->low_water_rq * UNIT_EXPAND) / dmap->expand_factor;
+ }
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Prepare output dev=%d, fragsize=%d, nfrags=%d, bytes_in_use=%d/%d",
+ adev->engine_num, dmap->fragment_size, dmap->nfrags,
+ dmap->bytes_in_use, dmap->buffsize);
+#endif
+
+ if ((ret =
+ adev->d->adrv_prepare_for_output (adev->engine_num,
+ dmap->fragment_size,
+ dmap->nfrags)) < 0)
+ {
+ return ret;
+ }
+
+ dmap->flags |= DMAP_PREPARED;
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_PREPARE_OUTPUT);
+#endif
+
+ return 0;
+}
+
+static int
+prepare_input (adev_p adev, dmap_p dmap)
+{
+ int ret, data_rate = 0;
+ audio_format_info_p fmt_info;
+
+ if (dmap->flags & DMAP_PREPARED)
+ return 0;
+
+ data_rate = 0;
+
+ dmap->flags &= ~DMAP_COOKED;
+ adev->user_parms.convert = 0;
+ adev->hw_parms.convert = 0;
+ dmap->convert_func = NULL;
+ dmap->convert_mode = 0;
+ dmap->expand_factor = UNIT_EXPAND;
+
+ if (adev->user_parms.rate != adev->hw_parms.rate)
+ dmap->flags |= DMAP_COOKED;
+ if (adev->user_parms.fmt != adev->hw_parms.fmt)
+ dmap->flags |= DMAP_COOKED;
+ if (adev->user_parms.channels != adev->hw_parms.channels)
+ dmap->flags |= DMAP_COOKED;
+ if ((adev->flags & ADEV_NONINTERLEAVED) && adev->hw_parms.channels > 1)
+ dmap->flags |= DMAP_COOKED;
+
+#if 1
+ if (always_cooked && !(dmap->mapping_flags & DMA_MAP_MAPPED))
+ dmap->flags |= DMAP_COOKED;
+#endif
+
+ if ((dmap->mapping_flags & DMA_MAP_MAPPED) && (dmap->flags & DMAP_COOKED))
+ {
+ cmn_err (CE_WARN, "Internal error in mmap() support\n");
+ dmap->flags &= ~DMAP_COOKED;
+ }
+
+ if (dmap->flags & DMAP_COOKED)
+ {
+ if ((ret =
+ setup_format_conversions (adev, dmap, &adev->hw_parms,
+ &adev->user_parms,
+ &adev->user_parms,
+ &adev->hw_parms,
+ adev->iformat_mask)) < 0)
+ {
+ DDB (cmn_err
+ (CE_CONT, "setup_format_conversions failed, err=%d\n", ret));
+ return ret;
+ }
+ }
+ else
+ dmap->expand_factor = UNIT_EXPAND;
+
+/*
+ * Compute device data rate and frame size
+ */
+ if ((fmt_info = oss_find_format (adev->hw_parms.fmt)) != NULL)
+ data_rate = fmt_info->bits;
+
+ data_rate /= 8;
+ if (data_rate < 1)
+ data_rate = 1;
+ data_rate *= adev->hw_parms.channels;
+ dmap->frame_size = data_rate;
+ data_rate *= adev->hw_parms.rate;
+ if (data_rate < 1)
+ data_rate = 8000;
+ dmap->data_rate = data_rate;
+
+/*
+ * Compute user/application frame size
+ */
+ data_rate = 8;
+ if ((fmt_info = oss_find_format (adev->user_parms.fmt)) != NULL)
+ data_rate = fmt_info->bits;
+
+ data_rate /= 8;
+ if (data_rate < 1)
+ data_rate = 1;
+ data_rate *= adev->user_parms.channels;
+ dmap->user_frame_size = data_rate;
+
+ setup_fragments (adev, dmap, OPEN_READ);
+
+#if 1
+ /* Compute 1/expand_factor */
+
+ if (dmap->expand_factor == 0)
+ {
+ cmn_err (CE_NOTE, "Internal error (expand_factor==0)\n");
+ dmap->expand_factor = UNIT_EXPAND;
+ }
+
+ {
+ int expand = dmap->expand_factor;
+ int expand2 = expand * 100 / UNIT_EXPAND;
+ DDB (cmn_err (CE_CONT, "Expand factor was = %d (%d.%02d)\n", expand,
+ expand2 / 100, expand2 % 100));
+ }
+
+ dmap->expand_factor = (UNIT_EXPAND * UNIT_EXPAND) / dmap->expand_factor;
+
+ {
+ int expand = dmap->expand_factor;
+ int expand2 = expand * 100 / UNIT_EXPAND;
+ DDB (cmn_err
+ (CE_CONT, "Expand factor inverted to = %d (%d.%02d)\n", expand,
+ expand2 / 100, expand2 % 100));
+ }
+#endif
+
+ if (dmap->low_water == -1)
+ {
+ dmap->low_water =
+ (dmap->low_water_rq * UNIT_EXPAND) / dmap->expand_factor;
+ }
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Prepare input dev=%d, fragsize=%d, nfrags=%d, bytes_in_use=%d",
+ adev->engine_num, dmap->fragment_size, dmap->nfrags,
+ dmap->bytes_in_use);
+#endif
+
+ if ((ret =
+ adev->d->adrv_prepare_for_input (adev->engine_num, dmap->fragment_size,
+ dmap->nfrags)) < 0)
+ {
+ DDB (cmn_err
+ (CE_CONT, "/dev/dsp%d: prepare_for_input failed, err=%d\n",
+ adev->engine_num, ret));
+ return ret;
+ }
+
+ dmap->flags |= DMAP_PREPARED;
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_PREPARE_INPUT);
+#endif
+
+ return 0;
+}
+
+static int
+launch_input (adev_p adev, dmap_p dmap)
+{
+#ifdef DO_TIMINGS
+ oss_do_timing ("Launch input called");
+#endif
+ if (dmap->flags & DMAP_STARTED)
+ return 0;
+
+ if (!(dmap->flags & DMAP_PREPARED))
+ {
+ cmn_err (CE_WARN, "launch_input while not prepared.\n");
+ return OSS_EIO;
+ }
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Launch_input calling d->start_input");
+#endif
+
+ if (adev->d->adrv_start_input != NULL)
+ {
+ if (adev->flags & ADEV_AUTOMODE)
+ adev->d->adrv_start_input (adev->engine_num, dmap->dmabuf_phys,
+ dmap->bytes_in_use, dmap->fragment_size,
+ 0);
+ else
+ adev->d->adrv_start_input (adev->engine_num, dmap->dmabuf_phys,
+ dmap->fragment_size, dmap->fragment_size,
+ 0);
+ }
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Launch_input calling trigger");
+#endif
+ dmap->flags |= DMAP_STARTED;
+ if (adev->d->adrv_trigger
+ && ((adev->enable_bits * adev->go) & PCM_ENABLE_INPUT))
+ {
+ adev->d->adrv_trigger (adev->engine_num, adev->enable_bits * adev->go);
+ }
+
+ return 0;
+}
+
+static int
+find_raw_input_space (adev_p adev, dmap_p dmap, int *dmapos)
+{
+ int count;
+ int tmout, n = 0;
+ oss_uint64_t offs, doffs;
+ int lim = 1;
+ unsigned int status;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ if (adev->nonblock)
+ get_input_pointer (adev, dmap, 1);
+ count = (int) (dmap->byte_counter - dmap->user_counter);
+ *dmapos=0;
+
+ if (dmap->flags & DMAP_COOKED)
+ {
+ lim = dmap->fragment_size;
+ }
+
+ while (count < lim)
+ {
+ if (adev->nonblock)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+#ifdef DO_TIMINGS
+ oss_do_timing ("*** EAGAIN ***");
+#endif
+ return OSS_EAGAIN;
+ }
+
+ if (n++ > 100)
+ {
+ cmn_err (CE_WARN, "Audio input %d doesn't get filled.\n",
+ adev->engine_num);
+ cmn_err (CE_CONT, "Counters %d / %d\n", count, lim);
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return OSS_EIO;
+ }
+
+ tmout = (dmap->fragment_size * OSS_HZ) / dmap->data_rate;
+ tmout += OSS_HZ / 2;
+
+ if (adev->go == 0)
+ tmout = 0;
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Sleep (in)");
+ oss_timing_enter (DF_SLEEPREAD);
+#endif
+ audio_engines[adev->engine_num]->dmap_in->error = 0;
+ if (!oss_sleep (adev->in_wq, &dmap->mutex, tmout, &flags, &status))
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Sleep (in) timed out");
+#endif
+ adev->timeout_count++;
+ if (adev->d->adrv_check_input)
+ {
+ int err = adev->d->adrv_check_input (adev->engine_num);
+ if (err == 0)
+ continue; /* Retry */
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return err;
+ }
+ cmn_err (CE_NOTE,
+ "Input timed out on audio engine %d (count=%lld)\n",
+ adev->engine_num, dmap->byte_counter);
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ FMA_EREPORT(adev->osdev, DDI_FM_DEVICE_STALL, NULL, NULL, NULL);
+ FMA_IMPACT(adev->osdev, DDI_SERVICE_LOST);
+ return OSS_EIO;
+ } /* Timed out */
+
+#ifdef DO_TIMINGS
+ oss_timing_leave (DF_SLEEPREAD);
+ oss_do_timing ("Sleep (in) done");
+#endif
+
+ if (status & WK_SIGNAL)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return OSS_EINTR;
+ }
+ count = (int) (dmap->byte_counter - dmap->user_counter);
+#ifdef DO_TIMINGS
+ oss_timing_printf ("User counter %d, byte_counter %d", dmap->user_counter,
+ dmap->byte_counter);
+#endif
+ }
+
+/* Now we should have some data */
+
+ if (adev->nonblock)
+ get_input_pointer (adev, dmap, 1);
+
+ offs = dmap->user_counter % dmap->bytes_in_use;
+ doffs = dmap->byte_counter % dmap->bytes_in_use;
+
+ count = (int) (dmap->bytes_in_use - offs);
+ if (offs <= doffs)
+ count = (int) (doffs - offs);
+ if (count == 0)
+ count = dmap->bytes_in_use;
+
+ *dmapos = offs;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ return count;
+}
+
+/*ARGSUSED*/
+static int
+move_raw_rdpointer (adev_p adev, dmap_p dmap, int len)
+{
+ int ret = 0;
+ oss_native_word flags;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Move rdpointer, offs=%d, incr %d", dmap->user_counter,
+ len);
+#endif
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ dmap->user_counter += len;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ return ret;
+}
+
+static void
+copy_read_noninterleaved(adev_t *adev, dmap_t *dmap, int dma_offs, unsigned char *localbuf, int local_offs, int l)
+{
+/*
+ * Copy audio data from non-interleaved device buffer to interleaved
+ * local buffer.
+ */
+// TODO: This function assumes 32 bit audio DATA
+
+ int ch, i, nc = adev->hw_parms.channels;
+ int *outbuf, *inbuf;
+
+ l /= sizeof(*outbuf)*nc;
+ dma_offs /= sizeof(*outbuf);
+ local_offs /= sizeof(*outbuf);
+
+ for (ch=0;ch<nc;ch++)
+ {
+ outbuf = (int*)(localbuf+local_offs);
+ outbuf += ch;
+
+ inbuf = (int *)(dmap->dmabuf + dmap->buffsize*ch / nc);
+ inbuf += dma_offs / nc;
+
+ for (i=0;i<l;i++)
+ {
+ *outbuf = *inbuf++;
+ outbuf += nc;
+ }
+ }
+
+}
+
+static int
+find_input_space (adev_p adev, dmap_p dmap, unsigned char **dbuf)
+{
+ unsigned char *p, *p1 = dmap->tmpbuf1, *p2 = dmap->tmpbuf2;
+ int err, l, l2, max, dmapos;
+
+ if (!(dmap->flags & DMAP_COOKED))
+ {
+ err=find_raw_input_space (adev, dmap, &dmapos);
+ *dbuf=dmap->dmabuf+dmapos;
+ return err;
+ }
+
+ if (dmap->tmpbuf_len > dmap->tmpbuf_ptr)
+ {
+ *dbuf = dmap->tmpbuf1 + dmap->tmpbuf_ptr;
+ return dmap->tmpbuf_len - dmap->tmpbuf_ptr;
+ }
+
+ dmap->tmpbuf_len = dmap->tmpbuf_ptr = 0;
+
+ if ((l = find_raw_input_space (adev, dmap, &dmapos)) < 0)
+ {
+ return l;
+ }
+ p=dmap->dmabuf;
+
+ if (dmap->expand_factor > UNIT_EXPAND)
+ max = (TMP_CONVERT_MAX * UNIT_EXPAND) / dmap->expand_factor;
+ else
+ max = TMP_CONVERT_MAX;
+
+ if (max > TMP_CONVERT_MAX)
+ max = TMP_CONVERT_MAX;
+
+ if (l > max)
+ l = max;
+ l = (l / dmap->frame_size) * dmap->frame_size; /* Truncate to nearest frame size */
+ l2 = l;
+ VMEM_CHECK (p1, l);
+ VMEM_CHECK (p+dmapos, l);
+
+ if ((adev->flags & ADEV_NONINTERLEAVED) && adev->hw_parms.channels > 1)
+ copy_read_noninterleaved(adev, dmap, dmapos, p1, 0, l);
+ else
+ memcpy (p1, p+dmapos, l);
+
+ move_raw_rdpointer (adev, dmap, l);
+
+ if ((err =
+ dmap->convert_func (adev, dmap, &p1, &l2,
+ &p2, &adev->hw_parms,
+ &adev->user_parms)) < 0)
+ return err;
+
+ dmap->tmpbuf1 = p1;
+ dmap->tmpbuf2 = p2;
+ dmap->tmpbuf_len = l2;
+
+ *dbuf = dmap->tmpbuf1;
+ return dmap->tmpbuf_len;
+}
+
+static int
+move_rdpointer (adev_p adev, dmap_p dmap, int len)
+{
+ if (!(dmap->flags & DMAP_COOKED) || dmap->tmpbuf_ptr >= dmap->tmpbuf_len)
+ {
+ dmap->tmpbuf_ptr = 0;
+ dmap->tmpbuf_len = 0;
+ return move_raw_rdpointer (adev, dmap, len);
+ }
+
+ if (dmap->tmpbuf_ptr < dmap->tmpbuf_len)
+ {
+ dmap->tmpbuf_ptr += len;
+
+ if (dmap->tmpbuf_ptr >= dmap->tmpbuf_len)
+ dmap->tmpbuf_len = dmap->tmpbuf_ptr = 0;
+
+ return 0;
+ }
+
+ cmn_err (CE_NOTE, "Why here?\n");
+ return OSS_EIO;
+}
+
+int
+oss_audio_read (int dev, struct fileinfo *file, uio_t * buf, int count)
+{
+ adev_p adev;
+ dmap_p dmap;
+ int c, l, p, ret, n;
+ unsigned char *dmabuf;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("--- audio_read(%d, %d) ---", dev, count);
+#endif
+
+ sync_seed++;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ adev = audio_engines[dev];
+ if (!adev->enabled)
+ return OSS_ENXIO;
+ if (adev->flags & ADEV_NOINPUT)
+ return OSS_EACCES;
+ dmap = adev->dmap_in;
+
+ if (!(adev->open_mode & OPEN_READ))
+ return OSS_ENOTSUP;
+ if (dmap->dma_mode == PCM_ENABLE_OUTPUT)
+ {
+ audio_reset_output (adev);
+ reset_dmap (dmap);
+ }
+
+/*
+ * Initial setup
+ */
+ oss_reset_wait_queue (adev->in_wq);
+
+ if (file != NULL)
+ {
+ if ((ISSET_FILE_FLAG (file, O_NONBLOCK)
+ && !(adev->open_flags & OF_BLOCK)) || adev->forced_nonblock)
+ adev->nonblock = 1;
+ else
+ adev->nonblock = 0;
+#ifdef DO_TIMINGS
+ if (adev->nonblock)
+ oss_do_timing ("*** NON BLOCKING READ ***");
+#endif
+ }
+
+ if (dmap->dma_mode != PCM_ENABLE_INPUT)
+ {
+ if ((ret = prepare_input (adev, dmap)) < 0)
+ {
+ DDB (cmn_err (CE_CONT, "Prepare input failed, err=%d\n", ret));
+ return ret;
+ }
+ dmap->dma_mode = PCM_ENABLE_INPUT;
+ launch_input (adev, dmap);
+ }
+
+ if (!(dmap->flags & DMAP_PREPARED))
+ { /* Not prepared. Why??? */
+ cmn_err (CE_WARN, "Intenal error (not prepared)\n");
+ return OSS_EIO;
+ }
+
+ c = count;
+ p = 0;
+ n = 0;
+
+ while (c > 0 && n++ < 1000)
+ {
+ if ((l = find_input_space (adev, dmap, &dmabuf)) < 0)
+ {
+ if (l == OSS_EINTR)
+ {
+ if (c == count) /* Nothing read yet */
+ return OSS_EINTR;
+ return count - c;
+ }
+ if (l == OSS_EAGAIN)
+ {
+ if (c == count) /* Nothing read yet */
+ return OSS_EAGAIN;
+ return count - c;
+ }
+ return l;
+ }
+
+ if (l > c)
+ l = c;
+
+ if (uiomove (dmabuf, l, UIO_READ, buf) != 0)
+ {
+ cmn_err (CE_WARN, "audio: uiomove(UIO_READ) failed\n");
+ return OSS_EFAULT;
+ }
+ if ((ret = move_rdpointer (adev, dmap, l)) < 0)
+ {
+ return ret;
+ }
+
+ c -= l;
+ p += l;
+ }
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("-------- Audio read done (%d)", count - c);
+#endif
+
+ return count - c;
+}
+
+/*ARGSUSED*/
+static int
+audio_space_in_queue (adev_p adev, dmap_p dmap, int count)
+{
+ int cnt;
+
+ cnt = (int) (dmap->byte_counter + dmap->bytes_in_use - dmap->user_counter);
+
+ if (cnt < 0)
+ {
+ cmn_err (CE_CONT, "Buffer %d overfilled (%d)\n", adev->engine_num, cnt);
+ }
+
+ if (!(dmap->mapping_flags & DMA_MAP_MAPPED))
+ if (cnt > dmap->bytes_in_use) /* Output underrun */
+ {
+#ifdef DO_TIMINGS
+ oss_timing_printf ("adev %d: Play underrun B", adev->engine_num);
+ oss_timing_printf (" User=%lld", dmap->user_counter);
+ oss_timing_printf (" Dev=%lld", dmap->byte_counter);
+ oss_timing_printf (" Tmp=%d", dmap->tmpbuf_ptr);
+#endif
+ cnt = dmap->bytes_in_use;
+ dmap->user_counter = dmap->byte_counter;
+ dmap->play_underruns++;
+ if (!dmap->underrun_flag)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Clearing the buffer");
+#endif
+ memset (dmap->dmabuf, dmap->neutral_byte, dmap->bytes_in_use);
+ }
+ dmap->underrun_flag = 1;
+ }
+
+ if ((dmap->user_counter + cnt) > (dmap->byte_counter + dmap->bytes_in_use))
+ cmn_err (CE_CONT, "Overflow %lld+%d, %lld\n", dmap->user_counter, cnt,
+ dmap->byte_counter);
+
+ return cnt;
+}
+
+static int
+find_output_space (adev_p adev, dmap_p dmap, int *size, int count)
+{
+ int offs;
+ int len, l2, n = 0, tmout;
+ oss_native_word flags;
+ int tout;
+ unsigned int status;
+
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "Internal error - dmap==NULL\n");
+ return OSS_EIO;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ len = audio_space_in_queue (adev, dmap, count);
+
+ tout = 0;
+ while (len < dmap->user_frame_size)
+ { /* Wait for some space */
+ if (tout++ > 10000)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ cmn_err (CE_WARN, "Internal timeout error B\n");
+ return OSS_EIO;
+ }
+
+ if (adev->nonblock || !(adev->enable_bits & PCM_ENABLE_OUTPUT))
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Space=%d\n", len);
+ oss_do_timing ("*** EAGAIN ***");
+#endif
+ if (!(adev->enable_bits & PCM_ENABLE_OUTPUT))
+ {
+ launch_output (adev, dmap);
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1021,
+ "Play buffer full when playback is triggered off."),
+ 0);
+ /*
+ * Errordesc:
+ * An application had written too many samples of data between
+ * turning off the PCM_ENABLE_OUTPUT trigger bit and turning it back
+ * again to trigger playback.
+ *
+ * Applications using SNDCTL_DSP_SETTRIGGER should avoid filling the
+ * available playback buffer before triggering output.
+ *
+ * One possible error causing this is that the application has
+ * triggered only recording on a duplex device.
+ */
+ }
+ return OSS_EAGAIN;
+ }
+
+ if (n++ > dmap->nfrags * 2)
+ {
+ cmn_err (CE_WARN, "Audio output %d doesn't drain (%lld/%lld %d).\n",
+ adev->engine_num, dmap->user_counter, dmap->byte_counter,
+ len);
+ cmn_err (CE_CONT, "len=%d/%d, total=%d\n", len, dmap->fragment_size,
+ dmap->bytes_in_use);
+#ifdef DO_TIMINGS
+ oss_do_timing ("Audio output doesn't drain");
+#endif
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ audio_reset_output (adev);
+ return OSS_EIO;
+ }
+
+ tmout = (dmap->fragment_size * OSS_HZ) / dmap->data_rate;
+ tmout += OSS_HZ;
+
+ if (adev->go == 0)
+ tmout = 0;
+
+ audio_engines[adev->engine_num]->dmap_out->error = 0;
+ if (adev->go == 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return OSS_EAGAIN;
+ }
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Sleep(%d)", adev->engine_num);
+ oss_timing_enter (DF_SLEEPWRITE);
+#endif
+ UP_STATUS (STS_SLEEP);
+ if (!oss_sleep (adev->out_wq, &dmap->mutex, tmout, &flags, &status))
+ {
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Sleep(%d) (out) timed out", adev->engine_num);
+#endif
+ adev->timeout_count++;
+
+ if (adev->d->adrv_check_output)
+ {
+ int err = adev->d->adrv_check_output (adev->engine_num);
+ if (err == 0)
+ continue; /* Retry */
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return err;
+ }
+ else
+ {
+ cmn_err (CE_NOTE,
+ "Output timed out on audio engine %d/'%s' (count=%lld)\n",
+ adev->engine_num, adev->name, dmap->byte_counter);
+ }
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ FMA_EREPORT(adev->osdev, DDI_FM_DEVICE_STALL, NULL, NULL, NULL);
+ FMA_IMPACT(adev->osdev, DDI_SERVICE_LOST);
+ return OSS_EIO;
+ } /* Timed out */
+ DOWN_STATUS (STS_SLEEP);
+
+#ifdef DO_TIMINGS
+ oss_timing_leave (DF_SLEEPWRITE);
+ oss_timing_printf ("Sleep(%d) (out) done", adev->engine_num);
+#endif
+
+ if (status & WK_SIGNAL)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Signal caught");
+#endif
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return OSS_EINTR;
+ }
+
+ len = audio_space_in_queue (adev, dmap, count);
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Free output space now %d bytes", len);
+#endif
+ } /* Wait for space */
+
+/*
+ * Now we hopefully have some free space in the buffer.
+ */
+
+ offs = (int) (dmap->user_counter % dmap->bytes_in_use);
+
+ l2 = dmap->bytes_in_use - offs;
+ if (len > l2)
+ len = l2;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ if (len < 0)
+ len = 0;
+
+ *size = len;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Got output buffer, offs %d/%d, len %d", offs,
+ dmap->bytes_in_use, len);
+#endif
+ if (offs < 0 || (offs + len) > dmap->bytes_in_use)
+ {
+ cmn_err (CE_WARN, "Bad audio output buffer %d/%d\n", offs, len);
+ return OSS_EIO;
+ }
+
+ return offs;
+}
+
+static int
+launch_output (adev_p adev, dmap_p dmap)
+{
+ oss_native_word flags;
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Launch output called");
+#endif
+ if (dmap->flags & DMAP_STARTED)
+ {
+ return 0;
+ }
+
+ if (dmap->user_counter == 0 && dmap->audio_callback == NULL
+ && dmap->mapping_flags == 0)
+ {
+ return 0;
+ }
+
+ if (!(dmap->flags & DMAP_PREPARED))
+ {
+ cmn_err (CE_WARN, "launch_output while not prepared. Engine=%d\n", adev->engine_num);
+ return OSS_EIO;
+ }
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Launch_output calling output_block");
+#endif
+
+ if (adev->d->adrv_output_block != NULL)
+ {
+ if (adev->flags & ADEV_AUTOMODE)
+ adev->d->adrv_output_block (adev->engine_num, dmap->dmabuf_phys,
+ dmap->bytes_in_use, dmap->fragment_size,
+ 0);
+ else
+ adev->d->adrv_output_block (adev->engine_num, dmap->dmabuf_phys,
+ dmap->fragment_size, dmap->fragment_size,
+ 0);
+ }
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Launch_output calling trigger");
+#endif
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ dmap->flags |= DMAP_STARTED;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ if (adev->d->adrv_trigger
+ && ((adev->enable_bits * adev->go) & PCM_ENABLE_OUTPUT))
+ {
+ adev->d->adrv_trigger (adev->engine_num, adev->enable_bits * adev->go);
+ }
+
+ return 0;
+}
+
+static int
+move_wrpointer (adev_p adev, dmap_p dmap, int len)
+{
+ int ret = 0;
+ oss_native_word flags;
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Move wrpointer, len %d", len);
+#endif
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ dmap->underrun_flag = 0;
+
+ dmap->user_counter += len;
+#ifdef DO_TIMINGS
+ oss_timing_printf (" User=%lld", dmap->user_counter);
+ oss_timing_printf (" Byte=%lld", dmap->byte_counter);
+ oss_timing_printf (" Fill=%lld", dmap->user_counter - dmap->byte_counter);
+#endif
+
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_UPDATE_OUTPUT);
+#endif
+
+ if (ret < 0 || dmap->flags & DMAP_STARTED)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return ret;
+ }
+
+ if (!(adev->enable_bits & PCM_ENABLE_OUTPUT))
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Output not triggered - skipping launch_output");
+#endif
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return ret;
+ }
+
+ if ((dmap->user_counter < dmap->fragment_size * 2)
+ && (dmap->user_counter < dmap->bytes_in_use / 2))
+ {
+#ifdef DO_TIMINGS
+ oss_timing_printf ("dmap->user_counter=%lld, dmap->fragment_size*2=%ld",
+ dmap->user_counter, dmap->fragment_size * 2);
+ oss_do_timing
+ ("Not enough data in the buffer yet - skipping launch_output");
+#endif
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ return ret;
+ }
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ ret = launch_output (adev, dmap);
+ return ret;
+}
+
+/*ARGSUSED*/
+static void
+store_tmp_data (adev_p adev, dmap_p dmap, unsigned char *buf, int count)
+{
+ dmap->leftover_buf = buf;
+ dmap->leftover_bytes = count;
+}
+
+static void
+copy_write_noninterleaved(adev_t *adev, dmap_t *dmap, int dma_offs, unsigned char *localbuf, int local_offs, int l)
+{
+/*
+ * Copy interleaved N channel data to non-interleaved device buffer.
+ */
+// TODO: This function assumes 32 bit audio DATA
+
+ int ch, i, nc = adev->hw_parms.channels;
+ int *inbuf, *outbuf;
+
+ l /= sizeof(*inbuf)*nc;
+ dma_offs /= sizeof(*inbuf);
+ local_offs /= sizeof(*inbuf);
+
+ for (ch=0;ch<nc;ch++)
+ {
+ inbuf = (int*)(localbuf+local_offs);
+ inbuf += ch;
+
+ outbuf = (int *)(dmap->dmabuf + dmap->buffsize*ch / nc);
+ outbuf += dma_offs / nc;
+
+ for (i=0;i<l;i++)
+ {
+ *outbuf++ = *inbuf;
+ inbuf += nc;
+ }
+ }
+
+}
+
+static int
+write_copy (adev_p adev, dmap_p dmap, unsigned char *buf, int count)
+{
+ int err, offs, spc, l, p = 0;
+
+ while (count)
+ {
+ l = count;
+
+ if ((offs = find_output_space (adev, dmap, &spc, l)) < 0)
+ {
+ if (offs == OSS_EAGAIN)
+ {
+ store_tmp_data (adev, dmap, buf + p, count);
+ launch_output (adev, dmap);
+ return OSS_EAGAIN;
+ }
+ return offs;
+ }
+
+ if (l > spc)
+ l = spc;
+
+ VMEM_CHECK (&dmap->dmabuf[offs], l);
+ VMEM_CHECK (buf + p, l);
+
+ if ((adev->flags & ADEV_NONINTERLEAVED) && adev->hw_parms.channels > 1)
+ {
+ copy_write_noninterleaved(adev, dmap, offs, buf + p, 0, l);
+ }
+ else
+ memcpy (&dmap->dmabuf[offs], buf + p, l);
+
+ if ((err = move_wrpointer (adev, dmap, l)) < 0)
+ return err;
+
+ count -= l;
+ p += l;
+ }
+ return 0;
+}
+
+int
+oss_audio_write (int dev, struct fileinfo *file, uio_t * buf, int count)
+{
+ adev_p adev;
+ oss_native_word flags;
+ dmap_p dmap;
+ int ret;
+ int l, c, spc, offs, p, err;
+ int tmout;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("--- audio_write(%d, %d) ---", dev, count);
+#endif
+
+ sync_seed++;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ adev = audio_engines[dev];
+ if (!adev->enabled)
+ return OSS_ENXIO;
+ if (adev->flags & ADEV_NOOUTPUT)
+ return OSS_EACCES;
+ dmap = adev->dmap_out;
+
+ if (!(adev->open_mode & OPEN_WRITE))
+ return OSS_ENOTSUP;
+
+ UP_STATUS (STS_WRITE);
+
+ if (dmap->dma_mode == PCM_ENABLE_INPUT)
+ {
+ audio_reset_input (adev);
+ reset_dmap (dmap);
+ }
+
+/*
+ * Initial setup
+ */
+ oss_reset_wait_queue (adev->out_wq);
+
+ if (file != NULL)
+ {
+ if ((ISSET_FILE_FLAG (file, O_NONBLOCK)
+ && !(adev->open_flags & OF_BLOCK)) || adev->forced_nonblock)
+ adev->nonblock = 1;
+ else
+ adev->nonblock = 0;
+#ifdef DO_TIMINGS
+ if (adev->nonblock)
+ oss_do_timing ("*** NON BLOCKING WRITE ***");
+#endif
+ }
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+
+ if (dmap->dma_mode != PCM_ENABLE_OUTPUT)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ if ((ret = prepare_output (adev, dmap)) < 0)
+ {
+ DOWN_STATUS (STS_WRITE);
+ return ret;
+ }
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ dmap->dma_mode = PCM_ENABLE_OUTPUT;
+ }
+
+ if (!(dmap->flags & DMAP_PREPARED))
+ { /* Not prepared. Why??? */
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ DOWN_STATUS (STS_WRITE);
+ cmn_err (CE_WARN, "Internal error (not prepared)\n");
+ return OSS_EIO;
+ }
+#if 1
+ if (dmap->leftover_bytes > 0)
+ {
+ unsigned char *b;
+ int l;
+
+ b = dmap->leftover_buf;
+ l = dmap->leftover_bytes;
+ dmap->leftover_bytes = 0;
+ dmap->leftover_buf = NULL;
+
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ if ((err = write_copy (adev, dmap, b, l)) < 0)
+ {
+ DOWN_STATUS (STS_WRITE);
+ return err;
+ }
+
+ dmap->leftover_bytes = 0;
+ dmap->leftover_buf = NULL;
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ }
+#endif
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ if (count <= 0)
+ {
+ DOWN_STATUS (STS_WRITE);
+ return 0;
+ }
+
+ c = count;
+ p = 0;
+
+ tmout = 0;
+
+ while (c > 0)
+ {
+#ifdef DO_TIMINGS
+ oss_timing_printf ("%d/%d bytes to go", c, count);
+#endif
+
+ if (tmout++ > 1000)
+ {
+ cmn_err (CE_WARN, "Internal timeout error A (%d/%d)\n", c, count);
+ return OSS_EIO;
+ }
+
+ l = c;
+ if (l > 8)
+ l &= ~7; /* Align it */
+
+ if ((offs = find_output_space (adev, dmap, &spc, l)) < 0)
+ {
+ if (offs == OSS_EINTR)
+ {
+ DOWN_STATUS (STS_WRITE);
+ if (c == count) /* Nothing written yet */
+ return OSS_EINTR;
+ return count - c;
+ }
+ if (offs == OSS_EAGAIN)
+ {
+ DOWN_STATUS (STS_WRITE);
+ if (c == count) /* Nothing written yet */
+ {
+ return OSS_EAGAIN;
+ }
+ return count - c;
+ }
+ DOWN_STATUS (STS_WRITE);
+ return offs;
+ }
+
+ if (dmap->convert_func == NULL)
+ {
+ if (dmap->device_write != NULL)
+ {
+ unsigned char *tmpbuf;
+ int l2;
+
+ if (dmap->tmpbuf1 == NULL)
+ {
+ dmap->tmpbuf1 = AUDIO_MALLOC (dmap->osdev, TMP_CONVERT_BUF_SIZE+512);
+ }
+
+/*
+ * Leave some room for data expansion so use just half of the available
+ * space.
+ */
+ tmpbuf = dmap->tmpbuf1;
+ if (l > spc / 2)
+ l = spc / 2;
+ if (l > TMP_CONVERT_BUF_SIZE / 2)
+ l = TMP_CONVERT_BUF_SIZE / 2;
+
+ l2 = l;
+ if (uiomove (tmpbuf, l, UIO_WRITE, buf) != 0)
+ {
+ cmn_err (CE_WARN,
+ "audio: uiomove(UIO_WRITE) failed (noconv)\n");
+ DOWN_STATUS (STS_WRITE);
+ return OSS_EFAULT;
+ }
+ if ((err =
+ dmap->device_write (adev, dmap, tmpbuf,
+ &dmap->dmabuf[offs], spc, &l,
+ &l2)) < 0)
+ {
+ DOWN_STATUS (STS_WRITE);
+ return err;
+ }
+ if ((err = move_wrpointer (adev, dmap, l2)) < 0)
+ {
+ DOWN_STATUS (STS_WRITE);
+ return err;
+ }
+ }
+ else
+ {
+ if (l > spc)
+ l = spc;
+ if (uiomove (&dmap->dmabuf[offs], l, UIO_WRITE, buf) != 0)
+ {
+ cmn_err (CE_WARN,
+ "audio: uiomove(UIO_WRITE) (noconv2) failed\n");
+ return OSS_EFAULT;
+ }
+ if ((err = move_wrpointer (adev, dmap, l)) < 0)
+ {
+ DOWN_STATUS (STS_WRITE);
+ return err;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Perform format conversions.
+ */
+ unsigned char *p1 = dmap->tmpbuf1, *p2 = dmap->tmpbuf2;
+ int l2, max, out_max;
+
+ if (spc > TMP_CONVERT_MAX)
+ spc = TMP_CONVERT_MAX / 2;
+
+ if (dmap->expand_factor > UNIT_EXPAND)
+ {
+ max = spc;
+
+ out_max = (spc * dmap->expand_factor) / UNIT_EXPAND; /* Output size */
+ if (out_max > TMP_CONVERT_BUF_SIZE) /* Potential overflow */
+ {
+ max = (TMP_CONVERT_BUF_SIZE * UNIT_EXPAND) / dmap->expand_factor;
+ }
+ }
+ else
+ max = spc;
+ if (max < dmap->frame_size)
+ max = dmap->frame_size;
+
+ if (max > TMP_CONVERT_MAX)
+ max = TMP_CONVERT_MAX / 2;
+
+ if (l > max)
+ l = max;
+ /* Avoid leaving too short "tails" */
+ if (c - l < 64)
+ l = c;
+
+ /* Round to integer number of samples */
+ l =
+ (((l + dmap->frame_size -
+ 1) / dmap->frame_size)) * dmap->frame_size;
+ if (l > c)
+ l = c;
+
+ l2 = l;
+
+ VMEM_CHECK (p1, l);
+ if (uiomove (p1, l, UIO_WRITE, buf) != 0)
+ cmn_err (CE_WARN, "audio: uiomove(UIO_WRITE) (conv) failed\n");
+ UP_STATUS (STS_CONVERT);
+ if ((err =
+ dmap->convert_func (adev, dmap, &p1, &l2,
+ &p2, &adev->user_parms,
+ &adev->hw_parms)) < 0)
+ {
+ cmn_err (CE_WARN, "Format conversion failed (%d)\n", err);
+ DOWN_STATUS (STS_WRITE | STS_CONVERT);
+ return err;
+ }
+ DOWN_STATUS (STS_CONVERT);
+
+ if ((err = write_copy (adev, dmap, p1, l2)) < 0)
+ {
+ if (err != OSS_EAGAIN)
+ {
+ DOWN_STATUS (STS_WRITE);
+ return err;
+ }
+
+ /* Handle non blocking I/O */
+ if (c == count) /* Nothing written yet */
+ {
+ DOWN_STATUS (STS_WRITE);
+ return OSS_EAGAIN;
+ }
+
+ DOWN_STATUS (STS_WRITE);
+ return count - c;
+
+ }
+ }
+
+ c -= l;
+ p += l;
+
+ if (l > 0)
+ tmout = 0;
+ }
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("--- Audio write done");
+#endif
+ DOWN_STATUS (STS_WRITE);
+ return count - c;
+}
+
+#ifdef MANAGE_DEV_DSP
+#ifdef VDEV_SUPPORT
+void
+oss_combine_write_lists (void)
+{
+ int i;
+
+ for (i = 0; i < dspoutlist2.ndevs; i++)
+ dspoutlist.devices[dspoutlist.ndevs++] = dspoutlist2.devices[i];
+
+ dspoutlist2.ndevs = 0;
+}
+
+/*ARGSUSED*/
+int
+oss_open_vdsp (int dev, int dev_type, struct fileinfo *file, int recursive,
+ int open_flags, int *newdev)
+{
+ int ret, i, d;
+ int mode = file->mode & O_ACCMODE;
+
+ DDB (cmn_err (CE_CONT, "oss_open_vdsp(%d, mode=%d)\n", dev, mode));
+
+ switch (dev)
+ {
+ case 1:
+ mode = OPEN_READ;
+ break;
+ case 2:
+ mode = OPEN_WRITE;
+ break;
+
+ /* default: Use the mode defined by O_ACCMODE */
+ }
+
+ dev = -1;
+ open_flags = get_open_flags (mode, open_flags, file);
+
+ switch (dev_type)
+ {
+ case OSS_DEV_VDSP:
+ dev_type = OSS_DEV_DSP;
+ break;
+#if 0
+ case OSS_DEV_VAUDIO:
+ dev_type = OSS_DEV_DEVAUDIO;
+ break;
+#endif
+ default:
+ cmn_err (CE_NOTE, "Unknown dev class %d\n", dev_type);
+ break;
+ }
+
+ if (audio_devfiles == NULL)
+ {
+ cmn_err (CE_NOTE, "No audio device files available\n");
+ return OSS_ENXIO;
+ }
+#ifdef MANAGE_DEV_DSP
+#ifdef VDEV_SUPPORT
+ oss_combine_write_lists ();
+#endif
+#endif
+
+#ifdef APPLIST_SUPPORT
+ {
+ char *appname;
+ appname = GET_PROCESS_NAME (file);
+ if (open_flags & OF_DEVAUDIO)
+ appname = "Devaudio_Support";
+
+ if ((dev = app_lookup (mode, appname, &open_flags)) >= 0)
+ if (audio_devfiles[dev]->enabled && !audio_devfiles[dev]->unloaded)
+ if ((ret =
+ oss_audio_open_devfile (dev, dev_type, file, 0, open_flags,
+ newdev)) >= 0)
+ {
+ dev = ret;
+ DDB (cmn_err
+ (CE_CONT, "Using dsp%d configured for this application\n",
+ dev));
+ goto done;
+ }
+ }
+#endif
+ DDB (cmn_err (CE_CONT, "\n"));
+ DDB (cmn_err (CE_CONT, "Out devs: "));
+ for (i = 0; i < dspoutlist.ndevs; i++)
+ DDB (cmn_err (CE_CONT, "%d ", dspoutlist.devices[i]));
+ for (i = 0; i < dspoutlist2.ndevs; i++)
+ DDB (cmn_err (CE_CONT, "(%d) ", dspoutlist2.devices[i]));
+ DDB (cmn_err (CE_CONT, "\n"));
+ DDB (cmn_err (CE_CONT, "In devs: "));
+ for (i = 0; i < dspinlist.ndevs; i++)
+ DDB (cmn_err (CE_CONT, "%d ", dspinlist.devices[i]));
+ DDB (cmn_err (CE_CONT, "\n"));
+ DDB (cmn_err (CE_CONT, "In/out devs: "));
+ for (i = 0; i < dspinoutlist.ndevs; i++)
+ DDB (cmn_err (CE_CONT, "%d ", dspinoutlist.devices[i]));
+ DDB (cmn_err (CE_CONT, "\n"));
+
+ switch (mode & (OPEN_READ | OPEN_WRITE))
+ {
+ case OPEN_WRITE:
+ DDB (cmn_err (CE_CONT, "Selecting output device: "));
+
+ for (i = 0; i < dspoutlist.ndevs; i++)
+ {
+ dev = dspoutlist.devices[i];
+ if (!audio_devfiles[dev]->enabled || audio_devfiles[dev]->unloaded)
+ {
+ dev = -1;
+ continue;
+ }
+
+ DDB (cmn_err (CE_CONT, "%d ", dev));
+ if ((ret =
+ oss_audio_open_devfile (dev, dev_type, file, 0, open_flags,
+ newdev)) >= 0)
+ {
+ dev = ret;
+ DDB (cmn_err (CE_CONT, "->%d ", dev));
+ break;
+ }
+ dev = -1;
+ }
+ break;
+
+ case OPEN_READ:
+ DDB (cmn_err (CE_CONT, "Selecting input device: "));
+ for (i = 0; i < dspinlist.ndevs; i++)
+ {
+ dev = dspinlist.devices[i];
+ if (!audio_devfiles[dev]->enabled || audio_devfiles[dev]->unloaded)
+ {
+ dev = -1;
+ continue;
+ }
+ DDB (cmn_err (CE_CONT, "%d ", dev));
+ if ((ret =
+ oss_audio_open_devfile (dev, dev_type, file, 0, open_flags,
+ newdev)) >= 0)
+ {
+ dev = ret;
+ DDB (cmn_err (CE_CONT, "->%d ", dev));
+ break;
+ }
+
+ dev = -1;
+ }
+ break;
+
+ case OPEN_WRITE | OPEN_READ:
+ DDB (cmn_err (CE_CONT, "Selecting input/output device: "));
+ for (i = 0; i < dspinoutlist.ndevs; i++)
+ {
+ dev = dspinoutlist.devices[i];
+ if (!audio_devfiles[dev]->enabled || audio_devfiles[dev]->unloaded)
+ {
+ dev = -1;
+ continue;
+ }
+ DDB (cmn_err (CE_CONT, "%d ", dev));
+ if ((ret =
+ oss_audio_open_devfile (dev, dev_type, file, 0, open_flags,
+ newdev)) >= 0)
+ {
+ dev = ret;
+ DDB (cmn_err (CE_CONT, "->%d ", dev));
+ break;
+ }
+ dev = -1;
+ }
+ break;
+ }
+
+ DDB (cmn_err (CE_CONT, " - got vdsp -> %d\n", dev));
+ if (dev == -1)
+ return OSS_EBUSY;
+
+done:
+/*
+ * Try to find which minor number matches this /dev/dsp# device. Note that the actual
+ * device type doesn't matter after this point so we can use OSS_DEV_DSP.
+ */
+ if ((d = oss_find_minor (OSS_DEV_DSP_ENGINE, dev)) < 0)
+ {
+ oss_audio_release (dev, file);
+ return d;
+ }
+
+ *newdev = d;
+ return dev;
+}
+#endif
+#endif
+
+static int
+audio_init_device (int dev)
+{
+ adev_p adev;
+
+ sync_seed = GET_JIFFIES ();
+ adev = audio_engines[dev];
+
+ MUTEX_INIT (adev->master_osdev, adev->mutex, MH_FRAMEW);
+
+ if (audio_engines[dev]->dmap_out == NULL
+ || audio_engines[dev]->dmap_in == NULL)
+ {
+ dmap_p dmap;
+
+ dmap = AUDIO_MALLOC (adev->osdev, sizeof (dmap_t));
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate dmap, dev=%d\n", dev);
+ return OSS_ENOMEM;
+ }
+
+ memset ((char *) dmap, 0, sizeof (dmap_t));
+
+ if (!(adev->flags & ADEV_NOOUTPUT) && adev->out_wq == NULL)
+ {
+ if ((adev->out_wq =
+ oss_create_wait_queue (adev->osdev, "audio_out")) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot create audio output wait queue\n");
+ return OSS_ENOMEM;
+ }
+ }
+
+ if (!(adev->flags & ADEV_NOINPUT) && adev->in_wq == NULL)
+ {
+ if ((adev->in_wq =
+ oss_create_wait_queue (adev->osdev, "audio_in")) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot create audio input wait queue\n");
+ return OSS_ENOMEM;
+ }
+ }
+
+ memset ((char *) dmap, 0, sizeof (dmap_t));
+ dmap->osdev = adev->osdev;
+ dmap->adev = adev;
+ dmap->master_osdev = adev->master_osdev;
+ MUTEX_INIT (dmap->master_osdev, dmap->mutex, MH_FRAMEW + 1);
+ adev->dmap_out = adev->dmap_in = dmap;
+
+ if (adev->flags & ADEV_DUPLEX)
+ {
+
+ dmap = AUDIO_MALLOC (adev->osdev, sizeof (dmap_t));
+ if (dmap == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate dmap, dev=%d\n", dev);
+ return OSS_ENOMEM;
+ }
+
+ memset ((char *) dmap, 0, sizeof (dmap_t));
+ dmap->osdev = adev->osdev;
+ dmap->adev = adev;
+ dmap->master_osdev = adev->master_osdev;
+ MUTEX_INIT (dmap->master_osdev, dmap->mutex, MH_FRAMEW + 1);
+ adev->dmap_in = dmap;
+ }
+ }
+
+ return 0;
+}
+
+void
+audio_uninit_device (int dev)
+{
+ adev_p adev;
+ /* oss_native_word flags; */
+
+ adev = audio_engines[dev];
+
+ if (adev->unloaded)
+ return;
+
+ if (adev->dmap_out != NULL && adev->dmap_out->dmabuf != NULL)
+ {
+ if (adev->d->adrv_free_buffer != NULL)
+ {
+ adev->d->adrv_free_buffer (dev, adev->dmap_out, OPEN_WRITE);
+ }
+ else
+ default_free_buffer (dev, adev->dmap_out, OPEN_WRITE);
+ adev->dmap_out->dmabuf = NULL;
+ }
+
+ if (adev->dmap_in != NULL
+ && (adev->dmap_in != adev->dmap_out && adev->dmap_in->dmabuf != NULL))
+ {
+ if (adev->d->adrv_free_buffer != NULL)
+ {
+ adev->d->adrv_free_buffer (dev, adev->dmap_in, OPEN_READ);
+ }
+ else
+ default_free_buffer (dev, adev->dmap_in, OPEN_READ);
+ adev->dmap_in->dmabuf = NULL;
+ }
+
+ if (adev->in_wq != NULL)
+ {
+ oss_remove_wait_queue (adev->in_wq);
+ adev->in_wq = NULL;
+ }
+ if (adev->out_wq != NULL)
+ {
+ oss_remove_wait_queue (adev->out_wq);
+ adev->out_wq = NULL;
+ }
+
+#ifdef CONFIG_OSS_VMIX
+ if (adev->vmix_mixer != NULL)
+ {
+ adev->vmix_mixer = NULL;
+ }
+#endif
+
+ MUTEX_CLEANUP (adev->mutex);
+
+ if (adev->dmap_out != NULL)
+ MUTEX_CLEANUP (adev->dmap_out->mutex);
+
+ if (adev->flags & ADEV_DUPLEX && adev->dmap_in != NULL
+ && adev->dmap_out != adev->dmap_in)
+ {
+ MUTEX_CLEANUP (adev->dmap_in->mutex);
+ }
+ adev->unloaded = 1;
+}
+
+void
+oss_audio_init (oss_device_t *osdev)
+{
+ MUTEX_INIT (osdev, audio_global_mutex, MH_DRV);
+}
+
+void
+oss_audio_uninit (void)
+{
+/*
+ * Release all memory/resources allocated by the audio core.
+ */
+ oss_memblk_unalloc(&audio_global_memblk);
+
+ MUTEX_CLEANUP (audio_global_mutex);
+}
+
+void
+oss_audio_inc_byte_counter (dmap_t * dmap, int increment)
+{
+ oss_uint64_t p1, p2;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ p1 = dmap->byte_counter / dmap->fragment_size;
+ dmap->byte_counter += increment;
+ p2 = dmap->byte_counter / dmap->fragment_size;
+
+ dmap->interrupt_count += (int) (p2 - p1);
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+}
+
+static void
+do_inputintr (int dev, int intr_flags)
+{
+ adev_p adev;
+ dmap_p dmap;
+ int cptr;
+ oss_native_word flags;
+
+ adev = audio_engines[dev];
+ dmap = adev->dmap_in;
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+
+ if (!(intr_flags & AINTR_NO_POINTER_UPDATES))
+ {
+ dmap->byte_counter += dmap->fragment_size;
+ dmap->interrupt_count++;
+ }
+
+ while (dmap->byte_counter > dmap->user_counter &&
+ (int) (dmap->byte_counter - dmap->user_counter) > dmap->bytes_in_use)
+ {
+ dmap->user_counter += dmap->fragment_size;
+ dmap->rec_overruns++;
+ }
+ dmap->fragment_counter = (dmap->fragment_counter + 1) % dmap->nfrags;
+
+ if (dmap->dmabuf_dma_handle != NULL) /* Some drivers don't use DMA */
+ OSS_DMA_SYNC(dmap->dmabuf_dma_handle, 0, dmap->bytes_in_use, OSS_DMA_SYNC_INBOUND);
+
+#ifdef DO_TIMINGS
+ oss_do_timing ("Wake up (in)");
+#endif
+ oss_wakeup (adev->in_wq, &dmap->mutex, &flags, POLLIN | POLLRDNORM);
+
+ if (adev->flags & ADEV_AUTOMODE)
+ {
+ goto finish;
+ }
+
+ cptr = dmap_get_qtail (dmap) * dmap->fragment_size;
+ if (adev->d->adrv_start_input != NULL)
+ adev->d->adrv_start_input (adev->engine_num, dmap->dmabuf_phys + cptr,
+ dmap->fragment_size, dmap->fragment_size, 1);
+finish:
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ if (dmap->audio_callback != NULL)
+ dmap->audio_callback (adev->engine_num, dmap->callback_parm);
+}
+
+static void
+audio_inputintr (int dev, int intr_flags)
+{
+ adev_p adev;
+ dmap_p dmap;
+ int n;
+ oss_uint64_t pos;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return;
+
+ adev = audio_engines[dev];
+ dmap = adev->dmap_in;
+
+ if (dmap->dma_mode != PCM_ENABLE_INPUT)
+ {
+ return;
+ }
+
+ if (!(dmap->flags & DMAP_STARTED))
+ {
+ return;
+ }
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Inputintr(%d)", dev);
+#endif
+
+ if (adev->d->adrv_get_input_pointer == NULL
+ || (intr_flags & AINTR_NO_POINTER_UPDATES))
+ {
+ do_inputintr (dev, intr_flags);
+ return;
+ }
+
+ pos =
+ adev->d->adrv_get_input_pointer (adev->engine_num, dmap,
+ PCM_ENABLE_INPUT) / dmap->fragment_size;
+ n = 0;
+
+ while (dmap_get_qtail (dmap) != pos && n++ < dmap->nfrags)
+ {
+ do_inputintr (dev, intr_flags);
+ }
+}
+
+static void
+finish_output_interrupt (adev_p adev, dmap_p dmap)
+{
+ if (dmap->dmabuf_dma_handle != NULL) /* Some drivers don't use DMA */
+ OSS_DMA_SYNC(dmap->dmabuf_dma_handle, 0, dmap->bytes_in_use, OSS_DMA_SYNC_OUTBOUND);
+
+#ifdef CONFIG_OSSD
+ ossd_event (adev->engine_num, OSSD_EV_UPDATE_OUTPUT);
+#endif
+ if (dmap->audio_callback != NULL)
+ {
+ dmap->audio_callback (adev->engine_num, dmap->callback_parm);
+ }
+}
+
+static void
+do_outputintr (int dev, int intr_flags)
+{
+ adev_p adev;
+ dmap_p dmap;
+ int cptr;
+ oss_native_word flags;
+
+ adev = audio_engines[dev];
+ dmap = adev->dmap_out;
+
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+
+ if (dmap->dmabuf == NULL)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ cmn_err (CE_WARN, "Output interrupt when no buffer is allocated\n");
+ return;
+ }
+
+ if (!(intr_flags & AINTR_NO_POINTER_UPDATES))
+ {
+ dmap->byte_counter += dmap->fragment_size;
+ dmap->interrupt_count++;
+ }
+
+ dmap->fragment_counter = (dmap->fragment_counter + 1) % dmap->nfrags;
+
+ if (dmap->user_counter <= dmap->byte_counter) /* Underrun */
+ {
+ if (!(dmap->mapping_flags & DMA_MAP_MAPPED))
+ {
+#ifdef DO_TIMINGS
+ oss_timing_printf ("adev %d: Play underrun A", dev);
+ oss_timing_printf (" User=%lld", dmap->user_counter);
+ oss_timing_printf (" Dev=%lld", dmap->byte_counter);
+ oss_timing_printf (" Tmp=%d", dmap->tmpbuf_ptr);
+#endif
+ dmap->play_underruns++;
+
+ if (!dmap->underrun_flag)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Clearing the buffer");
+#endif
+ memset (dmap->dmabuf, dmap->neutral_byte, dmap->buffsize);
+ }
+ dmap->underrun_flag = 1;
+#if 1
+ dmap->user_counter = dmap->byte_counter + dmap->fragment_size;
+#endif
+ }
+ }
+
+ if (audio_space_in_queue (adev, dmap, 0) >= 0 || adev->nonblock)
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Wake up (out)");
+#endif
+ oss_wakeup (adev->out_wq, &dmap->mutex, &flags, POLLOUT | POLLWRNORM);
+ }
+
+ if (adev->flags & ADEV_AUTOMODE)
+ {
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ finish_output_interrupt (adev, dmap);
+ return;
+ }
+
+ cptr = dmap_get_qhead (dmap) * dmap->fragment_size;
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+ if (adev->d->adrv_output_block != NULL)
+ {
+ adev->d->adrv_output_block (adev->engine_num, dmap->dmabuf_phys + cptr,
+ dmap->fragment_size, dmap->fragment_size,
+ 1);
+ }
+ finish_output_interrupt (adev, dmap);
+}
+
+static void
+audio_outputintr (int dev, int intr_flags)
+{
+ adev_p adev;
+ dmap_p dmap;
+ int n;
+ oss_uint64_t pos;
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return;
+
+ adev = audio_engines[dev];
+ dmap = adev->dmap_out;
+
+ if (dmap->dma_mode != PCM_ENABLE_OUTPUT)
+ {
+ return;
+ }
+
+ if (!(dmap->flags & DMAP_STARTED))
+ {
+ return;
+ }
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Outputintr(%d)", dev);
+#endif
+ UP_STATUS (STS_INTR);
+
+ if (adev->d->adrv_get_output_pointer == NULL
+ || (intr_flags & AINTR_NO_POINTER_UPDATES))
+ {
+ UP_STATUS (STS_DOINTR);
+ do_outputintr (dev, intr_flags);
+ DOWN_STATUS (STS_DOINTR | STS_INTR);
+ return;
+ }
+
+ pos = get_output_pointer (adev, dmap, 0) / dmap->fragment_size;
+ n = 0;
+
+ while (dmap_get_qhead (dmap) != pos && n++ < dmap->nfrags)
+ {
+ UP_STATUS (STS_DOINTR);
+ do_outputintr (dev, intr_flags);
+ DOWN_STATUS (STS_DOINTR);
+ }
+ DOWN_STATUS (STS_INTR);
+}
+
+void
+oss_audio_reset (int dev)
+{
+ adev_p adev;
+ if (dev < 0 || dev >= num_audio_engines)
+ return;
+ adev = audio_engines[dev];
+
+ audio_reset_adev (adev);
+
+ if (adev->dmask & DMASK_OUT)
+ reset_dmap (adev->dmap_out);
+ if (adev->dmask & DMASK_IN)
+ reset_dmap (adev->dmap_in);
+}
+
+void
+oss_audio_start_syncgroup (unsigned int syncgroup)
+{
+/*
+ * This routine is to be called by the /dev/midi driver to start a sync group
+ * at the right time.
+ */
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (audio_global_mutex, flags);
+ handle_syncstart (syncgroup & SYNC_DEVICE_MASK, syncgroup);
+ MUTEX_EXIT_IRQRESTORE (audio_global_mutex, flags);
+}
+
+#ifdef ALLOW_SELECT
+/*ARGSUSED*/
+static int
+chpoll_output (int dev, struct fileinfo *file, oss_poll_event_t * ev)
+{
+ short events = ev->events;
+ adev_p adev;
+ dmap_p dmap;
+ oss_native_word flags;
+ audio_buf_info bi;
+ int limit;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("--- audio_chpoll_output(%d, %08x) ---", dev, events);
+#endif
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+ adev = audio_engines[dev];
+
+ dmap = adev->dmap_out;
+ if (dmap->mapping_flags & DMA_MAP_MAPPED)
+ {
+#if 1
+ /*
+ * It might actually be better to permit pollling in mmapped
+ * mode rather than returning an error.
+ */
+ if (dmap->interrupt_count > 0)
+ ev->revents |= (POLLOUT | POLLWRNORM) & events;
+ return 0;
+#else
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1014,
+ "select/poll called for an OSS device in mmap mode."),
+ 0);
+ /*
+ * Errordesc:
+ * The select() and poll() system calls are not defined for OSS devices
+ * when the device is in mmap mode.
+ */
+ return OSS_EPERM;
+#endif
+ }
+
+ if (dmap->dma_mode == PCM_ENABLE_INPUT)
+ {
+ oss_audio_set_error (adev->engine_num, E_PLAY,
+ OSSERR (1015,
+ "select/poll called for wrong direction."),
+ 0);
+ /*
+ * Errordesc: The application has opened the device in read-only
+ * mode but it tried to use select/poll to check if the device is
+ * ready for write. This is pointless because that will never
+ * happen.
+ */
+ return 0;
+ }
+
+ get_ospace (audio_engines[dev], dmap, (ioctl_arg) & bi);
+ limit = bi.fragsize * bi.fragstotal / 4;
+ if (dmap->low_water > limit)
+ dmap->low_water = limit;
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ if (bi.bytes < dmap->low_water)
+ { /* No space yet */
+#ifdef DO_TIMINGS
+ oss_do_timing ("Output not ready yet");
+#endif
+ oss_register_poll (adev->out_wq, &dmap->mutex, &flags, ev);
+ }
+ else
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Reporting output ready");
+#endif
+ ev->revents |= (POLLOUT | POLLWRNORM) & events;
+ }
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+chpoll_input (int dev, struct fileinfo *file, oss_poll_event_t * ev)
+{
+ short events = ev->events;
+ adev_p adev;
+ dmap_p dmap;
+ oss_native_word flags;
+ audio_buf_info bi;
+ int limit;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("--- audio_chpoll_input(%d, %08x) ---", dev, events);
+#endif
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+ adev = audio_engines[dev];
+
+ dmap = adev->dmap_in;
+ if (dmap->mapping_flags & DMA_MAP_MAPPED)
+ {
+#if 1
+ /*
+ * It might actually be better to permit pollling in mmapped
+ * mode rather than returning an error.
+ */
+ if (dmap->interrupt_count > 0)
+ ev->revents |= (POLLOUT | POLLWRNORM) & events;
+ return 0;
+#else
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1013,
+ "select/poll called for an OSS device in mmap mode."),
+ 0);
+ /*
+ * Errordesc:
+ * The select() and poll() system calls are not defined for OSS devices
+ * when the device is in mmap mode.
+ */
+ return OSS_EIO;
+#endif
+ }
+
+ if (dmap->dma_mode != PCM_ENABLE_INPUT)
+ {
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1016,
+ "select/poll called for wrong direction."),
+ 0);
+ /*
+ * Errordesc: The application has opened the device in write-only
+ * mode but it tried to use select/poll to check if the device has any
+ * data available to read. This is pointless because that will never
+ * happen.
+ */
+ return 0;
+ }
+
+ if (!(dmap->flags & DMAP_STARTED))
+ {
+ oss_audio_set_error (adev->engine_num, E_REC,
+ OSSERR (1017,
+ "select/poll called before recording is started."),
+ 0);
+ /*
+ * Errordesc:
+ * The application should start recording (using SNDCTL_DSP_SETTRIGGER)
+ * before calling select/poll to wait for recorded data. If recording is
+ * not active then recorded data will never arrive and the application
+ * will just sit and wait without doing anything.
+ */
+ }
+
+ get_ispace (audio_engines[dev], dmap, (ioctl_arg) & bi);
+ limit = bi.fragsize * bi.fragstotal / 4;
+ if (dmap->low_water > limit)
+ dmap->low_water = limit;
+ MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+ if (bi.bytes < dmap->low_water)
+ { /* No space yet */
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Input not ready yet (%d/%d)\n", bi.bytes,
+ dmap->low_water);
+#endif
+ oss_register_poll (adev->in_wq, &dmap->mutex, &flags, ev);
+ }
+ else
+ {
+#ifdef DO_TIMINGS
+ oss_do_timing ("Reporting input ready");
+#endif
+ ev->revents |= (POLLIN | POLLRDNORM) & events;
+ }
+ MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
+
+ return 0;
+}
+
+/*ARGSUSED*/
+int
+oss_audio_chpoll (int dev, struct fileinfo *file, oss_poll_event_t * ev)
+{
+ short events = ev->events;
+ adev_p adev;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("--- audio_chpoll(%d, %08x) ---", dev, events);
+#endif
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+ adev = audio_engines[dev];
+
+ if ((events & (POLLOUT | POLLWRNORM)) && (adev->open_mode & OPEN_WRITE))
+ {
+ int err;
+
+ if ((err=chpoll_output (dev, file, ev))<0)
+ return err;
+ }
+
+ if ((events & (POLLIN | POLLRDNORM)) && (adev->open_mode & OPEN_READ))
+ {
+ int err;
+
+ if ((err=chpoll_input (dev, file, ev))<0)
+ return err;
+ }
+
+ return 0;
+}
+#endif
+
+/*ARGSUSED*/
+static void
+dummy_inputintr (int dev, int intr_flags)
+{
+ /* Dummy input interrupt handler */
+}
+
+/*ARGSUSED*/
+static void
+dummy_outputintr (int dev, int x)
+{
+ /* Dummy output interrupt handler */
+}
+
+static oss_cdev_drv_t audio_cdev_drv = {
+#ifdef VDEV_SUPPORT
+ oss_audio_open_devfile,
+#else
+ oss_audio_open_engine,
+#endif
+ oss_audio_release,
+ oss_audio_read,
+ oss_audio_write,
+ oss_audio_ioctl,
+#ifdef ALLOW_SELECT
+ oss_audio_chpoll
+#else
+ NULL
+#endif
+};
+
+#ifdef MANAGE_DEV_DSP
+#ifdef VDEV_SUPPORT
+static oss_cdev_drv_t vdsp_cdev_drv = {
+ oss_open_vdsp,
+ oss_audio_release,
+ oss_audio_read,
+ oss_audio_write,
+ oss_audio_ioctl,
+#ifdef ALLOW_SELECT
+ oss_audio_chpoll
+#else
+ NULL
+#endif
+};
+#endif
+#endif
+
+static oss_cdev_drv_t audio_engine_cdev_drv = {
+ oss_audio_open_engine,
+ oss_audio_release,
+ oss_audio_read,
+ oss_audio_write,
+ oss_audio_ioctl,
+#ifdef ALLOW_SELECT
+ oss_audio_chpoll
+#else
+ NULL
+#endif
+};
+
+void
+oss_audio_register_client (oss_audio_startup_func func, void *devc,
+ oss_device_t * osdev)
+{
+/*
+ * Register a callback for a driver that wants to be initialized after a new audio device
+ * is installed.
+ */
+
+ if (num_audio_startups >= MAX_STARTUPS)
+ return;
+
+ audio_startups[num_audio_startups].func = func;
+ audio_startups[num_audio_startups].devc = devc;
+ audio_startups[num_audio_startups].osdev = osdev;
+ num_audio_startups++;
+}
+
+void
+oss_add_audio_devlist (int list_id, int devfile)
+{
+#if 0
+/*
+ * Device list support is not in use at this moment
+ */
+ oss_devlist_t *list;
+ int i;
+
+ switch (list_id)
+ {
+ case OPEN_READ:
+ list = &dspinlist;
+ break;
+
+ case OPEN_WRITE:
+ list = &dspoutlist;
+ break;
+
+ case OPEN_READ | OPEN_WRITE:
+ list = &dspinoutlist;
+ break;
+
+ default:
+ cmn_err (CE_CONT, "Bad device list ID %d\n", list_id);
+ return;
+ }
+
+ for (i = 0; i < list->ndevs; i++)
+ if (list->devices[i] == devfile) /* Already there */
+ return;
+
+ /*
+ * Add the device to the list
+ */
+ list->devices[list->ndevs++] = devfile;
+#endif
+}
+
+#if 0
+static void
+add_to_devlists (adev_p adev)
+{
+/*
+ * Add the device to the default input, output and/or input/output lists
+ * for /dev/dsp.
+ */
+
+ if (!(adev->flags & ADEV_SPECIAL))
+ {
+ if (!(adev->flags & ADEV_NOOUTPUT))
+ { /* Output capable */
+
+ if (adev->flags & ADEV_VIRTUAL)
+ {
+ int n = dspoutlist.ndevs++;
+
+ if (adev->flags & ADEV_DEFAULT)
+ {
+ int i;
+
+ for (i = n; i > 0; i--)
+ dspoutlist.devices[i] = dspoutlist.devices[i - 1];
+ dspoutlist.devices[0] = adev->audio_devfile;
+ }
+ else
+ dspoutlist.devices[n] = adev->audio_devfile;
+ }
+ else
+ {
+ /* Put non-virtual devices to a secondary list */
+ int n = dspoutlist2.ndevs++;
+ dspoutlist2.devices[n] = adev->audio_devfile;
+ }
+
+ }
+
+ if (!(adev->flags & (ADEV_NOINPUT)))
+ { /* Input capable */
+
+ int n = dspinlist.ndevs++;
+
+ if (adev->flags & ADEV_DEFAULT)
+ {
+ int i;
+
+ for (i = n; i > 0; i--)
+ dspinlist.devices[i] = dspinlist.devices[i - 1];
+ dspinlist.devices[0] = adev->audio_devfile;
+ }
+ else
+ dspinlist.devices[n] = adev->audio_devfile;
+ }
+
+ if (!(adev->flags & (ADEV_NOINPUT | ADEV_NOOUTPUT))
+ || (adev->flags & ADEV_DUPLEX))
+ { /* Input/output capable */
+
+ int n = dspinoutlist.ndevs++;
+
+ if (adev->flags & ADEV_DEFAULT)
+ {
+ int i;
+
+ for (i = n; i > 0; i--)
+ dspinoutlist.devices[i] = dspinoutlist.devices[i - 1];
+ dspinoutlist.devices[0] = adev->audio_devfile;
+ }
+ else
+ dspinoutlist.devices[n] = adev->audio_devfile;
+ }
+ }
+}
+#endif
+
+static int
+resize_array(oss_device_t *osdev, adev_t ***arr, int *size, int increment)
+{
+ adev_t **old=*arr, **new = *arr;
+ int old_size = *size;
+ int new_size = *size;
+
+ if (new_size >= HARD_MAX_AUDIO_DEVFILES) /* Too many device files */
+ return 0;
+
+ new_size += increment;
+ if (new_size > HARD_MAX_AUDIO_DEVFILES)
+ new_size = HARD_MAX_AUDIO_DEVFILES;
+
+ if ((new=AUDIO_MALLOC(osdev, new_size * sizeof (adev_t *)))==NULL)
+ return 0;
+
+ memset(new, 0, new_size * sizeof(adev_t *));
+ if (old != NULL)
+ memcpy(new, old, old_size * sizeof(adev_t *));
+
+ *size = new_size;
+ *arr = new;
+
+ if (old != NULL)
+ AUDIO_FREE(osdev, old);
+
+ return 1;
+}
+
+int
+oss_install_audiodev_with_devname (int vers,
+ oss_device_t * osdev,
+ oss_device_t * master_osdev,
+ char *name,
+ const audiodrv_t * driver,
+ int driver_size,
+ int flags,
+ unsigned int format_mask, void *devc, int parent,
+ const char * devfile_name)
+{
+ audiodrv_t *d;
+ adev_t *op;
+ int i, num = -1, hidden_device = 0;
+ int update_devlists = 0;
+ int reinsterted_device = 0;
+ int chdev_flags = 0;
+ int devfile_num = 0;
+
+ if (devc == NULL)
+ {
+ cmn_err(CE_WARN, "devc==NULL for %s. Cannot install audio device\n", name);
+ return OSS_EINVAL;
+ }
+
+ if (name == NULL)
+ cmn_err (CE_CONT, "Name is really NULL\n");
+ if (master_osdev == NULL)
+ master_osdev = osdev;
+
+#ifdef VDEV_SUPPORT
+ if (flags & (ADEV_SHADOW | ADEV_HIDDEN))
+ hidden_device = 1;
+#else
+ flags &= ~ADEV_HIDDEN;
+ hidden_device = 0;
+#endif
+
+ if (audio_engines == NULL)
+ {
+ audio_engines = AUDIO_MALLOC (NULL, sizeof (adev_t *) * MAX_AUDIO_ENGINES);
+ memset (audio_engines, 0, sizeof (adev_t *) * MAX_AUDIO_ENGINES);
+ }
+
+ if (audio_devfiles == NULL)
+ {
+ audio_devfiles = AUDIO_MALLOC (NULL, sizeof (adev_t *) * MAX_AUDIO_DEVFILES);
+ memset (audio_devfiles, 0, sizeof (adev_t *) * MAX_AUDIO_DEVFILES);
+ }
+
+ if (vers != OSS_AUDIO_DRIVER_VERSION)
+ {
+ cmn_err (CE_WARN, "Incompatible audio driver for %s\n", name);
+ return OSS_EIO;
+ }
+
+ if (driver_size > sizeof (audiodrv_t))
+ driver_size = sizeof (audiodrv_t);
+/*
+ * Try to figure out if this device has earlier been installed. Sometimes it may happen that
+ * the low level driver gets unloaded while the osscore module still
+ * remains loaded. Try to re-use the same audio device number if possible.
+ */
+
+ num = -1;
+
+ for (i = 0; i < num_audio_engines; i++)
+ {
+
+ if ((audio_engines[i]->flags & (ADEV_SHADOW|ADEV_HIDDEN)) !=
+ (flags & (ADEV_SHADOW|ADEV_HIDDEN))) /* Different visibility */
+ continue;
+
+ if (audio_engines[i]->unloaded
+ && audio_engines[i]->os_id == oss_get_osid (osdev))
+ {
+ /* This audio device was previously connected to the same physical device */
+
+ num = i;
+ reinsterted_device = 1;
+ DDB (cmn_err
+ (CE_NOTE, "Audio device %d got re-installed again.\n", i));
+ break;
+ }
+ }
+
+ if (num == -1)
+ {
+
+ if (num_audio_engines >= MAX_AUDIO_ENGINES)
+ {
+ if (!resize_array(osdev, &audio_engines, &oss_max_audio_engines, AUDIO_ENGINE_INCREMENT))
+ {
+ cmn_err (CE_CONT, "Cannot grow audio_engines[]\n");
+ return OSS_EIO;
+ }
+ }
+
+ d = AUDIO_MALLOC (osdev, sizeof (audiodrv_t));
+ op = AUDIO_MALLOC (osdev, sizeof (adev_t));
+ memset ((char *) op, 0, sizeof (adev_t));
+ if (driver_size < sizeof (audiodrv_t))
+ memset ((char *) d, 0, sizeof (audiodrv_t));
+ memcpy ((char *) d, (char *) driver, driver_size);
+ num = num_audio_engines;
+ audio_engines[num] = op;
+ num_audio_engines++;
+
+ update_devlists = 1;
+
+ sprintf (op->handle, "%s-au%02d", osdev->handle,
+ osdev->num_audio_engines + 1);
+ op->port_number = osdev->num_audio_engines;
+ }
+ else
+ {
+ op = audio_engines[num];
+ d = audio_engines[num]->d;
+ if (driver_size < sizeof (audiodrv_t))
+ memset ((char *) d, 0, sizeof (audiodrv_t));
+ memcpy ((char *) d, (char *) driver, driver_size);
+ update_devlists = 0;
+ }
+
+ if (d == NULL || op == NULL)
+ {
+ cmn_err (CE_WARN, "Can't allocate driver for %s (adev=%p, d=%p)\n",
+ name, op, d);
+ return OSS_ENOSPC;
+ }
+
+ if (d->adrv_get_input_pointer == NULL)
+ d->adrv_get_input_pointer = d->adrv_get_buffer_pointer;
+ if (d->adrv_get_output_pointer == NULL)
+ d->adrv_get_output_pointer = d->adrv_get_buffer_pointer;
+
+ op->d = d;
+ op->os_id = oss_get_osid (osdev);
+ op->enabled = 0;
+ op->outputintr = dummy_outputintr;
+ op->inputintr = dummy_inputintr;
+ op->vmix_mixer = NULL;
+
+ strncpy (op->name, name, sizeof (op->name));
+ op->name[sizeof (op->name) - 1] = 0;
+ op->caps = 0;
+
+ op->flags = flags;
+ op->latency = -1; /* Unknown */
+
+ op->oformat_mask = format_mask;
+ op->iformat_mask = format_mask;
+ op->mixer_dev = -1;
+ op->min_channels = 1;
+ op->max_channels = 2;
+ op->min_rate = 8000;
+ op->max_rate = 44100;
+ op->devc = devc;
+ op->parent_dev = parent + 1;
+ op->dmap_in = NULL;
+ op->dmap_out = NULL;
+ memset (op->cmd, 0, sizeof (op->cmd));
+ op->pid = -1;
+ op->osdev = osdev;
+ op->master_osdev = master_osdev;
+ op->card_number = osdev->cardnum;
+ op->engine_num = op->rate_source = num;
+ op->real_dev = num;
+ op->redirect_in = -1;
+ op->redirect_out = -1;
+ op->dmabuf_alloc_flags = 0;
+ op->dmabuf_maxaddr = MEMLIMIT_32BITS;
+
+ audio_engines[num] = op;
+ op->next_out = NULL;
+ op->next_in = NULL;
+
+ op->song_name[0] = 0;
+ op->label[0] = 0;
+ op->nrates=0;
+
+ if ((flags & ADEV_SHADOW) && num > 0)
+ {
+ adev_p prev = audio_engines[num - 1]; /* Previous device */
+
+ prev->next_out = op;
+ prev->next_in = op;
+ }
+
+ if (audio_init_device (num) < 0)
+ return OSS_ENOMEM;
+
+/*
+ * Create the device node.
+ */
+#ifndef VDEV_SUPPORT
+ flat_device_model = 1;
+ hidden_device = 0;
+#endif
+
+ if (reinsterted_device)
+ {
+ /*
+ * A hotpluggable device has been reinserted in the system.
+ * Update the internal tables and re-create the device file entry.
+ * However don't create new audio engine and device file numbers.
+ */
+ devfile_num = op->audio_devfile;
+ chdev_flags |= CHDEV_REPLUG;
+ }
+ else
+ {
+ if (!hidden_device)
+ {
+ if (num_audio_devfiles >= MAX_AUDIO_DEVFILES)
+ {
+ if (!resize_array(osdev, &audio_devfiles, &oss_max_audio_devfiles, AUDIO_DEVFILE_INCREMENT))
+ {
+ cmn_err (CE_CONT, "Cannot grow audio_devfiles[]\n");
+ return num;
+ }
+ }
+
+ audio_devfiles[num_audio_devfiles] = op;
+ devfile_num = num_audio_devfiles++;
+ }
+ }
+
+ if (flat_device_model || !hidden_device)
+ {
+#ifdef NEW_DEVICE_NAMING
+ oss_devnode_t name;
+ char tmpl[32];
+
+ if (*devfile_name != 0)
+ {
+ /*
+ * A name was suggested by the low level driver
+ */
+ strcpy (tmpl, devfile_name);
+ }
+ else if (flags & ADEV_NOOUTPUT)
+ sprintf (tmpl, "pcmin%d", osdev->num_audiorec++);
+ else
+ sprintf (tmpl, "pcm%d", osdev->num_audioduplex++);
+
+# ifdef USE_DEVICE_SUBDIRS
+ sprintf (name, "oss/%s/%s", osdev->nick, tmpl);
+# else
+ sprintf (name, "%s_%s", osdev->nick, tmpl);
+# endif
+#else
+ sprintf (name, "dsp%d", num);
+#endif
+
+ op->real_dev = devfile_num;
+ op->audio_devfile = devfile_num;
+ audio_devfiles[devfile_num] = op;
+ sprintf (op->devnode, "/dev/%s", name);
+ oss_install_chrdev (master_osdev, name, OSS_DEV_DSP, devfile_num,
+ &audio_cdev_drv, chdev_flags);
+ osdev->num_audio_engines++;
+
+ op->enabled = 1;
+ op->unloaded = 0;
+
+ }
+ else
+ {
+ op->real_dev = -1;
+ if (devfile_num > 0 && (flags & ADEV_SHADOW))
+ {
+ /* Use the device node of the parent device file */
+ if (audio_devfiles[devfile_num - 1] != NULL)
+ strcpy (op->devnode, audio_devfiles[devfile_num - 1]->devnode);
+ else
+ strcpy (op->devnode, "Unknown");
+ audio_devfiles[devfile_num] = op;
+ }
+ else
+ {
+ strcpy (op->devnode, "HiddenAudioDevice");
+ }
+ op->enabled = 1;
+ op->unloaded = 0;
+ }
+
+//#ifdef VDEV_SUPPORT
+ oss_install_chrdev (osdev, NULL, OSS_DEV_DSP_ENGINE, num,
+ &audio_engine_cdev_drv, chdev_flags);
+//#endif
+
+#if 0
+ if (!reinsterted_device && update_devlists && !hidden_device)
+ add_to_devlists (op);
+#endif
+
+ {
+ int i;
+ for (i = 0; i < num_audio_engines; i++)
+ if (audio_engines[i] == NULL)
+ cmn_err (CE_WARN, "Audio engines %d==NULL\n", i);
+ for (i = 0; i < num_audio_devfiles; i++)
+ if (audio_devfiles[i] == NULL)
+ cmn_err (CE_WARN, "Audio devfiles %d==NULL\n", i);
+ }
+
+ return num;
+}
+
+int
+oss_install_audiodev (int vers,
+ oss_device_t * osdev,
+ oss_device_t * master_osdev,
+ char *name,
+ const audiodrv_t * driver,
+ int driver_size,
+ unsigned long long flags,
+ unsigned int format_mask, void *devc, int parent)
+{
+ return oss_install_audiodev_with_devname (vers,
+ osdev,
+ master_osdev,
+ name,
+ driver,
+ driver_size,
+ flags,
+ format_mask, devc, parent,
+ ""); /* Use default device file naming */
+}
+
+void
+oss_audio_delayed_attach (void)
+{
+ int i;
+
+ /*
+ * Serve possible other drivers waiting for new friends.
+ */
+ for (i = 0; i < num_audio_startups; i++)
+ {
+ if (audio_startups[i].osdev != NULL
+ && audio_startups[i].osdev->available)
+ {
+ if (audio_startups[i].func (audio_startups[i].devc))
+ audio_startups[i].osdev = NULL; /* Inactivate it */
+ }
+ }
+}
+
+/*ARGSUSED*/
+void
+install_vdsp (oss_device_t * osdev)
+{
+#ifdef MANAGE_DEV_DSP
+/*
+ * Install the driver for /dev/dsp (the multiplexer device)
+ *
+ * NOTE! Not used at this moment because /dev/dsp assignment is managed in user
+ * space (by ossdevlinks).
+ */
+#ifdef VDEV_SUPPORT
+ oss_install_chrdev (osdev, "dsp", OSS_DEV_VDSP, 0, &vdsp_cdev_drv,
+ CHDEV_VIRTUAL);
+ oss_install_chrdev (osdev, "dsp_in", OSS_DEV_VDSP, 1, &vdsp_cdev_drv,
+ CHDEV_VIRTUAL);
+ oss_install_chrdev (osdev, "dsp_out", OSS_DEV_VDSP, 2, &vdsp_cdev_drv,
+ CHDEV_VIRTUAL);
+#endif
+#endif
+}
diff --git a/kernel/framework/audio/oss_audiofmt.c b/kernel/framework/audio/oss_audiofmt.c
new file mode 100644
index 0000000..7917d9e
--- /dev/null
+++ b/kernel/framework/audio/oss_audiofmt.c
@@ -0,0 +1,1278 @@
+/*
+ * Purpose: Audio format conversion routines used by audio.c
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#undef NO_COOKED_MODE
+#define AUDIO_C
+
+#define GRC 3
+
+/* SINE_DEBUG enables internal test signal (sine wave) */
+#undef SINE_DEBUG
+
+#include "oss_config.h"
+#include "ulaw.h"
+#define __int8_t_defined
+#include "grc3.h"
+
+/*
+ * Audio format conversion stuff
+ */
+#define CNV_NONE 0x00000000
+#define CNV_SRC 0x00000001
+
+#define CNV_CHNMASK 0x000000f0
+#define CNV_M2S 0x00000010
+#define CNV_S2M 0x00000020
+#define CNV_MULT 0x00000040
+
+#define CNV_Flog 0x00001000
+#define CNV_F8bit 0x00002000
+#define CNV_F16bit 0x00004000
+#define CNV_F24bit 0x00008000
+#define CNV_F32bit 0x00010000
+
+#define CNV_Tlog 0x00100000
+#define CNV_T8bit 0x00200000
+#define CNV_T16bit 0x00400000
+#define CNV_T24bit 0x00800000
+#define CNV_T32bit 0x01000000
+
+#define CNV_SIGN 0x10000000
+#define CNV_ENDIAN 0x20000000
+#define CNV_TOLOG 0x40000000
+#define CNV_FROMLOG 0x80000000
+
+static audio_format_info_t audio_format_info[] = {
+ {"mu-Law", AFMT_MU_LAW, 0x80, 8, 0, ENDIAN_NONE, 1},
+ {"A-Law", AFMT_A_LAW, 0x80, 8, 0, ENDIAN_NONE, 1},
+ {"IMA-ADPCM", AFMT_IMA_ADPCM, 0x00, 4, 0, ENDIAN_NONE, 0, ALIGN_LSB, 1},
+ {"8", AFMT_U8, 0x80, 8, 1, ENDIAN_NONE, 0},
+ {"16(LE)", AFMT_S16_LE, 0x00, 16, 1, ENDIAN_LITTLE, 1},
+ {"16(BE)", AFMT_S16_BE, 0x00, 16, 1, ENDIAN_BIG, 1},
+ {"8(signed)", AFMT_S8, 0x00, 8, 1, ENDIAN_NONE, 1},
+ {"16(unsigned LE)", AFMT_U16_LE, 0x00, 16, 1, ENDIAN_LITTLE, 0},
+ {"16(unsigned BE)", AFMT_U16_BE, 0x00, 16, 1, ENDIAN_BIG, 0},
+ {"mp2/mp3", AFMT_MPEG, 0x00, 8, 0, ENDIAN_NONE, 0, ALIGN_LSB, 1},
+ {"AC3", AFMT_AC3, 0x00, 16, 0, ENDIAN_NONE, 0, ALIGN_LSB, 1},
+ {"SPDIF (RAW)", AFMT_SPDIF_RAW, 0x00, 32, 0, ENDIAN_NONE, 0, ALIGN_LSB, 1},
+ {"24(LE)", AFMT_S24_LE, 0x00, 32, 1, ENDIAN_LITTLE, 1, ALIGN_LSB},
+ {"24(BE)", AFMT_S24_BE, 0x00, 32, 1, ENDIAN_BIG, 1, ALIGN_LSB},
+ {"32(LE)", AFMT_S32_LE, 0x00, 32, 1, ENDIAN_LITTLE, 1},
+ {"32(BE)", AFMT_S32_BE, 0x00, 32, 1, ENDIAN_BIG, 1},
+ {"24(PACKED)", AFMT_S24_PACKED, 0x00, 24, 1, ENDIAN_LITTLE, 1, ALIGN_LSB},
+ {0, 0}
+};
+
+audio_format_info_p
+oss_find_format (unsigned int fmt)
+{
+ int i;
+
+ i = 0;
+
+ while (audio_format_info[i].fmt != 0)
+ {
+ if (audio_format_info[i].fmt == fmt)
+ return &audio_format_info[i];
+ i++;
+ }
+
+ return NULL;
+}
+
+#if 0
+/*
+ * Limiter stuff. Currently not in use.
+ */
+static const unsigned char limit8[] = {
+/*-128*/ 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72,
+/*-112*/ 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80,
+/* -96*/ 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 88,
+/* -80*/ 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 95, 95, 96,
+/* -64*/ 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103,
+ 104,
+/* -48*/ 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110,
+ 111, 111, 112,
+/* -32*/ 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118,
+ 119, 119, 120,
+/* -16*/ 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126,
+ 127, 127, 128,
+/* 0*/ 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134,
+ 134, 135, 135,
+/* 16*/ 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141, 142,
+ 142, 143, 143,
+/* 32*/ 144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149, 150,
+ 150, 151, 151,
+/* 48*/ 152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 157, 157, 158,
+ 158, 159, 159,
+/* 64*/ 160, 160, 161, 161, 162, 162, 163, 163, 164, 164, 165, 165, 166,
+ 166, 167, 167,
+/* 80*/ 168, 168, 169, 169, 170, 170, 171, 171, 172, 172, 173, 173, 174,
+ 174, 175, 175,
+/* 96*/ 176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182,
+ 182, 183, 183,
+/* 112*/ 184, 184, 185, 185, 186, 186, 187, 187, 188, 188, 189, 189, 190,
+ 190, 191, 191
+};
+
+static __inline__ void
+limit_8bit (unsigned char *buf, int l)
+{
+ int i;
+
+ for (i = 0; i < l; i++)
+ buf[i] = limit8[buf[i]];
+}
+
+static __inline__ void
+limit_16bit (short *buf, int l)
+{
+ int i;
+ l /= sizeof (*buf);
+
+ for (i = 0; i < l; i++)
+ buf[i] /= 2;
+}
+
+static __inline__ void
+limit_32bit (int *buf, int l)
+{
+ int i;
+ l /= sizeof (*buf);
+
+ for (i = 0; i < l; i++)
+ buf[i] /= 2;
+}
+
+static const unsigned char unlimit8[] = {
+/* 0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 16*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 32*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 48*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* 64*/ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+/* 80*/ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
+/* 96*/ 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
+/* 112*/ 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
+ 124, 126,
+/* 128*/ 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152,
+ 154, 156, 158,
+/* 144*/ 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184,
+ 186, 188, 190,
+/* 160*/ 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216,
+ 218, 220, 222,
+/* 176*/ 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248,
+ 250, 252, 254,
+/* 192*/ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+/* 208*/ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+/* 224*/ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+/* 240*/ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255
+};
+
+static __inline__ void
+unlimit_8bit (unsigned char *buf, int l)
+{
+ int i;
+
+ for (i = 0; i < l; i++)
+ buf[i] = unlimit8[buf[i]];
+}
+
+static __inline__ void
+unlimit_16bit (short *buf, int l)
+{
+ int i;
+ l /= sizeof (*buf);
+
+ for (i = 0; i < l; i++)
+ buf[i] *= 2;
+}
+
+static __inline__ void
+unlimit_32bit (int *buf, int l)
+{
+ int i;
+ l /= sizeof (*buf);
+
+ for (i = 0; i < l; i++)
+ buf[i] *= 2;
+}
+#endif
+
+/*ARGSUSED*/
+static int
+do_src (adev_p adev, dmap_p dmap, int srcrate, int tgtrate, void *p1,
+ void *p2, int *len, int channels, int bits, int ssize)
+{
+#if GRC == 2
+ int err, l, l1, l2;
+
+ l = *len;
+
+ err = src_convert (dmap->src, p1, l, bits, p2, 4096, 24, &l1, &l2, 0);
+ *len = l2;
+ if (l1 != l)
+ cmn_err (CE_NOTE, "Everything not taken %d/%d\n", l1, l);
+
+#endif
+
+#if GRC == 3
+ int ch, l, size, nsamples, err;
+
+ l = *len / ssize;
+ size = TMP_CONVERT_BUF_SIZE / ssize;
+ size /= channels;
+ nsamples = l / channels;
+
+ if (bits == 24)
+ bits = 32;
+
+# ifdef DO_TIMINGS
+ oss_timing_printf ("grc3_convert %d bytes / %d samples * %d channels in. ",
+ *len, nsamples, channels);
+# endif
+
+#if 0
+ /* Limit the volume levels before calling GRC3 */
+ buf = p1;
+
+ switch (ssize)
+ {
+ case 1:
+ limit_8bit ((unsigned char *) buf, *len);
+ break;
+ case 2:
+ limit_16bit ((short *) buf, *len);
+ break;
+ case 4:
+ limit_32bit ((int *) buf, *len);
+ break;
+ }
+#endif
+
+ for (ch = 0; ch < channels; ch++)
+ {
+ if ((err = grc3_convert (dmap->srcstate[ch], bits, adev->src_quality, /* Numbits, quality */
+ p1, p2, nsamples, size, channels, ch)) < 0)
+ {
+ cmn_err (CE_WARN, "SRC failed (%d), bits=%d, ssize=%d\n", err, bits,
+ ssize);
+ return OSS_EIO;
+ }
+
+ *len = ((grc3state_t *) dmap->srcstate[ch])->outsz * ssize * channels;
+ VMEM_CHECK (p2, *len);
+ }
+#if 0
+ buf = p2;
+ switch (ssize)
+ {
+ case 1:
+ unlimit_8bit ((unsigned char *) buf, *len);
+ break;
+ case 2:
+ unlimit_16bit ((short *) buf, *len);
+ break;
+ case 4:
+ unlimit_32bit ((int *) buf, *len);
+ break;
+ }
+#endif
+# ifdef DO_TIMINGS
+ oss_timing_printf ("-> %d bytes, %d samples out, %d samples in",
+ *len, ((grc3state_t *) dmap->srcstate[0])->outsz,
+ ((grc3state_t *) dmap->srcstate[0])->insz);
+# endif
+#endif
+
+ return 0;
+}
+
+static int
+setup_src (adev_p adev, dmap_p dmap, int srate, int trate, int sch, int tch)
+{
+ int ch, nch;
+
+ nch = sch;
+ if (tch < nch)
+ nch = tch;
+
+ if (adev->src_quality < 1)
+ adev->src_quality = 1;
+ if (adev->src_quality > 5)
+ adev->src_quality = 5;
+
+#if GRC == 2
+ if (nch > 2)
+ {
+ cmn_err (CE_WARN, "Too many channels for SRC (%d)\n", nch);
+ return OSS_EIO;
+ }
+ {
+ int val;
+ val = src_find_output_rate (trate, srate);
+ if (src_open (&dmap->src, srate, trate, nch, 0) != 0)
+ {
+ cmn_err (CE_CONT, "OSS audio: SRC open failed\n");
+ return OSS_EIO;
+ }
+ }
+#endif
+#if GRC == 3
+ if (nch > OSS_MAX_CONVERT_CHANNELS)
+ {
+ cmn_err (CE_WARN, "Too many channels for SRC (%d)\n", nch);
+ return OSS_EIO;
+ }
+#ifdef DO_TIMINGS
+ oss_timing_printf ("grc3_setup %d -> %d Hz, %d channels", srate, trate, nch);
+#endif
+
+ for (ch = 0; ch < nch; ch++)
+ {
+ if (dmap->srcstate[ch] == NULL)
+ {
+ dmap->srcstate[ch] = PMALLOC (dmap->osdev, sizeof (grc3state_t));
+ }
+ grc3_reset (dmap->srcstate[ch]);
+ grc3_setup (dmap->srcstate[ch], srate, trate);
+ }
+#endif
+ return 0;
+}
+
+#if !defined(__OpenBSD__)
+static __inline__ unsigned int
+swap32 (unsigned int x)
+{
+
+#if 1
+ unsigned int y = 0;
+ unsigned char *a = ((unsigned char *) &x) + 3;
+ unsigned char *b = (unsigned char *) &y;
+
+ *b++ = *a--;
+ *b++ = *a--;
+ *b++ = *a--;
+ *b++ = *a--;
+
+ return y;
+#else
+ /* Old version */
+ return ((x & 0x000000ff) << 24) |
+ ((x & 0x0000ff00) << 8) |
+ ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
+#endif
+}
+#endif
+
+#ifdef SINE_DEBUG
+#define SIN_STEPS 48
+static short sinebuf[48] = {
+ 0, 4276, 8480, 12539, 16383, 19947, 23169, 25995,
+ 28377, 30272, 31650, 32486, 32767, 32486, 31650, 30272,
+ 28377, 25995, 23169, 19947, 16383, 12539, 8480, 4276,
+ 0, -4276, -8480, -12539, -16383, -19947, -23169, -25995,
+ -28377, -30272, -31650, -32486, -32767, -32486, -31650, -30272,
+ -28377, -25995, -23169, -19947, -16383, -12539, -8480, -4276
+};
+static int sine_ptr = 0;
+#endif
+
+static int
+cnv_default (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl, unsigned char **tgtp,
+ sample_parms * source, sample_parms * target)
+{
+ void *p1 = *srcp, *p2 = *tgtp, *tmpp;
+ int len = *srcl, l, i;
+
+/*
+ * Convert samples to 24 bit (32 bit lsb aligned) if necessary.
+ */
+ VMEM_CHECK (p1, len);
+ VMEM_CHECK (p2, len);
+ if (source->fmt != AFMT_S24_NE)
+ switch (source->fmt)
+ {
+ case AFMT_U8:
+ {
+ unsigned char *fromp = p1;
+ unsigned int *top = p2;
+
+ l = len;
+ len = l * sizeof (int);
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = ((signed char) (*fromp++ ^ 0x80)) << 16;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S8:
+ {
+ char *fromp = p1;
+ int *top = p2;
+ int t;
+
+ l = len;
+ len = l * sizeof (int);
+
+ for (i = 0; i < l; i++)
+ {
+ t = (*fromp++) << 24;
+ *top++ = t >> 8;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_MU_LAW:
+ {
+ unsigned char *fromp = p1;
+ unsigned int *top = p2;
+
+ l = len;
+ len = l * sizeof (int);
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = ((signed char) (ulaw_dsp[(*fromp++)] ^ 0x80)) << 16;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S16_NE:
+ {
+ short *fromp = p1;
+ int *top = p2;
+
+ l = len / 2;
+ len = l * sizeof (int);
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = *fromp++ << 8;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S16_OE:
+ {
+ short *fromp = p1;
+ int *top = p2;
+
+ l = len / 2;
+ len = l * sizeof (int);
+
+ for (i = 0; i < l; i++)
+ {
+ short tmp;
+ int t;
+ tmp = *fromp++;
+ /* Try to maintain the sign bit by shifting 8 bits too far */
+ t = ((tmp & 0xff) << 24) | ((tmp & 0xff00) << 8);
+ *top++ = t >> 8;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S32_NE:
+ {
+ int *fromp = p1;
+ int *top = p2;
+
+ l = len / 4;
+ /* len = l * sizeof (int); */
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = *fromp++ >> 8;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S32_OE:
+ {
+ int *fromp = p1;
+ int *top = p2;
+
+ l = len / 4;
+ /* len = l * sizeof (int); */
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = swap32 (*fromp++) >> 8;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S24_OE:
+ {
+ int *fromp = p1;
+ int *top = p2;
+
+ l = len / 4;
+ /* len = l * sizeof (int); */
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = swap32 ((unsigned int) (*fromp++));
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S24_PACKED:
+ {
+ unsigned char *fromp = p1;
+ int *top = p2;
+
+ l = len / 3;
+ len = l * sizeof (int);
+
+ for (i = 0; i < l; i++)
+ {
+ int tmp = 0;
+
+#if 1
+ tmp |= (*fromp++);
+ tmp |= (*fromp++) << 8;
+ tmp |= (*fromp++) << 16;
+#else
+ tmp |= (*fromp++) << 16;
+ tmp |= (*fromp++) << 8;
+ tmp |= (*fromp++);
+#endif
+
+ *top++ = tmp;
+
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Unsupported conversion source format %08x\n",
+ source->fmt);
+ return OSS_EIO;
+ }
+
+ if (source->rate != target->rate && source->channels <= target->channels)
+ {
+ int err;
+
+ VMEM_CHECK (p1, len);
+ err =
+ do_src (adev, dmap, source->rate, target->rate, p1, p2, &len,
+ source->channels, 32, 4);
+ if (err < 0)
+ return err;
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+
+/*
+ * Convert between mono and stereo
+ */
+
+ if (source->channels != target->channels)
+ {
+ VMEM_CHECK (p1, len);
+ if (source->channels == 1 && target->channels == 2)
+ {
+ /* Mono -> Stereo */
+ int *fromp = p1, *top = p2;
+
+ l = len / sizeof (int); /* Number of (mono) samples */
+ len = len * 2; /* Number of bytes will get doubled */
+ for (i = 0; i < l; i++)
+ {
+ *top++ = *fromp;
+ *top++ = *fromp++;
+ }
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ else if (source->channels == 2 && target->channels == 1)
+ {
+ /* Stereo -> mono */
+ int *fromp = p1, *top = p2;
+
+ len = len / 2; /* Number of bytes will drop to a half */
+ l = len / sizeof (int); /* Number of (mono) samples */
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = *fromp++; /* Take just the left channel sample */
+ fromp++; /* discard the right channel one */
+ }
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ else
+ {
+ /* Multi channel conversions */
+
+ int *fromp = p1, *top = p2;
+ int n, nc, sc, tc;
+
+ l = len / sizeof (int);
+ n = l / source->channels;
+ len = len * target->channels / source->channels;
+
+ tc = target->channels;
+ sc = source->channels;
+ nc = tc;
+ if (nc > sc)
+ nc = sc;
+
+ memset (top, 0, len);
+
+ for (i = 0; i < n; i++)
+ {
+ int c;
+
+ for (c = 0; c < nc; c++)
+ top[c] = fromp[c];
+
+ fromp += sc;
+ top += tc;
+ }
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ }
+
+ if (source->rate != target->rate && source->channels > target->channels)
+ {
+ int err;
+
+ VMEM_CHECK (p1, len);
+ err =
+ do_src (adev, dmap, source->rate, target->rate, p1, p2, &len,
+ target->channels, 24, 4);
+ if (err < 0)
+ return err;
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+
+#ifdef SINE_DEBUG
+/*
+ * Debugging stuff. Overwrite the sample buffer with pure sine wave.
+ */
+ {
+ int *p = p1;
+ l = len / sizeof (int);
+ for (i = 0; i < l; i += 2)
+ {
+#if 1
+ *p++ = sinebuf[sine_ptr] << 15; /* Left chn */
+ *p++ = sinebuf[sine_ptr] << 15; /* Right chn */
+ sine_ptr = (sine_ptr + 1) % SIN_STEPS;
+#else
+ static short pp = 0;
+ *p++ = pp * 256;
+ *p++ = pp * 256;
+ pp++;
+#endif
+ }
+ }
+#endif
+
+/*
+ * Finally convert the samples from internal 24 bit format to the target format
+ */
+
+ if (target->fmt != AFMT_S24_NE)
+ switch (target->fmt)
+ {
+ case AFMT_U8:
+ {
+ unsigned int *fromp = p1;
+ unsigned char *top = p2;
+
+ l = len / sizeof (int);
+ len = l;
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = (*fromp++ >> 16) ^ 0x80;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S8:
+ {
+ int *fromp = p1;
+ char *top = p2;
+
+ l = len / sizeof (int);
+ len = l;
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = *fromp++ >> 16;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S16_NE:
+ {
+ int *fromp = p1;
+ short *top = p2;
+
+ l = len / sizeof (int);
+ len = l * sizeof (short);
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = *fromp++ >> 8;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S16_OE:
+ {
+ int *fromp = p1;
+ unsigned char *top = p2;
+
+ l = len / sizeof (int);
+ len = l * sizeof (short);
+
+ for (i = 0; i < l; i++)
+ {
+ int tmp;
+ tmp = *fromp++ >> 8;
+ *top++ = tmp & 0xff;
+ *top++ = (tmp >> 8) & 0xff;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S32_NE:
+ {
+ int *fromp = p1;
+ int *top = p2;
+
+ l = len / 4;
+ /* len = l * sizeof (int); */
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = *fromp++ << 8;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S32_OE:
+ {
+ int *fromp = p1;
+ int *top = p2;
+
+ l = len / 4;
+ /* len = l * sizeof (int); */
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = swap32 ((unsigned int) (*fromp++ << 8));
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S24_OE:
+ {
+ int *fromp = p1;
+ int *top = p2;
+
+ l = len / 4;
+ /* len = l * sizeof (int); */
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = swap32 ((unsigned int) (*fromp++));
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_S24_PACKED:
+ {
+ int *fromp = p1;
+ unsigned char *top = p2;
+
+ l = len / 4;
+ len = l * 3;
+
+ for (i = 0; i < l; i++)
+ {
+ int tmp = *fromp++;
+ *top++ = tmp & 0xff;
+ *top++ = (tmp >> 8) & 0xff;
+ *top++ = (tmp >> 16) & 0xff;
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ case AFMT_MU_LAW:
+ {
+ unsigned int *fromp = p1;
+ unsigned char *top = p2;
+
+ l = len / sizeof (int);
+ len = l;
+
+ for (i = 0; i < l; i++)
+ {
+ *top++ = dsp_ulaw[((*fromp++ >> 16) & 0xff) ^ 0x80];
+ }
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+ }
+ break;
+
+ default:
+ cmn_err (CE_WARN, "Unsupported conversion target format %08x\n",
+ target->fmt);
+ return OSS_EIO;
+ }
+
+ VMEM_CHECK (p1, len);
+ *srcl = len;
+ *srcp = p1;
+ *tgtp = p2;
+
+ return 0;
+}
+
+static int
+cnv_srconly (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl, unsigned char **tgtp,
+ sample_parms * source, sample_parms * target)
+{
+ void *p1 = *srcp, *p2 = *tgtp, *tmpp;
+ int len = *srcl;
+ int err;
+ int ssize = 2;
+ audio_format_info_p fmt;
+
+ VMEM_CHECK (p1, len);
+ VMEM_CHECK (p2, len);
+
+ if ((fmt = oss_find_format (source->fmt)) == NULL)
+ {
+ cmn_err (CE_WARN, "Unknown audio format %x\n", source->fmt);
+ return OSS_EIO;
+ }
+
+ switch (fmt->bits)
+ {
+ default:
+ case 8:
+ ssize = 1;
+ break;
+ case 16:
+ ssize = 2;
+ break;
+ case 24:
+ ssize = 4;
+ break;
+ case 32:
+ ssize = 4;
+ break;
+ }
+
+ err =
+ do_src (adev, dmap, source->rate, target->rate, p1, p2, &len,
+ source->channels, fmt->bits, ssize);
+ if (err < 0)
+ return err;
+
+ tmpp = p1;
+ p1 = p2;
+ p2 = tmpp;
+
+ VMEM_CHECK (p1, len);
+ *srcl = len;
+ *srcp = p1;
+ *tgtp = p2;
+
+ return 0;
+}
+
+#include "audiocnv.inc"
+
+static cnv_func_t
+select_converter (unsigned int cnv, int expand, audio_format_info_p src_f,
+ audio_format_info_p tgt_f)
+{
+#if 1
+ {
+ int expand2 = expand * 100 / UNIT_EXPAND;
+ DDB (cmn_err
+ (CE_CONT, "Expand = %d (%d.%02d)\n", expand, expand2 / 100,
+ expand2 % 100));
+ DDB (cmn_err (CE_CONT, "Convert = %08x / ", cnv));
+ if (cnv & CNV_SRC)
+ DDB (cmn_err (CE_CONT, "CNV_SRC "));
+ if (cnv & CNV_M2S)
+ DDB (cmn_err (CE_CONT, "CNV_M2S "));
+ if (cnv & CNV_S2M)
+ DDB (cmn_err (CE_CONT, "CNV_S2M "));
+ if (cnv & CNV_MULT)
+ DDB (cmn_err (CE_CONT, "CNV_MULT "));
+ if (cnv & CNV_Flog)
+ DDB (cmn_err (CE_CONT, "CNV_Flog "));
+ if (cnv & CNV_F8bit)
+ DDB (cmn_err (CE_CONT, "CNV_F8bit "));
+ if (cnv & CNV_F16bit)
+ DDB (cmn_err (CE_CONT, "CNV_F16bit "));
+ if (cnv & CNV_F24bit)
+ DDB (cmn_err (CE_CONT, "CNV_F24bit "));
+ if (cnv & CNV_F32bit)
+ DDB (cmn_err (CE_CONT, "CNV_F32bit "));
+ if (cnv & CNV_Tlog)
+ DDB (cmn_err (CE_CONT, "CNV_Tlog "));
+ if (cnv & CNV_T8bit)
+ DDB (cmn_err (CE_CONT, "CNV_T8bit "));
+ if (cnv & CNV_T16bit)
+ DDB (cmn_err (CE_CONT, "CNV_T16bit "));
+ if (cnv & CNV_T24bit)
+ DDB (cmn_err (CE_CONT, "CNV_T24bit "));
+ if (cnv & CNV_T32bit)
+ DDB (cmn_err (CE_CONT, "CNV_T32bit "));
+ if (cnv & CNV_SIGN)
+ DDB (cmn_err (CE_CONT, "CNV_SIGN "));
+ if (cnv & CNV_ENDIAN)
+ DDB (cmn_err (CE_CONT, "CNV_ENDIAN "));
+ if (cnv & CNV_TOLOG)
+ DDB (cmn_err (CE_CONT, "CNV_TOLOG "));
+ if (cnv & CNV_FROMLOG)
+ DDB (cmn_err (CE_CONT, "CNV_FROMLOG "));
+ DDB (cmn_err (CE_CONT, "\n"));
+ }
+ DDB (cmn_err (CE_CONT, "\n"));
+#endif
+
+ if (cnv == CNV_SRC) /* Only SRC is needed */
+ if (src_f->fmt & (CONVERTABLE_FORMATS & ~AFMT_MU_LAW)) /* Can convert this */
+#ifdef OSS_BIG_ENDIAN
+ if (src_f->endianess == ENDIAN_BIG)
+#else
+ if (src_f->endianess == ENDIAN_LITTLE)
+#endif
+ {
+ DDB (cmn_err (CE_CONT, "Only SRC\n"));
+ return cnv_srconly;
+ }
+
+ if (cnv & CNV_SRC)
+ { /* Needs SRC together with some other conversion. Use the default. */
+ return cnv_default;
+ }
+
+ if (src_f->endianess != tgt_f->endianess)
+ { /* Needs endianess handling - use the default for the time being. */
+ return cnv_default;
+ }
+
+#ifdef OSS_BIG_ENDIAN
+ if (src_f->endianess != ENDIAN_BIG)
+#else
+ if (src_f->endianess != ENDIAN_LITTLE)
+#endif
+ { /* Opposite endianess - use the default. */
+ return cnv_default;
+ }
+
+/*
+ * The remaining conversions don't use SRC and the endianess is native
+ * so they are easier to optimize.
+ */
+
+ switch (cnv)
+ {
+ case CNV_F8bit | CNV_T16bit:
+ return cnv_F8bits_T16bits;
+ case CNV_F8bit | CNV_T32bit:
+ return cnv_F8bits_T32bits;
+ case CNV_F16bit | CNV_T32bit:
+ return cnv_F16bits_T32bits;
+ case CNV_F32bit | CNV_T16bit:
+ return cnv_F32bits_T16bits;
+ case CNV_F32bit | CNV_T8bit:
+ return cnv_F32bits_T8bits;
+ case CNV_F16bit | CNV_T8bit:
+ return cnv_F16bits_T8bits;
+ }
+
+ DDB (cmn_err (CE_CONT, "Will use the default converter\n"));
+ return cnv_default;
+}
+
+/*ARGSUSED*/
+int
+setup_format_conversions (adev_p adev, dmap_p dmap, sample_parms * source,
+ sample_parms * target,
+ sample_parms * user,
+ sample_parms * device, int format_mask)
+{
+ int expand = UNIT_EXPAND;
+ unsigned int cnv = CNV_NONE;
+ audio_format_info_p src_f, tgt_f;
+
+ dmap->expand_factor = UNIT_EXPAND;
+
+ if (source->fmt == AFMT_AC3)
+ {
+ source->channels = target->channels = 2;
+ source->rate = target->rate;
+ target->fmt = source->fmt;
+ dmap->convert_mode = 0;
+ dmap->convert_func = NULL;
+ return 0;
+ }
+
+ if ((src_f = oss_find_format (source->fmt)) == NULL)
+ {
+ cmn_err (CE_CONT, "internal format error 1 (%x)\n", source->fmt);
+ return OSS_EIO;
+ }
+
+ if ((tgt_f = oss_find_format (target->fmt)) == NULL)
+ {
+ cmn_err (CE_CONT, "internal format error 2\n");
+ return OSS_EIO;
+ }
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("Setting up format conversions for device %d",
+ adev->engine_num);
+ oss_timing_printf (" Speed %d->%d", source->rate, target->rate);
+ oss_timing_printf (" Channels %d->%d", source->channels, target->channels);
+ oss_timing_printf (" Format %02x/%s->%02x/%s", source->fmt, src_f->name,
+ target->fmt, tgt_f->name);
+#endif
+ DDB (cmn_err
+ (CE_CONT, "Setting up format conversions for device %d\n",
+ adev->engine_num));
+ DDB (cmn_err (CE_CONT, " Speed %d->%d\n", source->rate, target->rate));
+ DDB (cmn_err
+ (CE_CONT, " Channels %d->%d\n", source->channels, target->channels));
+ DDB (cmn_err
+ (CE_CONT, " Format %02x/%s->%02x/%s\n", source->fmt, src_f->name,
+ target->fmt, tgt_f->name));
+
+ if (source->channels > OSS_MAX_CONVERT_CHANNELS
+ || target->channels > OSS_MAX_CONVERT_CHANNELS)
+ {
+ cmn_err
+ (CE_WARN,
+ "Audio format conversions not supported with more than %d channels\n",
+ OSS_MAX_CONVERT_CHANNELS);
+ dmap->flags &= ~DMAP_COOKED;
+ return OSS_EIO;
+ }
+
+ expand = (expand * target->rate) / source->rate;
+ expand = (expand * target->channels) / source->channels;
+ expand = (expand * tgt_f->bits) / src_f->bits;
+
+ dmap->expand_factor = expand;
+
+ if (source->rate != target->rate)
+ cnv |= CNV_SRC;
+
+ if (source->channels != target->channels) /* Change # of channels */
+ {
+ if (target->channels > 2 || source->channels > 2)
+ cnv |= CNV_MULT;
+ else
+ {
+ if (source->channels == 1 && target->channels == 2)
+ cnv |= CNV_M2S;
+ else
+ cnv |= CNV_S2M;
+ }
+ }
+
+ if (source->fmt != target->fmt)
+ {
+
+ if (src_f->endianess != tgt_f->endianess)
+ if (src_f->endianess != ENDIAN_NONE
+ && tgt_f->endianess != ENDIAN_NONE)
+ { /* Endianess change */
+ cnv |= CNV_ENDIAN;
+ }
+
+ if (src_f->endianess != ENDIAN_NONE && tgt_f->endianess != ENDIAN_NONE)
+ if (src_f->is_signed != tgt_f->is_signed)
+ {
+ cnv |= CNV_SIGN;
+ }
+
+ if (src_f->bits != tgt_f->bits)
+ {
+ switch (src_f->bits)
+ {
+ case 8:
+ cnv |= CNV_F8bit;
+ break;
+ case 16:
+ cnv |= CNV_F16bit;
+ break;
+ case 24:
+ cnv |= CNV_F24bit;
+ break;
+ case 32:
+ cnv |= CNV_F32bit;
+ break;
+ default:
+ cnv |= CNV_Flog;
+ }
+
+ switch (tgt_f->bits)
+ {
+ case 8:
+ cnv |= CNV_T8bit;
+ break;
+ case 16:
+ cnv |= CNV_T16bit;
+ break;
+ case 24:
+ cnv |= CNV_T24bit;
+ break;
+ case 32:
+ cnv |= CNV_T32bit;
+ break;
+ default:
+ cnv |= CNV_Tlog;
+ }
+ }
+
+ if (!src_f->is_linear)
+ cnv |= CNV_FROMLOG;
+
+ if (!tgt_f->is_linear)
+ cnv |= CNV_TOLOG;
+ }
+
+ dmap->convert_mode = cnv;
+
+ dmap->convert_func = select_converter (cnv, expand, src_f, tgt_f);
+
+ dmap->tmpbuf_len = dmap->tmpbuf_ptr = 0;
+ if (dmap->tmpbuf1 == NULL)
+ {
+ dmap->tmpbuf1 = PMALLOC (dmap->osdev, TMP_CONVERT_BUF_SIZE+512);
+ }
+
+ if (dmap->tmpbuf2 == NULL)
+ {
+ dmap->tmpbuf2 = PMALLOC (dmap->osdev, TMP_CONVERT_BUF_SIZE+512);
+ }
+
+ if (dmap->tmpbuf1 == NULL || dmap->tmpbuf2 == NULL)
+ return OSS_ENOSPC;
+
+ if (cnv & CNV_SRC)
+ if (setup_src
+ (adev, dmap, source->rate, target->rate, source->channels,
+ target->channels) < 0)
+ {
+ cmn_err (CE_CONT, "internal format error 3\n");
+ return OSS_EIO;
+ }
+
+ return 0;
+}
diff --git a/kernel/framework/audio/oss_grc3.c b/kernel/framework/audio/oss_grc3.c
new file mode 100644
index 0000000..d47379a
--- /dev/null
+++ b/kernel/framework/audio/oss_grc3.c
@@ -0,0 +1,451 @@
+/*
+ * Purpose: GRC3 Sample Rate Converter
+ *
+ * GRC library version 3.1
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#ifdef _KERNEL
+//#include "oss_config.h"
+#endif
+
+#ifdef _KERNEL
+#include <inttypes.h>
+#endif
+
+#include "grc3.h"
+
+char _grc3_copyright[] =
+ "GRC library version 3.0\n"
+ "Copyright (C)2001-2009 4Front Technologies\n"
+ "Copyright (C)2001-2002 by George Yohng\n\0" "GRC3 ENGINE";
+
+#ifdef GRC3_COMPILE_L
+#define filter_data filter_data_L
+#include "fltdata3_l.inc"
+#undef filter_data
+#endif
+
+#ifdef GRC3_COMPILE_M
+#define filter_data filter_data_M
+#include "fltdata1_m.inc"
+#undef filter_data
+#endif
+
+#ifdef GRC3_COMPILE_H
+#define filter_data filter_data_H
+#include "fltdata2_h.inc"
+#undef filter_data
+#define filter_data_HX filter_data_H
+#endif
+
+#ifdef GRC3_COMPILE_P
+#define filter_data filter_data_P
+#include "fltdata4_p.inc"
+#undef filter_data
+#define filter_data_PX filter_data_P
+#endif
+
+#if (CONFIG_OSS_GRC_MIN_QUALITY>CONFIG_OSS_GRC_MAX_QUALITY)
+#error Invalid values specified in CONFIG_OSS_GRC_XXX_QUALITY
+#endif
+
+#if !defined(GRC3_COMPILE_L) && !defined(GRC3_COMPILE_M) && !defined(GRC3_COMPILE_H) && !defined(GRC3_COMPILE_P)
+#error Invalid values specified in CONFIG_OSS_GRC_XXX_QUALITY
+#endif
+
+
+/* TODO: Wy doesn't -O and inlining work? */
+#undef __inline__
+#define __inline__
+
+static __inline__ int32_t
+_muldivu64 (GRCpreg uint32_t a, GRCpreg uint32_t val1, GRCpreg uint32_t val2)
+{
+ GRCvreg uint64_t v = ((uint64_t) a) * val1 / val2;
+ return (uint32_t) (v);
+}
+
+
+static __inline__ int32_t
+_grc_sat6 (GRCpreg int32_t a, GRCpreg int32_t b)
+{
+ GRCvreg int64_t v = ((int64_t) a) * b + (1 << 5);
+ return (int32_t) (v >> 6);
+}
+
+#if 0
+static __inline__ int32_t
+_grc_sat21 (GRCpreg int32_t a, GRCpreg int32_t b)
+{
+ GRCvreg int64_t v = ((int64_t) a) * b + (1 << 20);
+ return (int32_t) (v >> 21);
+}
+#endif
+
+static __inline__ int32_t
+_grc_sat31 (GRCpreg int32_t a, GRCpreg int32_t b)
+{
+ GRCvreg int64_t v = ((int64_t) a) * b + (1 << 30);
+ return (int32_t) (v >> 31);
+}
+
+
+#define DEFINE_FILTER(T)\
+ static __inline__ int32_t _filt31_##T(GRCpreg int32_t a, GRCpreg int32_t idx)\
+ {\
+ GRCvreg int64_t v=((int64_t)a)*filter_data_##T[idx>>15];\
+ return (int32_t)(v>>31);\
+ }
+
+#define DEFINE_FILTER_HQ(T)\
+ static __inline__ int32_t _filt31_##T(GRCpreg int32_t a, GRCpreg int32_t idx)\
+ {\
+ GRCvreg int32_t idx2=idx>>15;\
+ GRCvreg int64_t v=((int64_t)a)*\
+ \
+ (filter_data_##T[idx2] +\
+ \
+ (((int64_t)(idx&32767))*(filter_data_##T[idx2+1] - filter_data_##T[idx2])>>15));\
+ return (int32_t)(v>>31);\
+ }
+
+
+#ifdef GRC3_COMPILE_L
+DEFINE_FILTER (L)
+#endif
+
+#ifdef GRC3_COMPILE_M
+DEFINE_FILTER (M)
+#endif
+
+#ifdef GRC3_COMPILE_H
+DEFINE_FILTER (H)
+DEFINE_FILTER_HQ (HX)
+#endif
+
+#ifdef GRC3_COMPILE_P
+DEFINE_FILTER (P)
+DEFINE_FILTER_HQ (PX)
+#endif
+
+int32_t
+_clamp24 (int32_t v)
+{
+ return (v <= -0x007FFFFF) ? -0x007FFFFF :
+ (v >= 0x007FFFFF) ? 0x007FFFFF : v;
+}
+
+#define DEFINE_CONVD(T,SZ)\
+ static __inline__ int32_t _conv31d_##T(GRCpreg int32_t *history,GRCpreg uint32_t filter,GRCpreg uint32_t incv)\
+ {\
+ GRCvreg int32_t accum=0;\
+ \
+ filter = (1024<<15) - filter;\
+ \
+ while(filter<((uint32_t)(SZ<<15)))\
+ {\
+ accum+=_filt31_##T(*history,filter);\
+ filter+=incv;\
+ history--;\
+ }\
+ \
+ return accum;\
+ }
+
+#ifdef GRC3_COMPILE_L
+DEFINE_CONVD (L, 4096)
+#endif
+
+#ifdef GRC3_COMPILE_M
+DEFINE_CONVD (M, 8192)
+#endif
+
+#ifdef GRC3_COMPILE_H
+DEFINE_CONVD (H, 16384)
+DEFINE_CONVD (HX, 16384)
+#endif
+
+#ifdef GRC3_COMPILE_P
+DEFINE_CONVD (P, 32768)
+DEFINE_CONVD (PX, 32768)
+#endif
+
+#define ITERATION(p)\
+ accum+=_filt31_##p(*history,filter);\
+ filter+=(1024<<15);\
+ history--;
+
+#ifdef GRC3_COMPILE_L
+static __inline__ int32_t
+_conv31_L (GRCpreg int32_t * history, GRCpreg uint32_t filter)
+{
+ GRCvreg int32_t accum = 0;
+
+ ITERATION (L) ITERATION (L) ITERATION (L) ITERATION (L) return accum;
+}
+#endif
+
+
+#ifdef GRC3_COMPILE_M
+static __inline__ int32_t
+_conv31_M (GRCpreg int32_t * history, GRCpreg uint32_t filter)
+{
+ GRCvreg int32_t accum = 0;
+
+ ITERATION (M) ITERATION (M) ITERATION (M) ITERATION (M)
+ ITERATION (M) ITERATION (M) ITERATION (M) ITERATION (M) return accum;
+}
+#endif
+
+#ifdef GRC3_COMPILE_H
+static __inline__ int32_t
+_conv31_H (GRCpreg int32_t * history, GRCpreg uint32_t filter)
+{
+ GRCvreg int32_t accum = 0;
+
+ ITERATION (H) ITERATION (H) ITERATION (H) ITERATION (H)
+ ITERATION (H) ITERATION (H) ITERATION (H) ITERATION (H)
+ ITERATION (H) ITERATION (H) ITERATION (H) ITERATION (H)
+ ITERATION (H) ITERATION (H) ITERATION (H) ITERATION (H) return accum;
+}
+
+static __inline__ int32_t
+_conv31_HX (GRCpreg int32_t * history, GRCpreg uint32_t filter)
+{
+ GRCvreg int32_t accum = 0;
+
+ ITERATION (HX) ITERATION (HX) ITERATION (HX) ITERATION (HX)
+ ITERATION (HX) ITERATION (HX) ITERATION (HX) ITERATION (HX)
+ ITERATION (HX) ITERATION (HX) ITERATION (HX) ITERATION (HX)
+ ITERATION (HX) ITERATION (HX) ITERATION (HX) ITERATION (HX) return accum;
+}
+#endif
+
+#ifdef GRC3_COMPILE_P
+static __inline__ int32_t
+_conv31_P (GRCpreg int32_t * history, GRCpreg uint32_t filter)
+{
+ GRCvreg int32_t accum = 0;
+
+ ITERATION (P) ITERATION (P) ITERATION (P) ITERATION (P)
+ ITERATION (P) ITERATION (P) ITERATION (P) ITERATION (P)
+ ITERATION (P) ITERATION (P) ITERATION (P) ITERATION (P)
+ ITERATION (P) ITERATION (P) ITERATION (P) ITERATION (P)
+ ITERATION (P) ITERATION (P) ITERATION (P) ITERATION (P)
+ ITERATION (P) ITERATION (P) ITERATION (P) ITERATION (P)
+ ITERATION (P) ITERATION (P) ITERATION (P) ITERATION (P)
+ ITERATION (P) ITERATION (P) ITERATION (P) ITERATION (P) return accum;
+}
+
+static __inline__ int32_t
+_conv31_PX (GRCpreg int32_t * history, GRCpreg uint32_t filter)
+{
+ GRCvreg int32_t accum = 0;
+
+ ITERATION (PX) ITERATION (PX) ITERATION (PX) ITERATION (PX)
+ ITERATION (PX) ITERATION (PX) ITERATION (PX) ITERATION (PX)
+ ITERATION (PX) ITERATION (PX) ITERATION (PX) ITERATION (PX)
+ ITERATION (PX) ITERATION (PX) ITERATION (PX) ITERATION (PX)
+ ITERATION (PX) ITERATION (PX) ITERATION (PX) ITERATION (PX)
+ ITERATION (PX) ITERATION (PX) ITERATION (PX) ITERATION (PX)
+ ITERATION (PX) ITERATION (PX) ITERATION (PX) ITERATION (PX)
+ ITERATION (PX) ITERATION (PX) ITERATION (PX) ITERATION (PX) return accum;
+}
+#endif
+
+static __inline__ int16_t
+_swap16 (GRCpreg int32_t v)
+{
+ return (int16_t) ((((uint16_t) v) << 8) + (((uint16_t) v) >> 8));
+}
+
+static __inline__ int32_t
+_swap32 (GRCpreg int32_t v)
+{
+ return (int32_t) ((((uint32_t) v) >> 24) +
+ (((uint32_t) v) << 24) +
+ (((uint32_t) _swap16 ((int16_t) (v >> 8))) << 8));
+}
+
+#include "grc3code.inc"
+
+#define DECLCVT(bit,q,func)\
+ if ((domain==bit)&&(quality==q)) \
+ {\
+ if (!grc) return 0; \
+ return grc3_resample_##func(grc,\
+ (void *)src, \
+ (void *)dst, \
+ (int32_t)sz, \
+ (int32_t)bufsz, \
+ (int32_t)inc, \
+ (int32_t)offset \
+ ); \
+ }else
+
+int
+grc3_convert (grc3state_t * grc,
+ int domain, int quality,
+ void *src, void *dst,
+ int sz, int bufsz, int inc, int offset)
+{
+
+again:
+
+#ifdef GRC3_COMPILE_L
+ DECLCVT (8, 0, L8_8)
+ DECLCVT (16, 0, L16_16)
+ DECLCVT (-16, 0, Lv16_v16)
+ DECLCVT (32, 0, L32_32)
+ DECLCVT (-32, 0, Lv32_v32)
+
+ DECLCVT (8, 1, L8_8)
+ DECLCVT (16, 1, L16_16)
+ DECLCVT (-16, 1, Lv16_v16)
+ DECLCVT (32, 1, L32_32)
+ DECLCVT (-32, 1, Lv32_v32)
+#endif
+#ifdef GRC3_COMPILE_M
+ DECLCVT (8, 2, M8_8)
+ DECLCVT (16, 2, M16_16)
+ DECLCVT (-16, 2, Mv16_v16)
+ DECLCVT (32, 2, M32_32)
+ DECLCVT (-32, 2, Mv32_v32)
+#endif
+#ifdef GRC3_COMPILE_H
+ DECLCVT (8, 3, H8_8)
+ DECLCVT (16, 3, H16_16)
+ DECLCVT (-16, 3, Hv16_v16)
+ DECLCVT (32, 3, H32_32)
+ DECLCVT (-32, 3, Hv32_v32)
+ DECLCVT (8, 4, HX8_8)
+ DECLCVT (16, 4, HX16_16)
+ DECLCVT (-16, 4, HXv16_v16)
+ DECLCVT (32, 4, HX32_32)
+ DECLCVT (-32, 4, HXv32_v32)
+#endif
+#ifdef GRC3_COMPILE_P
+ DECLCVT (8, 5, P8_8)
+ DECLCVT (16, 5, P16_16)
+ DECLCVT (-16, 5, Pv16_v16)
+ DECLCVT (32, 5, P32_32)
+ DECLCVT (-32, 5, Pv32_v32)
+ DECLCVT (8, 6, PX8_8)
+ DECLCVT (16, 6, PX16_16)
+ DECLCVT (-16, 6, PXv16_v16)
+ DECLCVT (32, 6, PX32_32)
+ DECLCVT (-32, 6, PXv32_v32)
+#endif
+ {
+ if ((quality > 6) && (grc))
+ {
+ quality = DEFAULT_GRC_QUALITY;
+ goto again;
+ }
+
+ return -1;
+ }
+}
+
+int
+grc3_reset (grc3state_t * grc)
+{
+ int32_t t;
+ grc->ptr = 0;
+ grc->historyptr = grc->history + GRC3_MAXHISTORY;
+
+ for (t = 0; t < GRC3_MAXHISTORY * 2; t++)
+ grc->history[t] = 0;
+
+ return 1;
+}
+
+static int
+grc3_setup_up (grc3state_t * grc, uint32_t fromRate, uint32_t toRate)
+{
+ grc->srcrate = fromRate;
+ grc->dstrate = toRate;
+ grc->filtfactor = 0x80000000U / toRate;
+ return 1;
+}
+
+static int
+grc3_setup_dn (grc3state_t * grc, uint32_t fromRate, uint32_t toRate)
+{
+ grc->srcrate = fromRate;
+ grc->dstrate = toRate;
+ grc->filtfactor = 0x80000000U / fromRate;
+ grc->ptr_incv = _muldivu64 (1024 << 15, toRate, fromRate);
+ grc->sat = _muldivu64 (0x80000000U, toRate, fromRate);
+ return 1;
+}
+
+int
+grc3_setup (grc3state_t * grc, uint32_t fromRate, uint32_t toRate)
+{
+ while ((!(fromRate & 1)) && (!(toRate & 1)) && (fromRate > 0))
+ {
+ fromRate >>= 1;
+ toRate >>= 1;
+ }
+
+ if (fromRate <= toRate)
+ return grc3_setup_up (grc, fromRate, toRate);
+ else
+ return grc3_setup_dn (grc, fromRate, toRate);
+}
+
+
+#ifdef TESTCASE
+
+#include <stdio.h>
+grc3state_t grc1, grc2;
+
+#define BUFLEN (135*4) /* Randomish lenghth */
+
+int
+main ()
+{
+ int t, k, l;
+ short tmp;
+ short p[BUFLEN], o[BUFLEN * 8];
+
+ grc3_reset (&grc1);
+ grc3_setup (&grc1, 44100, 48000);
+ grc3_reset (&grc2);
+ grc3_setup (&grc2, 44100, 48000);
+
+
+ while ((l = read (0, p, sizeof (p))) > 0)
+ {
+ t = l / 4;
+ fprintf (stderr, "Convert %d (%d)", t, l);
+ grc3_convert (&grc1, 16, 4, p, o, t, (uint32_t) - 1, 2, 0);
+ grc3_convert (&grc2, 16, 4, p, o, t, (uint32_t) - 1, 2, 1);
+ l = grc2.outsz * 4;
+ fprintf (stderr, " -> %d (%d)\n", grc2.outsz, l);
+
+ if (write (1, o, l) != l)
+ {
+ perror ("write");
+ exit (-1);
+ }
+
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/kernel/framework/audio/oss_spdif.c b/kernel/framework/audio/oss_spdif.c
new file mode 100644
index 0000000..9b8c312
--- /dev/null
+++ b/kernel/framework/audio/oss_spdif.c
@@ -0,0 +1,627 @@
+/*
+ * Purpose: S/PDIF (IEC958) control bit and mixer extension management
+ *
+ * This code is used by some drivers to handle S/PDIF specific control
+ * functions (see {!xlink spdif_control} for more info.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "spdif.h"
+
+#define MAX_DEV 10
+static int ndevs = 0;
+static spdif_devc *devc_list[MAX_DEV] = { 0 };
+
+static void
+init_ctl (spdif_devc * devc, oss_digital_control * ctl)
+{
+ memset (ctl, 0, sizeof (*ctl));
+
+ ctl->caps = devc->caps;
+}
+
+static void
+block_mixer (spdif_devc * devc)
+{
+ devc->mixer_blocked = 1;
+ memcpy (&devc->cold_ctl, &devc->hot_ctl, sizeof (devc->hot_ctl));
+ devc->ctl = &devc->cold_ctl;
+
+}
+
+static void
+unblock_mixer (spdif_devc * devc)
+{
+ memcpy (&devc->hot_ctl, &devc->cold_ctl, sizeof (devc->hot_ctl));
+ devc->ctl = &devc->hot_ctl;
+ devc->mixer_blocked = 0;
+}
+
+int
+oss_spdif_install (spdif_devc * devc, oss_device_t * osdev,
+ spdif_driver_t * d, int driver_size, void *host_devc,
+ void *host_portc, int mixer_dev, int flags,
+ unsigned int caps)
+{
+ int i, pos;
+
+ if (devc->is_ok)
+ {
+ /* cmn_err (CE_WARN, "spdif: Bad usage - double init\n"); */
+ return 0;
+ }
+
+ if (d == NULL || driver_size != sizeof (spdif_driver_t))
+ {
+ cmn_err (CE_WARN, "spdif: Bad driver\n");
+ return OSS_EIO;
+ }
+
+ memset (devc, 0, sizeof (*devc));
+
+ devc->open_mode = 0;
+ devc->osdev = osdev;
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_FRAMEW + 2);
+ devc->d = d;
+ devc->flags = flags;
+ devc->host_devc = host_devc;
+ devc->host_portc = host_portc;
+ devc->mixer_dev = mixer_dev;
+ devc->ctl = &devc->hot_ctl;
+ devc->caps = caps;
+ devc->is_ok = 1;
+
+ pos=-1;
+
+ for (i=0;pos==-1 && i<ndevs;i++)
+ if (devc_list[i]==NULL)
+ {
+ pos = i;
+ }
+
+ if (pos==-1)
+ {
+ if (ndevs >= MAX_DEV)
+ {
+ cmn_err(CE_WARN, "Too many S/PDIF devices\n");
+ return OSS_EBUSY;
+ }
+
+ pos=ndevs++;
+ }
+
+ devc_list[pos] = devc;
+
+ init_ctl (devc, &devc->hot_ctl);
+ init_ctl (devc, &devc->cold_ctl);
+
+ return 0;
+}
+
+void
+oss_spdif_uninstall (spdif_devc * devc)
+{
+ int i;
+
+ for (i=0;i<ndevs;i++)
+ if (devc_list[i]==devc)
+ devc_list[i]=NULL;
+}
+
+int
+oss_spdif_open (spdif_devc * devc, int open_mode)
+{
+ oss_native_word flags;
+ flags = 0;
+ if (!devc->is_ok)
+ {
+ cmn_err (CE_WARN, "spdif: Bad usage - open\n");
+ return OSS_EIO;
+ }
+ MUTEX_ENTER (devc->mutex, flags);
+ devc->open_mode |= open_mode;
+ MUTEX_EXIT (devc->mutex, flags);
+ return 0;
+}
+
+void
+oss_spdif_close (spdif_devc * devc, int open_mode)
+{
+ oss_native_word flags;
+ flags = 0;
+ if (!devc->is_ok)
+ {
+ cmn_err (CE_WARN, "spdif: Bad usage - close\n");
+ return;
+ }
+ MUTEX_ENTER (devc->mutex, flags);
+ devc->open_mode &= ~open_mode;
+
+ if (devc->mixer_blocked && (open_mode & OPEN_WRITE))
+ {
+ unblock_mixer (devc);
+ }
+ MUTEX_EXIT (devc->mutex, flags);
+}
+
+static void
+update_rate_bits (spdif_devc * devc, int rate)
+{
+ unsigned char spd;
+/*
+ * Set S/PDIF rate control (TODO: Pro mode)
+ */
+
+ devc->hot_ctl.srate_out = rate;
+
+ switch (rate)
+ {
+ case 48000:
+ spd = 2;
+ break;
+ case 32000:
+ spd = 3;
+ break;
+ case 88200:
+ spd = 4;
+ break;
+ case 96000:
+ spd = 5;
+ break;
+ case 176400:
+ spd = 7;
+ break;
+ case 192000:
+ spd = 6;
+ break;
+ default:
+ spd = 0;
+ rate = 44100;
+ }
+
+ devc->hot_ctl.rate_bits = spd;
+
+ devc->hot_ctl.cbitout[3] &= ~0x0f;
+ devc->hot_ctl.cbitout[3] |= spd & 0x0f;
+ devc->hot_ctl.srate_out = rate;
+}
+
+void
+oss_spdif_setrate (spdif_devc * devc, int rate)
+{
+ oss_native_word flags;
+ flags = 0;
+ if (!devc->is_ok)
+ {
+ cmn_err (CE_WARN, "spdif: Bad usage - setrate\n");
+ return;
+ }
+ MUTEX_ENTER (devc->mutex, flags);
+
+ update_rate_bits (devc, rate);
+
+ if (devc->d->reprogram_device)
+ devc->d->reprogram_device (devc->host_devc, devc->host_portc,
+ &devc->hot_ctl, REPGM_RATE | REPGM_CBIT3);
+ MUTEX_EXIT (devc->mutex, flags);
+}
+
+static int spdif_mix_init (spdif_devc * devc);
+
+/*ARGSUSED*/
+static void
+switch_mode (spdif_devc * devc, oss_digital_control * ctl, int smurf)
+{
+ ctl->pro_mode = ctl->cbitout[0] & 0x01;
+
+ if (ctl == devc->ctl) /* Visible to mixer */
+ spdif_mix_init (devc); /* Re-create mixer extensions */
+}
+
+static void
+update_hardware (spdif_devc * devc, int repgm)
+{
+ if (repgm & REPGM_RATE)
+ update_rate_bits (devc, devc->hot_ctl.srate_out);
+ if (devc->d->reprogram_device)
+ devc->d->reprogram_device (devc->host_devc, devc->host_portc,
+ &devc->hot_ctl, repgm);
+}
+
+static int
+readctl (spdif_devc * devc, oss_digital_control * c, int open_mode)
+{
+ int valid = c->valid & ~(VAL_OUTMASK);
+ int ret = 0;
+ oss_native_word flags;
+ flags = 0;
+
+ MUTEX_ENTER (devc->mutex, flags);
+
+ memcpy (c, &devc->hot_ctl, sizeof (devc->hot_ctl));
+ memset (c->filler, 0, sizeof (c->filler)); /* Hide internal variables */
+ c->valid &= (VAL_OUTMASK);
+
+ if (open_mode & OPEN_READ)
+ {
+ if (devc->d->get_status)
+ ret = devc->d->get_status (devc->host_devc, devc->host_portc,
+ c, valid);
+ else
+ {
+ if (valid != 0) /* Can't get input status */
+ ret = OSS_EIO;
+ }
+ }
+
+ MUTEX_EXIT (devc->mutex, flags);
+ return ret;
+}
+
+/*ARGSUSED*/
+static int
+handle_request (spdif_devc * devc, oss_digital_control * c)
+{
+ return OSS_EIO;
+}
+
+static int
+writectl (spdif_devc * devc, oss_digital_control * c)
+{
+ int valid = c->valid;
+ int repgm = 0;
+ int err = 0;
+ oss_native_word flags;
+ flags = 0;
+
+ MUTEX_ENTER (devc->mutex, flags);
+ if (!devc->mixer_blocked)
+ block_mixer (devc);
+ c->valid = 0;
+ c->caps = devc->caps;
+
+ if ((valid & VAL_CBITOUT) &&
+ ((devc->caps & DIG_CBITOUT_MASK) != DIG_CBITOUT_NONE))
+ {
+ int smurf;
+
+ smurf = (devc->hot_ctl.cbitout[0] ^ c->cbitout[0]) & 1;
+ c->valid |= VAL_CBITOUT;
+ repgm |= REPGM_CBITALL;
+
+ if (smurf) /* Mode changet CONSUMER<->PRO */
+ {
+ repgm |= REPGM_ALL;
+ switch_mode (devc, &devc->hot_ctl, 0);
+ }
+
+ memcpy (&devc->hot_ctl.cbitout, &c->cbitout, sizeof (c->cbitout));
+ }
+
+ if ((valid & VAL_UBITOUT) && (devc->caps & DIG_UBITOUT))
+ {
+ c->valid |= VAL_UBITOUT;
+ repgm |= REPGM_UBITALL;
+ memcpy (&devc->hot_ctl.ubitout, &c->ubitout, sizeof (c->ubitout));
+ }
+
+ if ((c->out_vbit != VBIT_NOT_INDICATED) && (devc->caps & DIG_VBITOUT))
+ {
+ devc->hot_ctl.out_vbit = c->out_vbit;
+ repgm |= REPGM_VBIT;
+ }
+ else
+ c->out_vbit = VBIT_NOT_INDICATED;
+ c->in_vbit = VBIT_NOT_INDICATED;
+
+ devc->hot_ctl.valid = valid;
+
+ if ((valid & VAL_ORATE))
+ {
+ /* TODO: Check the rate */
+ update_rate_bits (devc, c->srate_out);
+ c->valid |= VAL_ORATE;
+ c->srate_out = devc->hot_ctl.srate_out;
+ }
+
+ if (valid & VAL_REQUEST)
+ {
+ err = handle_request (devc, c);
+ if (err >= 0)
+ c->valid |= VAL_REQUEST;
+ }
+
+ MUTEX_EXIT (devc->mutex, flags);
+ return err;
+}
+
+int
+oss_spdif_ioctl (spdif_devc * devc, int open_mode, unsigned int cmd,
+ ioctl_arg arg)
+{
+ if (!devc->is_ok)
+ {
+ cmn_err (CE_WARN, "spdif: Bad usage - ioctl\n");
+ return SPDIF_NOIOCTL; /* Not for me */
+ }
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_WRITECTL:
+ if (!(open_mode & OPEN_WRITE)) /* Not opened for output */
+ return OSS_ENOTSUP;
+ if (!(devc->flags & SPDF_OUT))
+ return OSS_ENOTSUP;
+ return writectl (devc, (oss_digital_control *) arg);
+ break;
+
+ case SNDCTL_DSP_READCTL:
+ if (!(devc->flags & (SPDF_OUT | SPDF_IN)))
+ return OSS_ENOTSUP;
+ return readctl (devc, (oss_digital_control *) arg, open_mode);
+ break;
+ }
+
+ return SPDIF_NOIOCTL; /* Not for me too */
+}
+
+static int
+spdif_set_control (spdif_devc * devc, int ctrl, unsigned int cmd, int value)
+{
+ int val;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ switch (ctrl)
+ {
+ case 1: /* spdif.enable (OFF/ON) */
+ return !!(devc->ctl->outsel & OUTSEL_DIGITAL);
+ break;
+
+ case 2: /* spdif.mode (CONSUMER|PRO) */
+ return !!(devc->ctl->cbitout[0] & 1);
+ break;
+
+ case 3: /* spdif.audio (AUDIO/DATA) */
+ return !!(devc->ctl->cbitout[0] & 2);
+ break;
+
+ case 4: /* spdif.vbit (OFF/ON) */
+ return (devc->ctl->out_vbit == VBIT_ON);
+ break;
+
+ case 5: /* spdif.copyright (YES/NO) */
+ return get_cbit (devc->ctl->cbitout, 0, 2);
+ break;
+
+ case 6: /* spdif.generation (COPY/ORIGINAL) */
+ return get_cbit (devc->ctl->cbitout, 1, 0);
+ break;
+
+ case 7: /* spdif.preemph (OFF 50/16usec) */
+ return devc->ctl->emphasis_type;
+ }
+
+ return OSS_EINVAL;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ switch (ctrl)
+ {
+ case 1: /* spdif.enable */
+ if (value)
+ devc->ctl->outsel |= OUTSEL_DIGITAL;
+ else
+ devc->ctl->outsel &= ~OUTSEL_DIGITAL;
+ update_hardware (devc, REPGM_OUTSEL);
+ return !!(devc->ctl->outsel & OUTSEL_DIGITAL);
+ break;
+
+ case 2: /* spdif.mode (CONSUMER|PRO) */
+ val = devc->ctl->cbitout[0] & 1;
+ value = !!value;
+
+ set_cbit (devc->ctl->cbitout, 0, 0, value);
+ if (val != value) /* Mode change */
+ switch_mode (devc, devc->ctl, 1);
+ update_hardware (devc, REPGM_ALL);
+ return get_cbit (devc->ctl->cbitout, 0, 0);
+ break;
+
+ case 3: /* spdif.audio (AUDIO|DATA) */
+ value = !!value;
+
+ set_cbit (devc->ctl->cbitout, 0, 1, value);
+ update_hardware (devc, REPGM_CBIT0);
+ return get_cbit (devc->ctl->cbitout, 0, 1);
+ break;
+
+ case 4: /* spdif.vbit (OFF/ON) */
+ devc->ctl->out_vbit = (value) ? VBIT_ON : VBIT_OFF;
+ update_hardware (devc, REPGM_VBIT);
+ return (devc->ctl->out_vbit == VBIT_ON);
+ break;
+
+ case 5: /* spdif.copyright (YES|NO) */
+ value = !!value;
+
+ set_cbit (devc->ctl->cbitout, 0, 2, value);
+ update_hardware (devc, REPGM_CBIT0);
+ return get_cbit (devc->ctl->cbitout, 0, 2);
+ break;
+
+ case 6: /* spdif.generation (COPY|ORIGINAL) */
+ value = !!value;
+
+ set_cbit (devc->ctl->cbitout, 1, 0, value);
+ update_hardware (devc, REPGM_CBIT1);
+ return get_cbit (devc->ctl->cbitout, 1, 0);
+ break;
+
+ case 7: /* spdif.preemph (OFF 50/15usec) */
+ value = !!value;
+ devc->ctl->emphasis_type = value;
+ if (devc->ctl->pro_mode)
+ {
+ devc->ctl->cbitout[0] &= ~0x1c;
+ if (value)
+ devc->ctl->cbitout[0] |= 0x0c;
+ }
+ else
+ {
+ devc->ctl->cbitout[0] &= ~0x28;
+ if (value)
+ devc->ctl->cbitout[0] |= 0x08;
+ }
+ update_hardware (devc, REPGM_CBIT0);
+ return value;
+
+ break;
+ }
+
+ return OSS_EINVAL;
+ }
+ return OSS_EINVAL;
+}
+
+static int
+spdif_set_mixer_control (int dev, int ctrl, unsigned int cmd, int value)
+{
+ int i, ret;
+ spdif_devc *devc = NULL;
+ oss_native_word flags;
+ flags = 0;
+
+ for (i = 0; i < ndevs && devc == NULL; i++)
+ if (devc_list[i]->mixer_dev == dev)
+ devc = devc_list[i];
+
+ if (devc == NULL)
+ return OSS_EINVAL;
+ MUTEX_ENTER (devc->mutex, flags);
+ ret = spdif_set_control (devc, ctrl, cmd, value);
+ MUTEX_EXIT (devc->mutex, flags);
+ return ret;
+}
+
+static int
+spdif_mix_init (spdif_devc * devc)
+{
+ int group, err, dev;
+
+ dev = devc->mixer_dev;
+
+ if (!devc->is_ok)
+ {
+ cmn_err (CE_WARN, "spdif: Bad usage - mix_init\n");
+ return OSS_EIO;
+ }
+
+ if (devc->group > 0)
+ mixer_ext_truncate (devc->mixer_dev, devc->group);
+ devc->group = 0;
+
+ if ((group = mixer_ext_create_group_flags (dev, 0, "SPDIF", MIXF_FLAT)) < 0)
+ return group;
+
+ devc->group = group;
+
+ if (devc->flags & SPDF_ENABLE)
+ if ((err = mixer_ext_create_control (dev, group,
+ 1, spdif_set_mixer_control,
+ MIXT_ONOFF,
+ "SPDIF_ENABLE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+ return err;
+
+ if ((devc->caps & DIG_CBITOUT_MASK))
+ {
+ if ((err = mixer_ext_create_control (dev, group,
+ 3, spdif_set_mixer_control,
+ MIXT_ENUM,
+ "SPDIF_AUDIO", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+ }
+
+ if (devc->caps & DIG_VBITOUT)
+ {
+ if ((err = mixer_ext_create_control (dev, group,
+ 4, spdif_set_mixer_control,
+ MIXT_ONOFF,
+ "SPDIF_VBIT", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+ }
+
+ if ((devc->caps & DIG_CBITOUT_MASK))
+ {
+ if ((err = mixer_ext_create_control (dev, group,
+ 7, spdif_set_mixer_control,
+ MIXT_ENUM,
+ "SPDIF_PREEMPH", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+ }
+
+ if ((devc->caps & DIG_PRO) && (devc->caps & DIG_CONSUMER))
+ {
+ /* Device supports both consumer and pro */
+ if ((err = mixer_ext_create_control (dev, group,
+ 2, spdif_set_mixer_control,
+ MIXT_ENUM,
+ "SPDIF_MODE", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+ }
+
+ /* Copyright management */
+ if ((devc->caps & DIG_CBITOUT_MASK) && !devc->ctl->pro_mode)
+ {
+ if ((err = mixer_ext_create_control (dev, group,
+ 5, spdif_set_mixer_control,
+ MIXT_ENUM,
+ "SPDIF_COPYRIGHT", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+
+ if ((err = mixer_ext_create_control (dev, group,
+ 6, spdif_set_mixer_control,
+ MIXT_ENUM,
+ "SPDIF_GENERAT", 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return err;
+ }
+
+ return 0;
+}
+
+int
+oss_spdif_mix_init (spdif_devc * devc)
+{
+ int ret;
+ oss_native_word flags;
+ flags = 0;
+ MUTEX_ENTER (devc->mutex, flags);
+ ret = spdif_mix_init (devc);
+ MUTEX_EXIT (devc->mutex, flags);
+ return ret;
+}
diff --git a/kernel/framework/audio/ulaw.h b/kernel/framework/audio/ulaw.h
new file mode 100644
index 0000000..d8b22ac
--- /dev/null
+++ b/kernel/framework/audio/ulaw.h
@@ -0,0 +1,83 @@
+/*
+ * Purpose: u-Law to and from 8 bit unsigned linear audio conversion tables
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+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/kernel/framework/include/.nomake b/kernel/framework/include/.nomake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/kernel/framework/include/.nomake
diff --git a/kernel/framework/include/ac97.h b/kernel/framework/include/ac97.h
new file mode 100644
index 0000000..da6fcf2
--- /dev/null
+++ b/kernel/framework/include/ac97.h
@@ -0,0 +1,179 @@
+/*
+ * Purpose: Definitions for the AC97 codec support library
+ *
+ * This header file must be included by all low level drivers that support
+ * AC97 based devices.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+typedef int (*ac97_ext_ioctl) (int dev, int audiodev, unsigned int cmd,
+ int arg);
+typedef struct
+{
+ int is_ok;
+ char name[30];
+ void *host_parms;
+ oss_device_t *osdev;
+ ac97_readfunc_t read;
+ ac97_writefunc_t write;
+ unsigned short ac97_id; /* Register 0x00 */
+ int mixer_dev;
+
+ /* Detected mixer capabilities */
+ int mastervol_bits;
+ int pcmvol_bits;
+ int rearvol_bits;
+ int centervol_bits;
+ int sidevol_bits;
+ int auxvol_bits;
+ int enh_bits; /* number of bits for the 3D enhance */
+ int micboost; /* 20db Mic boost on/off */
+ int *levels;
+ int recdevs;
+ ac97_ext_ioctl overrides[SOUND_MIXER_NRDEVICES];
+
+ int devmask;
+ int recmask;
+ int var_rate_support;
+ int fixed_rate;
+ int playrate_support; /* ac97 2.4 codec */
+#define PLAY_2CHAN 0
+#define PLAY_4CHAN 1
+#define PLAY_6CHAN 2
+#define PLAY_8CHAN 3
+ int spdifout_support;
+#define CS_SPDIFOUT 1 /* Cirrus Logic */
+#define AD_SPDIFOUT 2 /* Analog Devices */
+#define STAC_SPDIFOUT 3 /* Sigmatel */
+#define ALC_SPDIFOUT 4 /* Avance Logic */
+#define VIA_SPDIFOUT 5 /* VIA Technologies */
+#define CMI_SPDIFOUT 6 /* CMedia */
+#define YMF_SPDIFOUT 7 /* Yamaha */
+#define CX_SPDIFOUT 8 /* Conexant */
+ int spdif_slot;
+#define SPDIF_SLOT34 0x00 /*slot3/4 = bits 5/6 = 0 */
+#define SPDIF_SLOT78 0x10
+#define SPDIF_SLOT69 0x20
+#define SPDIF_SLOT1011 0x30
+ int spdifin_support;
+#define ALC_SPDIFIN 1 /* Avance Logic SPDIF Input */
+#define CMI_SPDIFIN 2 /* CMedia SPDIF Input */
+
+ int mixer_ext;
+#define ALC650_MIXER_EXT 1
+#define AD1980_MIXER_EXT 2
+#define VIA1616_MIXER_EXT 3
+#define CMI9739_MIXER_EXT 4
+#define CMI9780_MIXER_EXT 5
+#define STAC9758_MIXER_EXT 6
+#define WM9704_MIXER_EXT 7
+
+ int enh_3d;
+/*
+ * From AC97 register 0x00:
+ *
+ * 0x00=No enhancement
+ * 0x01=Analog Devices Phat Stereo
+ * 0x02=Creative Stereo Enhancement
+ * 0x03=National Semiconductor 3D Stereo Enhancement
+ * 0x04=Yamaha Ymersion
+ * 0x06=Crystal 3D Stereo Enhancement
+ * 0x07=Qsound QXpander
+ * 0x08=Spatializer 3D Stereo Enhancement
+ * 0x09=SRS 3D Stereo Enhancement
+ * 0x0b=AKM 3D Audio
+ * 0x0c=Aureal Stereo Enhancement
+ * 0x0d=Aztech 3D Audio Enhancement
+ * 0x0e=Binaura 3D Audio Enhancement
+ * 0x0f=ESS Technology
+ * 0x10=Harman International VMAx
+ * 0x11=NVidea 3D Stereo Enhancement
+ * 0x12=Philips Incredible Sound
+ * 0x13=Texas Instruments 3D Stereo Enhancement
+ * 0x14=VLSI Technology 3D Stereo Enhancement
+ * 0x18=Wolfson Analoque 3D stereo enhancement
+ * 0x1a=Sigmatel 3D Stereo enhancement (SS3D)
+ */
+ int extmixlevels[10]; /* volume controls for Rear/Center/additional chans */
+#define CENTER_VOL 0
+#define REAR_VOL 1
+#define SIDE_VOL 2
+ mixer_create_controls_t client_mixer_init;
+}
+ac97_devc;
+
+extern int ac97_install (ac97_devc * devc, char *name, ac97_readfunc_t readfn,
+ ac97_writefunc_t writefn, void *hostparms,
+ oss_device_t * osdev);
+#define AC97_INVERTED 0x1
+#define AC97_FORCE_SENSE 0x2
+extern int ac97_install_full (ac97_devc * devc, char *name,
+ ac97_readfunc_t readfn, ac97_writefunc_t writefn,
+ void *hostparms, oss_device_t * osdev, int flags);
+extern int ac97_init_ext (int dev, ac97_devc * devc,
+ mixer_create_controls_t func, int nextra);
+extern int ac97_varrate (ac97_devc * devc);
+extern int ac97_recrate (ac97_devc * devc, int srate);
+extern int ac97_playrate (ac97_devc * devc, int srate);
+extern void ac97_remove_control (ac97_devc * devc, int mask, int level);
+extern void ac97_override_control (ac97_devc * devc, int ctrl,
+ ac97_ext_ioctl func, int level);
+
+/* AC97 V2.2 mixer functions */
+extern int ac97_spdifin_ctl (int dev, int ctrl, unsigned int cmd, int value);
+extern int ac97_spdifout_ctl (int dev, int ctrl, unsigned int cmd, int value);
+extern void ac97_spdif_setup (int dev, int speed, int bits);
+extern int ac97_mixext_ctl (int dev, int ctrl, unsigned int cmd, int value);
+extern int ac97_mixer_set (ac97_devc * devc, int dev, int value);
+
+/* AC97 V2.2 Mixer extensions */
+#define VOL_CENTER 1
+#define VOL_REAR 2
+#define VOL_SIDE 3
+#define CENTER2MIC 4
+#define REAR2LINE 5
+#define SPREAD 6
+#define MICBOOST 7
+#define JACKSENSE 8
+#define DOWNMIX_LFE 9
+#define DOWNMIX_REAR 10
+
+/* SPDIF OUT Mixer Register Definitions */
+#define SPDIFOUT_ENABLE 1
+#define SPDIFOUT_PRO 2
+#define SPDIFOUT_AUDIO 3
+#define SPDIFOUT_COPY 4
+#define SPDIFOUT_PREEMPH 5
+#define SPDIFOUT_CATEGORY 6
+#define SPDIFOUT_GENERATION 7
+#define SPDIFOUT_RATE 8
+#define SPDIFOUT_VBIT 9
+#define SPDIFOUT_ADC 10
+
+/* SPDIF IN Mixer register Definitions */
+#define SPDIFIN_ENABLE 1
+#define SPDIFIN_PRO 2
+#define SPDIFIN_AUDIO 3
+#define SPDIFIN_COPY 4
+#define SPDIFIN_PREEMPH 5
+#define SPDIFIN_MODE 6
+#define SPDIFIN_CATEGORY 7
+#define SPDIFIN_GENERATION 8
+#define SPDIFIN_SOURCE 9
+#define SPDIFIN_CHAN 10
+#define SPDIFIN_RATE 11
+#define SPDIFIN_CLOCK 12
+#define SPDIFIN_SIGNAL 13
+#define SPDIFIN_VBIT 14
+#define SPDIFIN_MON 15
+#define SPDIFIN_LOOP 16
diff --git a/kernel/framework/include/audio_core.h b/kernel/framework/include/audio_core.h
new file mode 100644
index 0000000..59aa3bc
--- /dev/null
+++ b/kernel/framework/include/audio_core.h
@@ -0,0 +1,427 @@
+#ifndef AUDIO_CORE_H
+#define AUDIO_CORE_H
+/*
+ * Purpose: Internal definitions for the OS audio core
+ *
+ * IMPORTANT NOTICE!
+ *
+ * This file contains internal structures used by Open Sound Systems.
+ * They will change without any notice between OSS versions. Care must be taken
+ * to make sure any software using this header gets properly re-compiled before
+ * use.
+ *
+ * 4Front Technologies (or anybody else) takes no responsibility of damages
+ * caused by use of this file.
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * Max number of audio channels currently supported by the sample format converter.
+ */
+#define OSS_MAX_CONVERT_CHANNELS 64
+
+/*
+ * Size of the temporary buffer used for audio conversions.
+ *
+ * TMP_CONVERT_MAX defines how many bytes can be fed to the converter in
+ * one call.
+ *
+ * TMP_CONVERT_BUF_SIZE defines how many bytes of buffer will be allocated.
+ * This is larger than TMP_CONVERT_MAX because amount of data may get expanded
+ * during the conversion (for example if the output sampling rate or #channels
+ * is larger than in the input side).
+ */
+#define TMP_CONVERT_MAX (16*1024)
+#define TMP_CONVERT_BUF_SIZE (8*TMP_CONVERT_MAX)
+
+/*
+ * open_flags (for opening audio devices)
+ */
+#define OF_MMAP 0x00000001 /* Opening application is known to use mmap() */
+#define OF_BLOCK 0x00000002 /* Disable O_NONBLOCK */
+#define OF_NOCONV 0x00000010 /* Disable all fmt/src conversions */
+#define OF_DEVAUDIO 0x00000020 /* Solaris /dev/audio emulator */
+#define OF_SMALLFRAGS 0x00000040 /* Use smaller fragments than requested */
+#define OF_SMALLBUF 0x00000080 /* Allocate small (4k) buffer this time */
+#define OF_MEDIUMBUF 0x00000100 /* Allocate moderate (16k) buffer */
+
+#define CONVERTABLE_FORMATS \
+ (AFMT_U8|AFMT_S8|AFMT_MU_LAW|AFMT_S16_LE|AFMT_S16_BE|\
+ AFMT_S24_LE|AFMT_S24_BE|AFMT_S32_LE|AFMT_S32_BE|AFMT_S24_PACKED)
+
+#ifndef _KERNEL
+typedef struct _audiodrv_t audiodrv_t;
+#endif
+
+typedef struct
+{
+ char *name;
+ int fmt;
+ unsigned char neutral_byte;
+ char bits;
+ char is_linear;
+ char endianess;
+#define ENDIAN_NONE 0
+#define ENDIAN_LITTLE 1
+#define ENDIAN_BIG 2
+#ifdef OSS_BIG_ENDIAN
+# define ENDIAN_NATIVE ENDIAN_BIG
+#else
+# define ENDIAN_NATIVE ENDIAN_LITTLE
+#endif
+
+ char is_signed;
+ char alignment;
+#define ALIGN_MSB 0
+#define ALIGN_LSB 1
+ int no_convert;
+}
+audio_format_info_t, *audio_format_info_p;
+
+typedef struct
+{
+ int fmt, rate, channels;
+ int convert;
+}
+sample_parms;
+
+typedef struct _adev_t adev_t, *adev_p;
+typedef struct _dmap_t *dmap_p;
+typedef int (*cnv_func_t) (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl,
+ unsigned char **tgtp, sample_parms * source,
+ sample_parms * target);
+
+struct _dmap_t
+{
+/*
+ * Static fields (not to be cleared during open)
+ */
+#ifdef _KERNEL
+ oss_mutex_t mutex;
+#endif
+ oss_device_t *osdev;
+ oss_device_t *master_osdev; /* The osdev pointer of the master (for virtual drivers) */
+ adev_t *adev;
+ unsigned char *dmabuf;
+ oss_native_word dmabuf_phys;
+ oss_dma_handle_t dmabuf_dma_handle;
+ int buffsize;
+ int buffer_protected; /* Buffer is shared - don't modify/clear */
+ unsigned char *tmpbuf1, *tmpbuf2;
+ void *driver_use_ptr;
+ long driver_use_value;
+ /* Interrupt callback stuff */
+ void (*audio_callback) (int dev, int parm);
+ int callback_parm;
+
+#ifdef OS_DMA_PARMS
+ OS_DMA_PARMS
+#endif
+/*
+ * Dynamic fields (will be zeroed during open)
+ * Don't add anything before flags.
+ */
+ void *srcstate[OSS_MAX_CONVERT_CHANNELS];
+ oss_native_word flags;
+#define DMAP_NOTIMEOUT 0x00000001
+#define DMAP_POST 0x00000002
+#define DMAP_PREPARED 0x00000004
+#define DMAP_FRAGFIXED 0x00000008 /* Fragment size fixed */
+#define DMAP_STARTED 0x00000010
+#define DMAP_COOKED 0x00000020
+#define DMAP_SMALLBUF 0x00000040 /* Allocate small buffers */
+#define DMAP_MEDIUMBUF 0x00000040 /* Allocate 16k buffers */
+ int dma_mode; /* PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT or 0 */
+
+ /*
+ * Queue parameters.
+ */
+ int nfrags;
+ int fragment_size;
+ int bytes_in_use;
+ int data_rate; /* Bytes/second */
+ int frame_size; /* Device frame size */
+ int user_frame_size; /* Application frame size */
+ int fragsize_rq;
+ int low_water, low_water_rq;
+ volatile oss_uint64_t byte_counter;
+ volatile oss_uint64_t user_counter;
+ int interrupt_count;
+ int fragment_counter;
+ int expand_factor;
+
+ int mapping_flags;
+#define DMA_MAP_MAPPED 0x00000001
+ char neutral_byte;
+
+ int error;
+ int play_underruns, rec_overruns;
+ int underrun_flag;
+ int num_errors;
+#define MAX_AUDIO_ERRORS 5
+ int errors[MAX_AUDIO_ERRORS];
+ int error_parms[MAX_AUDIO_ERRORS];
+
+ unsigned char *leftover_buf;
+ int leftover_bytes;
+ int tmpbuf_len, tmpbuf_ptr;
+ cnv_func_t convert_func;
+ unsigned int convert_mode;
+ struct audio_buffer *(*user_import) (adev_t * adev,
+ dmap_t * dmap,
+ sample_parms * parms,
+ unsigned char *cbuf, int len);
+ int (*user_export) (adev_t * adev,
+ dmap_t * dmap, sample_parms * parms,
+ struct audio_buffer * buf, unsigned char *cbuf,
+ int maxbytes);
+ struct audio_buffer *(*device_read) (adev_t * adev,
+ dmap_t * dmap,
+ sample_parms * parms,
+ unsigned char *cbuf, int len);
+ int (*device_write) (adev_t * adev,
+ dmap_t * dmap,
+ void *frombuf, void *tobuf,
+ int maxspace, int *fromlen, int *tolen);
+};
+extern int dmap_get_qlen (dmap_t * dmap);
+extern int dmap_get_qhead (dmap_t * dmap);
+extern int dmap_get_qtail (dmap_t * dmap);
+
+struct _adev_t
+{
+ char name[64];
+ char handle[32];
+ int engine_num; /* Audio engine number */
+ int audio_devfile; /* Audio device file number */
+ int enabled;
+ int unloaded;
+ struct _adev_t *next_in, *next_out; /* Links to the next "shadow" devices */
+ long long flags;
+ int open_flags;
+ int src_quality;
+ int caps;
+ int magic; /* Secret low level driver ID */
+ int latency; /* In usecs, -1=unknown */
+
+
+ /*
+ * Sampling parameters
+ */
+
+ sample_parms user_parms, hw_parms;
+ int iformat_mask, oformat_mask; /* Bitmasks for supported audio formats */
+ int min_rate, max_rate; /* Sampling rate limits */
+ int min_channels, max_channels;
+ char *inch_names, *outch_names;
+ int xformat_mask; /* Format mask for current open mode */
+ int binding;
+ void *devc; /* Driver specific info */
+ audiodrv_t *d;
+ void *portc, *portc_play, *portc_record; /* Driver specific info */
+ dmap_t *dmap_in, *dmap_out;
+ int mixer_dev;
+ int open_mode;
+ int go;
+ int enable_bits;
+ int parent_dev; /* 0 -> no parent, 1 to n -> parent=parent_dev+1 */
+ int max_block; /* Maximum fragment size to be accepted */
+ int min_block; /* Minimum fragment size */
+ int min_fragments; /* Minimum number of fragments */
+ int max_fragments; /* Maximum number of fragments */
+ int max_intrate; /* Another form of min_block */
+ int dmabuf_alloc_flags;
+ oss_uint64_t dmabuf_maxaddr;
+ int fixed_rate;
+ int vmix_flags; /* special flags sent to virtual mixer */
+#define VMIX_MULTIFRAG 0x00000001 /* More than 2 fragments required (causes longer latencies) */
+#define VMIX_DISABLED 0x00000002 /* Not compatible with vmix */
+#define VMIX_NOINPUT 0x00000004 /* Disable input capability */
+#define VMIX_NOMAINVOL 0x00000008 /* No main volume sliders/meters please */
+ pid_t pid;
+ char cmd[16];
+ oss_device_t *osdev;
+ oss_device_t *master_osdev; /* The osdev pointer of the master (for virtual drivers) */
+ int setfragment_warned;
+ int getispace_error_count;
+ int redirect_in, redirect_out;
+ int dmask; /* Open dmaps */
+#define DMASK_OUT 0x01
+#define DMASK_IN 0x02
+ int nonblock;
+ int forced_nonblock;
+ int ossd_registered;
+ int sync_flags;
+#define SYNC_MASTER 0x01
+#define SYNC_SLAVE 0x02
+ int sync_group;
+ int sync_mode;
+ adev_t *sync_next; /* Next device in sync group */
+
+ int rate_source;
+ unsigned int nrates, rates[OSS_MAX_SAMPLE_RATES + 1];
+
+#ifdef _KERNEL
+ oss_mutex_t mutex;
+ oss_wait_queue_t *out_wq, *in_wq;
+#endif
+
+ int card_number;
+ int port_number;
+ int real_dev;
+
+/*
+ * By default OSS will let applications to use sampling rates and formats
+ * that are not supported by the hardware. Instead OSS performs the necessary
+ * format conversions in software. Applications that don't tolerate this kind
+ * of conversions usually disable them by using features of the OSS API
+ * (SNDCTL_DSP_COOKEDMODE). If this option is set to 0 then the format
+ * conversions will be disabled for all applications and devices unless the
+ * application explicitly enables them.
+ *
+ * cooked_enable is a global variable (int) defined in oss_core_options.c. The current
+ * value of this global variable will be copied to adev->cooked_enable when
+ * an audio engine is opened.
+ */
+ int cooked_enable;
+ int timeout_count;
+
+ void (*outputintr) (int dev, int intr_flags);
+ void (*inputintr) (int dev, int intr_flags);
+
+ int policy;
+ void *os_id; /* The device ID (dip) given by the system. */
+ oss_longname_t song_name;
+ oss_label_t label;
+ oss_devnode_t devnode;
+ void *vmix_mixer; /* Pointer to the vmix_mixer_t structure for this device */
+ void *prev_vmix_mixer; /* Reserved for vmix_core */
+};
+
+#define UNIT_EXPAND 1024
+
+/*
+ * The audio_devfiles and audio_engines tables contain pointers to
+ * the (same) adev_t structures. The difference is that
+ * audio_engines contains an entry for all audio devices/engines in the system
+ * (including hidden and shadow devices). The 'dev' parameter of most audio
+ * core routines and audio driver methods are indexes to this array.
+ *
+ * The audio_devfiles array is a "parallel" structure that contains only
+ * the audio engines that have a device file in /dev/oss (and usually also
+ * an legacy /dev/dsp# device file). This audio_devfiles array doesn't contain
+ * "hidden" audio engines.
+ *
+ * Each audio operations structure in audio_devfiles will also be in
+ * audio_engines but the indexes are different. Both arrays contain pointer to
+ * the same structure in memory (not a copy).
+ *
+ * For example the 6th audio device file (usually but not always /dev/dsp5) is
+ * audio_devfiles[5]. However it may be (say) audio_engines[11] if there are
+ * hidden devices created before it.
+ *
+ * /dev/dsp5 -> audio_devfile[5] == audio_engines[11]
+ *
+ * The next field of the adev_t structure contains a pointer
+ * to the next "identical" device. Most OSS implementations will
+ * try to open one of the subsequent devices in the next chain if
+ * the original device was busy. "Identical" means that the device suports
+ * multiple identical (hw mixing) engines or the vmix driver is used to
+ * add software mixing capability to the device.
+ */
+
+extern adev_t **audio_engines;
+extern int num_audio_engines;
+extern adev_t **audio_devfiles;
+extern int num_audio_devfiles;
+
+#if 0
+typedef struct
+{
+ int ndevs;
+ unsigned short devices[MAX_AUDIO_DEVFILES];
+}
+oss_devlist_t;
+
+extern oss_devlist_t dspoutlist, dspoutlist2, dspinlist, dspinoutlist;
+#endif
+
+int oss_install_audiodev (int vers,
+ oss_device_t * osdev,
+ oss_device_t * master_osdev,
+ char *name,
+ const audiodrv_t * driver,
+ int driver_size,
+ unsigned long long flags,
+ unsigned int format_mask, void *devc, int parent);
+
+int oss_install_audiodev_with_devname (int vers,
+ oss_device_t * osdev,
+ oss_device_t * master_osdev,
+ char *name,
+ const audiodrv_t * driver,
+ int driver_size,
+ int flags,
+ unsigned int format_mask, void *devc, int parent,
+ const char *devfile_name);
+extern void install_vdsp (oss_device_t * osdev);
+extern int *load_mixer_volumes (char *name, int *levels, int present);
+
+#ifdef _KERNEL
+int oss_audio_read (int dev, struct fileinfo *file, uio_t * buf, int count);
+int oss_audio_write (int dev, struct fileinfo *file, uio_t * buf, int count);
+int oss_audio_open_engine (int dev, int dev_class, struct fileinfo *file,
+ int recursive, int open_flags, int *newdev);
+int oss_audio_open_devfile (int dev, int dev_class, struct fileinfo *file,
+ int recursive, int open_flags, int *newdev);
+int oss_open_vdsp (int dev, int dev_type, struct fileinfo *file,
+ int recursive, int open_flags, int *newdev);
+void oss_audio_release (int dev, struct fileinfo *file);
+int oss_audio_ioctl (int dev, struct fileinfo *file,
+ unsigned int cmd, ioctl_arg arg);
+int oss_audio_set_format (int dev, int fmt, int format_mask);
+int oss_audio_set_channels (int dev, int ch);
+int oss_audio_set_rate (int dev, int val);
+void audio_uninit_device (int dev);
+int oss_audio_mmap (int dev, int direction);
+#endif
+
+/* From audiofmt.c */
+int setup_format_conversions (adev_p adev, dmap_p dmap, sample_parms * source,
+ sample_parms * target,
+ sample_parms * user,
+ sample_parms * device, int format_mask);
+audio_format_info_p oss_find_format (unsigned int fmt);
+
+
+#define oss_audio_outputintr(dev, flags) audio_engines[dev]->outputintr(dev, flags)
+#define oss_audio_inputintr(dev, flags) audio_engines[dev]->inputintr(dev, flags)
+void oss_audio_reset (int dev);
+void oss_audio_start_syncgroup (unsigned int syncgroup);
+typedef int (*oss_audio_startup_func) (void *devc);
+extern void oss_audio_register_client (oss_audio_startup_func func,
+ void *devc, oss_device_t * osdev);
+
+extern int oss_encode_enum (oss_mixer_enuminfo * ei, const char *s,
+ int version);
+extern char *audio_show_latency (int dev);
+extern void oss_audio_inc_byte_counter (dmap_t * dmap, int increment);
+extern void oss_add_audio_devlist (int list, int devfile);
+
+#ifndef SMALL_DMABUF_SIZE
+#define SMALL_DMABUF_SIZE (4*1024)
+#endif
+
+#define MEDIUM_DMABUF_SIZE (16*1024)
+#endif
diff --git a/kernel/framework/include/eq1.h b/kernel/framework/include/eq1.h
new file mode 100644
index 0000000..837605f
--- /dev/null
+++ b/kernel/framework/include/eq1.h
@@ -0,0 +1,1059 @@
+/*
+ * Purpose: This header file contains some coefficients for the 4 band equalizer
+ *
+ * This equalizer code is used by the SB Live/Audigy firmware.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+static const unsigned int eq_band1_data[][6] = {
+ {0x0FCEBCE0, 0xE083F660, 0x1F7C09A0, 0x0FADB020, 0xF08392F0, 0x00000000}, /* 0 */
+ {0x0FCF2D70, 0xE0834400, 0x1F7CBC00, 0x0FADF220, 0xF082E090, 0x00000000}, /* 1 */
+ {0x0FCF9D80, 0xE08292A0, 0x1F7D6D60, 0x0FAE3370, 0xF0822F10, 0x00000000}, /* 2 */
+ {0x0FD00D40, 0xE081E220, 0x1F7E1DE0, 0x0FAE7430, 0xF0817E90, 0x00000000}, /* 3 */
+ {0x0FD07CB0, 0xE0813280, 0x1F7ECD80, 0x0FAEB450, 0xF080CEF0, 0x00000000}, /* 4 */
+ {0x0FD0EBE0, 0xE08083A0, 0x1F7F7C60, 0x0FAEF410, 0xF0802030, 0x00000000}, /* 5 */
+ {0x0FD15A90, 0xE07FD600, 0x1F802A00, 0x0FAF32F0, 0xF07F7260, 0x00000000}, /* 6 */
+ {0x0FD1C910, 0xE07F2940, 0x1F80D6C0, 0x0FAF7150, 0xF07EC590, 0x00000000}, /* 7 */
+ {0x0FD23740, 0xE07E7D20, 0x1F8182E0, 0x0FAFAF30, 0xF07E1990, 0x00000000}, /* 8 */
+ {0x0FD2A510, 0xE07DD200, 0x1F822E00, 0x0FAFEC70, 0xF07D6E70, 0x00000000}, /* 9 */
+ {0x0FD312A0, 0xE07D27E0, 0x1F82D820, 0x0FB02930, 0xF07CC440, 0x00000000}, /* 10 */
+ {0x0FD37FC0, 0xE07C7EA0, 0x1F838160, 0x0FB06540, 0xF07C1B00, 0x00000000}, /* 11 */
+ {0x0FD3ECC0, 0xE07BD620, 0x1F8429E0, 0x0FB0A0D0, 0xF07B7290, 0x00000000}, /* 12 */
+ {0x0FD45930, 0xE07B2EC0, 0x1F84D140, 0x0FB0DBB0, 0xF07ACB10, 0x00000000}, /* 13 */
+ {0x0FD4C5A0, 0xE07A87E0, 0x1F857820, 0x0FB11620, 0xF07A2450, 0x00000000}, /* 14 */
+ {0x0FD531A0, 0xE079E220, 0x1F861DE0, 0x0FB14FF0, 0xF0797E80, 0x00000000}, /* 15 */
+ {0x0FD59D40, 0xE0793D20, 0x1F86C2E0, 0x0FB18930, 0xF078D990, 0x00000000}, /* 16 */
+ {0x0FD608A0, 0xE0789920, 0x1F8766E0, 0x0FB1C1E0, 0xF0783580, 0x00000000}, /* 17 */
+ {0x0FD673B0, 0xE077F600, 0x1F880A00, 0x0FB1F9F0, 0xF0779250, 0x00000000}, /* 18 */
+ {0x0FD6DE80, 0xE07753A0, 0x1F88AC60, 0x0FB23180, 0xF076F000, 0x00000000}, /* 19 */
+ {0x0FD74920, 0xE076B220, 0x1F894DE0, 0x0FB26880, 0xF0764E70, 0x00000000}, /* 20 */
+ {0x0FD7B340, 0xE07611A0, 0x1F89EE60, 0x0FB29ED0, 0xF075ADE0, 0x00000000}, /* 21 */
+ {0x0FD81D20, 0xE07571C0, 0x1F8A8E40, 0x0FB2D4B0, 0xF0750E10, 0x00000000}, /* 22 */
+ {0x0FD886F0, 0xE074D2A0, 0x1F8B2D60, 0x0FB30A10, 0xF0746F00, 0x00000000}, /* 23 */
+ {0x0FD8F060, 0xE0743480, 0x1F8BCB80, 0x0FB33EC0, 0xF073D0D0, 0x00000000}, /* 24 */
+ {0x0FD95980, 0xE0739740, 0x1F8C68C0, 0x0FB372F0, 0xF0733390, 0x00000000}, /* 25 */
+ {0x0FD9C260, 0xE072FAC0, 0x1F8D0540, 0x0FB3A690, 0xF0729700, 0x00000000}, /* 26 */
+ {0x0FDA2B00, 0xE0725F00, 0x1F8DA100, 0x0FB3D9B0, 0xF071FB40, 0x00000000}, /* 27 */
+ {0x0FDA9350, 0xE071C420, 0x1F8E3BE0, 0x0FB40C40, 0xF0716070, 0x00000000}, /* 28 */
+ {0x0FDAFB60, 0xE0712A40, 0x1F8ED5C0, 0x0FB43E20, 0xF070C670, 0x00000000}, /* 29 */
+ {0x0FDB6340, 0xE07090C0, 0x1F8F6F40, 0x0FB46FA0, 0xF0702D20, 0x00000000}, /* 30 */
+ {0x0FDBCAE0, 0xE06FF840, 0x1F9007C0, 0x0FB4A090, 0xF06F94A0, 0x00000000}, /* 31 */
+ {0x0FDC3220, 0xE06F60C0, 0x1F909F40, 0x0FB4D0E0, 0xF06EFD00, 0x00000000}, /* 32 */
+ {0x0FDC9930, 0xE06EC9E0, 0x1F913620, 0x0FB50090, 0xF06E6630, 0x00000000}, /* 33 */
+ {0x0FDD0020, 0xE06E33C0, 0x1F91CC40, 0x0FB52FF0, 0xF06DD010, 0x00000000}, /* 34 */
+ {0x0FDD6690, 0xE06D9EA0, 0x1F926160, 0x0FB55E80, 0xF06D3AD0, 0x00000000}, /* 35 */
+ {0x0FDDCCF0, 0xE06D0A20, 0x1F92F5E0, 0x0FB58CB0, 0xF06CA650, 0x00000000}, /* 36 */
+ {0x0FDE3310, 0xE06C7660, 0x1F9389A0, 0x0FB5BA50, 0xF06C1290, 0x00000000}, /* 37 */
+ {0x0FDE98F0, 0xE06BE360, 0x1F941CA0, 0x0FB5E770, 0xF06B7F90, 0x00000000}, /* 38 */
+ {0x0FDEFEA0, 0xE06B5140, 0x1F94AEC0, 0x0FB613E0, 0xF06AED80, 0x00000000}, /* 39 */
+ {0x0FDF6410, 0xE06ABFE0, 0x1F954020, 0x0FB63FF0, 0xF06A5C00, 0x00000000}, /* 40 */
+ {0x0FDFC940, 0xE06A2F40, 0x1F95D0C0, 0x0FB66B60, 0xF069CB70, 0x00000000}, /* 41 */
+ {0x0FE02E40, 0xE0699F40, 0x1F9660C0, 0x0FB69650, 0xF0693B70, 0x00000000}, /* 42 */
+ {0x0FE092E0, 0xE0691040, 0x1F96EFC0, 0x0FB6C0A0, 0xF068AC60, 0x00000000}, /* 43 */
+ {0x0FE0F780, 0xE06881C0, 0x1F977E40, 0x0FB6EAA0, 0xF0681DF0, 0x00000000}, /* 44 */
+ {0x0FE15BD0, 0xE067F420, 0x1F980BE0, 0x0FB713E0, 0xF0679050, 0x00000000}, /* 45 */
+ {0x0FE1BFE0, 0xE0676740, 0x1F9898C0, 0x0FB73CB0, 0xF0670370, 0x00000000}, /* 46 */
+ {0x0FE223D0, 0xE066DB20, 0x1F9924E0, 0x0FB764F0, 0xF0667740, 0x00000000}, /* 47 */
+ {0x0FE28790, 0xE0664FA0, 0x1F99B060, 0x0FB78CB0, 0xF065EBD0, 0x00000000}, /* 48 */
+ {0x0FE2EB10, 0xE065C4E0, 0x1F9A3B20, 0x0FB7B3F0, 0xF0656120, 0x00000000}, /* 49 */
+ {0x0FE34E30, 0xE0653B20, 0x1F9AC4E0, 0x0FB7DA80, 0xF064D730, 0x00000000}, /* 50 */
+ {0x0FE3B150, 0xE064B1E0, 0x1F9B4E20, 0x0FB800C0, 0xF0644DF0, 0x00000000}, /* 51 */
+ {0x0FE41440, 0xE0642940, 0x1F9BD6C0, 0x0FB82650, 0xF063C560, 0x00000000}, /* 52 */
+ {0x0FE476F0, 0xE063A1A0, 0x1F9C5E60, 0x0FB84B70, 0xF0633DA0, 0x00000000}, /* 53 */
+ {0x0FE4D960, 0xE0631A60, 0x1F9CE5A0, 0x0FB87000, 0xF062B680, 0x00000000}, /* 54 */
+ {0x0FE53BE0, 0xE0629400, 0x1F9D6C00, 0x0FB89420, 0xF0623020, 0x00000000}, /* 55 */
+ {0x0FE59DE0, 0xE0620E80, 0x1F9DF180, 0x0FB8B790, 0xF061AA80, 0x00000000}, /* 56 */
+ {0x0FE5FFE0, 0xE0618980, 0x1F9E7680, 0x0FB8DA90, 0xF0612590, 0x00000000}, /* 57 */
+ {0x0FE661B0, 0xE0610520, 0x1F9EFAE0, 0x0FB8FD20, 0xF060A140, 0x00000000}, /* 58 */
+ {0x0FE6C330, 0xE06081A0, 0x1F9F7E60, 0x0FB91F20, 0xF0601DA0, 0x00000000}, /* 59 */
+ {0x0FE724A0, 0xE05FFEC0, 0x1FA00140, 0x0FB94090, 0xF05F9AC0, 0x00000000}, /* 60 */
+ {0x0FE785F0, 0xE05F7C80, 0x1FA08380, 0x0FB96180, 0xF05F1890, 0x00000000}, /* 61 */
+ {0x0FE7E6F0, 0xE05EFB20, 0x1FA104E0, 0x0FB981E0, 0xF05E9710, 0x00000000}, /* 62 */
+ {0x0FE847F0, 0xE05E7A20, 0x1FA185E0, 0x0FB9A1E0, 0xF05E1620, 0x00000000}, /* 63 */
+ {0x0FE8A8B0, 0xE05DFA20, 0x1FA205E0, 0x0FB9C130, 0xF05D9610, 0x00000000}, /* 64 */
+ {0x0FE90950, 0xE05D7AA0, 0x1FA28560, 0x0FB9E010, 0xF05D1690, 0x00000000}, /* 65 */
+ {0x0FE969C0, 0xE05CFBC0, 0x1FA30440, 0x0FB9FE80, 0xF05C97C0, 0x00000000}, /* 66 */
+ {0x0FE9CA00, 0xE05C7DA0, 0x1FA38260, 0x0FBA1C50, 0xF05C19B0, 0x00000000}, /* 67 */
+ {0x0FEA2A30, 0xE05C0000, 0x1FA40000, 0x0FBA39C0, 0xF05B9C10, 0x00000000}, /* 68 */
+ {0x0FEA8A30, 0xE05B8360, 0x1FA47CA0, 0x0FBA5680, 0xF05B1F60, 0x00000000}, /* 69 */
+ {0x0FEAEA00, 0xE05B0720, 0x1FA4F8E0, 0x0FBA72D0, 0xF05AA320, 0x00000000}, /* 70 */
+ {0x0FEB49A0, 0xE05A8BC0, 0x1FA57440, 0x0FBA8EA0, 0xF05A27B0, 0x00000000}, /* 71 */
+ {0x0FEBA920, 0xE05A10E0, 0x1FA5EF20, 0x0FBAA9E0, 0xF059ACE0, 0x00000000}, /* 72 */
+ {0x0FEC08A0, 0xE05996A0, 0x1FA66960, 0x0FBAC4C0, 0xF05932A0, 0x00000000}, /* 73 */
+ {0x0FEC67F0, 0xE0591D20, 0x1FA6E2E0, 0x0FBADF00, 0xF058B910, 0x00000000}, /* 74 */
+ {0x0FECC710, 0xE058A400, 0x1FA75C00, 0x0FBAF8E0, 0xF0584010, 0x00000000}, /* 75 */
+ {0x0FED2600, 0xE0582BE0, 0x1FA7D420, 0x0FBB1210, 0xF057C7E0, 0x00000000}, /* 76 */
+ {0x0FED84F0, 0xE057B440, 0x1FA84BC0, 0x0FBB2AD0, 0xF0575030, 0x00000000}, /* 77 */
+ {0x0FEDE3D0, 0xE0573D20, 0x1FA8C2E0, 0x0FBB4330, 0xF056D910, 0x00000000}, /* 78 */
+ {0x0FEE4240, 0xE056C6E0, 0x1FA93920, 0x0FBB5AE0, 0xF05662C0, 0x00000000}, /* 79 */
+ {0x0FEEA100, 0xE05650E0, 0x1FA9AF20, 0x0FBB7230, 0xF055ECE0, 0x00000000}, /* 80 */
+ {0x0FEEFF40, 0xE055DBE0, 0x1FAA2420, 0x0FBB88F0, 0xF05577D0, 0x00000000}, /* 81 */
+ {0x0FEF5D80, 0xE0556760, 0x1FAA98A0, 0x0FBB9F20, 0xF0550350, 0x00000000}, /* 82 */
+ {0x0FEFBBD0, 0xE054F340, 0x1FAB0CC0, 0x0FBBB500, 0xF0548F50, 0x00000000}, /* 83 */
+ {0x0FF019E0, 0xE0548000, 0x1FAB8000, 0x0FBBCA30, 0xF0541BF0, 0x00000000}, /* 84 */
+ {0x0FF077C0, 0xE0540D60, 0x1FABF2A0, 0x0FBBDEF0, 0xF053A940, 0x00000000}, /* 85 */
+ {0x0FF0D5B0, 0xE0539B40, 0x1FAC64C0, 0x0FBBF330, 0xF0533730, 0x00000000}, /* 86 */
+ {0x0FF13370, 0xE05329E0, 0x1FACD620, 0x0FBC06F0, 0xF052C5B0, 0x00000000}, /* 87 */
+ {0x0FF19100, 0xE052B8E0, 0x1FAD4720, 0x0FBC1A20, 0xF05254C0, 0x00000000}, /* 88 */
+ {0x0FF1EEA0, 0xE05248A0, 0x1FADB760, 0x0FBC2CE0, 0xF051E490, 0x00000000}, /* 89 */
+ {0x0FF24C20, 0xE051D900, 0x1FAE2700, 0x0FBC3F20, 0xF05174D0, 0x00000000}, /* 90 */
+ {0x0FF2A980, 0xE05169A0, 0x1FAE9660, 0x0FBC50F0, 0xF05105A0, 0x00000000}, /* 91 */
+ {0x0FF306C0, 0xE050FB20, 0x1FAF04E0, 0x0FBC6240, 0xF0509710, 0x00000000}, /* 92 */
+ {0x0FF363E0, 0xE0508D60, 0x1FAF72A0, 0x0FBC72E0, 0xF0502930, 0x00000000}, /* 93 */
+ {0x0FF3C0F0, 0xE0502000, 0x1FAFE000, 0x0FBC8320, 0xF04FBBD0, 0x00000000}, /* 94 */
+ {0x0FF41E20, 0xE04FB320, 0x1FB04CE0, 0x0FBC92F0, 0xF04F4F00, 0x00000000}, /* 95 */
+ {0x0FF47AF0, 0xE04F4700, 0x1FB0B900, 0x0FBCA220, 0xF04EE2D0, 0x00000000}, /* 96 */
+ {0x0FF4D7E0, 0xE04EDB60, 0x1FB124A0, 0x0FBCB0E0, 0xF04E7730, 0x00000000}, /* 97 */
+ {0x0FF534B0, 0xE04E7040, 0x1FB18FC0, 0x0FBCBF40, 0xF04E0C10, 0x00000000}, /* 98 */
+ {0x0FF59170, 0xE04E05C0, 0x1FB1FA40, 0x0FBCCCF0, 0xF04DA190, 0x00000000}, /* 99 */
+ {0x0FF5EE00, 0xE04D9BE0, 0x1FB26420, 0x0FBCDA40, 0xF04D3790, 0x00000000}, /* 100 */
+ {0x0FF64AC0, 0xE04D3260, 0x1FB2CDA0, 0x0FBCE720, 0xF04CCE30, 0x00000000}, /* 101 */
+ {0x0FF6A740, 0xE04CC9A0, 0x1FB33660, 0x0FBCF360, 0xF04C6560, 0x00000000}, /* 102 */
+ {0x0FF703B0, 0xE04C6140, 0x1FB39EC0, 0x0FBCFF30, 0xF04BFD20, 0x00000000}, /* 103 */
+ {0x0FF76030, 0xE04BF980, 0x1FB40680, 0x0FBD0A80, 0xF04B9550, 0x00000000}, /* 104 */
+ {0x0FF7BC80, 0xE04B9260, 0x1FB46DA0, 0x0FBD1550, 0xF04B2E30, 0x00000000}, /* 105 */
+ {0x0FF818E0, 0xE04B2BA0, 0x1FB4D460, 0x0FBD1FB0, 0xF04AC770, 0x00000000}, /* 106 */
+ {0x0FF87510, 0xE04AC5C0, 0x1FB53A40, 0x0FBD2970, 0xF04A6170, 0x00000000}, /* 107 */
+ {0x0FF8D160, 0xE04A6020, 0x1FB59FE0, 0x0FBD32D0, 0xF049FBE0, 0x00000000}, /* 108 */
+ {0x0FF92D90, 0xE049FB00, 0x1FB60500, 0x0FBD3BB0, 0xF04996D0, 0x00000000}, /* 109 */
+ {0x0FF989B0, 0xE0499680, 0x1FB66980, 0x0FBD4400, 0xF0493250, 0x00000000}, /* 110 */
+ {0x0FF9E5C0, 0xE04932A0, 0x1FB6CD60, 0x0FBD4BE0, 0xF048CE60, 0x00000000}, /* 111 */
+ {0x0FFA41E0, 0xE048CF20, 0x1FB730E0, 0x0FBD5340, 0xF0486AE0, 0x00000000}, /* 112 */
+ {0x0FFA9DC0, 0xE0486C60, 0x1FB793A0, 0x0FBD5A10, 0xF0480820, 0x00000000}, /* 113 */
+ {0x0FFAF9E0, 0xE04809E0, 0x1FB7F620, 0x0FBD6080, 0xF047A5B0, 0x00000000}, /* 114 */
+ {0x0FFB55C0, 0xE047A820, 0x1FB857E0, 0x0FBD6650, 0xF04743D0, 0x00000000}, /* 115 */
+ {0x0FFBB1E0, 0xE04746A0, 0x1FB8B960, 0x0FBD6BD0, 0xF046E270, 0x00000000}, /* 116 */
+ {0x0FFC0DC0, 0xE046E5C0, 0x1FB91A40, 0x0FBD70C0, 0xF04681A0, 0x00000000}, /* 117 */
+ {0x0FFC69B0, 0xE0468580, 0x1FB97A80, 0x0FBD7520, 0xF0462150, 0x00000000}, /* 118 */
+ {0x0FFCC560, 0xE04625E0, 0x1FB9DA20, 0x0FBD78F0, 0xF045C190, 0x00000000}, /* 119 */
+ {0x0FFD2140, 0xE045C680, 0x1FBA3980, 0x0FBD7C70, 0xF0456240, 0x00000000}, /* 120 */
+ {0x0FFD7D30, 0xE04567A0, 0x1FBA9860, 0x0FBD7F60, 0xF0450360, 0x00000000}, /* 121 */
+ {0x0FFDD8F0, 0xE0450980, 0x1FBAF680, 0x0FBD81D0, 0xF044A530, 0x00000000}, /* 122 */
+ {0x0FFE34E0, 0xE044ABA0, 0x1FBB5460, 0x0FBD83D0, 0xF0444750, 0x00000000}, /* 123 */
+ {0x0FFE9090, 0xE0444E80, 0x1FBBB180, 0x0FBD8530, 0xF043EA20, 0x00000000}, /* 124 */
+ {0x0FFEEC90, 0xE043F180, 0x1FBC0E80, 0x0FBD8640, 0xF0438D30, 0x00000000}, /* 125 */
+ {0x0FFF4840, 0xE0439540, 0x1FBC6AC0, 0x0FBD86B0, 0xF0433100, 0x00000000}, /* 126 */
+ {0x0FFFA440, 0xE0433960, 0x1FBCC6A0, 0x0FBD86D0, 0xF042D510, 0x00000000}, /* 127 */
+ {0x10000000, 0xE042DE20, 0x1FBD21E0, 0x0FBD8640, 0xF04279C0, 0x00000000}, /* 128 */
+ {0x10005BC0, 0xE0428360, 0x1FBD7CA0, 0x0FBD8530, 0xF0421EF0, 0x00000000}, /* 129 */
+ {0x1000B7C0, 0xE04228C0, 0x1FBDD740, 0x0FBD83C0, 0xF041C490, 0x00000000}, /* 130 */
+ {0x10011380, 0xE041CF00, 0x1FBE3100, 0x0FBD81C0, 0xF0416AB0, 0x00000000}, /* 131 */
+ {0x10016F80, 0xE0417580, 0x1FBE8A80, 0x0FBD7F60, 0xF0411130, 0x00000000}, /* 132 */
+ {0x1001CB60, 0xE0411CA0, 0x1FBEE360, 0x0FBD7C60, 0xF040B850, 0x00000000}, /* 133 */
+ {0x10022760, 0xE040C400, 0x1FBF3C00, 0x0FBD78F0, 0xF0405FD0, 0x00000000}, /* 134 */
+ {0x10028320, 0xE0406C40, 0x1FBF93C0, 0x0FBD74F0, 0xF04007E0, 0x00000000}, /* 135 */
+ {0x1002DF40, 0xE04014A0, 0x1FBFEB60, 0x0FBD7080, 0xF03FB040, 0x00000000}, /* 136 */
+ {0x10033B40, 0xE03FBD80, 0x1FC04280, 0x0FBD6BA0, 0xF03F5930, 0x00000000}, /* 137 */
+ {0x10039720, 0xE03F6700, 0x1FC09900, 0x0FBD6620, 0xF03F02A0, 0x00000000}, /* 138 */
+ {0x1003F340, 0xE03F10E0, 0x1FC0EF20, 0x0FBD6030, 0xF03EAC80, 0x00000000}, /* 139 */
+ {0x10044F40, 0xE03EBB40, 0x1FC144C0, 0x0FBD59C0, 0xF03E56D0, 0x00000000}, /* 140 */
+ {0x1004ABA0, 0xE03E65C0, 0x1FC19A40, 0x0FBD5300, 0xF03E0180, 0x00000000}, /* 141 */
+ {0x100507C0, 0xE03E1120, 0x1FC1EEE0, 0x0FBD4B90, 0xF03DACC0, 0x00000000}, /* 142 */
+ {0x10056420, 0xE03DBCA0, 0x1FC24360, 0x0FBD43B0, 0xF03D5850, 0x00000000}, /* 143 */
+ {0x1005C040, 0xE03D68E0, 0x1FC29720, 0x0FBD3B40, 0xF03D0480, 0x00000000}, /* 144 */
+ {0x10061CA0, 0xE03D1560, 0x1FC2EAA0, 0x0FBD3260, 0xF03CB110, 0x00000000}, /* 145 */
+ {0x10067900, 0xE03CC260, 0x1FC33DA0, 0x0FBD2900, 0xF03C5E00, 0x00000000}, /* 146 */
+ {0x1006D560, 0xE03C6FE0, 0x1FC39020, 0x0FBD1F20, 0xF03C0B80, 0x00000000}, /* 147 */
+ {0x100731E0, 0xE03C1DE0, 0x1FC3E220, 0x0FBD14B0, 0xF03BB960, 0x00000000}, /* 148 */
+ {0x10078E80, 0xE03BCC00, 0x1FC43400, 0x0FBD09E0, 0xF03B67B0, 0x00000000}, /* 149 */
+ {0x1007EB00, 0xE03B7AC0, 0x1FC48540, 0x0FBCFE90, 0xF03B1660, 0x00000000}, /* 150 */
+ {0x100847C0, 0xE03B29E0, 0x1FC4D620, 0x0FBCF2C0, 0xF03AC580, 0x00000000}, /* 151 */
+ {0x1008A480, 0xE03AD9A0, 0x1FC52660, 0x0FBCE650, 0xF03A7530, 0x00000000}, /* 152 */
+ {0x10090160, 0xE03A8980, 0x1FC57680, 0x0FBCD980, 0xF03A2520, 0x00000000}, /* 153 */
+ {0x10095E40, 0xE03A3A20, 0x1FC5C5E0, 0x0FBCCC10, 0xF039D5B0, 0x00000000}, /* 154 */
+ {0x1009BB20, 0xE039EB00, 0x1FC61500, 0x0FBCBE40, 0xF0398690, 0x00000000}, /* 155 */
+ {0x100A1860, 0xE0399C20, 0x1FC663E0, 0x0FBCB000, 0xF03937D0, 0x00000000}, /* 156 */
+ {0x100A7560, 0xE0394E00, 0x1FC6B200, 0x0FBCA120, 0xF038E990, 0x00000000}, /* 157 */
+ {0x100AD2A0, 0xE0390020, 0x1FC6FFE0, 0x0FBC91C0, 0xF0389BB0, 0x00000000}, /* 158 */
+ {0x100B2FE0, 0xE038B2A0, 0x1FC74D60, 0x0FBC81E0, 0xF0384E40, 0x00000000}, /* 159 */
+ {0x100B8D60, 0xE0386580, 0x1FC79A80, 0x0FBC71A0, 0xF0380120, 0x00000000}, /* 160 */
+ {0x100BEAC0, 0xE0381900, 0x1FC7E700, 0x0FBC60A0, 0xF037B490, 0x00000000}, /* 161 */
+ {0x100C4880, 0xE037CCA0, 0x1FC83360, 0x0FBC4F70, 0xF0376840, 0x00000000}, /* 162 */
+ {0x100CA620, 0xE03780E0, 0x1FC87F20, 0x0FBC3D80, 0xF0371C70, 0x00000000}, /* 163 */
+ {0x100D03C0, 0xE0373560, 0x1FC8CAA0, 0x0FBC2B30, 0xF036D0F0, 0x00000000}, /* 164 */
+ {0x100D61A0, 0xE036EA60, 0x1FC915A0, 0x0FBC1850, 0xF0368600, 0x00000000}, /* 165 */
+ {0x100DBFA0, 0xE0369FE0, 0x1FC96020, 0x0FBC04E0, 0xF0363B70, 0x00000000}, /* 166 */
+ {0x100E1DC0, 0xE03655A0, 0x1FC9AA60, 0x0FBBF100, 0xF035F120, 0x00000000}, /* 167 */
+ {0x100E7C00, 0xE0360BA0, 0x1FC9F460, 0x0FBBDCC0, 0xF035A740, 0x00000000}, /* 168 */
+ {0x100EDA60, 0xE035C260, 0x1FCA3DA0, 0x0FBBC7C0, 0xF0355DE0, 0x00000000}, /* 169 */
+ {0x100F38C0, 0xE0357960, 0x1FCA86A0, 0x0FBBB260, 0xF03514D0, 0x00000000}, /* 170 */
+ {0x100F9760, 0xE0353080, 0x1FCACF80, 0x0FBB9C90, 0xF034CC10, 0x00000000}, /* 171 */
+ {0x100FF620, 0xE034E840, 0x1FCB17C0, 0x0FBB8630, 0xF03483D0, 0x00000000}, /* 172 */
+ {0x101054C0, 0xE034A060, 0x1FCB5FA0, 0x0FBB6F30, 0xF0343BF0, 0x00000000}, /* 173 */
+ {0x1010B3E0, 0xE03458E0, 0x1FCBA720, 0x0FBB57D0, 0xF033F470, 0x00000000}, /* 174 */
+ {0x101112E0, 0xE03411C0, 0x1FCBEE40, 0x0FBB3FE0, 0xF033AD40, 0x00000000}, /* 175 */
+ {0x101171E0, 0xE033CB20, 0x1FCC34E0, 0x0FBB2760, 0xF03366A0, 0x00000000}, /* 176 */
+ {0x1011D180, 0xE0338480, 0x1FCC7B80, 0x0FBB0E80, 0xF0332020, 0x00000000}, /* 177 */
+ {0x101230C0, 0xE0333EA0, 0x1FCCC160, 0x0FBAF4F0, 0xF032DA30, 0x00000000}, /* 178 */
+ {0x10129080, 0xE032F900, 0x1FCD0700, 0x0FBADB00, 0xF0329490, 0x00000000}, /* 179 */
+ {0x1012F040, 0xE032B3A0, 0x1FCD4C60, 0x0FBAC090, 0xF0324F40, 0x00000000}, /* 180 */
+ {0x10135020, 0xE0326EC0, 0x1FCD9140, 0x0FBAA590, 0xF0320A50, 0x00000000}, /* 181 */
+ {0x1013B040, 0xE0322A60, 0x1FCDD5A0, 0x0FBA89F0, 0xF031C5E0, 0x00000000}, /* 182 */
+ {0x10141060, 0xE031E640, 0x1FCE19C0, 0x0FBA6DF0, 0xF03181B0, 0x00000000}, /* 183 */
+ {0x101470E0, 0xE031A240, 0x1FCE5DC0, 0x0FBA5170, 0xF0313DD0, 0x00000000}, /* 184 */
+ {0x1014D160, 0xE0315EE0, 0x1FCEA120, 0x0FBA3450, 0xF030FA60, 0x00000000}, /* 185 */
+ {0x101531E0, 0xE0311BE0, 0x1FCEE420, 0x0FBA16B0, 0xF030B760, 0x00000000}, /* 186 */
+ {0x101592C0, 0xE030D940, 0x1FCF26C0, 0x0FB9F890, 0xF03074B0, 0x00000000}, /* 187 */
+ {0x1015F3C0, 0xE03096C0, 0x1FCF6940, 0x0FB9D9F0, 0xF0303240, 0x00000000}, /* 188 */
+ {0x10165500, 0xE03054C0, 0x1FCFAB40, 0x0FB9BAC0, 0xF02FF040, 0x00000000}, /* 189 */
+ {0x1016B660, 0xE0301320, 0x1FCFECE0, 0x0FB99B20, 0xF02FAE90, 0x00000000}, /* 190 */
+ {0x101717E0, 0xE02FD1E0, 0x1FD02E20, 0x0FB97AE0, 0xF02F6D50, 0x00000000}, /* 191 */
+ {0x101779A0, 0xE02F90E0, 0x1FD06F20, 0x0FB95A30, 0xF02F2C50, 0x00000000}, /* 192 */
+ {0x1017DB80, 0xE02F5020, 0x1FD0AFE0, 0x0FB93900, 0xF02EEBA0, 0x00000000}, /* 193 */
+ {0x10183DA0, 0xE02F0FE0, 0x1FD0F020, 0x0FB91730, 0xF02EAB60, 0x00000000}, /* 194 */
+ {0x10189FC0, 0xE02ED020, 0x1FD12FE0, 0x0FB8F4C0, 0xF02E6B70, 0x00000000}, /* 195 */
+ {0x10190240, 0xE02E9040, 0x1FD16FC0, 0x0FB8D210, 0xF02E2BD0, 0x00000000}, /* 196 */
+ {0x101964E0, 0xE02E5100, 0x1FD1AF00, 0x0FB8AEB0, 0xF02DEC90, 0x00000000}, /* 197 */
+ {0x1019C7A0, 0xE02E1240, 0x1FD1EDC0, 0x0FB88AB0, 0xF02DADB0, 0x00000000}, /* 198 */
+ {0x101A2AA0, 0xE02DD3C0, 0x1FD22C40, 0x0FB86640, 0xF02D6F20, 0x00000000}, /* 199 */
+ {0x101A8DE0, 0xE02D9560, 0x1FD26AA0, 0x0FB84150, 0xF02D30D0, 0x00000000}, /* 200 */
+ {0x101AF140, 0xE02D57A0, 0x1FD2A860, 0x0FB81BC0, 0xF02CF2F0, 0x00000000}, /* 201 */
+ {0x101B5500, 0xE02D19C0, 0x1FD2E640, 0x0FB7F5D0, 0xF02CB540, 0x00000000}, /* 202 */
+ {0x101BB8C0, 0xE02CDCC0, 0x1FD32340, 0x0FB7CF30, 0xF02C7810, 0x00000000}, /* 203 */
+ {0x101C1CC0, 0xE02C9FA0, 0x1FD36060, 0x0FB7A830, 0xF02C3B20, 0x00000000}, /* 204 */
+ {0x101C8120, 0xE02C6300, 0x1FD39D00, 0x0FB78070, 0xF02BFE70, 0x00000000}, /* 205 */
+ {0x101CE5A0, 0xE02C26A0, 0x1FD3D960, 0x0FB75850, 0xF02BC220, 0x00000000}, /* 206 */
+ {0x101D4A40, 0xE02BEAE0, 0x1FD41520, 0x0FB72F80, 0xF02B8640, 0x00000000}, /* 207 */
+ {0x101DAF20, 0xE02BAF40, 0x1FD450C0, 0x0FB70640, 0xF02B4AA0, 0x00000000}, /* 208 */
+ {0x101E1440, 0xE02B73E0, 0x1FD48C20, 0x0FB6DC70, 0xF02B0F40, 0x00000000}, /* 209 */
+ {0x101E79C0, 0xE02B38C0, 0x1FD4C740, 0x0FB6B220, 0xF02AD430, 0x00000000}, /* 210 */
+ {0x101EDF40, 0xE02AFE20, 0x1FD501E0, 0x0FB68730, 0xF02A9980, 0x00000000}, /* 211 */
+ {0x101F4520, 0xE02AC3C0, 0x1FD53C40, 0x0FB65BB0, 0xF02A5F20, 0x00000000}, /* 212 */
+ {0x101FAB60, 0xE02A89A0, 0x1FD57660, 0x0FB62FC0, 0xF02A2500, 0x00000000}, /* 213 */
+ {0x10201180, 0xE02A4FE0, 0x1FD5B020, 0x0FB60330, 0xF029EB50, 0x00000000}, /* 214 */
+ {0x10207820, 0xE02A1680, 0x1FD5E980, 0x0FB5D600, 0xF029B1D0, 0x00000000}, /* 215 */
+ {0x1020DEE0, 0xE029DD60, 0x1FD622A0, 0x0FB5A860, 0xF02978B0, 0x00000000}, /* 216 */
+ {0x10214600, 0xE029A460, 0x1FD65BA0, 0x0FB57A30, 0xF0293FD0, 0x00000000}, /* 217 */
+ {0x1021AD60, 0xE0296BC0, 0x1FD69440, 0x0FB54B80, 0xF0290730, 0x00000000}, /* 218 */
+ {0x10221500, 0xE02933A0, 0x1FD6CC60, 0x0FB51C30, 0xF028CEF0, 0x00000000}, /* 219 */
+ {0x10227CC0, 0xE028FBA0, 0x1FD70460, 0x0FB4EC40, 0xF0289700, 0x00000000}, /* 220 */
+ {0x1022E4E0, 0xE028C400, 0x1FD73C00, 0x0FB4BBE0, 0xF0285F60, 0x00000000}, /* 221 */
+ {0x10234D20, 0xE0288CC0, 0x1FD77340, 0x0FB48AD0, 0xF0282810, 0x00000000}, /* 222 */
+ {0x1023B5E0, 0xE0285580, 0x1FD7AA80, 0x0FB45940, 0xF027F0F0, 0x00000000}, /* 223 */
+ {0x10241EC0, 0xE0281EE0, 0x1FD7E120, 0x0FB42720, 0xF027BA30, 0x00000000}, /* 224 */
+ {0x102487C0, 0xE027E860, 0x1FD817A0, 0x0FB3F470, 0xF02783C0, 0x00000000}, /* 225 */
+ {0x1024F140, 0xE027B220, 0x1FD84DE0, 0x0FB3C130, 0xF0274D90, 0x00000000}, /* 226 */
+ {0x10255B00, 0xE0277C60, 0x1FD883A0, 0x0FB38D40, 0xF02717B0, 0x00000000}, /* 227 */
+ {0x1025C500, 0xE02746A0, 0x1FD8B960, 0x0FB358F0, 0xF026E200, 0x00000000}, /* 228 */
+ {0x10262F40, 0xE0271160, 0x1FD8EEA0, 0x0FB323F0, 0xF026ACD0, 0x00000000}, /* 229 */
+ {0x102699E0, 0xE026DC80, 0x1FD92380, 0x0FB2EE60, 0xF02677C0, 0x00000000}, /* 230 */
+ {0x102704C0, 0xE026A7C0, 0x1FD95840, 0x0FB2B840, 0xF0264300, 0x00000000}, /* 231 */
+ {0x10276FE0, 0xE0267320, 0x1FD98CE0, 0x0FB28190, 0xF0260E80, 0x00000000}, /* 232 */
+ {0x1027DB60, 0xE0263EE0, 0x1FD9C120, 0x0FB24A60, 0xF025DA40, 0x00000000}, /* 233 */
+ {0x10284740, 0xE0260AE0, 0x1FD9F520, 0x0FB21290, 0xF025A650, 0x00000000}, /* 234 */
+ {0x1028B340, 0xE025D760, 0x1FDA28A0, 0x0FB1DA10, 0xF02572C0, 0x00000000}, /* 235 */
+ {0x10291F80, 0xE025A420, 0x1FDA5BE0, 0x0FB1A100, 0xF0253F60, 0x00000000}, /* 236 */
+ {0x10298C40, 0xE02570E0, 0x1FDA8F20, 0x0FB16780, 0xF0250C40, 0x00000000}, /* 237 */
+ {0x1029F960, 0xE0253E00, 0x1FDAC200, 0x0FB12D50, 0xF024D970, 0x00000000}, /* 238 */
+ {0x102A66A0, 0xE0250B80, 0x1FDAF480, 0x0FB0F280, 0xF024A6E0, 0x00000000}, /* 239 */
+ {0x102AD440, 0xE024D940, 0x1FDB26C0, 0x0FB0B730, 0xF02474A0, 0x00000000}, /* 240 */
+ {0x102B4220, 0xE024A760, 0x1FDB58A0, 0x0FB07B20, 0xF02442B0, 0x00000000}, /* 241 */
+ {0x102BB060, 0xE02475A0, 0x1FDB8A60, 0x0FB03EA0, 0xF02410F0, 0x00000000}, /* 242 */
+ {0x102C1F40, 0xE0244400, 0x1FDBBC00, 0x0FB00180, 0xF023DF60, 0x00000000}, /* 243 */
+ {0x102C8E00, 0xE0241300, 0x1FDBED00, 0x0FAFC3B0, 0xF023AE40, 0x00000000}, /* 244 */
+ {0x102CFD60, 0xE023E1E0, 0x1FDC1E20, 0x0FAF8560, 0xF0237D40, 0x00000000}, /* 245 */
+ {0x102D6CE0, 0xE023B160, 0x1FDC4EA0, 0x0FAF4670, 0xF0234C90, 0x00000000}, /* 246 */
+ {0x102DDD00, 0xE02380C0, 0x1FDC7F40, 0x0FAF0700, 0xF0231C20, 0x00000000}, /* 247 */
+ {0x102E4D40, 0xE02350A0, 0x1FDCAF60, 0x0FAEC6C0, 0xF022EC00, 0x00000000}, /* 248 */
+ {0x102EBDE0, 0xE02320E0, 0x1FDCDF20, 0x0FAE8600, 0xF022BC10, 0x00000000}, /* 249 */
+ {0x102F2F00, 0xE022F100, 0x1FDD0F00, 0x0FAE44C0, 0xF0228C60, 0x00000000}, /* 250 */
+ {0x102FA040, 0xE022C1A0, 0x1FDD3E60, 0x0FAE02C0, 0xF0225CF0, 0x00000000}, /* 251 */
+ {0x10301220, 0xE0229280, 0x1FDD6D80, 0x0FADC020, 0xF0222DD0, 0x00000000}, /* 252 */
+ {0x10308420, 0xE02263C0, 0x1FDD9C40, 0x0FAD7CE0, 0xF021FF00, 0x00000000}, /* 253 */
+ {0x1030F680, 0xE0223520, 0x1FDDCAE0, 0x0FAD3910, 0xF021D050, 0x00000000}, /* 254 */
+ {0x10316960, 0xE02206C0, 0x1FDDF940, 0x0FACF4A0, 0xF021A1F0, 0x00000000}, /* 255 */
+ {0x1031DCA0, 0xE021D860, 0x1FDE27A0, 0x0FACAFB0, 0xF02173B0, 0x00000000}, /* 256 */
+ {0, 0, 0, 0, 0, 0}
+};
+
+static const unsigned int eq_band2_data[][6] = {
+ {0x0E210CA0, 0xE52A2D20, 0x1AD5D2E0, 0x0CDFB8A0, 0xF4FF3AC0, 0x00000000}, /* 0 */
+ {0x0E24F640, 0xE52465C0, 0x1ADB9A40, 0x0CE19F90, 0xF4F96A30, 0x00000000}, /* 1 */
+ {0x0E28DE90, 0xE51EA3E0, 0x1AE15C20, 0x0CE38250, 0xF4F39F20, 0x00000000}, /* 2 */
+ {0x0E2CC590, 0xE518E7A0, 0x1AE71860, 0x0CE560D0, 0xF4EDD990, 0x00000000}, /* 3 */
+ {0x0E30AB40, 0xE51330C0, 0x1AECCF40, 0x0CE73B20, 0xF4E81990, 0x00000000}, /* 4 */
+ {0x0E348FD0, 0xE50D7F20, 0x1AF280E0, 0x0CE91130, 0xF4E25F00, 0x00000000}, /* 5 */
+ {0x0E387300, 0xE507D340, 0x1AF82CC0, 0x0CEAE310, 0xF4DCAA00, 0x00000000}, /* 6 */
+ {0x0E3C5500, 0xE5022CC0, 0x1AFDD340, 0x0CECB0B0, 0xF4D6FA60, 0x00000000}, /* 7 */
+ {0x0E4035B0, 0xE4FC8BA0, 0x1B037460, 0x0CEE7A00, 0xF4D15050, 0x00000000}, /* 8 */
+ {0x0E441530, 0xE4F6F000, 0x1B091000, 0x0CF03F30, 0xF4CBABA0, 0x00000000}, /* 9 */
+ {0x0E47F380, 0xE4F159C0, 0x1B0EA640, 0x0CF20020, 0xF4C60C80, 0x00000000}, /* 10 */
+ {0x0E4BD090, 0xE4EBC8E0, 0x1B143720, 0x0CF3BCC0, 0xF4C072C0, 0x00000000}, /* 11 */
+ {0x0E4FAC70, 0xE4E63D80, 0x1B19C280, 0x0CF57530, 0xF4BADE70, 0x00000000}, /* 12 */
+ {0x0E538720, 0xE4E0B760, 0x1B1F48A0, 0x0CF72950, 0xF4B54F80, 0x00000000}, /* 13 */
+ {0x0E5760D0, 0xE4DB36C0, 0x1B24C940, 0x0CF8D940, 0xF4AFC600, 0x00000000}, /* 14 */
+ {0x0E5B3920, 0xE4D5BB60, 0x1B2A44A0, 0x0CFA84E0, 0xF4AA41E0, 0x00000000}, /* 15 */
+ {0x0E5F1070, 0xE4D04580, 0x1B2FBA80, 0x0CFC2C50, 0xF4A4C340, 0x00000000}, /* 16 */
+ {0x0E62E690, 0xE4CAD4C0, 0x1B352B40, 0x0CFDCF80, 0xF49F49F0, 0x00000000}, /* 17 */
+ {0x0E66BBA0, 0xE4C569A0, 0x1B3A9660, 0x0CFF6E60, 0xF499D5F0, 0x00000000}, /* 18 */
+ {0x0E6A8FC0, 0xE4C00380, 0x1B3FFC80, 0x0D010900, 0xF4946750, 0x00000000}, /* 19 */
+ {0x0E6E6290, 0xE4BAA2E0, 0x1B455D20, 0x0D029F60, 0xF48EFE10, 0x00000000}, /* 20 */
+ {0x0E723470, 0xE4B54780, 0x1B4AB880, 0x0D043170, 0xF4899A20, 0x00000000}, /* 21 */
+ {0x0E760530, 0xE4AFF1A0, 0x1B500E60, 0x0D05BF30, 0xF4843BA0, 0x00000000}, /* 22 */
+ {0x0E79D4F0, 0xE4AAA0C0, 0x1B555F40, 0x0D0748C0, 0xF47EE240, 0x00000000}, /* 23 */
+ {0x0E7DA3C0, 0xE4A55520, 0x1B5AAAE0, 0x0D08CE10, 0xF4798E50, 0x00000000}, /* 24 */
+ {0x0E817160, 0xE4A00F20, 0x1B5FF0E0, 0x0D0A4EE0, 0xF4743FB0, 0x00000000}, /* 25 */
+ {0x0E853E30, 0xE49ACE00, 0x1B653200, 0x0D0BCBA0, 0xF46EF630, 0x00000000}, /* 26 */
+ {0x0E8909D0, 0xE4959240, 0x1B6A6DC0, 0x0D0D4400, 0xF469B220, 0x00000000}, /* 27 */
+ {0x0E8CD4A0, 0xE4905BC0, 0x1B6FA440, 0x0D0EB820, 0xF4647340, 0x00000000}, /* 28 */
+ {0x0E909E80, 0xE48B2A80, 0x1B74D580, 0x0D1027E0, 0xF45F3990, 0x00000000}, /* 29 */
+ {0x0E946770, 0xE485FE40, 0x1B7A01C0, 0x0D119370, 0xF45A0530, 0x00000000}, /* 30 */
+ {0x0E982F70, 0xE480D760, 0x1B7F28A0, 0x0D12FA90, 0xF454D600, 0x00000000}, /* 31 */
+ {0x0E9BF680, 0xE47BB580, 0x1B844A80, 0x0D145D80, 0xF44FAC10, 0x00000000}, /* 32 */
+ {0x0E9FBCA0, 0xE4769920, 0x1B8966E0, 0x0D15BC00, 0xF44A8760, 0x00000000}, /* 33 */
+ {0x0EA381E0, 0xE47181C0, 0x1B8E7E40, 0x0D171640, 0xF44567C0, 0x00000000}, /* 34 */
+ {0x0EA74660, 0xE46C6F40, 0x1B9390C0, 0x0D186C50, 0xF4404D60, 0x00000000}, /* 35 */
+ {0x0EAB0A10, 0xE4676220, 0x1B989DE0, 0x0D19BDE0, 0xF43B3820, 0x00000000}, /* 36 */
+ {0x0EAECCB0, 0xE4625A40, 0x1B9DA5C0, 0x0D1B0B20, 0xF4362810, 0x00000000}, /* 37 */
+ {0x0EB28EC0, 0xE45D5740, 0x1BA2A8C0, 0x0D1C5420, 0xF4311D20, 0x00000000}, /* 38 */
+ {0x0EB64FE0, 0xE4585980, 0x1BA7A680, 0x0D1D98D0, 0xF42C1760, 0x00000000}, /* 39 */
+ {0x0EBA1030, 0xE45360C0, 0x1BAC9F40, 0x0D1ED910, 0xF42716B0, 0x00000000}, /* 40 */
+ {0x0EBDCFE0, 0xE44E6D20, 0x1BB192E0, 0x0D201510, 0xF4221B20, 0x00000000}, /* 41 */
+ {0x0EC18EA0, 0xE4497EA0, 0x1BB68160, 0x0D214CA0, 0xF41D24B0, 0x00000000}, /* 42 */
+ {0x0EC54CD0, 0xE4449500, 0x1BBB6B00, 0x0D228000, 0xF4183340, 0x00000000}, /* 43 */
+ {0x0EC90A20, 0xE43FB0A0, 0x1BC04F60, 0x0D23AED0, 0xF4134700, 0x00000000}, /* 44 */
+ {0x0ECCC6D0, 0xE43AD120, 0x1BC52EE0, 0x0D24D970, 0xF40E5FC0, 0x00000000}, /* 45 */
+ {0x0ED082E0, 0xE435F6A0, 0x1BCA0960, 0x0D25FFB0, 0xF4097D80, 0x00000000}, /* 46 */
+ {0x0ED43E10, 0xE4312140, 0x1BCEDEC0, 0x0D272190, 0xF404A050, 0x00000000}, /* 47 */
+ {0x0ED7F8D0, 0xE42C50C0, 0x1BD3AF40, 0x0D283F10, 0xF3FFC830, 0x00000000}, /* 48 */
+ {0x0EDBB2C0, 0xE4278560, 0x1BD87AA0, 0x0D295830, 0xF3FAF510, 0x00000000}, /* 49 */
+ {0x0EDF6C20, 0xE422BEC0, 0x1BDD4140, 0x0D2A6D00, 0xF3F626E0, 0x00000000}, /* 50 */
+ {0x0EE324F0, 0xE41DFD40, 0x1BE202C0, 0x0D2B7D60, 0xF3F15DB0, 0x00000000}, /* 51 */
+ {0x0EE6DCF0, 0xE41940C0, 0x1BE6BF40, 0x0D2C8960, 0xF3EC99A0, 0x00000000}, /* 52 */
+ {0x0EEA94A0, 0xE4148900, 0x1BEB7700, 0x0D2D9110, 0xF3E7DA50, 0x00000000}, /* 53 */
+ {0x0EEE4BB0, 0xE40FD620, 0x1BF029E0, 0x0D2E9460, 0xF3E32010, 0x00000000}, /* 54 */
+ {0x0EF20220, 0xE40B2880, 0x1BF4D780, 0x0D2F9320, 0xF3DE6AC0, 0x00000000}, /* 55 */
+ {0x0EF5B820, 0xE4067F60, 0x1BF980A0, 0x0D308DB0, 0xF3D9BA40, 0x00000000}, /* 56 */
+ {0x0EF96D70, 0xE401DB60, 0x1BFE24A0, 0x0D3183C0, 0xF3D50ED0, 0x00000000}, /* 57 */
+ {0x0EFD2270, 0xE3FD3C20, 0x1C02C3E0, 0x0D327570, 0xF3D06820, 0x00000000}, /* 58 */
+ {0x0F00D6E0, 0xE3F8A1E0, 0x1C075E20, 0x0D3362B0, 0xF3CBC670, 0x00000000}, /* 59 */
+ {0x0F048AE0, 0xE3F40C40, 0x1C0BF3C0, 0x0D344B90, 0xF3C72990, 0x00000000}, /* 60 */
+ {0x0F083E70, 0xE3EF7B80, 0x1C108480, 0x0D353010, 0xF3C29190, 0x00000000}, /* 61 */
+ {0x0F0BF180, 0xE3EAEFC0, 0x1C151040, 0x0D361000, 0xF3BDFE60, 0x00000000}, /* 62 */
+ {0x0F0FA440, 0xE3E668A0, 0x1C199760, 0x0D36EBA0, 0xF3B97010, 0x00000000}, /* 63 */
+ {0x0F135680, 0xE3E1E640, 0x1C1E19C0, 0x0D37C2E0, 0xF3B4E690, 0x00000000}, /* 64 */
+ {0x0F170890, 0xE3DD68C0, 0x1C229740, 0x0D3895B0, 0xF3B061E0, 0x00000000}, /* 65 */
+ {0x0F1ABA10, 0xE3D8F000, 0x1C271000, 0x0D396400, 0xF3ABE1F0, 0x00000000}, /* 66 */
+ {0x0F1E6B40, 0xE3D47C00, 0x1C2B8400, 0x0D3A2DE0, 0xF3A766E0, 0x00000000}, /* 67 */
+ {0x0F221C30, 0xE3D00CC0, 0x1C2FF340, 0x0D3AF360, 0xF3A2F080, 0x00000000}, /* 68 */
+ {0x0F25CCE0, 0xE3CBA220, 0x1C345DE0, 0x0D3BB460, 0xF39E7ED0, 0x00000000}, /* 69 */
+ {0x0F297D30, 0xE3C73C60, 0x1C38C3A0, 0x0D3C70F0, 0xF39A1200, 0x00000000}, /* 70 */
+ {0x0F2D2D20, 0xE3C2DB40, 0x1C3D24C0, 0x0D3D28F0, 0xF395A9E0, 0x00000000}, /* 71 */
+ {0x0F30DD00, 0xE3BE7EC0, 0x1C418140, 0x0D3DDCA0, 0xF3914660, 0x00000000}, /* 72 */
+ {0x0F348C70, 0xE3BA2700, 0x1C45D900, 0x0D3E8BD0, 0xF38CE7A0, 0x00000000}, /* 73 */
+ {0x0F383BC0, 0xE3B5D3E0, 0x1C4A2C20, 0x0D3F3680, 0xF3888DB0, 0x00000000}, /* 74 */
+ {0x0F3BEAF0, 0xE3B18580, 0x1C4E7A80, 0x0D3FDCC0, 0xF3843850, 0x00000000}, /* 75 */
+ {0x0F3F99E0, 0xE3AD3BA0, 0x1C52C460, 0x0D407E80, 0xF37FE7A0, 0x00000000}, /* 76 */
+ {0x0F4348B0, 0xE3A8F660, 0x1C5709A0, 0x0D411BD0, 0xF37B9B90, 0x00000000}, /* 77 */
+ {0x0F46F750, 0xE3A4B5C0, 0x1C5B4A40, 0x0D41B490, 0xF3775420, 0x00000000}, /* 78 */
+ {0x0F4AA5E0, 0xE3A079A0, 0x1C5F8660, 0x0D4248F0, 0xF3731150, 0x00000000}, /* 79 */
+ {0x0F4E5430, 0xE39C4260, 0x1C63BDA0, 0x0D42D8A0, 0xF36ED330, 0x00000000}, /* 80 */
+ {0x0F520280, 0xE3980F60, 0x1C67F0A0, 0x0D436400, 0xF36A9980, 0x00000000}, /* 81 */
+ {0x0F55B0B0, 0xE393E120, 0x1C6C1EE0, 0x0D43EAB0, 0xF3666480, 0x00000000}, /* 82 */
+ {0x0F595F00, 0xE38FB740, 0x1C7048C0, 0x0D446D10, 0xF3623410, 0x00000000}, /* 83 */
+ {0x0F5D0D10, 0xE38B9200, 0x1C746E00, 0x0D44EAC0, 0xF35E0830, 0x00000000}, /* 84 */
+ {0x0F60BB40, 0xE3877140, 0x1C788EC0, 0x0D456400, 0xF359E0D0, 0x00000000}, /* 85 */
+ {0x0F646950, 0xE3835500, 0x1C7CAB00, 0x0D45D8C0, 0xF355BE00, 0x00000000}, /* 86 */
+ {0x0F681760, 0xE37F3D60, 0x1C80C2A0, 0x0D4648D0, 0xF3519FB0, 0x00000000}, /* 87 */
+ {0x0F6BC5B0, 0xE37B2A00, 0x1C84D600, 0x0D46B480, 0xF34D85E0, 0x00000000}, /* 88 */
+ {0x0F6F73E0, 0xE3771B20, 0x1C88E4E0, 0x0D471B90, 0xF3497090, 0x00000000}, /* 89 */
+ {0x0F732220, 0xE37310E0, 0x1C8CEF20, 0x0D477E10, 0xF3455FB0, 0x00000000}, /* 90 */
+ {0x0F76D0B0, 0xE36F0AC0, 0x1C90F540, 0x0D47DC10, 0xF3415340, 0x00000000}, /* 91 */
+ {0x0F7A7F40, 0xE36B0940, 0x1C94F6C0, 0x0D483580, 0xF33D4B60, 0x00000000}, /* 92 */
+ {0x0F7E2DD0, 0xE3670C20, 0x1C98F3E0, 0x0D488A50, 0xF33947D0, 0x00000000}, /* 93 */
+ {0x0F81DCB0, 0xE3631360, 0x1C9CECA0, 0x0D48DA90, 0xF33548C0, 0x00000000}, /* 94 */
+ {0x0F858BB0, 0xE35F1F00, 0x1CA0E100, 0x0D492650, 0xF3314E10, 0x00000000}, /* 95 */
+ {0x0F893AD0, 0xE35B2F20, 0x1CA4D0E0, 0x0D496D60, 0xF32D57D0, 0x00000000}, /* 96 */
+ {0x0F8CEA50, 0xE3574360, 0x1CA8BCA0, 0x0D49AFF0, 0xF32965D0, 0x00000000}, /* 97 */
+ {0x0F9099E0, 0xE3535C20, 0x1CACA3E0, 0x0D49EDE0, 0xF3257840, 0x00000000}, /* 98 */
+ {0x0F9449D0, 0xE34F7920, 0x1CB086E0, 0x0D4A2720, 0xF3218F10, 0x00000000}, /* 99 */
+ {0x0F97F9F0, 0xE34B9A60, 0x1CB465A0, 0x0D4A5BE0, 0xF31DAA30, 0x00000000}, /* 100 */
+ {0x0F9BAA70, 0xE347C020, 0x1CB83FE0, 0x0D4A8BF0, 0xF319C9A0, 0x00000000}, /* 101 */
+ {0x0F9F5B40, 0xE343E9E0, 0x1CBC1620, 0x0D4AB770, 0xF315ED60, 0x00000000}, /* 102 */
+ {0x0FA30C60, 0xE3401800, 0x1CBFE800, 0x0D4ADE50, 0xF3121570, 0x00000000}, /* 103 */
+ {0x0FA6BDB0, 0xE33C4A80, 0x1CC3B580, 0x0D4B0080, 0xF30E41C0, 0x00000000}, /* 104 */
+ {0x0FAA6F90, 0xE3388140, 0x1CC77EC0, 0x0D4B1E00, 0xF30A7260, 0x00000000}, /* 105 */
+ {0x0FAE21B0, 0xE334BC20, 0x1CCB43E0, 0x0D4B3700, 0xF306A740, 0x00000000}, /* 106 */
+ {0x0FB1D460, 0xE330FB40, 0x1CCF04C0, 0x0D4B4B40, 0xF302E060, 0x00000000}, /* 107 */
+ {0x0FB58770, 0xE32D3E80, 0x1CD2C180, 0x0D4B5AE0, 0xF2FF1DB0, 0x00000000}, /* 108 */
+ {0x0FB93B00, 0xE3298600, 0x1CD67A00, 0x0D4B65D0, 0xF2FB5F30, 0x00000000}, /* 109 */
+ {0x0FBCEEF0, 0xE325D1C0, 0x1CDA2E40, 0x0D4B6C10, 0xF2F7A4F0, 0x00000000}, /* 110 */
+ {0x0FC0A390, 0xE3222180, 0x1CDDDE80, 0x0D4B6DB0, 0xF2F3EED0, 0x00000000}, /* 111 */
+ {0x0FC45880, 0xE31E7560, 0x1CE18AA0, 0x0D4B6A90, 0xF2F03CF0, 0x00000000}, /* 112 */
+ {0x0FC80E10, 0xE31ACD80, 0x1CE53280, 0x0D4B62D0, 0xF2EC8F30, 0x00000000}, /* 113 */
+ {0x0FCBC420, 0xE31729C0, 0x1CE8D640, 0x0D4B5640, 0xF2E8E5A0, 0x00000000}, /* 114 */
+ {0x0FCF7AE0, 0xE3138A20, 0x1CEC75E0, 0x0D4B4510, 0xF2E54020, 0x00000000}, /* 115 */
+ {0x0FD33210, 0xE30FEE80, 0x1CF01180, 0x0D4B2F20, 0xF2E19EC0, 0x00000000}, /* 116 */
+ {0x0FD6E9F0, 0xE30C5700, 0x1CF3A900, 0x0D4B1470, 0xF2DE0180, 0x00000000}, /* 117 */
+ {0x0FDAA2A0, 0xE308C380, 0x1CF73C80, 0x0D4AF520, 0xF2DA6860, 0x00000000}, /* 118 */
+ {0x0FDE5BC0, 0xE3053440, 0x1CFACBC0, 0x0D4AD0F0, 0xF2D6D340, 0x00000000}, /* 119 */
+ {0x0FE215A0, 0xE301A8E0, 0x1CFE5720, 0x0D4AA820, 0xF2D34240, 0x00000000}, /* 120 */
+ {0x0FE5D030, 0xE2FE2180, 0x1D01DE80, 0x0D4A7A70, 0xF2CFB550, 0x00000000}, /* 121 */
+ {0x0FE98B90, 0xE2FA9E20, 0x1D0561E0, 0x0D4A4820, 0xF2CC2C40, 0x00000000}, /* 122 */
+ {0x0FED47A0, 0xE2F71EE0, 0x1D08E120, 0x0D4A1100, 0xF2C8A760, 0x00000000}, /* 123 */
+ {0x0FF10480, 0xE2F3A380, 0x1D0C5C80, 0x0D49D510, 0xF2C52670, 0x00000000}, /* 124 */
+ {0x0FF4C220, 0xE2F02C00, 0x1D0FD400, 0x0D499460, 0xF2C1A990, 0x00000000}, /* 125 */
+ {0x0FF88090, 0xE2ECB8C0, 0x1D134740, 0x0D494ED0, 0xF2BE30A0, 0x00000000}, /* 126 */
+ {0x0FFC3FD0, 0xE2E94940, 0x1D16B6C0, 0x0D490480, 0xF2BABBB0, 0x00000000}, /* 127 */
+ {0x10000000, 0xE2E5DDC0, 0x1D1A2240, 0x0D48B550, 0xF2B74AB0, 0x00000000}, /* 128 */
+ {0x1003C120, 0xE2E27600, 0x1D1D8A00, 0x0D486170, 0xF2B3DD80, 0x00000000}, /* 129 */
+ {0x10078300, 0xE2DF1260, 0x1D20EDA0, 0x0D4808A0, 0xF2B07460, 0x00000000}, /* 130 */
+ {0x100B45C0, 0xE2DBB260, 0x1D244DA0, 0x0D47AB10, 0xF2AD0F10, 0x00000000}, /* 131 */
+ {0x100F09A0, 0xE2D85680, 0x1D27A980, 0x0D4748A0, 0xF2A9ADC0, 0x00000000}, /* 132 */
+ {0x1012CE60, 0xE2D4FE60, 0x1D2B01A0, 0x0D46E150, 0xF2A65050, 0x00000000}, /* 133 */
+ {0x10169420, 0xE2D1AA00, 0x1D2E5600, 0x0D467530, 0xF2A2F6B0, 0x00000000}, /* 134 */
+ {0x101A5B00, 0xE2CE59A0, 0x1D31A660, 0x0D460420, 0xF29FA100, 0x00000000}, /* 135 */
+ {0x101E22C0, 0xE2CB0D00, 0x1D34F300, 0x0D458E40, 0xF29C4F10, 0x00000000}, /* 136 */
+ {0x1021EBA0, 0xE2C7C440, 0x1D383BC0, 0x0D451370, 0xF2990100, 0x00000000}, /* 137 */
+ {0x1025B580, 0xE2C47F40, 0x1D3B80C0, 0x0D4493C0, 0xF295B6D0, 0x00000000}, /* 138 */
+ {0x102980A0, 0xE2C13DE0, 0x1D3EC220, 0x0D440F30, 0xF2927040, 0x00000000}, /* 139 */
+ {0x102D4CC0, 0xE2BE0060, 0x1D41FFA0, 0x0D4385B0, 0xF28F2DA0, 0x00000000}, /* 140 */
+ {0x10311A00, 0xE2BAC6E0, 0x1D453920, 0x0D42F720, 0xF28BEED0, 0x00000000}, /* 141 */
+ {0x1034E8A0, 0xE2B790E0, 0x1D486F20, 0x0D4263C0, 0xF288B3B0, 0x00000000}, /* 142 */
+ {0x1038B840, 0xE2B45E80, 0x1D4BA180, 0x0D41CB70, 0xF2857C40, 0x00000000}, /* 143 */
+ {0x103C8920, 0xE2B13020, 0x1D4ECFE0, 0x0D412E20, 0xF28248B0, 0x00000000}, /* 144 */
+ {0x10405B40, 0xE2AE0540, 0x1D51FAC0, 0x0D408BE0, 0xF27F18C0, 0x00000000}, /* 145 */
+ {0x10442EE0, 0xE2AADDE0, 0x1D552220, 0x0D3FE4C0, 0xF27BEC70, 0x00000000}, /* 146 */
+ {0x10480380, 0xE2A7BA60, 0x1D5845A0, 0x0D3F3890, 0xF278C3F0, 0x00000000}, /* 147 */
+ {0x104BD9A0, 0xE2A49AA0, 0x1D5B6560, 0x0D3E8750, 0xF2759F20, 0x00000000}, /* 148 */
+ {0x104FB100, 0xE2A17E60, 0x1D5E81A0, 0x0D3DD120, 0xF2727DF0, 0x00000000}, /* 149 */
+ {0x105389A0, 0xE29E6600, 0x1D619A00, 0x0D3D15D0, 0xF26F6080, 0x00000000}, /* 150 */
+ {0x105763C0, 0xE29B5100, 0x1D64AF00, 0x0D3C55A0, 0xF26C46A0, 0x00000000}, /* 151 */
+ {0x105B3F60, 0xE2983F80, 0x1D67C080, 0x0D3B9060, 0xF2693050, 0x00000000}, /* 152 */
+ {0x105F1C20, 0xE2953200, 0x1D6ACE00, 0x0D3AC5F0, 0xF2661DC0, 0x00000000}, /* 153 */
+ {0x1062FAA0, 0xE29227C0, 0x1D6DD840, 0x0D39F6A0, 0xF2630EC0, 0x00000000}, /* 154 */
+ {0x1066DA80, 0xE28F2140, 0x1D70DEC0, 0x0D392230, 0xF2600340, 0x00000000}, /* 155 */
+ {0x106ABC00, 0xE28C1E20, 0x1D73E1E0, 0x0D3848B0, 0xF25CFB60, 0x00000000}, /* 156 */
+ {0x106E9EE0, 0xE2891EA0, 0x1D76E160, 0x0D376A00, 0xF259F710, 0x00000000}, /* 157 */
+ {0x10728360, 0xE2862280, 0x1D79DD80, 0x0D368650, 0xF256F640, 0x00000000}, /* 158 */
+ {0x10766960, 0xE2832A20, 0x1D7CD5E0, 0x0D359D70, 0xF253F910, 0x00000000}, /* 159 */
+ {0x107A5140, 0xE2803500, 0x1D7FCB00, 0x0D34AF90, 0xF250FF60, 0x00000000}, /* 160 */
+ {0x107E3A60, 0xE27D43A0, 0x1D82BC60, 0x0D33BC70, 0xF24E0920, 0x00000000}, /* 161 */
+ {0x10822560, 0xE27A55A0, 0x1D85AA60, 0x0D32C430, 0xF24B1680, 0x00000000}, /* 162 */
+ {0x10861200, 0xE2776B00, 0x1D889500, 0x0D31C6D0, 0xF2482730, 0x00000000}, /* 163 */
+ {0x108A0040, 0xE2748400, 0x1D8B7C00, 0x0D30C430, 0xF2453B80, 0x00000000}, /* 164 */
+ {0x108DF060, 0xE271A040, 0x1D8E5FC0, 0x0D2FBC70, 0xF2425330, 0x00000000}, /* 165 */
+ {0x1091E240, 0xE26EBFE0, 0x1D914020, 0x0D2EAF90, 0xF23F6E50, 0x00000000}, /* 166 */
+ {0x1095D5C0, 0xE26BE320, 0x1D941CE0, 0x0D2D9D60, 0xF23C8CE0, 0x00000000}, /* 167 */
+ {0x1099CB20, 0xE26909C0, 0x1D96F640, 0x0D2C8600, 0xF239AEF0, 0x00000000}, /* 168 */
+ {0x109DC260, 0xE2663380, 0x1D99CC80, 0x0D2B6970, 0xF236D440, 0x00000000}, /* 169 */
+ {0x10A1BB60, 0xE26360E0, 0x1D9C9F20, 0x0D2A4790, 0xF233FD00, 0x00000000}, /* 170 */
+ {0x10A5B660, 0xE2609180, 0x1D9F6E80, 0x0D292070, 0xF2312930, 0x00000000}, /* 171 */
+ {0x10A9B340, 0xE25DC5A0, 0x1DA23A60, 0x0D27F410, 0xF22E58B0, 0x00000000}, /* 172 */
+ {0x10ADB1E0, 0xE25AFD00, 0x1DA50300, 0x0D26C260, 0xF22B8B90, 0x00000000}, /* 173 */
+ {0x10B1B2C0, 0xE2583780, 0x1DA7C880, 0x0D258B90, 0xF228C1C0, 0x00000000}, /* 174 */
+ {0x10B5B580, 0xE2557560, 0x1DAA8AA0, 0x0D244F50, 0xF225FB40, 0x00000000}, /* 175 */
+ {0x10B9BA40, 0xE252B6C0, 0x1DAD4940, 0x0D230DB0, 0xF2233820, 0x00000000}, /* 176 */
+ {0x10BDC0E0, 0xE24FFB20, 0x1DB004E0, 0x0D21C6D0, 0xF2207840, 0x00000000}, /* 177 */
+ {0x10C1C9C0, 0xE24D4300, 0x1DB2BD00, 0x0D207A80, 0xF21DBBC0, 0x00000000}, /* 178 */
+ {0x10C5D4A0, 0xE24A8E00, 0x1DB57200, 0x0D1F28E0, 0xF21B0260, 0x00000000}, /* 179 */
+ {0x10C9E1C0, 0xE247DC40, 0x1DB823C0, 0x0D1DD1F0, 0xF2184C60, 0x00000000}, /* 180 */
+ {0x10CDF0E0, 0xE2452DC0, 0x1DBAD240, 0x0D1C7590, 0xF2159980, 0x00000000}, /* 181 */
+ {0x10D20240, 0xE2428260, 0x1DBD7DA0, 0x0D1B13D0, 0xF212E9F0, 0x00000000}, /* 182 */
+ {0x10D615C0, 0xE23FDA40, 0x1DC025C0, 0x0D19ACB0, 0xF2103D90, 0x00000000}, /* 183 */
+ {0x10DA2B80, 0xE23D3560, 0x1DC2CAA0, 0x0D184010, 0xF20D9470, 0x00000000}, /* 184 */
+ {0x10DE4380, 0xE23A93C0, 0x1DC56C40, 0x0D16CE00, 0xF20AEE80, 0x00000000}, /* 185 */
+ {0x10E25DC0, 0xE237F540, 0x1DC80AC0, 0x0D155660, 0xF2084BD0, 0x00000000}, /* 186 */
+ {0x10E67A40, 0xE23559E0, 0x1DCAA620, 0x0D13D960, 0xF205AC40, 0x00000000}, /* 187 */
+ {0x10EA9940, 0xE232C180, 0x1DCD3E80, 0x0D1256F0, 0xF2030FC0, 0x00000000}, /* 188 */
+ {0x10EEBA80, 0xE2302C60, 0x1DCFD3A0, 0x0D10CEF0, 0xF2007680, 0x00000000}, /* 189 */
+ {0x10F2DE20, 0xE22D9A40, 0x1DD265C0, 0x0D0F4180, 0xF1FDE070, 0x00000000}, /* 190 */
+ {0x10F70420, 0xE22B0B80, 0x1DD4F480, 0x0D0DAE70, 0xF1FB4D60, 0x00000000}, /* 191 */
+ {0x10FB2CC0, 0xE2287F80, 0x1DD78080, 0x0D0C15E0, 0xF1F8BD70, 0x00000000}, /* 192 */
+ {0x10FF57A0, 0xE225F6E0, 0x1DDA0920, 0x0D0A77C0, 0xF1F630B0, 0x00000000}, /* 193 */
+ {0x11038520, 0xE2237120, 0x1DDC8EE0, 0x0D08D410, 0xF1F3A6F0, 0x00000000}, /* 194 */
+ {0x1107B500, 0xE220EEA0, 0x1DDF1160, 0x0D072AB0, 0xF1F12050, 0x00000000}, /* 195 */
+ {0x110BE780, 0xE21E6F00, 0x1DE19100, 0x0D057BC0, 0xF1EE9CB0, 0x00000000}, /* 196 */
+ {0x11101CA0, 0xE21BF260, 0x1DE40DA0, 0x0D03C740, 0xF1EC1C20, 0x00000000}, /* 197 */
+ {0x11145460, 0xE21978C0, 0x1DE68740, 0x0D020D10, 0xF1E99E90, 0x00000000}, /* 198 */
+ {0x11188EC0, 0xE2170220, 0x1DE8FDE0, 0x0D004D40, 0xF1E72410, 0x00000000}, /* 199 */
+ {0x111CCBA0, 0xE2148EC0, 0x1DEB7140, 0x0CFE87B0, 0xF1E4ACA0, 0x00000000}, /* 200 */
+ {0x11210B80, 0xE2121E00, 0x1DEDE200, 0x0CFCBC90, 0xF1E23810, 0x00000000}, /* 201 */
+ {0x11254DA0, 0xE20FB080, 0x1DF04F80, 0x0CFAEB90, 0xF1DFC6B0, 0x00000000}, /* 202 */
+ {0x112992E0, 0xE20D45C0, 0x1DF2BA40, 0x0CF914F0, 0xF1DD5820, 0x00000000}, /* 203 */
+ {0x112DDAE0, 0xE20ADE00, 0x1DF52200, 0x0CF738A0, 0xF1DAEC80, 0x00000000}, /* 204 */
+ {0x113225A0, 0xE2087960, 0x1DF786A0, 0x0CF55680, 0xF1D883F0, 0x00000000}, /* 205 */
+ {0x11367340, 0xE2061760, 0x1DF9E8A0, 0x0CF36EA0, 0xF1D61E30, 0x00000000}, /* 206 */
+ {0x113AC3A0, 0xE203B880, 0x1DFC4780, 0x0CF180E0, 0xF1D3BB80, 0x00000000}, /* 207 */
+ {0x113F16E0, 0xE2015C80, 0x1DFEA380, 0x0CEF8D60, 0xF1D15BA0, 0x00000000}, /* 208 */
+ {0x11436D40, 0xE1FF0320, 0x1E00FCE0, 0x0CED9420, 0xF1CEFEA0, 0x00000000}, /* 209 */
+ {0x1147C660, 0xE1FCACE0, 0x1E035320, 0x0CEB94E0, 0xF1CCA4B0, 0x00000000}, /* 210 */
+ {0x114C22A0, 0xE1FA5980, 0x1E05A680, 0x0CE98FE0, 0xF1CA4D80, 0x00000000}, /* 211 */
+ {0x115081E0, 0xE1F808C0, 0x1E07F740, 0x0CE78500, 0xF1C7F910, 0x00000000}, /* 212 */
+ {0x1154E420, 0xE1F5BB00, 0x1E0A4500, 0x0CE57430, 0xF1C5A7A0, 0x00000000}, /* 213 */
+ {0x11594980, 0xE1F37000, 0x1E0C9000, 0x0CE35D80, 0xF1C35900, 0x00000000}, /* 214 */
+ {0x115DB1C0, 0xE1F12800, 0x1E0ED800, 0x0CE140D0, 0xF1C10D40, 0x00000000}, /* 215 */
+ {0x11621D80, 0xE1EEE280, 0x1E111D80, 0x0CDF1E50, 0xF1BEC440, 0x00000000}, /* 216 */
+ {0x11668C20, 0xE1ECA000, 0x1E136000, 0x0CDCF5B0, 0xF1BC7E20, 0x00000000}, /* 217 */
+ {0x116AFE00, 0xE1EA6060, 0x1E159FA0, 0x0CDAC720, 0xF1BA3AD0, 0x00000000}, /* 218 */
+ {0x116F7360, 0xE1E82320, 0x1E17DCE0, 0x0CD892A0, 0xF1B7FA20, 0x00000000}, /* 219 */
+ {0x1173EBA0, 0xE1E5E900, 0x1E1A1700, 0x0CD65800, 0xF1B5BC50, 0x00000000}, /* 220 */
+ {0x11786760, 0xE1E3B160, 0x1E1C4EA0, 0x0CD41770, 0xF1B38130, 0x00000000}, /* 221 */
+ {0x117CE660, 0xE1E17CA0, 0x1E1E8360, 0x0CD1D0C0, 0xF1B148F0, 0x00000000}, /* 222 */
+ {0x118168C0, 0xE1DF4AA0, 0x1E20B560, 0x0CCF83F0, 0xF1AF1360, 0x00000000}, /* 223 */
+ {0x1185EE60, 0xE1DD1B40, 0x1E22E4C0, 0x0CCD3110, 0xF1ACE080, 0x00000000}, /* 224 */
+ {0x118A7780, 0xE1DAEEA0, 0x1E251160, 0x0CCAD810, 0xF1AAB060, 0x00000000}, /* 225 */
+ {0x118F0420, 0xE1D8C4A0, 0x1E273B60, 0x0CC87900, 0xF1A882F0, 0x00000000}, /* 226 */
+ {0x11939420, 0xE1D69D60, 0x1E2962A0, 0x0CC613A0, 0xF1A65830, 0x00000000}, /* 227 */
+ {0x119827C0, 0xE1D478A0, 0x1E2B8760, 0x0CC3A830, 0xF1A43010, 0x00000000}, /* 228 */
+ {0x119CBEE0, 0xE1D256A0, 0x1E2DA960, 0x0CC13680, 0xF1A20AB0, 0x00000000}, /* 229 */
+ {0x11A15960, 0xE1D03780, 0x1E2FC880, 0x0CBEBE80, 0xF19FE800, 0x00000000}, /* 230 */
+ {0x11A5F7C0, 0xE1CE1AC0, 0x1E31E540, 0x0CBC4060, 0xF19DC7F0, 0x00000000}, /* 231 */
+ {0x11AA99A0, 0xE1CC0080, 0x1E33FF80, 0x0CB9BBF0, 0xF19BAA60, 0x00000000}, /* 232 */
+ {0x11AF3F40, 0xE1C9E900, 0x1E361700, 0x0CB73140, 0xF1998F80, 0x00000000}, /* 233 */
+ {0x11B3E880, 0xE1C7D420, 0x1E382BE0, 0x0CB4A040, 0xF1977750, 0x00000000}, /* 234 */
+ {0x11B89560, 0xE1C5C1E0, 0x1E3A3E20, 0x0CB208D0, 0xF19561B0, 0x00000000}, /* 235 */
+ {0x11BD4660, 0xE1C3B200, 0x1E3C4E00, 0x0CAF6B30, 0xF1934EA0, 0x00000000}, /* 236 */
+ {0x11C1FAC0, 0xE1C1A500, 0x1E3E5B00, 0x0CACC710, 0xF1913E30, 0x00000000}, /* 237 */
+ {0x11C6B340, 0xE1BF9A20, 0x1E4065E0, 0x0CAA1CA0, 0xF18F3040, 0x00000000}, /* 238 */
+ {0x11CB6F60, 0xE1BD9200, 0x1E426E00, 0x0CA76BD0, 0xF18D24D0, 0x00000000}, /* 239 */
+ {0x11D02F80, 0xE1BB8C80, 0x1E447380, 0x0CA4B460, 0xF18B1C10, 0x00000000}, /* 240 */
+ {0x11D4F3A0, 0xE1B98980, 0x1E467680, 0x0CA1F6A0, 0xF18915D0, 0x00000000}, /* 241 */
+ {0x11D9BB80, 0xE1B78900, 0x1E487700, 0x0C9F3250, 0xF1871210, 0x00000000}, /* 242 */
+ {0x11DE87A0, 0xE1B58AE0, 0x1E4A7520, 0x0C9C6790, 0xF18510D0, 0x00000000}, /* 243 */
+ {0x11E357C0, 0xE1B38F60, 0x1E4C70A0, 0x0C999640, 0xF1831210, 0x00000000}, /* 244 */
+ {0x11E82BC0, 0xE1B19640, 0x1E4E69C0, 0x0C96BE60, 0xF18115D0, 0x00000000}, /* 245 */
+ {0x11ED0400, 0xE1AF9FA0, 0x1E506060, 0x0C93DFF0, 0xF17F1C10, 0x00000000}, /* 246 */
+ {0x11F1E040, 0xE1ADAB80, 0x1E525480, 0x0C90FAF0, 0xF17D24C0, 0x00000000}, /* 247 */
+ {0x11F6C0C0, 0xE1ABB9C0, 0x1E544640, 0x0C8E0F40, 0xF17B2FF0, 0x00000000}, /* 248 */
+ {0x11FBA580, 0xE1A9CA80, 0x1E563580, 0x0C8B1CF0, 0xF1793D90, 0x00000000}, /* 249 */
+ {0x12008E80, 0xE1A7DD80, 0x1E582280, 0x0C8823F0, 0xF1774D90, 0x00000000}, /* 250 */
+ {0x12057BA0, 0xE1A5F300, 0x1E5A0D00, 0x0C852450, 0xF1756000, 0x00000000}, /* 251 */
+ {0x120A6D40, 0xE1A40AE0, 0x1E5BF520, 0x0C821DF0, 0xF17374E0, 0x00000000}, /* 252 */
+ {0x120F6320, 0xE1A22560, 0x1E5DDAA0, 0x0C7F10C0, 0xF1718C30, 0x00000000}, /* 253 */
+ {0x12145D40, 0xE1A04200, 0x1E5FBE00, 0x0C7BFCE0, 0xF16FA5E0, 0x00000000}, /* 254 */
+ {0x12195BE0, 0xE19E6140, 0x1E619EC0, 0x0C78E230, 0xF16DC200, 0x00000000}, /* 255 */
+ {0x121E5F00, 0xE19C82A0, 0x1E637D60, 0x0C75C0A0, 0xF16BE070, 0x00000000}, /* 256 */
+ {0, 0, 0, 0, 0, 0}
+};
+
+static const unsigned int eq_band3_data[][6] = {
+ {0x0A8FA710, 0xF0DE1CC0, 0x0F21E340, 0x06E98708, 0xFE86D1E6, 0x00000000}, /* 0 */
+ {0x0A98CEF0, 0xF0D49FD0, 0x0F2B6030, 0x06EB53F0, 0xFE7BDD2A, 0x00000000}, /* 1 */
+ {0x0AA1FC80, 0xF0CB2420, 0x0F34DBE0, 0x06ED1998, 0xFE70E9E2, 0x00000000}, /* 2 */
+ {0x0AAB3000, 0xF0C1A9A0, 0x0F3E5660, 0x06EED7F0, 0xFE65F80C, 0x00000000}, /* 3 */
+ {0x0AB46950, 0xF0B83090, 0x0F47CF70, 0x06F08EE8, 0xFE5B07C8, 0x00000000}, /* 4 */
+ {0x0ABDA890, 0xF0AEB8C0, 0x0F514740, 0x06F23E78, 0xFE501902, 0x00000000}, /* 5 */
+ {0x0AC6EDA0, 0xF0A54260, 0x0F5ABDA0, 0x06F3E688, 0xFE452BDE, 0x00000000}, /* 6 */
+ {0x0AD038B0, 0xF09BCD60, 0x0F6432A0, 0x06F58708, 0xFE3A4050, 0x00000000}, /* 7 */
+ {0x0AD98990, 0xF09259D0, 0x0F6DA630, 0x06F71FE8, 0xFE2F567E, 0x00000000}, /* 8 */
+ {0x0AE2E090, 0xF088E7B0, 0x0F771850, 0x06F8B138, 0xFE246E4E, 0x00000000}, /* 9 */
+ {0x0AEC3D60, 0xF07F7720, 0x0F8088E0, 0x06FA3AC0, 0xFE1987EE, 0x00000000}, /* 10 */
+ {0x0AF5A040, 0xF0760820, 0x0F89F7E0, 0x06FBBC80, 0xFE0EA350, 0x00000000}, /* 11 */
+ {0x0AFF0920, 0xF06C9AC0, 0x0F936540, 0x06FD3668, 0xFE03C092, 0x00000000}, /* 12 */
+ {0x0B0877F0, 0xF0632EF0, 0x0F9CD110, 0x06FEA868, 0xFDF8DFA8, 0x00000000}, /* 13 */
+ {0x0B11ECF0, 0xF059C4C0, 0x0FA63B40, 0x07001270, 0xFDEE00A0, 0x00000000}, /* 14 */
+ {0x0B1B6800, 0xF0505C50, 0x0FAFA3B0, 0x07017470, 0xFDE32390, 0x00000000}, /* 15 */
+ {0x0B24E910, 0xF046F590, 0x0FB90A70, 0x0702CE68, 0xFDD8487C, 0x00000000}, /* 16 */
+ {0x0B2E7050, 0xF03D9090, 0x0FC26F70, 0x07042040, 0xFDCD6F70, 0x00000000}, /* 17 */
+ {0x0B37FDB0, 0xF0342D60, 0x0FCBD2A0, 0x070569E0, 0xFDC2986C, 0x00000000}, /* 18 */
+ {0x0B419140, 0xF02ACBE0, 0x0FD53420, 0x0706AB40, 0xFDB7C378, 0x00000000}, /* 19 */
+ {0x0B4B2B00, 0xF0216C50, 0x0FDE93B0, 0x0707E450, 0xFDACF0B0, 0x00000000}, /* 20 */
+ {0x0B54CAF0, 0xF0180EA0, 0x0FE7F160, 0x070914F8, 0xFDA22020, 0x00000000}, /* 21 */
+ {0x0B5E7120, 0xF00EB2E0, 0x0FF14D20, 0x070A3D30, 0xFD9751B8, 0x00000000}, /* 22 */
+ {0x0B681D90, 0xF0055910, 0x0FFAA6F0, 0x070B5CE8, 0xFD8C8590, 0x00000000}, /* 23 */
+ {0x0B71D030, 0xEFFC0140, 0x1003FEC0, 0x070C7410, 0xFD81BBB4, 0x00000000}, /* 24 */
+ {0x0B7B8930, 0xEFF2AB60, 0x100D54A0, 0x070D82A0, 0xFD76F428, 0x00000000}, /* 25 */
+ {0x0B854890, 0xEFE957A0, 0x1016A860, 0x070E8880, 0xFD6C2EF8, 0x00000000}, /* 26 */
+ {0x0B8F0E40, 0xEFE005E0, 0x101FFA20, 0x070F85A0, 0xFD616C28, 0x00000000}, /* 27 */
+ {0x0B98DA40, 0xEFD6B640, 0x102949C0, 0x071079E8, 0xFD56ABD0, 0x00000000}, /* 28 */
+ {0x0BA2ACC0, 0xEFCD68C0, 0x10329740, 0x07116558, 0xFD4BEDEC, 0x00000000}, /* 29 */
+ {0x0BAC8590, 0xEFC41D80, 0x103BE280, 0x071247E8, 0xFD413290, 0x00000000}, /* 30 */
+ {0x0BB664F0, 0xEFBAD460, 0x10452BA0, 0x07132170, 0xFD3679B0, 0x00000000}, /* 31 */
+ {0x0BC04AB0, 0xEFB18D80, 0x104E7280, 0x0713F1E8, 0xFD2BC370, 0x00000000}, /* 32 */
+ {0x0BCA36F0, 0xEFA84900, 0x1057B700, 0x0714B940, 0xFD210FD0, 0x00000000}, /* 33 */
+ {0x0BD429C0, 0xEF9F06A0, 0x1060F960, 0x07157770, 0xFD165ECC, 0x00000000}, /* 34 */
+ {0x0BDE2310, 0xEF95C6A0, 0x106A3960, 0x07162C58, 0xFD0BB084, 0x00000000}, /* 35 */
+ {0x0BE82310, 0xEF8C8900, 0x10737700, 0x0716D808, 0xFD0104E8, 0x00000000}, /* 36 */
+ {0x0BF22990, 0xEF834DC0, 0x107CB240, 0x07177A50, 0xFCF65C14, 0x00000000}, /* 37 */
+ {0x0BFC36C0, 0xEF7A1500, 0x1085EB00, 0x07181328, 0xFCEBB60C, 0x00000000}, /* 38 */
+ {0x0C064A90, 0xEF70DEA0, 0x108F2160, 0x0718A280, 0xFCE112DC, 0x00000000}, /* 39 */
+ {0x0C106510, 0xEF67AAC0, 0x10985540, 0x07192850, 0xFCD67288, 0x00000000}, /* 40 */
+ {0x0C1A8670, 0xEF5E7940, 0x10A186C0, 0x0719A490, 0xFCCBD514, 0x00000000}, /* 41 */
+ {0x0C24AE60, 0xEF554A80, 0x10AAB580, 0x071A1710, 0xFCC13A98, 0x00000000}, /* 42 */
+ {0x0C2EDD10, 0xEF4C1E40, 0x10B3E1C0, 0x071A7FD0, 0xFCB6A314, 0x00000000}, /* 43 */
+ {0x0C3912B0, 0xEF42F4A0, 0x10BD0B60, 0x071ADEC8, 0xFCAC0E84, 0x00000000}, /* 44 */
+ {0x0C434F10, 0xEF39CDA0, 0x10C63260, 0x071B33F0, 0xFCA17D10, 0x00000000}, /* 45 */
+ {0x0C4D9250, 0xEF30A940, 0x10CF56C0, 0x071B7F10, 0xFC96EEA8, 0x00000000}, /* 46 */
+ {0x0C57DC70, 0xEF2787A0, 0x10D87860, 0x071BC040, 0xFC8C6358, 0x00000000}, /* 47 */
+ {0x0C622D80, 0xEF1E68A0, 0x10E19760, 0x071BF760, 0xFC81DB28, 0x00000000}, /* 48 */
+ {0x0C6C8590, 0xEF154C60, 0x10EAB3A0, 0x071C2450, 0xFC77562C, 0x00000000}, /* 49 */
+ {0x0C76E480, 0xEF0C3300, 0x10F3CD00, 0x071C4718, 0xFC6CD460, 0x00000000}, /* 50 */
+ {0x0C814A80, 0xEF031C60, 0x10FCE3A0, 0x071C5FA8, 0xFC6255DC, 0x00000000}, /* 51 */
+ {0x0C8BB780, 0xEEFA08A0, 0x1105F760, 0x071C6DE0, 0xFC57DA98, 0x00000000}, /* 52 */
+ {0x0C962BB0, 0xEEF0F7C0, 0x110F0840, 0x071C71B8, 0xFC4D62A0, 0x00000000}, /* 53 */
+ {0x0CA0A6F0, 0xEEE7E9C0, 0x11181640, 0x071C6B10, 0xFC42EDFC, 0x00000000}, /* 54 */
+ {0x0CAB2940, 0xEEDEDEA0, 0x11212160, 0x071C59F0, 0xFC387CC0, 0x00000000}, /* 55 */
+ {0x0CB5B2D0, 0xEED5D680, 0x112A2980, 0x071C3E38, 0xFC2E0EEC, 0x00000000}, /* 56 */
+ {0x0CC043A0, 0xEECCD140, 0x11332EC0, 0x071C17E0, 0xFC23A484, 0x00000000}, /* 57 */
+ {0x0CCADBA0, 0xEEC3CF20, 0x113C30E0, 0x071BE6D8, 0xFC193D90, 0x00000000}, /* 58 */
+ {0x0CD57AE0, 0xEEBAD000, 0x11453000, 0x071BAAF8, 0xFC0EDA24, 0x00000000}, /* 59 */
+ {0x0CE02170, 0xEEB1D3E0, 0x114E2C20, 0x071B6440, 0xFC047A44, 0x00000000}, /* 60 */
+ {0x0CEACF70, 0xEEA8DAE0, 0x11572520, 0x071B12B0, 0xFBFA1DE8, 0x00000000}, /* 61 */
+ {0x0CF584B0, 0xEE9FE500, 0x11601B00, 0x071AB628, 0xFBEFC530, 0x00000000}, /* 62 */
+ {0x0D004170, 0xEE96F240, 0x11690DC0, 0x071A4E80, 0xFBE57008, 0x00000000}, /* 63 */
+ {0x0D0B0590, 0xEE8E02C0, 0x1171FD40, 0x0719DBD0, 0xFBDB1EA0, 0x00000000}, /* 64 */
+ {0x0D15D140, 0xEE851660, 0x117AE9A0, 0x07195DF0, 0xFBD0D0D8, 0x00000000}, /* 65 */
+ {0x0D20A460, 0xEE7C2D40, 0x1183D2C0, 0x0718D4D0, 0xFBC686D0, 0x00000000}, /* 66 */
+ {0x0D2B7F10, 0xEE734760, 0x118CB8A0, 0x07184060, 0xFBBC4088, 0x00000000}, /* 67 */
+ {0x0D366170, 0xEE6A64A0, 0x11959B60, 0x0717A090, 0xFBB1FE00, 0x00000000}, /* 68 */
+ {0x0D414B60, 0xEE618560, 0x119E7AA0, 0x0716F548, 0xFBA7BF58, 0x00000000}, /* 69 */
+ {0x0D4C3D00, 0xEE58A960, 0x11A756A0, 0x07163E88, 0xFB9D8470, 0x00000000}, /* 70 */
+ {0x0D573660, 0xEE4FD0A0, 0x11B02F60, 0x07157C40, 0xFB934D70, 0x00000000}, /* 71 */
+ {0x0D623760, 0xEE46FB60, 0x11B904A0, 0x0714AE40, 0xFB891A60, 0x00000000}, /* 72 */
+ {0x0D6D4050, 0xEE3E2980, 0x11C1D680, 0x0713D490, 0xFB7EEB30, 0x00000000}, /* 73 */
+ {0x0D7850E0, 0xEE355B20, 0x11CAA4E0, 0x0712EF10, 0xFB74C008, 0x00000000}, /* 74 */
+ {0x0D836960, 0xEE2C9020, 0x11D36FE0, 0x0711FDC0, 0xFB6A98C8, 0x00000000}, /* 75 */
+ {0x0D8E89D0, 0xEE23C8A0, 0x11DC3760, 0x07110090, 0xFB6075A0, 0x00000000}, /* 76 */
+ {0x0D99B240, 0xEE1B04A0, 0x11E4FB60, 0x070FF758, 0xFB565670, 0x00000000}, /* 77 */
+ {0x0DA4E2A0, 0xEE124420, 0x11EDBBE0, 0x070EE210, 0xFB4C3B60, 0x00000000}, /* 78 */
+ {0x0DB01B00, 0xEE098740, 0x11F678C0, 0x070DC0A8, 0xFB422460, 0x00000000}, /* 79 */
+ {0x0DBB5B70, 0xEE00CDE0, 0x11FF3220, 0x070C9310, 0xFB381180, 0x00000000}, /* 80 */
+ {0x0DC6A3E0, 0xEDF81820, 0x1207E7E0, 0x070B5938, 0xFB2E02D0, 0x00000000}, /* 81 */
+ {0x0DD1F4B0, 0xEDEF6600, 0x12109A00, 0x070A1320, 0xFB23F850, 0x00000000}, /* 82 */
+ {0x0DDD4D80, 0xEDE6B780, 0x12194880, 0x0708C088, 0xFB19F200, 0x00000000}, /* 83 */
+ {0x0DE8AE90, 0xEDDE0CC0, 0x1221F340, 0x07076178, 0xFB0FEFF0, 0x00000000}, /* 84 */
+ {0x0DF417F0, 0xEDD565A0, 0x122A9A60, 0x0705F5E8, 0xFB05F220, 0x00000000}, /* 85 */
+ {0x0DFF89B0, 0xEDCCC220, 0x12333DE0, 0x07047DC8, 0xFAFBF898, 0x00000000}, /* 86 */
+ {0x0E0B03C0, 0xEDC42260, 0x123BDDA0, 0x0702F8E8, 0xFAF20360, 0x00000000}, /* 87 */
+ {0x0E168620, 0xEDBB86A0, 0x12447960, 0x07016748, 0xFAE81290, 0x00000000}, /* 88 */
+ {0x0E221110, 0xEDB2EE60, 0x124D11A0, 0x06FFC8E8, 0xFADE2608, 0x00000000}, /* 89 */
+ {0x0E2DA480, 0xEDAA5A20, 0x1255A5E0, 0x06FE1D98, 0xFAD43DF0, 0x00000000}, /* 90 */
+ {0x0E394070, 0xEDA1C980, 0x125E3680, 0x06FC6558, 0xFACA5A40, 0x00000000}, /* 91 */
+ {0x0E44E4F0, 0xED993D00, 0x1266C300, 0x06FAA008, 0xFAC07B10, 0x00000000}, /* 92 */
+ {0x0E509210, 0xED90B420, 0x126F4BE0, 0x06F8CDA0, 0xFAB6A048, 0x00000000}, /* 93 */
+ {0x0E5C47F0, 0xED882F40, 0x1277D0C0, 0x06F6EE18, 0xFAACCA00, 0x00000000}, /* 94 */
+ {0x0E680680, 0xED7FAE40, 0x128051C0, 0x06F50150, 0xFAA2F848, 0x00000000}, /* 95 */
+ {0x0E73CDD0, 0xED773140, 0x1288CEC0, 0x06F30728, 0xFA992B08, 0x00000000}, /* 96 */
+ {0x0E7F9DF0, 0xED6EB840, 0x129147C0, 0x06F0FFA8, 0xFA8F6268, 0x00000000}, /* 97 */
+ {0x0E8B7700, 0xED664300, 0x1299BD00, 0x06EEEAB0, 0xFA859E58, 0x00000000}, /* 98 */
+ {0x0E9758F0, 0xED5DD200, 0x12A22E00, 0x06ECC838, 0xFA7BDEF0, 0x00000000}, /* 99 */
+ {0x0EA343C0, 0xED5564E0, 0x12AA9B20, 0x06EA9818, 0xFA722420, 0x00000000}, /* 100 */
+ {0x0EAF37B0, 0xED4CFBE0, 0x12B30420, 0x06E85A50, 0xFA686E00, 0x00000000}, /* 101 */
+ {0x0EBB34B0, 0xED4496E0, 0x12BB6920, 0x06E60EC0, 0xFA5EBC90, 0x00000000}, /* 102 */
+ {0x0EC73AD0, 0xED3C35E0, 0x12C3CA20, 0x06E3B570, 0xFA550FC8, 0x00000000}, /* 103 */
+ {0x0ED34A00, 0xED33D920, 0x12CC26E0, 0x06E14E38, 0xFA4B67D0, 0x00000000}, /* 104 */
+ {0x0EDF6270, 0xED2B8060, 0x12D47FA0, 0x06DED8F0, 0xFA41C488, 0x00000000}, /* 105 */
+ {0x0EEB8420, 0xED232BE0, 0x12DCD420, 0x06DC55C0, 0xFA382610, 0x00000000}, /* 106 */
+ {0x0EF7AF50, 0xED1ADB60, 0x12E524A0, 0x06D9C460, 0xFA2E8C60, 0x00000000}, /* 107 */
+ {0x0F03E3A0, 0xED128F40, 0x12ED70C0, 0x06D724D0, 0xFA24F780, 0x00000000}, /* 108 */
+ {0x0F102170, 0xED0A4720, 0x12F5B8E0, 0x06D47700, 0xFA1B6788, 0x00000000}, /* 109 */
+ {0x0F1C68E0, 0xED020340, 0x12FDFCC0, 0x06D1BAE0, 0xFA11DC50, 0x00000000}, /* 110 */
+ {0x0F28B9B0, 0xECF9C3A0, 0x13063C60, 0x06CEF050, 0xFA085608, 0x00000000}, /* 111 */
+ {0x0F351420, 0xECF18840, 0x130E77C0, 0x06CC1740, 0xF9FED4A8, 0x00000000}, /* 112 */
+ {0x0F417830, 0xECE95120, 0x1316AEE0, 0x06C92FB0, 0xF9F55830, 0x00000000}, /* 113 */
+ {0x0F4DE5F0, 0xECE11E60, 0x131EE1A0, 0x06C63960, 0xF9EBE0A8, 0x00000000}, /* 114 */
+ {0x0F5A5D60, 0xECD8EFE0, 0x13271020, 0x06C33470, 0xF9E26E28, 0x00000000}, /* 115 */
+ {0x0F66DEC0, 0xECD0C5A0, 0x132F3A60, 0x06C020B0, 0xF9D90090, 0x00000000}, /* 116 */
+ {0x0F7369F0, 0xECC89FC0, 0x13376040, 0x06BCFE10, 0xF9CF97F8, 0x00000000}, /* 117 */
+ {0x0F7FFF00, 0xECC07E40, 0x133F81C0, 0x06B9CC88, 0xF9C63478, 0x00000000}, /* 118 */
+ {0x0F8C9E20, 0xECB86100, 0x13479F00, 0x06B68C00, 0xF9BCD5F0, 0x00000000}, /* 119 */
+ {0x0F994730, 0xECB04840, 0x134FB7C0, 0x06B33C58, 0xF9B37C78, 0x00000000}, /* 120 */
+ {0x0FA5FA60, 0xECA833E0, 0x1357CC20, 0x06AFDD88, 0xF9AA2828, 0x00000000}, /* 121 */
+ {0x0FB2B7A0, 0xECA023E0, 0x135FDC20, 0x06AC6F78, 0xF9A0D8E0, 0x00000000}, /* 122 */
+ {0x0FBF7F30, 0xEC981860, 0x1367E7A0, 0x06A8F210, 0xF9978EC0, 0x00000000}, /* 123 */
+ {0x0FCC5110, 0xEC901140, 0x136FEEC0, 0x06A56550, 0xF98E49B8, 0x00000000}, /* 124 */
+ {0x0FD92D10, 0xEC880EA0, 0x1377F160, 0x06A1C908, 0xF98509E0, 0x00000000}, /* 125 */
+ {0x0FE61390, 0xEC801080, 0x137FEF80, 0x069E1D38, 0xF97BCF30, 0x00000000}, /* 126 */
+ {0x0FF30480, 0xEC7816E0, 0x1387E920, 0x069A61C0, 0xF97299B0, 0x00000000}, /* 127 */
+ {0x10000000, 0xEC7021C0, 0x138FDE40, 0x069696A0, 0xF9696960, 0x00000000}, /* 128 */
+ {0x100D0600, 0xEC683120, 0x1397CEE0, 0x0692BBA8, 0xF9603E48, 0x00000000}, /* 129 */
+ {0x101A16C0, 0xEC604500, 0x139FBB00, 0x068ED0E0, 0xF9571878, 0x00000000}, /* 130 */
+ {0x10273200, 0xEC585D80, 0x13A7A280, 0x068AD618, 0xF94DF7E8, 0x00000000}, /* 131 */
+ {0x10345800, 0xEC507A80, 0x13AF8580, 0x0686CB50, 0xF944DC98, 0x00000000}, /* 132 */
+ {0x10418900, 0xEC489C00, 0x13B76400, 0x0682B070, 0xF93BC690, 0x00000000}, /* 133 */
+ {0x104EC4E0, 0xEC40C240, 0x13BF3DC0, 0x067E8560, 0xF932B5D8, 0x00000000}, /* 134 */
+ {0x105C0B80, 0xEC38ED20, 0x13C712E0, 0x067A4A08, 0xF929AA78, 0x00000000}, /* 135 */
+ {0x10695D40, 0xEC311C80, 0x13CEE380, 0x0675FE50, 0xF920A458, 0x00000000}, /* 136 */
+ {0x1076BA20, 0xEC295080, 0x13D6AF80, 0x0671A238, 0xF917A3A8, 0x00000000}, /* 137 */
+ {0x10842220, 0xEC218940, 0x13DE76C0, 0x066D35A0, 0xF90EA850, 0x00000000}, /* 138 */
+ {0x10919540, 0xEC19C6A0, 0x13E63960, 0x0668B870, 0xF905B250, 0x00000000}, /* 139 */
+ {0x109F13C0, 0xEC1208C0, 0x13EDF740, 0x06642A90, 0xF8FCC1C0, 0x00000000}, /* 140 */
+ {0x10AC9D80, 0xEC0A4F60, 0x13F5B0A0, 0x065F8C00, 0xF8F3D690, 0x00000000}, /* 141 */
+ {0x10BA32A0, 0xEC029AC0, 0x13FD6540, 0x065ADC88, 0xF8EAF0D0, 0x00000000}, /* 142 */
+ {0x10C7D360, 0xEBFAEAE0, 0x14051520, 0x06561C20, 0xF8E21078, 0x00000000}, /* 143 */
+ {0x10D57FA0, 0xEBF33FC0, 0x140CC040, 0x06514AD0, 0xF8D935A0, 0x00000000}, /* 144 */
+ {0x10E33760, 0xEBEB9940, 0x141466C0, 0x064C6860, 0xF8D06030, 0x00000000}, /* 145 */
+ {0x10F0FB00, 0xEBE3F780, 0x141C0880, 0x064774C8, 0xF8C79038, 0x00000000}, /* 146 */
+ {0x10FECA60, 0xEBDC5A80, 0x1423A580, 0x06426FF8, 0xF8BEC5C0, 0x00000000}, /* 147 */
+ {0x110CA560, 0xEBD4C260, 0x142B3DA0, 0x063D59D0, 0xF8B600D8, 0x00000000}, /* 148 */
+ {0x111A8C60, 0xEBCD2EE0, 0x1432D120, 0x06383240, 0xF8AD4158, 0x00000000}, /* 149 */
+ {0x11287F60, 0xEBC5A060, 0x143A5FA0, 0x0632F938, 0xF8A48770, 0x00000000}, /* 150 */
+ {0x11367E60, 0xEBBE1680, 0x1441E980, 0x062DAE98, 0xF89BD318, 0x00000000}, /* 151 */
+ {0x11448980, 0xEBB69180, 0x14496E80, 0x06285248, 0xF8932448, 0x00000000}, /* 152 */
+ {0x1152A0C0, 0xEBAF1160, 0x1450EEA0, 0x0622E438, 0xF88A7B00, 0x00000000}, /* 153 */
+ {0x1160C460, 0xEBA795E0, 0x14586A20, 0x061D6458, 0xF881D748, 0x00000000}, /* 154 */
+ {0x116EF440, 0xEBA01F60, 0x145FE0A0, 0x0617D280, 0xF8793928, 0x00000000}, /* 155 */
+ {0x117D3080, 0xEB98ADC0, 0x14675240, 0x06122EC8, 0xF870A0A8, 0x00000000}, /* 156 */
+ {0x118B7960, 0xEB9140E0, 0x146EBF20, 0x060C78D8, 0xF8680DB8, 0x00000000}, /* 157 */
+ {0x1199CEC0, 0xEB89D8C0, 0x14762740, 0x0606B0D0, 0xF85F8068, 0x00000000}, /* 158 */
+ {0x11A830C0, 0xEB8275A0, 0x147D8A60, 0x0600D680, 0xF856F8B8, 0x00000000}, /* 159 */
+ {0x11B69F80, 0xEB7B1760, 0x1484E8A0, 0x05FAE9D8, 0xF84E76B0, 0x00000000}, /* 160 */
+ {0x11C51B00, 0xEB73BE20, 0x148C41E0, 0x05F4EAB0, 0xF845FA50, 0x00000000}, /* 161 */
+ {0x11D3A360, 0xEB6C69A0, 0x14939660, 0x05EED910, 0xF83D8388, 0x00000000}, /* 162 */
+ {0x11E238C0, 0xEB651A00, 0x149AE600, 0x05E8B4D8, 0xF8351268, 0x00000000}, /* 163 */
+ {0x11F0DB20, 0xEB5DCF60, 0x14A230A0, 0x05E27DF0, 0xF82CA708, 0x00000000}, /* 164 */
+ {0x11FF8A80, 0xEB5689C0, 0x14A97640, 0x05DC3430, 0xF8244158, 0x00000000}, /* 165 */
+ {0x120E4720, 0xEB4F48E0, 0x14B0B720, 0x05D5D798, 0xF81BE148, 0x00000000}, /* 166 */
+ {0x121D1100, 0xEB480D00, 0x14B7F300, 0x05CF6800, 0xF81386F0, 0x00000000}, /* 167 */
+ {0x122BE820, 0xEB40D640, 0x14BF29C0, 0x05C8E568, 0xF80B3258, 0x00000000}, /* 168 */
+ {0x123ACCE0, 0xEB39A420, 0x14C65BE0, 0x05C24FA8, 0xF802E360, 0x00000000}, /* 169 */
+ {0x1249BF20, 0xEB327720, 0x14CD88E0, 0x05BBA6A8, 0xF7FA9A30, 0x00000000}, /* 170 */
+ {0x1258BF00, 0xEB2B4F20, 0x14D4B0E0, 0x05B4EA58, 0xF7F256C0, 0x00000000}, /* 171 */
+ {0x1267CC80, 0xEB242C00, 0x14DBD400, 0x05AE1A98, 0xF7EA1900, 0x00000000}, /* 172 */
+ {0x1276E7A0, 0xEB1D0E00, 0x14E2F200, 0x05A73750, 0xF7E1E110, 0x00000000}, /* 173 */
+ {0x128610A0, 0xEB15F4E0, 0x14EA0B20, 0x05A04080, 0xF7D9AEE0, 0x00000000}, /* 174 */
+ {0x129547C0, 0xEB0EE0A0, 0x14F11F60, 0x059935F8, 0xF7D18260, 0x00000000}, /* 175 */
+ {0x12A48CC0, 0xEB07D1A0, 0x14F82E60, 0x059217A0, 0xF7C95BA0, 0x00000000}, /* 176 */
+ {0x12B3DFC0, 0xEB00C780, 0x14FF3880, 0x058AE570, 0xF7C13AC0, 0x00000000}, /* 177 */
+ {0x12C34120, 0xEAF9C240, 0x15063DC0, 0x05839F48, 0xF7B91F90, 0x00000000}, /* 178 */
+ {0x12D2B0C0, 0xEAF2C220, 0x150D3DE0, 0x057C4510, 0xF7B10A30, 0x00000000}, /* 179 */
+ {0x12E22EC0, 0xEAEBC700, 0x15143900, 0x0574D6B0, 0xF7A8FAA0, 0x00000000}, /* 180 */
+ {0x12F1BB20, 0xEAE4D100, 0x151B2F00, 0x056D5410, 0xF7A0F0E0, 0x00000000}, /* 181 */
+ {0x13015600, 0xEADDDFE0, 0x15222020, 0x0565BD20, 0xF798ECE0, 0x00000000}, /* 182 */
+ {0x1310FF80, 0xEAD6F400, 0x15290C00, 0x055E11B8, 0xF790EEC0, 0x00000000}, /* 183 */
+ {0x1320B7E0, 0xEAD00CE0, 0x152FF320, 0x055651C0, 0xF788F660, 0x00000000}, /* 184 */
+ {0x13307F00, 0xEAC92B00, 0x1536D500, 0x054E7D30, 0xF78103E0, 0x00000000}, /* 185 */
+ {0x13405500, 0xEAC24E00, 0x153DB200, 0x054693E8, 0xF7791720, 0x00000000}, /* 186 */
+ {0x13503A00, 0xEABB7620, 0x154489E0, 0x053E95D0, 0xF7713040, 0x00000000}, /* 187 */
+ {0x13602E00, 0xEAB4A360, 0x154B5CA0, 0x053682C8, 0xF7694F30, 0x00000000}, /* 188 */
+ {0x13703160, 0xEAADD580, 0x15522A80, 0x052E5AC0, 0xF76173F0, 0x00000000}, /* 189 */
+ {0x138043C0, 0xEAA70CE0, 0x1558F320, 0x05261DA0, 0xF7599E90, 0x00000000}, /* 190 */
+ {0x139065C0, 0xEAA04940, 0x155FB6C0, 0x051DCB48, 0xF751CF10, 0x00000000}, /* 191 */
+ {0x13A09700, 0xEA998AA0, 0x15667560, 0x05156390, 0xF74A0550, 0x00000000}, /* 192 */
+ {0x13B0D800, 0xEA92D120, 0x156D2EE0, 0x050CE680, 0xF7424180, 0x00000000}, /* 193 */
+ {0x13C12880, 0xEA8C1CA0, 0x1573E360, 0x050453F0, 0xF73A8390, 0x00000000}, /* 194 */
+ {0x13D188E0, 0xEA856D40, 0x157A92C0, 0x04FBABB8, 0xF732CB60, 0x00000000}, /* 195 */
+ {0x13E1F920, 0xEA7EC300, 0x15813D00, 0x04F2EDD8, 0xF72B1920, 0x00000000}, /* 196 */
+ {0x13F27940, 0xEA781DA0, 0x1587E260, 0x04EA1A30, 0xF7236CA0, 0x00000000}, /* 197 */
+ {0x14030960, 0xEA717D80, 0x158E8280, 0x04E13098, 0xF71BC610, 0x00000000}, /* 198 */
+ {0x1413A9A0, 0xEA6AE280, 0x15951D80, 0x04D830F8, 0xF7142570, 0x00000000}, /* 199 */
+ {0x14245A40, 0xEA644C60, 0x159BB3A0, 0x04CF1B48, 0xF70C8A90, 0x00000000}, /* 200 */
+ {0x14351B20, 0xEA5DBB80, 0x15A24480, 0x04C5EF58, 0xF704F5A0, 0x00000000}, /* 201 */
+ {0x1445EC60, 0xEA572FC0, 0x15A8D040, 0x04BCAD18, 0xF6FD6690, 0x00000000}, /* 202 */
+ {0x1456CE40, 0xEA50A900, 0x15AF5700, 0x04B35470, 0xF6F5DD60, 0x00000000}, /* 203 */
+ {0x1467C0C0, 0xEA4A2740, 0x15B5D8C0, 0x04A9E548, 0xF6EE5A00, 0x00000000}, /* 204 */
+ {0x1478C400, 0xEA43AAC0, 0x15BC5540, 0x04A05F78, 0xF6E6DC90, 0x00000000}, /* 205 */
+ {0x1489D820, 0xEA3D3340, 0x15C2CCC0, 0x0496C2F0, 0xF6DF64E0, 0x00000000}, /* 206 */
+ {0x149AFD20, 0xEA36C0E0, 0x15C93F20, 0x048D0F98, 0xF6D7F340, 0x00000000}, /* 207 */
+ {0x14AC3360, 0xEA305380, 0x15CFAC80, 0x04834550, 0xF6D08760, 0x00000000}, /* 208 */
+ {0x14BD7AA0, 0xEA29EB40, 0x15D614C0, 0x047963F0, 0xF6C92160, 0x00000000}, /* 209 */
+ {0x14CED320, 0xEA238840, 0x15DC77C0, 0x046F6B78, 0xF6C1C150, 0x00000000}, /* 210 */
+ {0x14E03D20, 0xEA1D2A20, 0x15E2D5E0, 0x04655BB8, 0xF6BA6720, 0x00000000}, /* 211 */
+ {0x14F1B8A0, 0xEA16D140, 0x15E92EC0, 0x045B3498, 0xF6B312D0, 0x00000000}, /* 212 */
+ {0x150345C0, 0xEA107D40, 0x15EF82C0, 0x0450F610, 0xF6ABC450, 0x00000000}, /* 213 */
+ {0x1514E460, 0xEA0A2E80, 0x15F5D180, 0x04469FE0, 0xF6A47BC0, 0x00000000}, /* 214 */
+ {0x152694E0, 0xEA03E4E0, 0x15FC1B20, 0x043C3208, 0xF69D3910, 0x00000000}, /* 215 */
+ {0x15385780, 0xE9FDA040, 0x16025FC0, 0x0431AC68, 0xF695FC40, 0x00000000}, /* 216 */
+ {0x154A2BE0, 0xE9F760C0, 0x16089F40, 0x04270ED8, 0xF68EC540, 0x00000000}, /* 217 */
+ {0x155C12A0, 0xE9F12640, 0x160ED9C0, 0x041C5948, 0xF6879430, 0x00000000}, /* 218 */
+ {0x156E0B80, 0xE9EAF100, 0x16150F00, 0x04118B90, 0xF6806900, 0x00000000}, /* 219 */
+ {0x158016C0, 0xE9E4C0C0, 0x161B3F40, 0x0406A5A8, 0xF67943B0, 0x00000000}, /* 220 */
+ {0x15923460, 0xE9DE95A0, 0x16216A60, 0x03FBA760, 0xF6722430, 0x00000000}, /* 221 */
+ {0x15A464E0, 0xE9D86F80, 0x16279080, 0x03F090A8, 0xF66B0A90, 0x00000000}, /* 222 */
+ {0x15B6A7E0, 0xE9D24E80, 0x162DB180, 0x03E56150, 0xF663F6D0, 0x00000000}, /* 223 */
+ {0x15C8FDC0, 0xE9CC3280, 0x1633CD80, 0x03DA194C, 0xF65CE8F0, 0x00000000}, /* 224 */
+ {0x15DB66A0, 0xE9C61BA0, 0x1639E460, 0x03CEB880, 0xF655E0F0, 0x00000000}, /* 225 */
+ {0x15EDE280, 0xE9C009E0, 0x163FF620, 0x03C33ED0, 0xF64EDEC0, 0x00000000}, /* 226 */
+ {0x16007180, 0xE9B9FD40, 0x164602C0, 0x03B7AC08, 0xF647E280, 0x00000000}, /* 227 */
+ {0x161313E0, 0xE9B3F580, 0x164C0A80, 0x03AC0028, 0xF640EC10, 0x00000000}, /* 228 */
+ {0x1625C980, 0xE9ADF300, 0x16520D00, 0x03A03AFC, 0xF639FB70, 0x00000000}, /* 229 */
+ {0x163892C0, 0xE9A7F580, 0x16580A80, 0x03945C74, 0xF63310C0, 0x00000000}, /* 230 */
+ {0x164B6FE0, 0xE9A1FD00, 0x165E0300, 0x03886470, 0xF62C2BC0, 0x00000000}, /* 231 */
+ {0x165E6080, 0xE99C09A0, 0x1663F660, 0x037C52CC, 0xF6254CC0, 0x00000000}, /* 232 */
+ {0x16716520, 0xE9961B40, 0x1669E4C0, 0x03702770, 0xF61E7380, 0x00000000}, /* 233 */
+ {0x16847DA0, 0xE9903200, 0x166FCE00, 0x0363E230, 0xF617A020, 0x00000000}, /* 234 */
+ {0x1697AA60, 0xE98A4DC0, 0x1675B240, 0x03578300, 0xF610D280, 0x00000000}, /* 235 */
+ {0x16AAEB80, 0xE9846E80, 0x167B9180, 0x034B09B4, 0xF60A0AD0, 0x00000000}, /* 236 */
+ {0x16BE40E0, 0xE97E9460, 0x16816BA0, 0x033E7640, 0xF60348E0, 0x00000000}, /* 237 */
+ {0x16D1AAC0, 0xE978BF40, 0x168740C0, 0x0331C874, 0xF5FC8CD0, 0x00000000}, /* 238 */
+ {0x16E52940, 0xE972EF40, 0x168D10C0, 0x03250030, 0xF5F5D680, 0x00000000}, /* 239 */
+ {0x16F8BCC0, 0xE96D2420, 0x1692DBE0, 0x03181D5C, 0xF5EF2600, 0x00000000}, /* 240 */
+ {0x170C64E0, 0xE9675E20, 0x1698A1E0, 0x030B1FD8, 0xF5E87B60, 0x00000000}, /* 241 */
+ {0x17202220, 0xE9619D00, 0x169E6300, 0x02FE0784, 0xF5E1D670, 0x00000000}, /* 242 */
+ {0x1733F480, 0xE95BE120, 0x16A41EE0, 0x02F0D434, 0xF5DB3750, 0x00000000}, /* 243 */
+ {0x1747DC00, 0xE9562A40, 0x16A9D5C0, 0x02E385DC, 0xF5D49E10, 0x00000000}, /* 244 */
+ {0x175BD920, 0xE9507840, 0x16AF87C0, 0x02D61C4C, 0xF5CE0A90, 0x00000000}, /* 245 */
+ {0x176FEBC0, 0xE94ACB40, 0x16B534C0, 0x02C89770, 0xF5C77CE0, 0x00000000}, /* 246 */
+ {0x17841400, 0xE9452340, 0x16BADCC0, 0x02BAF72C, 0xF5C0F4E0, 0x00000000}, /* 247 */
+ {0x17985200, 0xE93F8060, 0x16C07FA0, 0x02AD3B4C, 0xF5BA72B0, 0x00000000}, /* 248 */
+ {0x17ACA600, 0xE939E260, 0x16C61DA0, 0x029F63BC, 0xF5B3F650, 0x00000000}, /* 249 */
+ {0x17C11020, 0xE9344960, 0x16CBB6A0, 0x02917050, 0xF5AD7FA0, 0x00000000}, /* 250 */
+ {0x17D59040, 0xE92EB560, 0x16D14AA0, 0x028360F8, 0xF5A70EB0, 0x00000000}, /* 251 */
+ {0x17EA2720, 0xE9292640, 0x16D6D9C0, 0x0275358C, 0xF5A0A380, 0x00000000}, /* 252 */
+ {0x17FED420, 0xE9239C40, 0x16DC63C0, 0x0266EDE4, 0xF59A3E10, 0x00000000}, /* 253 */
+ {0x181397C0, 0xE91E1720, 0x16E1E8E0, 0x025889EC, 0xF593DE60, 0x00000000}, /* 254 */
+ {0x18287220, 0xE9189720, 0x16E768E0, 0x024A096C, 0xF58D8470, 0x00000000}, /* 255 */
+ {0x183D6380, 0xE9131BE0, 0x16ECE420, 0x023B6C64, 0xF5873030, 0x00000000}, /* 256 */
+ {0, 0, 0, 0, 0, 0}
+};
+
+static const unsigned int eq_band4_data[][6] = {
+ {0x08EDE970, 0x068EB7E8, 0xF9714818, 0x042F8650, 0x02E2902C, 0x00000000}, /* 0 */
+ {0x08F87E00, 0x06941150, 0xF96BEEB0, 0x042FA4A0, 0x02D7DD6C, 0x00000000}, /* 1 */
+ {0x09031E40, 0x06996C00, 0xF9669400, 0x042FB9C0, 0x02CD280C, 0x00000000}, /* 2 */
+ {0x090DCA40, 0x069EC7F8, 0xF9613808, 0x042FC5B0, 0x02C2700C, 0x00000000}, /* 3 */
+ {0x09188210, 0x06A42538, 0xF95BDAC8, 0x042FC860, 0x02B7B590, 0x00000000}, /* 4 */
+ {0x092345D0, 0x06A983C0, 0xF9567C40, 0x042FC1B0, 0x02ACF880, 0x00000000}, /* 5 */
+ {0x092E1590, 0x06AEE388, 0xF9511C78, 0x042FB180, 0x02A23900, 0x00000000}, /* 6 */
+ {0x0938F130, 0x06B44480, 0xF94BBB80, 0x042F97C8, 0x029776F4, 0x00000000}, /* 7 */
+ {0x0943D8F0, 0x06B9A6B0, 0xF9465950, 0x042F7468, 0x028CB2A0, 0x00000000}, /* 8 */
+ {0x094ECCD0, 0x06BF0A18, 0xF940F5E8, 0x042F4758, 0x0281EBD4, 0x00000000}, /* 9 */
+ {0x0959CCD0, 0x06C46EA0, 0xF93B9160, 0x042F1070, 0x027722C4, 0x00000000}, /* 10 */
+ {0x0964D900, 0x06C9D448, 0xF9362BB8, 0x042ECFA0, 0x026C5760, 0x00000000}, /* 11 */
+ {0x096FF170, 0x06CF3B18, 0xF930C4E8, 0x042E84C8, 0x026189C4, 0x00000000}, /* 12 */
+ {0x097B1630, 0x06D4A308, 0xF92B5CF8, 0x042E2FE0, 0x0256B9E8, 0x00000000}, /* 13 */
+ {0x09864760, 0x06DA0C10, 0xF925F3F0, 0x042DD0C8, 0x024BE7D8, 0x00000000}, /* 14 */
+ {0x099184F0, 0x06DF7630, 0xF92089D0, 0x042D6768, 0x024113A4, 0x00000000}, /* 15 */
+ {0x099CCF00, 0x06E4E150, 0xF91B1EB0, 0x042CF3A8, 0x02363D5C, 0x00000000}, /* 16 */
+ {0x09A82590, 0x06EA4D80, 0xF915B280, 0x042C7568, 0x022B64FC, 0x00000000}, /* 17 */
+ {0x09B388D0, 0x06EFBAB8, 0xF9104548, 0x042BECA0, 0x02208A94, 0x00000000}, /* 18 */
+ {0x09BEF8B0, 0x06F528E8, 0xF90AD718, 0x042B5930, 0x0215AE28, 0x00000000}, /* 19 */
+ {0x09CA7530, 0x06FA9818, 0xF90567E8, 0x042ABB00, 0x020ACFCC, 0x00000000}, /* 20 */
+ {0x09D5FE80, 0x07000838, 0xF8FFF7C8, 0x042A11F0, 0x01FFEF90, 0x00000000}, /* 21 */
+ {0x09E194A0, 0x07057948, 0xF8FA86B8, 0x04295DF0, 0x01F50D6A, 0x00000000}, /* 22 */
+ {0x09ED37A0, 0x070AEB50, 0xF8F514B0, 0x04289EF0, 0x01EA296A, 0x00000000}, /* 23 */
+ {0x09F8E790, 0x07105E30, 0xF8EFA1D0, 0x0427D4C0, 0x01DF439E, 0x00000000}, /* 24 */
+ {0x0A04A490, 0x0715D200, 0xF8EA2E00, 0x0426FF68, 0x01D45C10, 0x00000000}, /* 25 */
+ {0x0A106E90, 0x071B46A0, 0xF8E4B960, 0x04261EA8, 0x01C972C6, 0x00000000}, /* 26 */
+ {0x0A1C45B0, 0x0720BC20, 0xF8DF43E0, 0x04253280, 0x01BE87D0, 0x00000000}, /* 27 */
+ {0x0A2829F0, 0x07263260, 0xF8D9CDA0, 0x04243AD0, 0x01B39B34, 0x00000000}, /* 28 */
+ {0x0A341B70, 0x072BA978, 0xF8D45688, 0x04233780, 0x01A8ACFE, 0x00000000}, /* 29 */
+ {0x0A401A50, 0x07312160, 0xF8CEDEA0, 0x04222878, 0x019DBD3C, 0x00000000}, /* 30 */
+ {0x0A4C2680, 0x07369A10, 0xF8C965F0, 0x04210DA0, 0x0192CBE6, 0x00000000}, /* 31 */
+ {0x0A584000, 0x073C1370, 0xF8C3EC90, 0x041FE6D0, 0x0187D924, 0x00000000}, /* 32 */
+ {0x0A646710, 0x07418D88, 0xF8BE7278, 0x041EB400, 0x017CE4E4, 0x00000000}, /* 33 */
+ {0x0A709BB0, 0x07470868, 0xF8B8F798, 0x041D7510, 0x0171EF3A, 0x00000000}, /* 34 */
+ {0x0A7CDDE0, 0x074C83D8, 0xF8B37C28, 0x041C29E0, 0x0166F83C, 0x00000000}, /* 35 */
+ {0x0A892DC0, 0x07520010, 0xF8ADFFF0, 0x041AD260, 0x015BFFE2, 0x00000000}, /* 36 */
+ {0x0A958B50, 0x07577CD8, 0xF8A88328, 0x04196E68, 0x0151063C, 0x00000000}, /* 37 */
+ {0x0AA1F6C0, 0x075CFA58, 0xF8A305A8, 0x0417FDF0, 0x01460B5C, 0x00000000}, /* 38 */
+ {0x0AAE6FF0, 0x07627860, 0xF89D87A0, 0x041680D8, 0x013B0F4C, 0x00000000}, /* 39 */
+ {0x0ABAF700, 0x0767F6F8, 0xF8980908, 0x0414F6F0, 0x01301208, 0x00000000}, /* 40 */
+ {0x0AC78C20, 0x076D7630, 0xF89289D0, 0x04136038, 0x012513A2, 0x00000000}, /* 41 */
+ {0x0AD42F40, 0x0772F5E8, 0xF88D0A18, 0x0411BC90, 0x011A142E, 0x00000000}, /* 42 */
+ {0x0AE0E080, 0x07787628, 0xF88789D8, 0x04100BD0, 0x010F13B0, 0x00000000}, /* 43 */
+ {0x0AEDA000, 0x077DF6F0, 0xF8820910, 0x040E4DE8, 0x01041222, 0x00000000}, /* 44 */
+ {0x0AFA6DA0, 0x07837830, 0xF87C87D0, 0x040C82C0, 0x00F90FB1, 0x00000000}, /* 45 */
+ {0x0B074990, 0x0788F9D8, 0xF8770628, 0x040AAA30, 0x00EE0C46, 0x00000000}, /* 46 */
+ {0x0B1433E0, 0x078E7C00, 0xF8718400, 0x0408C420, 0x00E307F9, 0x00000000}, /* 47 */
+ {0x0B212CA0, 0x0793FE98, 0xF86C0168, 0x0406D080, 0x00D802D0, 0x00000000}, /* 48 */
+ {0x0B2E33F0, 0x07998190, 0xF8667E70, 0x0404CF28, 0x00CCFCDD, 0x00000000}, /* 49 */
+ {0x0B3B49D0, 0x079F04E8, 0xF860FB18, 0x0402C008, 0x00C1F627, 0x00000000}, /* 50 */
+ {0x0B486E50, 0x07A488A8, 0xF85B7758, 0x0400A2F8, 0x00B6EEC1, 0x00000000}, /* 51 */
+ {0x0B55A180, 0x07AA0CB0, 0xF855F350, 0x03FE77E4, 0x00ABE6A7, 0x00000000}, /* 52 */
+ {0x0B62E380, 0x07AF9110, 0xF8506EF0, 0x03FC3EAC, 0x00A0DDEB, 0x00000000}, /* 53 */
+ {0x0B703440, 0x07B515B8, 0xF84AEA48, 0x03F9F730, 0x0095D48A, 0x00000000}, /* 54 */
+ {0x0B7D9410, 0x07BA9AB8, 0xF8456548, 0x03F7A160, 0x008ACAA3, 0x00000000}, /* 55 */
+ {0x0B8B02B0, 0x07C01FE0, 0xF83FE020, 0x03F53D08, 0x007FC03D, 0x00000000}, /* 56 */
+ {0x0B988080, 0x07C5A550, 0xF83A5AB0, 0x03F2CA28, 0x0074B556, 0x00000000}, /* 57 */
+ {0x0BA60D70, 0x07CB2B08, 0xF834D4F8, 0x03F04894, 0x0069AA02, 0x00000000}, /* 58 */
+ {0x0BB3A9A0, 0x07D0B0E0, 0xF82F4F20, 0x03EDB830, 0x005E9E47, 0x00000000}, /* 59 */
+ {0x0BC154E0, 0x07D636E0, 0xF829C920, 0x03EB18DC, 0x00539239, 0x00000000}, /* 60 */
+ {0x0BCF0FA0, 0x07DBBD10, 0xF82442F0, 0x03E86A84, 0x004885CB, 0x00000000}, /* 61 */
+ {0x0BDCD9C0, 0x07E14368, 0xF81EBC98, 0x03E5AD08, 0x003D7927, 0x00000000}, /* 62 */
+ {0x0BEAB380, 0x07E6C9E0, 0xF8193620, 0x03E2E048, 0x00326C41, 0x00000000}, /* 63 */
+ {0x0BF89CB0, 0x07EC5068, 0xF813AF98, 0x03E00430, 0x00275F36, 0x00000000}, /* 64 */
+ {0x0C069570, 0x07F1D700, 0xF80E2900, 0x03DD188C, 0x001C51F8, 0x00000000}, /* 65 */
+ {0x0C149E00, 0x07F75DA8, 0xF808A258, 0x03DA1D58, 0x001144A9, 0x00000000}, /* 66 */
+ {0x0C22B650, 0x07FCE458, 0xF8031BA8, 0x03D71260, 0x00063746, 0x00000000}, /* 67 */
+ {0x0C30DE80, 0x08026B10, 0xF7FD94F0, 0x03D3F798, 0xFFFB29D9, 0x00000000}, /* 68 */
+ {0x0C3F16B0, 0x0807F1C0, 0xF7F80E40, 0x03D0CCDC, 0xFFF01C75, 0x00000000}, /* 69 */
+ {0x0C4D5EE0, 0x080D7870, 0xF7F28790, 0x03CD9208, 0xFFE50F19, 0x00000000}, /* 70 */
+ {0x0C5BB710, 0x0812FF10, 0xF7ED00F0, 0x03CA4704, 0xFFDA01DA, 0x00000000}, /* 71 */
+ {0x0C6A1F80, 0x081885A0, 0xF7E77A60, 0x03C6EBB4, 0xFFCEF4C2, 0x00000000}, /* 72 */
+ {0x0C789820, 0x081E0C10, 0xF7E1F3F0, 0x03C37FF0, 0xFFC3E7DB, 0x00000000}, /* 73 */
+ {0x0C872130, 0x08239270, 0xF7DC6D90, 0x03C003A8, 0xFFB8DB2E, 0x00000000}, /* 74 */
+ {0x0C95BAA0, 0x082918A0, 0xF7D6E760, 0x03BC76B0, 0xFFADCEBC, 0x00000000}, /* 75 */
+ {0x0CA46470, 0x082E9EB0, 0xF7D16150, 0x03B8D8F0, 0xFFA2C2A3, 0x00000000}, /* 76 */
+ {0x0CB31EF0, 0x08342490, 0xF7CBDB70, 0x03B52A40, 0xFF97B6DA, 0x00000000}, /* 77 */
+ {0x0CC1E9F0, 0x0839AA40, 0xF7C655C0, 0x03B16A88, 0xFF8CAB80, 0x00000000}, /* 78 */
+ {0x0CD0C5C0, 0x083F2FC0, 0xF7C0D040, 0x03AD99AC, 0xFF81A089, 0x00000000}, /* 79 */
+ {0x0CDFB270, 0x0844B500, 0xF7BB4B00, 0x03A9B78C, 0xFF76960B, 0x00000000}, /* 80 */
+ {0x0CEEAFF0, 0x084A39F0, 0xF7B5C610, 0x03A5C404, 0xFF6B8C13, 0x00000000}, /* 81 */
+ {0x0CFDBE60, 0x084FBEB0, 0xF7B04150, 0x03A1BEF4, 0xFF6082A8, 0x00000000}, /* 82 */
+ {0x0D0CDDE0, 0x08554310, 0xF7AABCF0, 0x039DA844, 0xFF5579D9, 0x00000000}, /* 83 */
+ {0x0D1C0E90, 0x085AC730, 0xF7A538D0, 0x03997FC8, 0xFF4A71A4, 0x00000000}, /* 84 */
+ {0x0D2B5070, 0x08604AF0, 0xF79FB510, 0x03954568, 0xFF3F6A21, 0x00000000}, /* 85 */
+ {0x0D3AA3A0, 0x0865CE50, 0xF79A31B0, 0x0390F908, 0xFF346358, 0x00000000}, /* 86 */
+ {0x0D4A0830, 0x086B5160, 0xF794AEA0, 0x038C9A80, 0xFF295D4C, 0x00000000}, /* 87 */
+ {0x0D597E30, 0x0870D3F0, 0xF78F2C10, 0x038829B4, 0xFF1E5814, 0x00000000}, /* 88 */
+ {0x0D6905D0, 0x08765630, 0xF789A9D0, 0x0383A67C, 0xFF1353A5, 0x00000000}, /* 89 */
+ {0x0D789F10, 0x087BD7F0, 0xF7842810, 0x037F10C4, 0xFF085021, 0x00000000}, /* 90 */
+ {0x0D884A20, 0x08815940, 0xF77EA6C0, 0x037A6864, 0xFEFD4D88, 0x00000000}, /* 91 */
+ {0x0D9806E0, 0x0886DA10, 0xF77925F0, 0x0375AD3C, 0xFEF24BE8, 0x00000000}, /* 92 */
+ {0x0DA7D5A0, 0x088C5A60, 0xF773A5A0, 0x0370DF28, 0xFEE74B3E, 0x00000000}, /* 93 */
+ {0x0DB7B650, 0x0891DA30, 0xF76E25D0, 0x036BFE08, 0xFEDC4BA8, 0x00000000}, /* 94 */
+ {0x0DC7A920, 0x08975970, 0xF768A690, 0x036709C8, 0xFED14D20, 0x00000000}, /* 95 */
+ {0x0DD7AE10, 0x089CD820, 0xF76327E0, 0x03620234, 0xFEC64FBA, 0x00000000}, /* 96 */
+ {0x0DE7C550, 0x08A25640, 0xF75DA9C0, 0x035CE730, 0xFEBB537E, 0x00000000}, /* 97 */
+ {0x0DF7EEF0, 0x08A7D3C0, 0xF7582C40, 0x0357B8A4, 0xFEB05878, 0x00000000}, /* 98 */
+ {0x0E082AF0, 0x08AD50A0, 0xF752AF60, 0x03527660, 0xFEA55EAE, 0x00000000}, /* 99 */
+ {0x0E187990, 0x08B2CCF0, 0xF74D3310, 0x034D2050, 0xFE9A662A, 0x00000000}, /* 100 */
+ {0x0E28DAC0, 0x08B84880, 0xF747B780, 0x0347B648, 0xFE8F6EFC, 0x00000000}, /* 101 */
+ {0x0E394EA0, 0x08BDC360, 0xF7423CA0, 0x03423824, 0xFE84792C, 0x00000000}, /* 102 */
+ {0x0E49D570, 0x08C33DA0, 0xF73CC260, 0x033CA5D4, 0xFE7984C0, 0x00000000}, /* 103 */
+ {0x0E5A6F20, 0x08C8B720, 0xF73748E0, 0x0336FF20, 0xFE6E91C4, 0x00000000}, /* 104 */
+ {0x0E6B1BC0, 0x08CE2FE0, 0xF731D020, 0x033143F4, 0xFE63A046, 0x00000000}, /* 105 */
+ {0x0E7BDB90, 0x08D3A7D0, 0xF72C5830, 0x032B7428, 0xFE58B054, 0x00000000}, /* 106 */
+ {0x0E8CAE90, 0x08D91F10, 0xF726E0F0, 0x03258F94, 0xFE4DC1E8, 0x00000000}, /* 107 */
+ {0x0E9D94D0, 0x08DE9570, 0xF7216A90, 0x031F9620, 0xFE42D51A, 0x00000000}, /* 108 */
+ {0x0EAE8E70, 0x08E40B10, 0xF71BF4F0, 0x031987A4, 0xFE37E9F2, 0x00000000}, /* 109 */
+ {0x0EBF9B90, 0x08E97FD0, 0xF7168030, 0x031363F8, 0xFE2D0070, 0x00000000}, /* 110 */
+ {0x0ED0BC50, 0x08EEF3B0, 0xF7110C50, 0x030D2B00, 0xFE2218AA, 0x00000000}, /* 111 */
+ {0x0EE1F0C0, 0x08F466B0, 0xF70B9950, 0x0306DC9C, 0xFE1732AA, 0x00000000}, /* 112 */
+ {0x0EF33900, 0x08F9D8D0, 0xF7062730, 0x0300789C, 0xFE0C4E74, 0x00000000}, /* 113 */
+ {0x0F049510, 0x08FF49F0, 0xF700B610, 0x02F9FEE4, 0xFE016C0E, 0x00000000}, /* 114 */
+ {0x0F160530, 0x0904BA40, 0xF6FB45C0, 0x02F36F54, 0xFDF68B8C, 0x00000000}, /* 115 */
+ {0x0F278950, 0x090A2980, 0xF6F5D680, 0x02ECC9B8, 0xFDEBACF0, 0x00000000}, /* 116 */
+ {0x0F3921A0, 0x090F97D0, 0xF6F06830, 0x02E60E00, 0xFDE0D04C, 0x00000000}, /* 117 */
+ {0x0F4ACE50, 0x09150530, 0xF6EAFAD0, 0x02DF3C08, 0xFDD5F5A8, 0x00000000}, /* 118 */
+ {0x0F5C8F70, 0x091A7180, 0xF6E58E80, 0x02D85398, 0xFDCB1D04, 0x00000000}, /* 119 */
+ {0x0F6E64F0, 0x091FDCC0, 0xF6E02340, 0x02D15498, 0xFDC04674, 0x00000000}, /* 120 */
+ {0x0F804F10, 0x09254700, 0xF6DAB900, 0x02CA3EE8, 0xFDB57200, 0x00000000}, /* 121 */
+ {0x0F924DF0, 0x092AB030, 0xF6D54FD0, 0x02C31260, 0xFDAA9FAC, 0x00000000}, /* 122 */
+ {0x0FA461B0, 0x09301840, 0xF6CFE7C0, 0x02BBCED4, 0xFD9FCF84, 0x00000000}, /* 123 */
+ {0x0FB68A40, 0x09357F30, 0xF6CA80D0, 0x02B47424, 0xFD9501A0, 0x00000000}, /* 124 */
+ {0x0FC8C7D0, 0x093AE500, 0xF6C51B00, 0x02AD022C, 0xFD8A35F8, 0x00000000}, /* 125 */
+ {0x0FDB1AA0, 0x094049B0, 0xF6BFB650, 0x02A578C8, 0xFD7F6C98, 0x00000000}, /* 126 */
+ {0x0FED82A0, 0x0945AD30, 0xF6BA52D0, 0x029DD7D0, 0xFD74A588, 0x00000000}, /* 127 */
+ {0x10000000, 0x094B0F90, 0xF6B4F070, 0x02961F24, 0xFD69E0DC, 0x00000000}, /* 128 */
+ {0x101292E0, 0x095070B0, 0xF6AF8F50, 0x028E4E94, 0xFD5F1E94, 0x00000000}, /* 129 */
+ {0x10253B40, 0x0955D0A0, 0xF6AA2F60, 0x02866600, 0xFD545EC0, 0x00000000}, /* 130 */
+ {0x1037F940, 0x095B2F40, 0xF6A4D0C0, 0x027E6548, 0xFD49A170, 0x00000000}, /* 131 */
+ {0x104ACD20, 0x09608CB0, 0xF69F7350, 0x02764C40, 0xFD3EE694, 0x00000000}, /* 132 */
+ {0x105DB700, 0x0965E8E0, 0xF69A1720, 0x026E1ABC, 0xFD342E40, 0x00000000}, /* 133 */
+ {0x1070B6E0, 0x096B43C0, 0xF694BC40, 0x0265D0A4, 0xFD297898, 0x00000000}, /* 134 */
+ {0x1083CCC0, 0x09709D40, 0xF68F62C0, 0x025D6DC4, 0xFD1EC584, 0x00000000}, /* 135 */
+ {0x1096F900, 0x0975F570, 0xF68A0A90, 0x0254F1F4, 0xFD141514, 0x00000000}, /* 136 */
+ {0x10AA3BA0, 0x097B4C50, 0xF684B3B0, 0x024C5D18, 0xFD096754, 0x00000000}, /* 137 */
+ {0x10BD94A0, 0x0980A1D0, 0xF67F5E30, 0x0243AF0C, 0xFCFEBC58, 0x00000000}, /* 138 */
+ {0x10D10440, 0x0985F5F0, 0xF67A0A10, 0x023AE7A4, 0xFCF41420, 0x00000000}, /* 139 */
+ {0x10E48AA0, 0x098B48A0, 0xF674B760, 0x023206B4, 0xFCE96EB8, 0x00000000}, /* 140 */
+ {0x10F827C0, 0x099099F0, 0xF66F6610, 0x02290C18, 0xFCDECC20, 0x00000000}, /* 141 */
+ {0x110BDBE0, 0x0995E9D0, 0xF66A1630, 0x021FF7A8, 0xFCD42C68, 0x00000000}, /* 142 */
+ {0x111FA720, 0x099B3830, 0xF664C7D0, 0x0216C934, 0xFCC98F94, 0x00000000}, /* 143 */
+ {0x113389A0, 0x09A08520, 0xF65F7AE0, 0x020D80AC, 0xFCBEF5BC, 0x00000000}, /* 144 */
+ {0x11478360, 0x09A5D0A0, 0xF65A2F60, 0x02041DD4, 0xFCB45ED4, 0x00000000}, /* 145 */
+ {0x115B94A0, 0x09AB1A90, 0xF654E570, 0x01FAA080, 0xFCA9CAF0, 0x00000000}, /* 146 */
+ {0x116FBD40, 0x09B062F0, 0xF64F9D10, 0x01F1089A, 0xFC9F3A14, 0x00000000}, /* 147 */
+ {0x1183FDA0, 0x09B5A9D0, 0xF64A5630, 0x01E755F6, 0xFC94AC60, 0x00000000}, /* 148 */
+ {0x119855E0, 0x09BAEF20, 0xF64510E0, 0x01DD885E, 0xFC8A21B8, 0x00000000}, /* 149 */
+ {0x11ACC600, 0x09C032E0, 0xF63FCD20, 0x01D39FBA, 0xFC7F9A40, 0x00000000}, /* 150 */
+ {0x11C14E40, 0x09C57510, 0xF63A8AF0, 0x01C99BDA, 0xFC7515F0, 0x00000000}, /* 151 */
+ {0x11D5EE80, 0x09CAB590, 0xF6354A70, 0x01BF7C8E, 0xFC6A94DC, 0x00000000}, /* 152 */
+ {0x11EAA740, 0x09CFF480, 0xF6300B80, 0x01B541B6, 0xFC601704, 0x00000000}, /* 153 */
+ {0x11FF7860, 0x09D531C0, 0xF62ACE40, 0x01AAEB22, 0xFC559C70, 0x00000000}, /* 154 */
+ {0x12146220, 0x09DA6D60, 0xF62592A0, 0x01A078AC, 0xFC4B2530, 0x00000000}, /* 155 */
+ {0x12296480, 0x09DFA750, 0xF62058B0, 0x0195EA34, 0xFC40B150, 0x00000000}, /* 156 */
+ {0x123E7FC0, 0x09E4DFA0, 0xF61B2060, 0x018B3F7E, 0xFC3640C8, 0x00000000}, /* 157 */
+ {0x1253B3E0, 0x09EA1630, 0xF615E9D0, 0x01807874, 0xFC2BD3AC, 0x00000000}, /* 158 */
+ {0x12690120, 0x09EF4B00, 0xF610B500, 0x017594D4, 0xFC2169FC, 0x00000000}, /* 159 */
+ {0x127E67A0, 0x09F47E20, 0xF60B81E0, 0x016A9490, 0xFC1703D0, 0x00000000}, /* 160 */
+ {0x1293E780, 0x09F9AF70, 0xF6065090, 0x015F7764, 0xFC0CA120, 0x00000000}, /* 161 */
+ {0x12A980E0, 0x09FEDF00, 0xF6012100, 0x01543D2E, 0xFC0241F8, 0x00000000}, /* 162 */
+ {0x12BF33C0, 0x0A040CD0, 0xF5FBF330, 0x0148E5D0, 0xFBF7E668, 0x00000000}, /* 163 */
+ {0x12D50060, 0x0A0938C0, 0xF5F6C740, 0x013D7118, 0xFBED8E78, 0x00000000}, /* 164 */
+ {0x12EAE700, 0x0A0E62F0, 0xF5F19D10, 0x0131DED4, 0xFBE33A20, 0x00000000}, /* 165 */
+ {0x1300E7A0, 0x0A138B40, 0xF5EC74C0, 0x01262EE2, 0xFBD8E978, 0x00000000}, /* 166 */
+ {0x13170280, 0x0A18B1C0, 0xF5E74E40, 0x011A6100, 0xFBCE9C80, 0x00000000}, /* 167 */
+ {0x132D3780, 0x0A1DD660, 0xF5E229A0, 0x010E752E, 0xFBC45348, 0x00000000}, /* 168 */
+ {0x13438720, 0x0A22F920, 0xF5DD06E0, 0x01026B18, 0xFBBA0DC8, 0x00000000}, /* 169 */
+ {0x1359F140, 0x0A2819F0, 0xF5D7E610, 0x00F642A1, 0xFBAFCC18, 0x00000000}, /* 170 */
+ {0x13707620, 0x0A2D38E0, 0xF5D2C720, 0x00E9FBA3, 0xFBA58E40, 0x00000000}, /* 171 */
+ {0x13871600, 0x0A3255F0, 0xF5CDAA10, 0x00DD95E1, 0xFB9B5428, 0x00000000}, /* 172 */
+ {0x139DD0C0, 0x0A377100, 0xF5C88F00, 0x00D11143, 0xFB911E00, 0x00000000}, /* 173 */
+ {0x13B4A6A0, 0x0A3C8A20, 0xF5C375E0, 0x00C46D9C, 0xFB86EBC8, 0x00000000}, /* 174 */
+ {0x13CB97E0, 0x0A41A140, 0xF5BE5EC0, 0x00B7AAAA, 0xFB7CBD78, 0x00000000}, /* 175 */
+ {0x13E2A4A0, 0x0A46B670, 0xF5B94990, 0x00AAC84D, 0xFB729318, 0x00000000}, /* 176 */
+ {0x13F9CD00, 0x0A4BC9A0, 0xF5B43660, 0x009DC65F, 0xFB686CC0, 0x00000000}, /* 177 */
+ {0x141110E0, 0x0A50DAD0, 0xF5AF2530, 0x0090A4B0, 0xFB5E4A68, 0x00000000}, /* 178 */
+ {0x142870E0, 0x0A55E9F0, 0xF5AA1610, 0x00836300, 0xFB542C20, 0x00000000}, /* 179 */
+ {0x143FECE0, 0x0A5AF710, 0xF5A508F0, 0x0076013A, 0xFB4A11E8, 0x00000000}, /* 180 */
+ {0x14578520, 0x0A600220, 0xF59FFDE0, 0x00687F20, 0xFB3FFBC8, 0x00000000}, /* 181 */
+ {0x146F3980, 0x0A650B10, 0xF59AF4F0, 0x005ADC9D, 0xFB35E9E0, 0x00000000}, /* 182 */
+ {0x14870AA0, 0x0A6A1200, 0xF595EE00, 0x004D1961, 0xFB2BDC08, 0x00000000}, /* 183 */
+ {0x149EF860, 0x0A6F16D0, 0xF590E930, 0x003F354A, 0xFB21D268, 0x00000000}, /* 184 */
+ {0x14B702C0, 0x0A741980, 0xF58BE680, 0x00313035, 0xFB17CD00, 0x00000000}, /* 185 */
+ {0x14CF2A40, 0x0A791A10, 0xF586E5F0, 0x002309F1, 0xFB0DCBD8, 0x00000000}, /* 186 */
+ {0x14E76EA0, 0x0A7E1880, 0xF581E780, 0x0014C24B, 0xFB03CEF8, 0x00000000}, /* 187 */
+ {0x14FFD0A0, 0x0A8314E0, 0xF57CEB20, 0x00065903, 0xFAF9D658, 0x00000000}, /* 188 */
+ {0x15184FC0, 0x0A880EF0, 0xF577F110, 0xFFF7CE06, 0xFAEFE218, 0x00000000}, /* 189 */
+ {0x1530ECC0, 0x0A8D06F0, 0xF572F910, 0xFFE92120, 0xFAE5F230, 0x00000000}, /* 190 */
+ {0x1549A740, 0x0A91FCB0, 0xF56E0350, 0xFFDA5212, 0xFADC06A8, 0x00000000}, /* 191 */
+ {0x15627FC0, 0x0A96F040, 0xF5690FC0, 0xFFCB60A9, 0xFAD21F70, 0x00000000}, /* 192 */
+ {0x157B7660, 0x0A9BE1A0, 0xF5641E60, 0xFFBC4CD2, 0xFAC83CC0, 0x00000000}, /* 193 */
+ {0x15948B20, 0x0AA0D0C0, 0xF55F2F40, 0xFFAD164B, 0xFABE5E80, 0x00000000}, /* 194 */
+ {0x15ADBE80, 0x0AA5BDB0, 0xF55A4250, 0xFF9DBCD3, 0xFAB484A8, 0x00000000}, /* 195 */
+ {0x15C71060, 0x0AAAA850, 0xF55557B0, 0xFF8E4056, 0xFAAAAF58, 0x00000000}, /* 196 */
+ {0x15E080A0, 0x0AAF90B0, 0xF5506F50, 0xFF7EA0A3, 0xFAA0DE98, 0x00000000}, /* 197 */
+ {0x15FA1020, 0x0AB476D0, 0xF54B8930, 0xFF6EDD77, 0xFA971258, 0x00000000}, /* 198 */
+ {0x1613BEC0, 0x0AB95AB0, 0xF546A550, 0xFF5EF6A1, 0xFA8D4AA8, 0x00000000}, /* 199 */
+ {0x162D8C80, 0x0ABE3C30, 0xF541C3D0, 0xFF4EEBFD, 0xFA838798, 0x00000000}, /* 200 */
+ {0x16477980, 0x0AC31B60, 0xF53CE4A0, 0xFF3EBD5B, 0xFA79C930, 0x00000000}, /* 201 */
+ {0x16618620, 0x0AC7F850, 0xF53807B0, 0xFF2E6A85, 0xFA700F60, 0x00000000}, /* 202 */
+ {0x167BB280, 0x0ACCD2E0, 0xF5332D20, 0xFF1DF33D, 0xFA665A48, 0x00000000}, /* 203 */
+ {0x1695FEC0, 0x0AD1AB20, 0xF52E54E0, 0xFF0D575C, 0xFA5CA9D0, 0x00000000}, /* 204 */
+ {0x16B06B40, 0x0AD68100, 0xF5297F00, 0xFEFC96B2, 0xFA52FE18, 0x00000000}, /* 205 */
+ {0x16CAF7E0, 0x0ADB5470, 0xF524AB90, 0xFEEBB0FE, 0xFA495718, 0x00000000}, /* 206 */
+ {0x16E5A520, 0x0AE025A0, 0xF51FDA60, 0xFEDAA62A, 0xFA3FB4D8, 0x00000000}, /* 207 */
+ {0x170072C0, 0x0AE4F450, 0xF51B0BB0, 0xFEC975E6, 0xFA361768, 0x00000000}, /* 208 */
+ {0x171B6140, 0x0AE9C0A0, 0xF5163F60, 0xFEB8200E, 0xFA2C7EC0, 0x00000000}, /* 209 */
+ {0x173670C0, 0x0AEE8A90, 0xF5117570, 0xFEA6A470, 0xFA22EAF0, 0x00000000}, /* 210 */
+ {0x1751A140, 0x0AF35210, 0xF50CADF0, 0xFE9502C6, 0xFA195BE8, 0x00000000}, /* 211 */
+ {0x176CF340, 0x0AF81710, 0xF507E8F0, 0xFE833AF4, 0xFA0FD1C8, 0x00000000}, /* 212 */
+ {0x178866C0, 0x0AFCD9B0, 0xF5032650, 0xFE714CC4, 0xFA064C90, 0x00000000}, /* 213 */
+ {0x17A3FBC0, 0x0B0199E0, 0xF4FE6620, 0xFE5F37F0, 0xF9FCCC38, 0x00000000}, /* 214 */
+ {0x17BFB2E0, 0x0B0657A0, 0xF4F9A860, 0xFE4CFC5C, 0xF9F350D0, 0x00000000}, /* 215 */
+ {0x17DB8BE0, 0x0B0B12D0, 0xF4F4ED30, 0xFE3A99BE, 0xF9E9DA60, 0x00000000}, /* 216 */
+ {0x17F78720, 0x0B0FCB90, 0xF4F03470, 0xFE280FE6, 0xF9E068E0, 0x00000000}, /* 217 */
+ {0x1813A4E0, 0x0B1481D0, 0xF4EB7E30, 0xFE155EA4, 0xF9D6FC68, 0x00000000}, /* 218 */
+ {0x182FE580, 0x0B193590, 0xF4E6CA70, 0xFE0285BC, 0xF9CD94E0, 0x00000000}, /* 219 */
+ {0x184C4880, 0x0B1DE6D0, 0xF4E21930, 0xFDEF8508, 0xF9C43270, 0x00000000}, /* 220 */
+ {0x1868CEA0, 0x0B229580, 0xF4DD6A80, 0xFDDC5C3C, 0xF9BAD508, 0x00000000}, /* 221 */
+ {0x18857820, 0x0B2741B0, 0xF4D8BE50, 0xFDC90B34, 0xF9B17CA8, 0x00000000}, /* 222 */
+ {0x18A244E0, 0x0B2BEB50, 0xF4D414B0, 0xFDB591B4, 0xF9A82960, 0x00000000}, /* 223 */
+ {0x18BF3560, 0x0B309270, 0xF4CF6D90, 0xFDA1EF84, 0xF99EDB38, 0x00000000}, /* 224 */
+ {0x18DC4940, 0x0B3536E0, 0xF4CAC920, 0xFD8E2474, 0xF9959230, 0x00000000}, /* 225 */
+ {0x18F98180, 0x0B39D8E0, 0xF4C62720, 0xFD7A304C, 0xF98C4E40, 0x00000000}, /* 226 */
+ {0x1916DDA0, 0x0B3E7840, 0xF4C187C0, 0xFD6612C8, 0xF9830F80, 0x00000000}, /* 227 */
+ {0x19345E60, 0x0B431510, 0xF4BCEAF0, 0xFD51CBBC, 0xF979D5F0, 0x00000000}, /* 228 */
+ {0x19520380, 0x0B47AF40, 0xF4B850C0, 0xFD3D5AF0, 0xF970A190, 0x00000000}, /* 229 */
+ {0x196FCD80, 0x0B4C46D0, 0xF4B3B930, 0xFD28C030, 0xF9677260, 0x00000000}, /* 230 */
+ {0x198DBC60, 0x0B50DBD0, 0xF4AF2430, 0xFD13FB38, 0xF95E4868, 0x00000000}, /* 231 */
+ {0x19ABD080, 0x0B556E20, 0xF4AA91E0, 0xFCFF0BDC, 0xF95523B0, 0x00000000}, /* 232 */
+ {0x19CA09C0, 0x0B59FDE0, 0xF4A60220, 0xFCE9F1E0, 0xF94C0440, 0x00000000}, /* 233 */
+ {0x19E868E0, 0x0B5E8B00, 0xF4A17500, 0xFCD4AD00, 0xF942EA10, 0x00000000}, /* 234 */
+ {0x1A06EDE0, 0x0B631570, 0xF49CEA90, 0xFCBF3D04, 0xF939D528, 0x00000000}, /* 235 */
+ {0x1A2598A0, 0x0B679D30, 0xF49862D0, 0xFCA9A1C8, 0xF930C598, 0x00000000}, /* 236 */
+ {0x1A446980, 0x0B6C2250, 0xF493DDB0, 0xFC93DB14, 0xF927BB58, 0x00000000}, /* 237 */
+ {0x1A636100, 0x0B70A4D0, 0xF48F5B30, 0xFC7DE898, 0xF91EB668, 0x00000000}, /* 238 */
+ {0x1A827F20, 0x0B752490, 0xF48ADB70, 0xFC67CA20, 0xF915B6D8, 0x00000000}, /* 239 */
+ {0x1AA1C400, 0x0B79A1B0, 0xF4865E50, 0xFC517F68, 0xF90CBC98, 0x00000000}, /* 240 */
+ {0x1AC12FE0, 0x0B7E1C20, 0xF481E3E0, 0xFC3B0858, 0xF903C7C8, 0x00000000}, /* 241 */
+ {0x1AE0C320, 0x0B8293D0, 0xF47D6C30, 0xFC24649C, 0xF8FAD860, 0x00000000}, /* 242 */
+ {0x1B007DC0, 0x0B8708D0, 0xF478F730, 0xFC0D93EC, 0xF8F1EE58, 0x00000000}, /* 243 */
+ {0x1B206000, 0x0B8B7B20, 0xF47484E0, 0xFBF69630, 0xF8E909C8, 0x00000000}, /* 244 */
+ {0x1B406A60, 0x0B8FEAB0, 0xF4701550, 0xFBDF6B08, 0xF8E02A98, 0x00000000}, /* 245 */
+ {0x1B609CC0, 0x0B945790, 0xF46BA870, 0xFBC81258, 0xF8D750D8, 0x00000000}, /* 246 */
+ {0x1B80F780, 0x0B98C1B0, 0xF4673E50, 0xFBB08BD8, 0xF8CE7CA0, 0x00000000}, /* 247 */
+ {0x1BA17AE0, 0x0B9D2910, 0xF462D6F0, 0xFB98D748, 0xF8C5ADE0, 0x00000000}, /* 248 */
+ {0x1BC22720, 0x0BA18DB0, 0xF45E7250, 0xFB80F468, 0xF8BCE490, 0x00000000}, /* 249 */
+ {0x1BE2FC40, 0x0BA5EFA0, 0xF45A1060, 0xFB68E2F8, 0xF8B420D0, 0x00000000}, /* 250 */
+ {0x1C03FAC0, 0x0BAA4EC0, 0xF455B140, 0xFB50A2D0, 0xF8AB6290, 0x00000000}, /* 251 */
+ {0x1C2522A0, 0x0BAEAB20, 0xF45154E0, 0xFB3833A0, 0xF8A2A9D0, 0x00000000}, /* 252 */
+ {0x1C467420, 0x0BB304B0, 0xF44CFB50, 0xFB1F9530, 0xF899F6A0, 0x00000000}, /* 253 */
+ {0x1C67EFA0, 0x0BB75B80, 0xF448A480, 0xFB06C750, 0xF8914908, 0x00000000}, /* 254 */
+ {0x1C899580, 0x0BBBAF90, 0xF4445070, 0xFAEDC9A0, 0xF888A0E0, 0x00000000}, /* 255 */
+ {0x1CAB6560, 0x0BC000C0, 0xF43FFF40, 0xFAD49C10, 0xF87FFE70, 0x00000000}, /* 256 */
+ {0, 0, 0, 0, 0, 0}
+};
diff --git a/kernel/framework/include/grc3.h b/kernel/framework/include/grc3.h
new file mode 100644
index 0000000..f47e902
--- /dev/null
+++ b/kernel/framework/include/grc3.h
@@ -0,0 +1,339 @@
+/*
+ * Purpose: GRC library version 3.1 internal definitions
+ *
+ * GRC3 is a high quality sample rate conversion module that uses fixed point
+ * arithmetic.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 GRC3_H_INCLUDED
+#define GRC3_H_INCLUDED
+
+#if !defined(CONFIG_OSS_GRC_MIN_QUALITY) || CONFIG_OSS_GRC_MIN_QUALITY > 6
+#define CONFIG_OSS_GRC_MIN_QUALITY 0
+#endif
+
+#if !defined(CONFIG_OSS_GRC_MAX_QUALITY) || CONFIG_OSS_GRC_MAX_QUALITY < CONFIG_OSS_GRC_MIN_QUALITY
+#define CONFIG_OSS_GRC_MAX_QUALITY 6
+#endif
+
+
+#if (CONFIG_OSS_GRC_MIN_QUALITY<=1)&&(CONFIG_OSS_GRC_MAX_QUALITY>=0)
+#define GRC3_COMPILE_L
+#endif
+
+#if (CONFIG_OSS_GRC_MIN_QUALITY<=2)&&(CONFIG_OSS_GRC_MAX_QUALITY>=2)
+#define GRC3_COMPILE_M
+#endif
+
+#if (CONFIG_OSS_GRC_MIN_QUALITY<=4)&&(CONFIG_OSS_GRC_MAX_QUALITY>=3)
+#define GRC3_COMPILE_H
+#endif
+
+#if (CONFIG_OSS_GRC_MIN_QUALITY<=6)&&(CONFIG_OSS_GRC_MAX_QUALITY>=5)
+#define GRC3_COMPILE_P
+#endif
+
+#if (CONFIG_OSS_GRC_MIN_QUALITY<=3)
+ #if (CONFIG_OSS_GRC_MAX_QUALITY>=3)
+ #define DEFAULT_GRC_QUALITY 3
+ #else
+ #define DEFAULT_GRC_QUALITY CONFIG_OSS_GRC_MAX_QUALITY
+ #endif
+#else
+ #define DEFAULT_GRC_QUALITY CONFIG_OSS_GRC_MIN_QUALITY
+#endif
+
+
+#define GRCinline inline static
+#define GRCpreg register
+#define GRCvreg register
+
+
+#define GRC3_MAXHISTORY 4096
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct s_grc3state_t
+ {
+ uint32_t srcrate;
+ uint32_t dstrate;
+ uint32_t ptr;
+ uint32_t ptr_incv;
+
+ uint32_t sat;
+ uint32_t filtfactor;
+ int32_t *historyptr;
+ int32_t dummy_pad1;
+
+ int32_t history[GRC3_MAXHISTORY * 2];
+
+ uint32_t insz;
+ uint32_t outsz;
+ }
+ grc3state_t;
+
+
+/*****************************************************************************
+
+ Tutorial on how to use GRC3 rate conversion
+
+1. First, you create an instance of grc3state_t for each channel. If you
+ are working with stereo files - you will need 2 of such instances,
+ for quadro - 4.
+
+ The instances may be allocated in either static or dynamic memory - that
+ makes no difference to the convertor. So, if your program has to process
+ one stereo stream, there's no reason why should you use malloc/free to
+ allocate/deallocate structures. Also, in device drivers, you can
+ use static variables as well:
+
+ static grc3state_t grc[2]; // for two channels
+
+
+2. Before starting any conversion, grc3state_t instances should be initialized
+ properly, and you do this with grc3_setup function. Function itself does
+ not allocate additional memory or change anything except grc3state_t
+ structure, so this is thread safe, and you don't have to do additional
+ "deinitialization".
+
+ If you are doing interleaved audio (stereo/quadro/whatever) conversion,
+ you should do setup on each of the channels, and should have separate
+ instance of grc3state_t for each channel. As you will understand further,
+ such conversion is done separately. And now, the setup function:
+
+ int grc3_setup( grc3state_t *grc,
+ uint32_t fromRate,
+ uint32_t toRate );
+
+ grc - pointer to grc3state_t instance
+ fromRate - source sample rate
+ toRate - destination sample rate
+
+ RETURNS - 1 on success, and 0 if conversion is not supported
+
+ Note, that sample rates itself are not important - the important thing
+ is ratio between those sample rates. So, for example, if you have to
+ convert from 24000Hz to 48000Hz, it's ok to write:
+
+ result = grc3_setup( &grc[0], 240, 480 );
+
+ Sometimes (in MIDI synths) it would be desired to use fractional sample
+ rates. For example, setup for conversion from 33100.78 to 48000 may look
+ like this:
+
+ result = grc3_setup( &grc[0], 3310078, 4800000);
+
+ Note, that on stereo, GRC3 setup will look like this:
+
+ static grc3state_t grc[2];
+
+ // ...
+
+ result =
+ grc3_setup( &grc[0], 3310078, 4800000)
+ && grc3_setup( &grc[1], 3310078, 4800000);
+
+
+ Note, that you should not rely on grc3_setup's fast execution or any
+ execution timing. It may contain some massive arithmetic and even huge
+ loops, so avoid putting grc3_setup to inner loops and calling in
+ latency-dependent code.
+
+
+3. Next, before running a stream through grc3_convert function, you should
+ reset each of grc3state_t instance used:
+
+ int grc3_reset(grc3state_t *grc);
+
+
+ grc - pointer to GRC3 instance variable
+
+ RETURNS - 1 on success, 0 on failure
+
+ So, for stereo, this appears to be:
+
+ static grc3state_t grc[2];
+
+ // ...
+
+ grc3_reset( &grc[0] );
+ grc3_reset( &grc[1] );
+
+
+4. Finally, doing conversion is easy:
+
+ int grc3_convert( grc3state_t *grc,
+ int domain,
+ int quality,
+ const void *src,
+ void *dst,
+ int maxInSize,
+ int maxOutSize,
+ int interleave,
+ int offset );
+
+
+ grc - pointer to initialized grc3state_t instance; you
+ can specify NULL to check whether a particular
+ domain/quality pair is supported, check return value
+
+ domain - number of bits in stream;
+ supported values are 8, 16, 32, -16, -32;
+
+ minus sign stands for swapped-endian conversion; that
+ will do big-endian conversion on little-endian machines
+ and little-endian conversion on big-endian machines
+
+ quality - quality to use for conversion, supported values are:
+
+ 0 - D lowest quality (normally equals to low quality)
+ 1 - L low quality (spline interpolation)
+ 2 - M medium quality (lagrange interpolation)
+ 3 - H high quality
+ 4 - HX high quality (high quality with extra precision)
+ 5 - P production quality
+
+ 6 - PX production quality (prod quality with extra precision)
+ (PX is currently disabled because it causes a crash)
+
+ src - source audio buffer
+
+ dst - destination audio buffer;
+
+ maxInSize - size of input buffer (in samples per channel!)
+
+ maxOutSize - size of output buffer (in samples per channel!)
+ (will never overrun this size)
+
+ interleave - interleave factor; for MONO or non-interleaved data
+ it should be equal to 1;
+
+ 2 - STEREO interleaved audio
+ 4 - QUADRO interleaved audio
+
+ So, basically, this parameter should be equal to number
+ of interleaved channels
+
+ offset - number of interleaved channel currently processing,
+ starting from 0; for MONO or non-interleaved data
+ it should be equal to 0
+
+
+ RETURNS in case of grc != NULL
+
+ - actual number if INPUT samples processed,
+ or -1 in case if conversion is not supported;
+
+ For unsupported quality values, it will fall back to
+ "D" quality (the lowest one)
+
+ also on return it sets:
+
+ grc->insz == number of input samples processed
+ grc->outsz == number of output samples
+
+
+
+ RETURNS in case of grc == NULL
+
+ - will return 0 in case quality/domain pair is supported
+
+ if specified quality and/or bitdepth is not supported,
+ then function will return -1
+
+ Note, that if quality is not supported but bitdepth is,
+ calling the function with real data will fall back
+ to the worst quality available.
+
+
+
+5. Interleaved processing of N channels is done like this:
+
+
+ static grc3state_t grc[N];
+ int t;
+
+ //...
+
+
+ for(t=0; t<N; t++)
+ {
+ grc3_setup( &grc[t], 22050, 48000 );
+
+ grc3_reset( &grc[t] );
+ }
+
+
+ //...
+
+ while (...)
+ {
+
+ for(t=0; t<N; t++)
+ {
+ grc3_convert(
+ &grc[t], // instance pointer
+
+ 16, 4, // numbits, quality
+
+ in_buffer, // input buffer
+ out_buffer, // input buffer
+
+ in_samples_count, // number of samples
+ // in in_buffer
+ 2048, // size of out_buffer
+
+ N, t // num of channels, channel#
+
+ );
+ }
+
+
+ // Normally, for interleaved data, ->outsz of all instances will
+ // be the same for the same stream
+
+ put_sound_somewhere( out_buffer,
+ grc[0]->outsz * N * sizeof(out_buffer[0]) );
+
+ }
+
+
+6. If you use the same storage and the same setup for processing few separate
+ non-related sounds, to prevent the feedback of sound1's tail to sound2's
+ beginning - do grc3_reset on the state instances before calling
+ grc_convert.
+
+******************************************************************************/
+
+
+ int grc3_setup (grc3state_t * grc, uint32_t fromRate, uint32_t toRate);
+
+ int grc3_reset (grc3state_t * grc);
+
+ int grc3_convert (grc3state_t * grc,
+ int domain, int quality,
+ void *src, void *dst,
+ int sz, int bufsz, int inc, int offset);
+
+
+ int32_t _clamp24 (int32_t v);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
diff --git a/kernel/framework/include/internal.h b/kernel/framework/include/internal.h
new file mode 100644
index 0000000..66ca04e
--- /dev/null
+++ b/kernel/framework/include/internal.h
@@ -0,0 +1,164 @@
+/*
+ * Purpose: Definitions for internal use by OSS
+ *
+ * Definitions for private use by the ossctl program. Everything defined
+ * in this file is likely to change without notice between OSS versions.
+ *
+ * Note that thse ioctl calls are not for public use. They cannot be used by
+ * applications that are not part of the official OSS distribution.
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 _INTERNAL_H_
+#define _INTERNAL_H_
+
+/*
+ * This file defines ioctl codes 200 to 255 in the 'X' block. These codes may be
+ * reused for internal purposes by other OSSv4 implementations that don't use
+ * this file. Implementations based on the 'stock' OSS code can add their
+ * private use ioctl codes in this file. However in such case it's recommended
+ * to notify the OSS development community (4Front Technologies) so that the
+ * code can be marked as reserved in the official sources.
+ *
+ */
+
+#define OSS_MAXERR 200
+typedef struct
+{
+ int nerrors;
+ int errors[OSS_MAXERR];
+ int error_parms[OSS_MAXERR];
+}
+oss_error_info;
+#define BOOTERR_BAD_PCIIRQ 1
+#define BOOTERR_AC97CODEC 2
+#define BOOTERR_IRQSTORM 3
+#define BOOTERR_BIGMEM 4
+
+extern oss_error_info oss_booterrors;
+
+#if 0
+typedef struct
+{
+ int mode; /* OPEN_READ and/or OPEN_WRITE */
+ oss_devlist_t devlist;
+}
+oss_reroute_t;
+#endif
+
+typedef struct
+{
+/*
+ * Private structure for renumbering legacy dsp, mixer and MIDI devices
+ */
+ int n;
+ short map[HARD_MAX_AUDIO_DEVFILES];
+} oss_renumber_t;
+/*
+ * Some internal use only ioctl calls ('X', 200-255)
+ */
+#if 0
+#define OSSCTL_GET_REROUTE __SIOWR('X', 200, oss_reroute_t)
+#define OSSCTL_SET_REROUTE __SIOW ('X', 200, oss_reroute_t)
+#endif
+
+#ifdef APPLIST_SUPPORT
+/*
+ * Application redirection list for audio.c.
+ */
+typedef struct
+{
+ char name[32 + 1]; /* Command name (such as xmms) */
+ int mode; /* OPEN_READ|OPEN_WRITE */
+ int dev; /* "Target" audio device number */
+ int open_flags; /* Open flags to be passed to oss_audio_open_engine */
+} app_routing_t;
+
+#define APPLIST_SIZE 64
+extern app_routing_t oss_applist[APPLIST_SIZE];
+extern int oss_applist_size;
+
+#define OSSCTL_RESET_APPLIST __SIO ('X', 201)
+#define OSSCTL_ADD_APPLIST __SIOW ('X', 201, app_routing_t)
+#endif
+
+/*
+ * Legacy device file numbering calls
+ */
+#define OSSCTL_RENUM_AUDIODEVS __SIOW ('X', 202, oss_renumber_t)
+#define OSSCTL_RENUM_MIXERDEVS __SIOW ('X', 203, oss_renumber_t)
+#define OSSCTL_RENUM_MIDIDEVS __SIOW ('X', 204, oss_renumber_t)
+
+/*
+ * vmixctl related ioctl calls
+ */
+
+typedef struct
+{
+ int masterdev;
+ int inputdev;
+
+ int attach_flags;
+
+/*
+ * 0x000000xx reserved
+ * for #clients to prealloc
+ */
+#define VMIX_INSTALL_NOPREALLOC 0x00000100
+#define VMIX_INSTALL_NOINPUT 0x00000200
+#define VMIX_INSTALL_VISIBLE 0x00000400
+#define VMIX_INSTALL_MANUAL 0x00000800 /* By vmxctl */
+} vmixctl_attach_t;
+
+typedef struct
+{
+ int masterdev;
+ int rate;
+} vmixctl_rate_t;
+
+typedef int oss_chninfo[128];
+typedef struct
+{
+ int masterdev;
+ oss_chninfo map;
+} vmixctl_map_t;
+
+#define VMIXCTL_ATTACH __SIOW ('X', 220, vmixctl_attach_t)
+#define VMIXCTL_DETACH __SIOW ('X', 221, vmixctl_attach_t)
+#define VMIXCTL_RATE __SIOW ('X', 222, vmixctl_rate_t)
+#define VMIXCTL_REMAP __SIOW ('X', 223, vmixctl_map_t)
+
+/*
+ * FreeBSD compatibility ioctl
+ */
+#define FREEBSD_GETBLKSIZE __SIOR ('P', 4, int)
+
+#ifdef DO_TIMINGS
+#define DFLAG_ALL 0x00000001
+#define DFLAG_PROFILE 0x00000002
+/*
+ * Time counters
+ */
+#define DF_IDDLE 0
+#define DF_WRITE 1
+#define DF_READ 2
+#define DF_INTERRUPT 3
+#define DF_SLEEPWRITE 4
+#define DF_SLEEPREAD 5
+#define DF_SRCWRITE 6
+#define DF_SRCREAD 7
+#define DF_NRBINS 8
+#endif
+
+#endif
diff --git a/kernel/framework/include/midi_core.h b/kernel/framework/include/midi_core.h
new file mode 100644
index 0000000..2d95efc
--- /dev/null
+++ b/kernel/framework/include/midi_core.h
@@ -0,0 +1,337 @@
+#ifndef MIDI_CORE_H
+#define MIDI_CORE_H
+/*
+ * Purpose: Structure and function definitions for OSS MIDI core
+ *
+ * IMPORTANT NOTICE!
+ *
+ * This file contains internal structures used by Open Sound Systems.
+ * They will change without any notice between OSS versions. Care must be taken
+ * to make sure any software using this header gets properly re-compiled before
+ * use.
+ *
+ * 4Front Technologies (or anybody else) takes no responsibility of damages
+ * caused by use of this file.
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define OSS_MIDI_DRIVER_VERSION 1
+
+struct midi_input_info
+{ /* MIDI input scanner variables */
+#define MI_MAX 32
+ 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;
+ int m_f1_flag; /* MTC Quarter frame message flag */
+};
+
+
+typedef int (*oss_midi_inputbyte_t) (int dev, unsigned char data);
+typedef int (*oss_midi_inputbuf_t) (int dev, unsigned char *data, int len);
+typedef int (*oss_midi_outputintr_t) (int dev);
+
+typedef struct _midi_driver
+{
+ int (*open) (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf,
+ oss_midi_outputintr_t outputintr);
+ void (*close) (int dev, int mode);
+ int (*ioctl) (int dev, unsigned int cmd, ioctl_arg arg);
+ int (*outputc) (int dev, unsigned char data);
+ int (*bulk_write) (int dev, unsigned char *buf, int len);
+ int max_bulk_bytes; /* Maximum len parameter for the bulk_write() entry point */
+ void (*flush_output) (int dev);
+ int (*wait_output) (int dev);
+ void (*timer_setup) (int dev);
+ void (*init_device) (int dev);
+} midi_driver_t;
+
+/*
+ * MIDI ports (physical and virtual)
+ */
+
+typedef struct midi_queue_t midi_queue_t;
+
+typedef struct _midi_operations
+{
+ int dev; /* MIDI device number */
+ char name[64];
+ midi_driver_t *d;
+ int caps;
+ int open_mode; /* OPEN_READ | OPEN_WRITE */
+
+ int working_mode; /* See SNDCTL_MIDI_SETMODE */
+ int timebase;
+ int tempo;
+ struct midi_input_info in_info;
+ struct coproc_operations *coproc;
+ void *devc;
+ void *os_id; /* The device ID (dip) given by the system. */
+ int enabled;
+ int unloaded;
+ int is_killed;
+ oss_device_t *osdev;
+ oss_device_t *master_osdev; /* osdev struct of the master device (for virtual drivers) */
+ int card_number;
+ int port_number;
+ oss_devnode_t devnode;
+ int real_dev;
+ char handle[32];
+ unsigned long flags;
+#define MFLAG_NOSEQUENCER 0x00000001 /* Device not to be opened by the sequencer driver */
+#define MFLAG_VIRTUAL 0x00000002
+#define MFLAG_SELFTIMING 0x00000004 /* Generates MTC timing itself */
+#define MFLAG_CLIENT 0x00000008 /* Client side virtual device */
+#define MFLAG_SERVER 0x00000010 /* Client side virtual device */
+#define MFLAG_INTERNAL 0x00000020 /* Internal device */
+#define MFLAG_EXTERNAL 0x00000040 /* External device */
+
+#define MFLAG_INPUT 0x00000080
+#define MFLAG_OUTPUT 0x00000100
+
+#define MFLAG_OUTINTR 0x00000200 /* Supports output interrupts - no polling needed */
+#define MFLAG_MTC 0x00000400 /* Device is MTC/SMPTE capable */
+#define MFLAG_QUIET 0x00000800 /* No automatic messages */
+
+ void (*input_callback) (int dev, unsigned char midich);
+ void (*event_input) (int dev, unsigned char *data, int len);
+
+#ifndef CONFIGURE_C
+ oss_mutex_t mutex;
+ oss_wait_queue_t *in_wq, *out_wq;
+ timeout_id_t out_timeout;
+#endif
+ pid_t pid;
+ int magic;
+ char cmd[16];
+
+ int prech_timeout; /* Wait time for the first input byte */
+
+/*
+ * MTC generator
+ */
+
+ int mtc_timebase;
+ int mtc_phase; /* Which part should be sent next */
+ long long mtc_t0;
+ int mtc_prev_t, mtc_codetype, mtc_current;
+ timeout_id_t mtc_timeout_id;
+
+/*
+ * Event queues
+ */
+
+ struct midi_queue_t *in_queue, *out_queue;
+
+/*
+ * Timer
+ */
+ int timer_driver;
+ int timer_dev;
+ int latency; /* In usecs, -1=unknown */
+ int is_timing_master;
+} mididev_t, *mididev_p;
+
+/*
+ * MIDI clients (/dev/midi device files)
+ */
+
+typedef struct
+{
+ int num; /* Own index in the oss_midi_clients[] table */
+ int open_mode; /* OPEN_READ and/or OPEN_WRITE */
+ mididev_p mididev; /* Pointer to the MIDI device (or NULL) */
+} oss_midi_client_t;
+
+#define MAX_MIDI_CLIENTS (MAX_MIDI_DEV + 20)
+extern int num_midi_clients;
+extern oss_midi_client_t *oss_midi_clients[MAX_MIDI_CLIENTS];
+
+extern mididev_t **midi_devs;
+extern int num_mididevs;
+
+struct oss_timer_driver;
+typedef void (*oss_midi_wait_callback_t) (void *arg);
+
+typedef struct
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+ int driver_dev;
+ int timer_dev;
+ char *name; /* Pointer to driver->name */
+ int refcount; /* Number of /dev/midi* devices currently using this timer */
+ unsigned long password; /* Random number given when an instance is created */
+
+ struct oss_timer_driver *d;
+
+ oss_midi_time_t next_tick, prev_tick;
+ oss_midi_time_t bookmark_tick;
+ oss_uint64_t bookmark_time;
+ int tempo, pending_tempo;
+ int timebase;
+ int run_state; /* 0=stopped, 1=run */
+ oss_uint64_t prev_time, next_time;
+
+ void *devc;
+ void *timerc;
+ oss_midi_wait_callback_t callback;
+
+ /*
+ * Bitmap of MIDI devices linked with this one
+ */
+ unsigned int midimap[(MAX_MIDI_DEV + 31) / 32];
+ oss_uint64_t midi_times[MAX_MIDI_DEV]; /* Next event times in usecs */
+ oss_midi_time_t midi_ticks[MAX_MIDI_DEV];
+} tdev_t;
+
+typedef struct oss_timer_driver
+{
+/*
+ * Driver methods
+ */
+ int (*create_instance) (int timer_dev, int driver_dev);
+ void (*free_instance) (int timer_dev, int driver_dev);
+ int (*attach_client) (int timer_dev, int mididev);
+ void (*detach_client) (int timer_dev, int mididev);
+ int (*ioctl) (int timer_dev, unsigned int cmd, ioctl_arg arg);
+ int (*wait) (int timer_dev, unsigned long long time,
+ oss_midi_wait_callback_t callback, void *arg);
+ unsigned long long (*get_current_time) (int timer_dev);
+ int (*set_source) (int timer_dev, int source);
+ int (*set_tempo) (int timer_dev, int tempo);
+ int (*set_timebase) (int timer_dev, int timebase);
+ int (*start) (int timer_dev, oss_uint64_t tick);
+ int (*stop) (int timer_dev);
+ int (*cont) (int timer_dev);
+
+/*
+ * Dynamic content
+ */
+ char name[64];
+ int driver_dev;
+ oss_device_t *osdev;
+ void *devc;
+ oss_mutex_t mutex;
+ int max_instances;
+ int num_instances;
+ unsigned int flags;
+ int priority;
+ int resolution; /* In usecs */
+} oss_timer_driver_t;
+
+#define OSS_TIMER_DRIVER_VERSION 1
+
+extern int oss_install_timer (int version, char *name, oss_timer_driver_t * d, int driver_size, unsigned int flags, int max_instances, int resolution, /* In usecs */
+ void *devc, oss_device_t * osdev);
+extern int oss_timer_create_instance (int driver_dev, mididev_t * mididev);
+extern int oss_timer_attach_client (int timer_dev, mididev_t * mididev);
+extern void oss_timer_detach_client (int timer_dev, mididev_t * mididev);
+extern int oss_timer_set_tempo (int timer_dev, int tempo);
+extern int oss_timer_set_timebase (int timer_dev, int timebase);
+extern int oss_timer_wait_time (int timer_dev, int midi_dev, int latency,
+ oss_midi_time_t time,
+ oss_midi_wait_callback_t callback,
+ unsigned short options);
+extern oss_midi_time_t oss_timer_get_current_time (int timer_dev, int latency,
+ int use_abs);
+extern int oss_timer_get_timeout (int timer_dev, int midi_dev);
+extern void oss_timer_start (int timer_dev);
+extern void oss_timer_stop (int timer_dev);
+extern void oss_timer_continue (int timer_dev);
+extern int oss_timer_is_running (int timer_dev);
+
+extern oss_timer_driver_t *oss_timer_drivers[MAX_TIMER_DEV];
+extern int oss_num_timer_drivers;
+
+extern tdev_t *oss_timer_devs[MAX_TIMER_DEV];
+extern int oss_num_timers;
+
+#define MIDI_MARK_OPENED(md, mode) \
+{ \
+ char *cmd; \
+ md->open_mode=mode; \
+ if ((cmd = GET_PROCESS_NAME ()) != NULL) \
+ { \
+ strncpy (md->cmd, cmd, sizeof (md->cmd)); \
+ md->cmd [sizeof (md->cmd) - 1] = '\0'; \
+ } \
+ md->pid = GET_PROCESS_PID (); \
+}
+
+#define MIDI_MARK_CLOSED(md) \
+{ \
+ memset (md->cmd, 0, sizeof (md->cmd)); \
+ md->pid = -1; \
+ md->open_mode=0; \
+}
+
+extern void oss_midi_init (oss_device_t * osdev);
+extern void oss_midi_uninit (void);
+extern void oss_midi_copy_timer (int dev, int source_dev);
+extern void midi_mapper_init (oss_device_t * osdev);
+extern void midi_mapper_uninit (void);
+extern int midi_mapper_autobind (int client_dev, int mode);
+extern int oss_midi_ioctl (int dev, struct fileinfo *file,
+ unsigned int cmd, ioctl_arg arg);
+
+/* Interrupt callback functions */
+extern int oss_midi_input_byte (int dev, unsigned char data);
+extern int oss_midi_input_buf (int dev, unsigned char *data, int len);
+extern int oss_midi_output_intr (int dev);
+
+extern int
+oss_install_mididev (int version,
+ char *id, char *name,
+ midi_driver_t * d, int driver_size,
+ unsigned int flags, void *devc, oss_device_t * osdev);
+
+extern void install_vmidi (oss_device_t * osdev);
+
+/*
+ * Prototypes for midi_queue.c
+ */
+extern midi_queue_t *midi_queue_alloc (oss_device_t * osdev,
+ const char *name);
+extern void midi_queue_free (midi_queue_t * queue);
+
+extern int midi_queue_alloc_record (midi_queue_t * queue,
+ unsigned char **data, int len,
+ midi_packet_header_t * hdr);
+extern int midi_queue_put (midi_queue_t * queue, unsigned char *data, int len,
+ midi_packet_header_t * hdr);
+extern int midi_queue_get (midi_queue_t * queue, unsigned char **data,
+ int max_len, midi_packet_header_t ** hdr);
+extern int midi_queue_find_buffer (midi_queue_t * queue, unsigned char **data,
+ midi_packet_header_t ** hdr);
+extern void midi_queue_remove_chars (midi_queue_t * queue, int len);
+extern void midi_queue_removeall (midi_queue_t * queue);
+extern void oss_midi_set_defaults (mididev_t * mididev);
+extern int midi_queue_isempty (midi_queue_t * queue);
+extern int midi_queue_spaceleft (midi_queue_t * queue);
+extern void midi_queue_debugging (midi_queue_t * queue);
+extern void midi_queue_trace (midi_queue_t * queue);
+extern int oss_init_timers (oss_device_t * osdev);
+extern int oss_uninit_timers (void);
+extern void attach_oss_default_timer (oss_device_t * osdev);
+extern void detach_oss_default_timer (void);
+
+#endif
diff --git a/kernel/framework/include/midiparser.h b/kernel/framework/include/midiparser.h
new file mode 100644
index 0000000..3aed4a7
--- /dev/null
+++ b/kernel/framework/include/midiparser.h
@@ -0,0 +1,38 @@
+/*
+ * Purpose: Definitions for the MIDI message parser
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+typedef struct midiparser_common midiparser_common_t, *midiparser_common_p;
+
+#define CAT_VOICE 0
+#define CAT_MTC 1
+#define CAT_SYSEX 2
+#define CAT_CHN 3
+#define CAT_REALTIME 4
+
+typedef void (*midiparser_callback_t) (void *context, int category,
+ unsigned char msg, unsigned char ch,
+ unsigned char *parms, int len);
+typedef void (*midiparser_mtc_callback_t) (void *context,
+ oss_mtc_data_t * mtc);
+
+extern midiparser_common_p midiparser_create (midiparser_callback_t callback,
+ void *comntext);
+extern void midiparser_unalloc (midiparser_common_p common);
+extern void midiparser_mtc_callback (midiparser_common_p common,
+ midiparser_mtc_callback_t callback);
+
+extern void midiparser_input (midiparser_common_p common, unsigned char data);
+extern void midiparser_input_buf (midiparser_common_p common,
+ unsigned char *data, int len);
diff --git a/kernel/framework/include/mixer_core.h b/kernel/framework/include/mixer_core.h
new file mode 100644
index 0000000..ac4009f
--- /dev/null
+++ b/kernel/framework/include/mixer_core.h
@@ -0,0 +1,138 @@
+#ifndef MIXER_CORE_H
+#define MIXER_CORE_H
+
+/*
+ * Purpose: Mixer specific internal structure and function definitions.
+ *
+ * IMPORTANT NOTICE!
+ *
+ * This file contains internal structures used by Open Sound Systems.
+ * They will change without any notice between OSS versions. Care must be taken
+ * to make sure any software using this header gets properly re-compiled before
+ * use.
+ *
+ * 4Front Technologies (or anybody else) takes no responsibility of damages
+ * caused by use of this file.
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+typedef struct
+{
+ oss_mixext ext;
+ mixer_ext_fn handler;
+ oss_mixer_enuminfo *enum_info;
+ char *description; /* For "tooltips" */
+}
+oss_mixext_desc;
+
+struct _mixer_operations_t
+{
+ oss_devname_t name;
+ oss_id_t id;
+
+ mixer_driver_t *d;
+
+ void *devc;
+ void *hw_devc;
+ int modify_counter;
+
+ /* Mixer extension interface */
+ int nr_extra_ext;
+ mixer_create_controls_t create_controls;
+ int nr_ext;
+ int names_checked;
+ int max_ext;
+ int timestamp;
+ oss_mixext_desc *extensions;
+ int ignore_mask; /* Controls ignored by mixer ext API */
+
+ /* Misc info */
+ int card_number;
+ int port_number;
+ int enabled;
+ int unloaded;
+ int magic;
+ int caps;
+ int flags;
+ oss_handle_t handle;
+ oss_device_t *osdev;
+ oss_device_t *master_osdev; /* osdev struct of the master device (for virtual drivers) */
+ void *os_id; /* The device ID (dip) given by the system. */
+
+/*
+ * Priority is used for selecting the preferred mixer (usually the motherboard
+ * device). By default the priority is 0. Value of -2 means that this mixer
+ * should not be used as the default mixer. -1 means that this mixer can
+ * be used as the default mixer only if no better mixer exists. priority=10
+ * is used for known motherboard devices. 2 can be used by non-motherboard
+ * mixers that support the usual main volume setting
+ * (SNDCTL_MIXER_READ/WRITE_MAINVOL). 3-9 are reserved. Values higher than 10
+ * can only be set manually by the user.
+ */
+ int priority;
+ oss_devnode_t devnode;
+ int real_dev; /* Legacy device mapping */
+
+ /*
+ * Virtual mixer extension support (optional)
+ */
+ void *vmix_devc;
+ mixer_create_controls_t create_vmix_controls;
+};
+
+typedef struct _mixer_operations_t mixdev_t, *mixdev_p;
+
+extern mixer_operations_t **mixer_devs;
+extern void *mixer_devs_p;
+extern int num_mixers;
+extern void touch_mixer (int dev);
+extern int oss_mixer_ext (int orig_dev, int dev_class, unsigned int cmd,
+ ioctl_arg arg);
+extern int mixer_ext_set_enum (oss_mixer_enuminfo * ent);
+
+extern char mix_cvt[];
+
+int oss_install_mixer (int vers,
+ oss_device_t * osdev,
+ oss_device_t * master_osdev,
+ const char *name,
+ mixer_driver_t * driver, int driver_size, void *devc);
+
+extern int oss_legacy_mixer_ioctl (int mixdev, int audiodev, unsigned int cmd,
+ ioctl_arg arg);
+extern int mixer_ext_create_group (int dev, int parent, const char *id);
+extern int mixer_ext_create_group_flags (int dev, int parent, const char *id,
+ unsigned int flags);
+extern int mixer_ext_create_control (int dev, int parent, int ctrl,
+ mixer_ext_fn func, int type,
+ const char *id, int maxvalue, int flags);
+extern int mixer_ext_rw (int dev, int ctrl, unsigned int cmd, int value);
+extern int mixer_ext_recrw (int dev, int ctrl, unsigned int cmd, int value);
+extern int mixer_ext_set_init_fn (int dev, mixer_create_controls_t func,
+ int nextra);
+extern int mixer_ext_rebuild_all (int dev, mixer_create_controls_t func, int nextra);
+/*
+ * mixer_ext_set_vmix_init_fn() is reserved for the vmix driver to create
+ * additional virtual mixing related mixer controls.
+ */
+extern int mixer_ext_set_vmix_init_fn (int dev, mixer_create_controls_t func,
+ int nextra, void *devc);
+oss_mixext *mixer_find_ext (int dev, int enumber);
+extern int mixer_ext_truncate (int dev, int index);
+extern int mixer_ext_set_strings (int dev, int ctl, const char *s,
+ int version);
+extern int mixer_ext_set_description (int dev, int ctrl, const char *desc);
+extern int oss_mixer_ioctl (int dev, struct fileinfo *bogus, unsigned int cmd,
+ ioctl_arg arg);
+#endif
diff --git a/kernel/framework/include/oss_calls.h b/kernel/framework/include/oss_calls.h
new file mode 100644
index 0000000..7562176
--- /dev/null
+++ b/kernel/framework/include/oss_calls.h
@@ -0,0 +1,68 @@
+/*
+ * Purpose: Prototypes for various internal routines of OSS.
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * sndstat.c
+ */
+void store_msg (char *msg);
+#ifdef DO_TIMINGS
+/* Run time debugging stuff (for testing purposes only) */
+void oss_do_timing (char *txt);
+void oss_do_timing2 (int timing_mask, char *txt);
+void timing_set_device (int dev, dmap_t * dmap);
+typedef oss_native_word (*oss_timing_timer_func) (void *);
+void timing_install_timer (oss_timing_timer_func, void *);
+void oss_timing_enter (int bin);
+void oss_timing_leave (int bin);
+void timing_open (void);
+void timing_close (void);
+#endif
+
+#ifdef LICENSED_VERSION
+typedef int (*put_status_func_t) (const char *s);
+typedef int (*put_status_int_t) (unsigned int val, int radix);
+extern void oss_print_license (put_status_func_t put_status,
+ put_status_int_t put_status_int);
+extern int oss_license_handle_time (time_t t);
+#endif
+
+extern void install_sndstat (oss_device_t * osdev);
+extern void install_dev_mixer (oss_device_t * osdev);
+
+/*
+ * vmix_core.c
+ */
+
+extern void vmix_core_uninit (void);
+extern void vmix_core_init (oss_device_t *osdev);
+extern int vmix_attach_audiodev(oss_device_t *osdev, int masterdev, int input_master, unsigned int attach_flags);
+extern int vmix_detach_audiodev(int masterdev);
+extern int vmix_create_client(void *vmix_mixer);
+extern void vmix_change_devnames(void *vmix_mixer, const char *name);
+extern int vmix_set_master_rate(int masterdev, int rate);
+extern int vmix_set_channel_map(int masterdev, void *map);
+
+/*
+ * oss_audio_core.c
+ */
+
+extern void oss_audio_init (oss_device_t *osdev);
+extern void oss_audio_uninit (void);
+
+/*
+ * Internal debugging (oss_mixer_core.c)
+ */
+extern void oss_timing_printf (char *s, ...);
diff --git a/kernel/framework/include/oss_config.h b/kernel/framework/include/oss_config.h
new file mode 100644
index 0000000..fdd940f
--- /dev/null
+++ b/kernel/framework/include/oss_config.h
@@ -0,0 +1,377 @@
+/* oss_config.h
+ *
+ * Purpose: The top level header file for compiling OSS itself.
+ *
+ * This is the mother of all headers in OSS. All core files should include this
+ * file.
+ *
+ * However low level drivers must never include this file. Instead they should
+ * use the autogenerated drv_cfg.h file.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 OSS_CONFIG_H
+#define OSS_CONFIG_H
+
+#define NEW_DEVICE_NAMING /* /dev/sblive0_dsp0 instead of /dev/dsp0 and so on */
+
+#include "soundcard.h"
+
+struct _oss_device_t;
+typedef int *ioctl_arg;
+
+/* Check various wrappers when changing these two function pointer defs */
+typedef int (*oss_tophalf_handler_t) (struct _oss_device_t * osdev);
+typedef void (*oss_bottomhalf_handler_t) (struct _oss_device_t * osdev);
+
+#include <ossddk/oss_exports.h>
+#include <local_config.h>
+#include <os.h>
+
+#include <ossddk/ossddk.h>
+
+#ifndef OS_VERSION
+#error OS_VERSION not defined in os.h
+#endif
+
+/*
+ * Memory block allocation (oss_memblk.h/c)
+ */
+#include <oss_memblk.h>
+
+/*
+ * Memory allocation/free routines for structures to be freed automatically
+ * when OSS is unloaded.
+ */
+#define PMALLOC(osdev, size) oss_memblk_malloc(&oss_global_memblk, size)
+#define PMFREE(osdev, addr) oss_memblk_free(&oss_global_memblk, addr)
+
+/*
+ * Currently /dev/dsp is managed in user land by ossdevlinks instead of
+ * using the previous kernel level device lists feature (earlier maintained by
+ * the ossctl utility). Define MANAGE_DEV_DSP to return back this functionality
+ * in the driver. Also remove the related code in the user land tools
+ * (ossdevlinks).
+ */
+#undef MANAGE_DEV_DSP
+
+#ifndef ERESTARTSYS
+#define ERESTARTSYS EAGAIN
+#endif
+
+#ifndef OSS_HZ
+#define OSS_HZ HZ
+#endif
+
+#ifndef OSS_PAGE_MASK
+#define OSS_PAGE_MASK (-1)
+#endif
+
+#ifndef HW_PRINTF
+#define HW_PRINTF(x)
+#endif
+
+#ifndef GET_PROCESS_NAME
+#define GET_PROCESS_NAME() NULL
+#endif
+
+#ifndef GET_PROCESS_PID
+#define GET_PROCESS_PID() -1
+#endif
+
+#ifndef FMA_EREPORT
+/* FMA is only available under Solaris */
+#define FMA_EREPORT(osdev, detail, name, type, value)
+#define FMA_IMPACT(osdev, impact)
+#endif
+
+#include "oss_version.h"
+/* #include "aw.h" */
+#define EXCLUDE_GUS_IODETECT
+
+#ifndef IOC_IS_OUTPUT
+#define IOC_IS_OUTPUT(cmd) cmd & SIOC_IN
+#endif
+
+#define DSP_DEFAULT_SPEED 48000
+#define DSP_DEFAULT_FMT AFMT_S16_LE
+
+#define ON 1
+#define OFF 0
+
+typedef struct oss_wait_queue oss_wait_queue_t;
+
+#include "audio_core.h"
+#include "mixer_core.h"
+#include "oss_calls.h"
+#include "internal.h"
+
+#ifndef DEB
+#define DEB(x)
+#endif
+
+#ifndef DDB
+#define DDB(x) {}
+#endif
+
+#ifndef CDB
+#define CDB(x) {}
+#endif
+
+#define TIMER_ARMED 121234
+#define TIMER_NOT_ARMED 1
+
+#ifdef DO_MEMDEBUG
+extern void oss_vmem_check (char *file, int line, oss_native_word offs,
+ int bytes);
+extern void oss_pmem_check (char *file, int line, oss_native_word offs,
+ int bytes);
+# define VMEM_CHECK(offs, bytes) oss_vmem_check(__FILE__, __LINE__, (oss_native_word)offs, bytes)
+# define PMEM_CHECK(offs, bytes) oss_pmem_check(__FILE__, __LINE__, (oss_native_word)offs, bytes)
+#else
+# define VMEM_CHECK(offs, bytes)
+# define PMEM_CHECK(offs, bytes)
+#endif
+
+#ifndef OSS_BIG_ENDIAN
+#define USE_REMUX
+#endif
+
+typedef struct
+{
+ char *const key, *const name;
+} oss_device_table_t;
+
+
+typedef struct
+{
+#ifdef _KERNEL
+ int (*open) (int dev, int dev_class, struct fileinfo * file,
+ int recursive, int open_flags, int *redirect);
+ void (*close) (int dev, struct fileinfo * file);
+ int (*read) (int dev, struct fileinfo * file, uio_t * buf, int count);
+ int (*write) (int dev, struct fileinfo * file, uio_t * buf, int count);
+ int (*ioctl) (int dev, struct fileinfo * file,
+ unsigned int cmd, ioctl_arg arg);
+ int (*chpoll) (int dev, struct fileinfo * file, oss_poll_event_t * ev);
+#else
+ int dummy;
+#endif
+} oss_cdev_drv_t;
+
+typedef struct _oss_cdev_t oss_cdev_t;
+
+struct _oss_cdev_t
+{
+#ifdef DEV_HDR
+ DEV_HDR devHdr;
+#endif
+ oss_cdev_t *hl; /* Hash link (for operating system ports that use it) */
+ int minor;
+ int dev_class;
+ int instance;
+ oss_cdev_drv_t *d;
+ char name[32];
+ oss_device_t *osdev;
+ void *info;
+ int active;
+ int open_count;
+ struct fileinfo file;
+};
+
+extern oss_cdev_t **oss_cdevs;
+extern int oss_num_cdevs;
+
+/*
+ * Global initialization and cleanup functions (common to all operating systems)
+ */
+extern void oss_common_init (oss_device_t * osdev);
+extern void oss_unload_drivers (void);
+/*
+ * The following calls are operating system dependent. They should be defined
+ * in os.c for each operating system.
+ */
+extern int oss_register_device (oss_device_t * osdev, const char *name);
+extern void oss_unregister_device (oss_device_t * osdev);
+extern int oss_find_minor (int dev_class, int instance);
+extern int oss_disable_device (oss_device_t * osdev);
+extern void oss_install_chrdev (oss_device_t * osdev, char *name,
+ int dev_class, int instance,
+ oss_cdev_drv_t * drv, int flags);
+#define CHDEV_VIRTUAL 0x00000001
+#define CHDEV_REPLUG 0x00000002 /* Hot (un)pluggable device got replugged */
+extern int oss_register_interrupts (oss_device_t * osdev, int intrnum,
+ oss_tophalf_handler_t top,
+ oss_bottomhalf_handler_t bottom);
+extern void oss_unregister_interrupts (oss_device_t * osdev);
+
+/*
+ * DMA buffer management
+ */
+extern int oss_alloc_dmabuf (int dev, dmap_p dmap, int direction);
+extern int __oss_alloc_dmabuf (int dev, dmap_p dmap, unsigned int alloc_flags,
+ oss_uint64_t maxaddr, int direction);
+/* Alloc flags */
+#define DMABUF_NONCONTIG 0x00000001
+#define DMABUF_ISA 0x00000002
+#define DMABUF_QUIET 0x00000004
+#define DMABUF_SIZE_16BITS 0x00000008 /* Max buffer size 64k-1 */
+#define DMABUF_LARGE 0x00000010 /* Allocate a 356k buffer */
+/* Maxaddr defs */
+#define MEMLIMIT_ISA 0x0000000000ffffffLL
+#define MEMLIMIT_28BITS 0x000000000fffffffLL
+#define MEMLIMIT_30BITS 0x000000003fffffffLL
+#define MEMLIMIT_31BITS 0x000000007fffffffLL
+#define MEMLIMIT_32BITS 0x00000000ffffffffLL
+#define MEMLIMIT_64BITS 0xffffffffffffffffLL
+extern void oss_free_dmabuf (int dev, dmap_p dmap);
+
+/*
+ * Device management routines
+ */
+extern void *oss_get_osid (oss_device_t * osdev);
+extern void oss_reserve_device (oss_device_t * osdev);
+extern void oss_unreserve_device (oss_device_t * osdev, int decrement);
+/*
+ * Sleep/wakeup support (os.c)
+ */
+extern oss_wait_queue_t *oss_create_wait_queue (oss_device_t * osdev,
+ const char *name);
+extern void oss_reset_wait_queue (oss_wait_queue_t * wq);
+extern void oss_remove_wait_queue (oss_wait_queue_t * wq);
+extern int oss_sleep (oss_wait_queue_t * wq, oss_mutex_t * mutex, int ticks,
+ oss_native_word * flags, unsigned int *status);
+extern int oss_register_poll (oss_wait_queue_t * wq, oss_mutex_t * mutex,
+ oss_native_word * flags, oss_poll_event_t * ev);
+extern void oss_wakeup (oss_wait_queue_t * wq, oss_mutex_t * mutex,
+ oss_native_word * flags, short events);
+/*
+ * Wait status flags (make sure these match osscore.c for Linux)
+ */
+#define WK_NONE 0x00
+#define WK_WAKEUP 0x01
+#define WK_TIMEOUT 0x02
+#define WK_SIGNAL 0x04
+#define WK_SLEEP 0x08
+#define WK_SELECT 0x10
+
+/*
+ * Mutex hierarchy levels
+ * Used by LOCK_ALLOC in UnixWare/OpenServer
+ */
+#define MH_GLOBAL 1
+#define MH_FRAMEW 5
+#define MH_DRV 10
+#define MH_TOP 20
+
+#define OSS_HISTORY_SIZE 5
+#define OSS_HISTORY_STRSIZE 256
+typedef char oss_history_t[OSS_HISTORY_STRSIZE];
+extern oss_history_t oss_history[OSS_HISTORY_SIZE];
+extern int oss_history_p;
+
+#ifdef LICENSED_VERSION
+#include <license.h>
+#endif
+
+extern void create_new_card (char *shortname, char *longname);
+
+/*
+ * Config option support.
+ */
+typedef struct
+{
+ char *name;
+ int *ptr;
+} oss_option_map_t;
+
+extern void oss_load_options (oss_device_t * osdev, oss_option_map_t map[]);
+extern oss_option_map_t oss_global_options[];
+
+extern int detect_trace;
+
+extern int oss_num_cards;
+extern int oss_get_cardinfo (int cardnum, oss_card_info * ci);
+extern oss_device_t *osdev_create (dev_info_t * dip, int dev_type,
+ int instance, const char *nick,
+ const char *handle);
+extern oss_device_t *osdev_clone (oss_device_t * orig_osdev,
+ int new_instance);
+extern void osdev_delete (oss_device_t * osdev);
+
+/*
+ * oss_pci_byteswap() turns on/off hardware level byte swapping.
+ * mode=0 : Don't do byte swapping in the bus interface (default)
+ * mode=1 : Do automatic byte swapping (BE machines) on the bus interface.
+ */
+extern void oss_pci_byteswap (oss_device_t * osdev, int mode);
+
+extern void oss_pcie_init (oss_device_t * osdev, int flags);
+
+/*
+ * Process information routines
+ */
+
+extern int oss_get_procinfo(int what);
+#define OSS_GET_PROCINFO_UID 1
+#define OSS_GET_PROCINFO_GID 2
+#define OSS_GET_PROCINFO_PGID 3
+
+/*
+ * Error reporting
+ */
+#define E_REC 1
+#define E_PLAY 2
+extern void oss_audio_set_error (int dev, int mode, int err, int parm);
+#define OSSERR(cntx, msg) cntx
+
+/*
+ * DMA/cache syncronization macros (should be defined in os.h if they
+ * are necessary for the OS/arch.
+ */
+#ifndef OSS_DMA_SYNC
+//# define OSS_DMA_SYNC_INBOUND For direction device to CPU
+//# define OSS_DMA_SYNC_OUTBOUND For direction CPU to device
+# define OSS_DMA_SYNC(handle, offs, len, direc) do { \
+ } while (0)
+#endif
+
+/*
+ * Ensure that various obsolete OSS 3.x features are not used any more
+ * in the drivers.
+ */
+#define osp osp_is_obsolete[]
+#define CREATE_OSP(osdev) CREATE_OSP_is_obsolete
+#define printk() printk_is_obsolete
+#define REQUEST_REGION(start, len, name) REQUEST_REGION_is_obsolete
+#define CHECK_REGION(start, len) CHECK_REGION_is_obsolete
+#define RELEASE_REGION(start, len) RELEASE_REGION_is_obsolete
+#define ALLOCATE_DMA_CHN ALLOCATE_DMA_CHN_is_obsolete
+#define FREE_DMA_CHN FREE_DMA_CHN_is_obsolete
+#define OPEN_DMA_CHN OPEN_DMA_CHN_is_obsolete
+#define CLOSE_DMA_CHN OPEN_DMA_CHN_is_obsolete
+#if !defined(__bsdi__)
+#define tenmicrosec(x) tenmicrosec_is_obsolete()
+#endif
+#define request_sound_timer(x) request_sound_timer_is_obsolete
+#define sound_stop_timer(x) sound_stop_timer_is_obsolete
+#define snd_set_irq_handler(x) snd_set_irq_handler_is_obsolete
+#define snd_release_irq (vect, x) snd_release_irq_is_obsolete
+#define conf_printf (name, hw_config) conf_printf_is_obsolete
+#define conf_printf2 (name, base, irq, dma, dma2) conf_printf2_is_obsolete
+#define sound_disable_module (void) sound_disable_module_is_obsolete
+#define IOCTL_GET IOCTL_GET_is_obsolete
+#define IOCTL_OUT IOCTL_OUT_is_obsolete
+#define CONTIG_MALLOC_ISA CONTIG_MALLOC_ISA_is_obsolete()
+
+#endif
diff --git a/kernel/framework/include/oss_memblk.h b/kernel/framework/include/oss_memblk.h
new file mode 100644
index 0000000..42b3f0b
--- /dev/null
+++ b/kernel/framework/include/oss_memblk.h
@@ -0,0 +1,22 @@
+/*
+ * Purpose: OSS memory block allocation and management routines.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+typedef struct _oss_memblk_t oss_memblk_t;
+
+extern oss_memblk_t *oss_global_memblk;
+
+extern void *oss_memblk_malloc(oss_memblk_t **, int size);
+extern void oss_memblk_free(oss_memblk_t **, void *addr);
+extern void oss_memblk_unalloc(oss_memblk_t **);
diff --git a/kernel/framework/include/oss_pci.h b/kernel/framework/include/oss_pci.h
new file mode 100644
index 0000000..17dc7b3
--- /dev/null
+++ b/kernel/framework/include/oss_pci.h
@@ -0,0 +1,67 @@
+/*
+ * Purpose: Definitions of various PCI specific constants and functions
+ *
+ * All drivers for PCI devices should included this file.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 OSS_PCI_H
+#define OSS_PCI_H
+#define OSS_HAVE_PCI
+#define PCIBIOS_SUCCESSFUL 0x00
+#define PCIBIOS_FAILED -1
+
+#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
+#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
+#define PCI_VENDOR_ID 0x00
+#define PCI_REVISION_ID 0x08
+#define PCI_COMMAND 0x04
+#define PCI_DEVICE_ID 0x02
+#define PCI_LATENCY_TIMER 0x0d
+#define PCI_INTERRUPT_LINE 0x3c
+#define PCI_BASE_ADDRESS_0 0x10
+
+#define PCI_MEM_BASE_ADDRESS_0 0x10
+#define PCI_MEM_BASE_ADDRESS_1 0x14
+#define PCI_MEM_BASE_ADDRESS_2 0x18
+#define PCI_MEM_BASE_ADDRESS_3 0x1c
+#define PCI_BASE_ADDRESS_1 0x14
+#define PCI_BASE_ADDRESS_2 0x18
+#define PCI_BASE_ADDRESS_3 0x1c
+#define PCI_BASE_ADDRESS_4 0x20
+#define PCI_BASE_ADDRESS_5 0x24
+#define PCI_COMMAND_IO 0x01
+#define PCI_COMMAND_MEMORY 0x02
+#define PCI_COMMAND_MASTER 0x04
+#define PCI_COMMAND_PARITY 0x40
+#define PCI_COMMAND_SERR 0x100
+
+#define PCI_STATUS 0x06
+#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
+#define PCI_SUBSYSTEM_ID 0x2e
+
+extern int pci_read_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char *val);
+extern int pci_read_config_irq (oss_device_t * osdev, offset_t where,
+ unsigned char *val);
+extern int pci_read_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short *val);
+extern int pci_read_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int *val);
+extern int pci_write_config_byte (oss_device_t * osdev, offset_t where,
+ unsigned char val);
+extern int pci_write_config_word (oss_device_t * osdev, offset_t where,
+ unsigned short val);
+extern int pci_write_config_dword (oss_device_t * osdev, offset_t where,
+ unsigned int val);
+extern int pci_enable_msi (oss_device_t * osdev);
+#endif
diff --git a/kernel/framework/include/oss_version.h b/kernel/framework/include/oss_version.h
new file mode 100644
index 0000000..4905733
--- /dev/null
+++ b/kernel/framework/include/oss_version.h
@@ -0,0 +1,13 @@
+/*
+ * Purpose: OSS version ID
+ */
+#include <buildid.h>
+#include <timestamp.h>
+
+#ifndef OSS_LICENSE
+#define OSS_LICENSE "" /* Empty means commercial license */
+#endif
+
+#define OSS_VERSION_ID "4.2"
+#define OSS_VERSION_STRING OSS_VERSION_ID " (b " OSS_BUILD_ID "/" OSS_COMPILE_DATE ")"
+#define OSS_INTERNAL_VERSION 0x040199
diff --git a/kernel/framework/include/ossddk/oss_exports.h b/kernel/framework/include/ossddk/oss_exports.h
new file mode 100644
index 0000000..437e3f4
--- /dev/null
+++ b/kernel/framework/include/ossddk/oss_exports.h
@@ -0,0 +1,101 @@
+#ifndef _OSS_EXPORTS_H
+#define _OSS_EXPORTS_H
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * Driver (bus) types
+ *
+ * Note that OSSDDK drivers can only use DRV_PCI or DRV_VIRTUAL. The other
+ * bus types will not work properly because support for them is missing
+ * from the DDK layer.
+ */
+
+#define DRV_UNKNOWN 0
+#define DRV_PCI 1
+#define DRV_USB 2
+#define DRV_VIRTUAL 3
+#define DRV_VMIX 4 /* Like DRV_VIRTUAL. Used by the vmix module. */
+#define DRV_STREAMS 5
+#define DRV_ISA 6
+#define DRV_FIREWIRE 7
+#define DRV_CLONE 8 /* Clone of some other device */
+
+/*
+ * Device class numbers. Unlike with earlier OSS versions (up to v4.0)
+ * the minor number doesn't have any special meaning. Minor numbers
+ * will be allocated in the order the device files are initialized. Even
+ * the major number doesn't necessaily be the same for all OSS devices.
+ * Minor numbers will be just indexes to a table (in os.c) that contains
+ * the device class code, instance number, driver call table and things like that.
+ * Ideally OSS will use devfs to expose the available devices.
+ */
+
+extern int oss_max_audio_devfiles;
+extern int oss_max_audio_engines;
+
+#define MAX_SYNTH_DEV 6 // TODO: Remove
+#define MAX_AUDIO_DEVFILES oss_max_audio_devfiles
+#define MAX_AUDIO_ENGINES oss_max_audio_engines
+#define SYNC_DEVICE_MASK 0xffff
+
+#include "oss_limits.h"
+/*
+ * Device file class codes. Note that these numbers don't have any kind of relationship with minor numbers.
+ */
+
+#define OSS_DEV_STATUS 0 /* /dev/sndstat */
+#define OSS_DEV_VDSP 1 /* /dev/dsp (multiplexer device) */
+#define OSS_DEV_VAUDIO 2 /* /dev/audio (multiplexer device) */
+#define OSS_DEV_AWFM 3 /* Reserved for historic purposes */
+#define OSS_DEV_OSSD 4 /* /dev/ossd - ossd process support */
+#define OSS_DEV_AUDIOCTL 5 /* Audioctl device */
+#define OSS_DEV_MIXER 6 /* /dev/mixer0 */
+#define OSS_DEV_SEQ 7 /* /dev/sequencer */
+#define OSS_DEV_MUSIC 8 /* /dev/music AKA /dev/sequencer2 */
+#define OSS_DEV_VMIDI 9 /* /dev/midi (multiplexer device) */
+#define OSS_DEV_MIDI 10 /* /dev/midi## */
+#define OSS_DEV_DEVAUDIO 11 /* /dev/audio# */
+#define OSS_DEV_DSP 12 /* /dev/dsp# */
+#define OSS_DEV_MISC 13 /* Special purpose device files */
+#define OSS_DEV_DSP_ENGINE 14 /* Hidden DSP engines */
+
+extern int oss_max_cdevs;
+#define OSS_MAX_CDEVS oss_max_cdevs
+
+/*
+ * Misc definitions
+ */
+
+typedef struct _oss_device_t oss_device_t;
+
+#if defined(linux) && defined(OSS_MAINLINE_BUILD)
+#include <stdint.h>
+#endif
+
+/*
+ * AC97
+ */
+typedef int (*ac97_readfunc_t) (void *, int);
+typedef int (*ac97_writefunc_t) (void *, int, int);
+typedef struct _ac97_handle_t ac97_handle_t;
+
+/*
+ * Mixer
+ */
+typedef struct _mixer_driver_t mixer_driver_t;
+typedef struct _mixer_operations_t mixer_operations_t;
+typedef int (*mixer_create_controls_t) (int dev);
+typedef int (*mixer_ext_fn) (int dev, int ctrl, unsigned int cmd, int value);
+
+extern void oss_audio_delayed_attach (void);
+#endif
diff --git a/kernel/framework/include/ossddk/oss_limits.PHh b/kernel/framework/include/ossddk/oss_limits.PHh
new file mode 100644
index 0000000..f5f97ac
--- /dev/null
+++ b/kernel/framework/include/ossddk/oss_limits.PHh
@@ -0,0 +1,35 @@
+/*
+ * Misc limits
+ */
+
+#ifdef __USE_PHPMAKE__
+<?php
+ require getenv("PHPMAKE_LIBPATH") . "library.php";
+
+ phpmake_init_c();
+
+ // Set the initial defaults
+ $MAX_MIXER_DEV = 16;
+ $MAX_MIDI_DEV = 32;
+ $MAX_TIMER_DEV = $MAX_MIDI_DEV + 4;
+ $HARD_MAX_AUDIO_DEVFILES = 256;
+
+ if (getenv("PHPMAKE_PROJECTPATH"))
+ {
+ include getenv("PHPMAKE_PROJECTPATH") . "limits.php";
+ }
+
+ echo "#define MAX_MIXER_DEV\t" . $MAX_MIXER_DEV . "\n";
+ echo "#define MAX_MIDI_DEV\t" . $MAX_MIDI_DEV . "\n";
+ echo "#define MAX_TIMER_DEV\t" . $MAX_TIMER_DEV . "\n";
+ echo "#define HARD_MAX_AUDIO_DEVFILES\t" . $HARD_MAX_AUDIO_DEVFILES . "\n";
+?>
+#else
+/*
+ * Altrnative version for systems where Phpmake is not used
+ */
+#define MAX_MIXER_DEV 16
+#define MAX_MIDI_DEV 32
+#define MAX_TIMER_DEV (MAX_MIDI_DEV+4)
+#define HARD_MAX_AUDIO_DEVFILES 256
+#endif
diff --git a/kernel/framework/include/ossddk/ossddk.h b/kernel/framework/include/ossddk/ossddk.h
new file mode 100644
index 0000000..2fcf46f
--- /dev/null
+++ b/kernel/framework/include/ossddk/ossddk.h
@@ -0,0 +1,267 @@
+#ifndef OSSDDK_H
+#define OSSDDK_H
+
+/*
+ * ossddk.h - Open Sound System Driver Devlopment Kit (DDK) exported defs.
+ *
+ * Copyright (C) 4Front Technologies 2005 - All rights reserved.
+ */
+
+#define OSSDDK_VERSION 0x02 /* 0.2 */
+
+#include "oss_exports.h"
+
+/*
+ * Audio interface
+ */
+#define OSS_AUDIO_DRIVER_VERSION 2
+
+typedef struct _dmap_t dmap_t;
+
+/*
+ * Audio device flags (adev_t->flags)
+ */
+#define ADEV_DEFAULT 0x0000000000000001LL /* Preferred default audio device candidate */
+#define ADEV_AUTOMODE 0x0000000000000002LL /* Playbak pointer loops automatically */
+#define ADEV_DUPLEX 0x0000000000000004LL /* Device permits full duplex (O_RDWR method) */
+#define ADEV_NOINPUT 0x0000000000000008LL /* Device cannot do input */
+#define ADEV_NOOUTPUT 0x0000000000000010LL /* Device cannot do output */
+#define ADEV_VMIX 0x0000000000000020LL /* Device is virtual mixer one */
+
+/* NOTE! 0x0000000000000040 is free */
+
+#define ADEV_VIRTUAL 0x0000000000000080LL /* Virtual audio device */
+#define ADEV_OPENED 0x0000000000000100LL /* Will be set when the device is open */
+#define ADEV_NOCONVERT 0x0000000000000200LL /* No automatic format conversions are permitted */
+
+/*
+ * ADEV_HIDDEN is reserved for internal use by the audio core and it must
+ * not be set by low level drivers. Instead low level drivers should set
+ * adev->caps |= PCM_CAP_HIDDEN if they like to hide the device file from
+ * ordinary audio applications.
+ */
+#define ADEV_HIDDEN 0x0000000000001000LL
+
+#define ADEV_FIXEDRATE 0x0000000000002000LL /* Fixed sampling rate (obsolete) */
+#define ADEV_16BITONLY 0x0000000000004000LL /* Only 16 bit audio support */
+#define ADEV_STEREOONLY 0x0000000000008000LL /* Only stereo (requires 16BITONLY) */
+#define ADEV_SHADOW 0x0000000000010000LL /* "shadow" device */
+#define ADEV_8BITONLY 0x0000000000020000LL /* Only 8 bits */
+#define ADEV_32BITONLY 0x0000000000040000LL /* Only 24 or 32 bits */
+#define ADEV_NOVIRTUAL 0x0000000000080000LL /* Don't install SoftOSS automatically for this device */
+#define ADEV_NOSRC 0x0000000000100000LL /* Don't do any kind of SRC */
+#define ADEV_SPECIAL 0x0000000000200000LL /* Multich or otherwise special dev */
+#define ADEV_NOMMAP 0x0000000000400000LL /* No MMAP capability */
+#define ADEV_DISABLE_VIRTUAL 0x0000000000800000LL /* Not compatible with virtual drivers */
+#define ADEV_COLD 0x0000000001000000LL /* Reserved for a future feature - DO NOT USE */
+#define ADEV_HWMIX 0x0000000002000000LL /* Device supports "hardware mixing" */
+#define ADEV_LOOP 0x0000000004000000LL /* Loopback device */
+#define ADEV_NONINTERLEAVED 0x0000000008000000LL /* DMA buffer _NOT_ interleaved */
+
+#ifdef _KERNEL
+typedef struct _audiodrv_t
+{
+ int (*adrv_open) (int dev, int mode, int open_flags);
+ void (*adrv_close) (int dev, int mode);
+ void (*adrv_output_block) (int dev, oss_native_word buf,
+ int count, int fragsize, int intrflag);
+ void (*adrv_start_input) (int dev, oss_native_word buf,
+ int count, int fragsize, int intrflag);
+ int (*adrv_ioctl) (int dev, unsigned int cmd, int *arg);
+ int (*adrv_prepare_for_input) (int dev, int fragsize, int nfrags);
+ int (*adrv_prepare_for_output) (int dev, int fragsize, int nfrags);
+ void (*adrv_halt_io) (int dev);
+ int (*adrv_local_qlen) (int dev);
+ void *not_used; /* Out of order */
+ void (*adrv_halt_input) (int dev);
+ void (*adrv_halt_output) (int dev);
+ void (*adrv_trigger) (int dev, int bits);
+ int (*adrv_set_rate) (int dev, int speed);
+ unsigned int (*adrv_set_format) (int dev, unsigned int bits);
+ short (*adrv_set_channels) (int dev, short channels);
+ void (*adrv_postprocess_write) (int dev); /* Device spesific postprocessing for written data */
+ void (*adrv_preprocess_read) (int dev); /* Device spesific preprocessing for read data */
+ /* Timeout handlers for input and output */
+ int (*adrv_check_input) (int dev);
+ int (*adrv_check_output) (int dev);
+ int (*adrv_alloc_buffer) (int dev, dmap_t * dmap, int direction);
+ int (*adrv_free_buffer) (int dev, dmap_t * dmap, int direction);
+ void (*adrv_lock_buffer) (int dev, int direction);
+ void *dummy; /* Not used any more */
+ int (*adrv_get_buffer_pointer) (int dev, dmap_t * dmap, int direction);
+ int (*adrv_calibrate_speed) (int dev, int nominal_rate, int true_rate);
+#define SYNC_ATTACH 0
+#define SYNC_PREPARE 1
+#define SYNC_TRIGGER 2
+ int (*adrv_sync_control) (int dev, int event, int mode);
+ void (*adrv_prepare_to_stop) (int dev);
+ int (*adrv_get_input_pointer) (int dev, dmap_t * dmap, int direction);
+ int (*adrv_get_output_pointer) (int dev, dmap_t * dmap, int direction);
+ int (*adrv_bind) (int dev, unsigned int cmd, int *arg);
+ void (*adrv_setup_fragments) (int dev, dmap_t * dmap, int direction);
+ int (*adrv_redirect) (int dev, int mode, int open_flags);
+ int (*adrv_ioctl_override) (int dev, unsigned int cmd, int *arg);
+} audiodrv_t;
+#endif
+
+/*
+ * Mixer interface
+ */
+#define OSS_MIXER_DRIVER_VERSION 2
+#define OSSDDK_MIXER_ROOT 0
+
+struct _mixer_driver_t
+{
+ int (*ioctl) (int dev, int audiodev, unsigned int cmd, int *arg);
+};
+#define AINTR_LOCALQUEUE 0x00000001
+#define AINTR_NO_POINTER_UPDATES 0x00000002
+
+#if 0
+/*
+ * The ossddk_* functions are not included in OSS for the time being
+ */
+#ifdef _KERNEL
+extern oss_device_t *ossddk_register_device (int ddkvers,
+ dev_info_t * dip,
+ int drvtype,
+ int instance, const char *nick,
+#ifdef sun
+ ddi_iblock_cookie_t
+ iblock_cookie,
+#endif
+ void *devc,
+ const char *longname);
+extern int ossddk_disable_device (oss_device_t * osdev);
+extern void *ossddk_osdev_get_devc (oss_device_t * osdev);
+extern void ossddk_unregister_device (oss_device_t * osdev);
+
+#ifdef sun
+/*
+ * OSS driver entry point routines
+ */
+extern int oss_open (dev_t * dev_p, int open_flags, int otyp,
+ cred_t * cred_p);
+extern int oss_close (dev_t dev, int flag, int otyp, cred_t * cred_p);
+extern int oss_ioctl (dev_t dev, int cmd, intptr_t arg, int mode,
+ cred_t * cred_p, int *rval_p);
+extern int oss_read (dev_t dev, struct uio *uiop, cred_t * credp);
+extern int oss_write (dev_t dev, struct uio *uiop, cred_t * cred_p);
+extern int oss_chpoll (dev_t dev, short events, int anyyet, short *reventsp,
+ struct pollhead **phpp);
+extern int oss_mmap (dev_t dev, off_t offset, int nprot);
+#endif
+
+#if defined(amd64) || defined(sparc) || defined(x86_64)
+typedef unsigned long long coreaddr_t;
+#else
+typedef unsigned long coreaddr_t;
+#endif
+
+int ossddk_install_audiodev (int vers,
+ oss_device_t * osdev,
+ oss_device_t * master_osdev,
+ char *name,
+ const audiodrv_t * driver,
+ int driver_size,
+ int flags,
+ unsigned int format_mask, void *devc,
+ int parent);
+
+extern void ossddk_adev_set_devc (int dev, void *devc);
+extern void ossddk_adev_set_portc (int dev, void *portc);
+extern void ossddk_adev_set_portc_play (int dev, void *portc);
+extern void ossddk_adev_set_portc_record (int dev, void *portc);
+extern void ossddk_adev_set_portnum (int dev, int portnum);
+extern void ossddk_adev_set_mixer (int dev, int mixer_dev);
+extern void ossddk_adev_set_rates (int dev, int min_rate, int max_rate,
+ int nrates, int rates[20]);
+extern void ossddk_adev_set_formats (int dev, unsigned int oformats,
+ unsigned int iformats);
+extern void ossddk_adev_set_caps (int dev, unsigned int caps);
+extern void ossddk_adev_set_flags (int dev, unsigned int caps);
+extern void ossddk_adev_set_channels (int dev, int min_channels,
+ int max_channels);
+extern void ossddk_adev_set_buflimits (int dev, int min_fragment,
+ int max_fragment);
+extern void ossddk_adev_set_enable_flag (int dev, int state);
+extern void ossddk_adev_set_unloaded_flag (int dev, int state);
+extern void ossddk_adev_set_magic (int dev, int magic);
+extern void ossddk_adev_set_ratesource (int dev, int rate_source);
+extern void ossddk_adev_set_songname (int dev, char *song);
+extern void ossddk_adev_set_label (int dev, char *label);
+
+extern void *ossddk_adev_get_devc (int dev);
+extern void *ossddk_adev_get_portc (int dev);
+extern void *ossddk_adev_get_portc_play (int dev);
+extern void *ossddk_adev_get_portc_record (int dev);
+extern dmap_t *ossddk_adev_get_dmapout (int dev);
+extern dmap_t *ossddk_adev_get_dmapin (int dev);
+extern char *ossddk_adev_get_songname (int dev);
+extern char *ossddk_adev_get_label (int dev);
+extern int ossddk_adev_get_flags (int dev);
+
+extern void ossddk_audio_outputintr (int dev, int intr_flags);
+extern void ossddk_audio_inputintr (int dev, int intr_flags);
+
+typedef void (*oss_audio_callback_t) (int dev, int parm);
+extern void ossddk_dmap_set_dmabuf (dmap_t * dmap, unsigned char *buf);
+extern void ossddk_dmap_set_phys (dmap_t * dmap, unsigned long addr);
+extern void ossddk_dmap_set_buffsize (dmap_t * dmap, int size);
+extern void ossddk_dmap_set_private (dmap_t * dmap, void *ptr);
+extern void ossddk_dmap_set_callback (dmap_t * dmap,
+ oss_audio_callback_t cb, int arg);
+extern void ossddk_dmap_set_fragsize (dmap_t * dmap, int size);
+extern void ossddk_dmap_set_numfrags (dmap_t * dmap, int nfrags);
+extern void ossddk_dmap_set_playerror (dmap_t * dmap, int err, int parm);
+extern void ossddk_dmap_set_recerror (dmap_t * dmap, int err, int parm);
+
+extern void *ossddk_dmap_get_private (dmap_t * dmap);
+extern int ossddk_dmap_get_fragsize (dmap_t * dmap);
+extern int ossddk_dmap_get_numfrags (dmap_t * dmap);
+extern int ossddk_dmap_get_buffused (dmap_t * dmap);
+extern unsigned char *ossddk_dmap_get_dmabuf (dmap_t * dmap);
+extern unsigned long ossddk_dmap_get_phys (dmap_t * dmap);
+extern int ossddk_dmap_get_buffsize (dmap_t * dmap);
+extern int ossddk_dmap_get_qhead (dmap_t * dmap);
+extern int ossddk_dmap_get_qtail (dmap_t * dmap);
+
+int ossddk_install_mixer (int vers,
+ oss_device_t * osdev,
+ oss_device_t * master_osdev,
+ const char *name,
+ mixer_driver_t * driver,
+ int driver_size, void *devc);
+extern void *ossddk_mixer_get_devc (int dev);
+extern void ossddk_mixer_touch (int dev);
+extern int ossddk_mixer_create_group (int dev, int parent, const char *id);
+extern int ossddk_mixer_create_control (int dev, int parent, int ctrl,
+ mixer_ext_fn func, int type,
+ const char *id, int maxvalue,
+ int flags);
+extern int ossddk_mixer_truncate (int dev, int index);
+extern int ossddk_mixer_set_strings (int dev, int ctl, const char *s,
+ int version);
+
+/*
+ * AC97 interface
+ */
+
+extern int ossddk_ac97_install (ac97_handle_t ** handle, char *name,
+ ac97_readfunc_t readfn,
+ ac97_writefunc_t writefn, void *hostparms,
+ oss_device_t * osdev);
+extern void ossddk_ac97_remove (ac97_handle_t * handle);
+extern int ossddk_ac97_set_ext_init (ac97_handle_t * handle,
+ mixer_create_controls_t func,
+ int nextra);
+extern int ossddk_ac97_is_varrate (ac97_handle_t * handle);
+extern int ossddk_ac97_set_recrate (ac97_handle_t * handle, int srate);
+extern int ossddk_ac97_set_playrate (ac97_handle_t * handle, int srate);
+
+#endif /* _KERNEL */
+#endif
+
+#define OSSDDK_OK 0
+
+#endif
diff --git a/kernel/framework/include/remux.h b/kernel/framework/include/remux.h
new file mode 100644
index 0000000..ff65791
--- /dev/null
+++ b/kernel/framework/include/remux.h
@@ -0,0 +1,42 @@
+/*
+ * Purpose: Definitions for the audio remux engine
+ *
+ * This header file is to be included in all drivers that use the remux engine
+ * for multi channel audio.
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+extern void
+remux_install (char *name, oss_device_t * osdev, int frontdev, int reardev,
+ int center_lfe_dev, int surrounddev);
+
+#define MAX_SUBDEVS 4
+
+typedef struct remux_devc
+{
+ oss_device_t *osdev;
+ oss_mutex_t mutex;
+
+ int audio_dev;
+
+ int n_physdevs;
+ int physdev[MAX_SUBDEVS];
+
+ int maxchannels;
+ struct fileinfo finfo[MAX_SUBDEVS];
+
+ int open_mode;
+ int channels;
+ int speed;
+} remux_devc;
diff --git a/kernel/framework/include/spdif.h b/kernel/framework/include/spdif.h
new file mode 100644
index 0000000..a2d1938
--- /dev/null
+++ b/kernel/framework/include/spdif.h
@@ -0,0 +1,97 @@
+#ifndef SPDIF_H
+#define SPDIF_H
+/*
+ * Purpose: Definitions for S/PDIF (IEC958) control bit and mixer extension manager
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+typedef struct oss_spdif_driver spdif_driver_t;
+
+#define set_cbit(array, byte, bit, v) {array[byte] &= ~(1 << bit);array[byte] |= ((v&1)<<bit);}
+#define get_cbit(array, byte, bit) ((array[byte] >> bit)&1)
+
+
+typedef struct
+{
+ int is_ok;
+ oss_mutex_t mutex;
+ oss_device_t *osdev;
+
+ void *host_devc;
+ void *host_portc;
+ int flags;
+ unsigned int caps;
+#define SPDF_IN 0x00000001
+#define SPDF_OUT 0x00000002
+#define SPDF_ENABLE 0x00000004
+#define SPDF_RATECTL 0x00000008
+ spdif_driver_t *d;
+ oss_digital_control *ctl, hot_ctl, cold_ctl;
+ int open_mode;
+ int mixer_dev;
+
+ int group;
+ int mixer_blocked;
+} spdif_devc;
+
+
+/*
+ * reprogram 'mask' bits
+ */
+
+#define REPGM_ALL 0xffffffff
+#define REPGM_NOTHING 0x00000000
+#define REPGM_RATE 0x00000001
+#define REPGM_VBIT 0x00000002
+#define REPGM_DENABLE 0x00000004
+#define REPGM_AENABLE 0x00000008
+#define REPGM_CBIT0 0x00000010
+#define REPGM_CBIT1 0x00000020
+#define REPGM_CBIT2 0x00000040
+#define REPGM_CBIT3 0x00000080
+#define REPGM_CBIT4_23 0x00000100
+#define REPGM_CBITALL 0x000001f0
+#define REPGM_UBITALL 0x00000200
+#define REPGM_OUTSEL 0x00000400
+
+#define SPDIF_NOIOCTL 0x12344321 /* Bits of magic */
+
+struct oss_spdif_driver
+{
+ int (*reprogram_device) (void *_devc, void *_portc,
+ oss_digital_control * ctl, unsigned int mask);
+ int (*get_status) (void *_devc, void *_portc, oss_digital_control * ctl,
+ int rqbits);
+ int (*exec_request) (void *_devc, void *_portc, int rq, int param);
+};
+
+extern int oss_spdif_install (spdif_devc * devc, oss_device_t * osdev,
+ spdif_driver_t * d, int driver_size,
+ void *host_devc, void *host_portc,
+ int mixer_dev, int flags, unsigned int caps);
+extern void oss_spdif_uninstall (spdif_devc * devc);
+extern int oss_spdif_open (spdif_devc * devc, int open_mode);
+extern void oss_spdif_close (spdif_devc * devc, int open_mode);
+extern void oss_spdif_setrate (spdif_devc * devc, int rate);
+extern int oss_spdif_mix_init (spdif_devc * devc);
+extern int oss_spdif_ioctl (spdif_devc * devc, int open_mode, unsigned int cmd,
+ ioctl_arg arg);
+
+/*
+ * oss_digital_control->filler usage
+ */
+#define pro_mode filler[0]
+#define rate_bits filler[1]
+#define emphasis_type filler[2]
+
+#endif
diff --git a/kernel/framework/include/uart401.h b/kernel/framework/include/uart401.h
new file mode 100644
index 0000000..1f46fa1
--- /dev/null
+++ b/kernel/framework/include/uart401.h
@@ -0,0 +1,46 @@
+#ifndef UART401_H
+#define UART401_H
+/*
+ * Purpose: Definitions for the MPU-401 (UART) support library
+ */
+
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 MIDI_CORE_H
+#include "midi_core.h"
+#endif
+
+/*
+ * Purpose: Definitions for the MPU-401 UART driver
+ */
+
+typedef struct uart401_devc
+{
+ oss_native_word base;
+ int irq;
+ oss_device_t *osdev;
+ int running;
+ oss_mutex_t mutex;
+ oss_midi_inputbuf_t save_input_buffer;
+ int opened, disabled;
+ volatile unsigned char input_byte;
+ int my_dev;
+ int share_irq;
+}
+uart401_devc;
+
+extern int uart401_init (uart401_devc * devc, oss_device_t * osdev, int base,
+ char *name);
+extern void uart401_irq (uart401_devc * devc);
+extern void uart401_disable (uart401_devc * devc);
+#endif
diff --git a/kernel/framework/include/udi.h b/kernel/framework/include/udi.h
new file mode 100644
index 0000000..4fda377
--- /dev/null
+++ b/kernel/framework/include/udi.h
@@ -0,0 +1,111 @@
+/*
+ * Purpose: USB abstraction structures and functions used by OSS
+ *
+ * OS dependent wrappers for various USB related kernel interfaces. Each
+ * operating system will have it's private udi.c file which implements
+ * the services defined here.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/* typedef struct udi_usb_devc udi_usb_devc; // Moved to os.h */
+
+typedef struct
+{
+ char *altsetting_labels;
+ int default_altsetting;
+ unsigned int altsetting_mask;
+} ossusb_altsetting_def_t;
+
+#define MAX_ALTSETTINGS 20
+
+typedef struct udi_usb_devinfo
+{
+ int vendor, product;
+ char *name;
+ const ossusb_altsetting_def_t altsettings[MAX_ALTSETTINGS];
+}
+udi_usb_devinfo;
+
+typedef struct
+{
+ void *(*attach) (udi_usb_devc * devc, oss_device_t * osdev);
+ void (*disconnect) (void *devc);
+} udi_usb_driver;
+
+extern int udi_attach_usbdriver (oss_device_t * osdev,
+ const udi_usb_devinfo * devlist,
+ udi_usb_driver * driver);
+extern void udi_unload_usbdriver (oss_device_t * osdev);
+
+extern int udi_usb_trace;
+extern int udi_usbdev_get_class (udi_usb_devc * usbdev);
+extern int udi_usbdev_get_subclass (udi_usb_devc * usbdev);
+extern int udi_usbdev_get_vendor (udi_usb_devc * usbdev);
+extern int udi_usbdev_get_product (udi_usb_devc * usbdev);
+extern int udi_usbdev_get_inum (udi_usb_devc * usbdev);
+extern unsigned char *udi_usbdev_get_endpoint (udi_usb_devc * usbdev,
+ int altsetting, int n,
+ int *len);
+#define EP_IN 0
+#define EP_OUT 1
+extern char *udi_usbdev_get_name (udi_usb_devc * usbdev);
+extern char *udi_usbdev_get_altsetting_labels (udi_usb_devc * usbdev, int if_num, int *default_alt, unsigned int *mask);
+extern char *udi_usbdev_get_string (udi_usb_devc * usbdev, int ix);
+extern char *udi_usbdev_get_devpath (udi_usb_devc * usbdev);
+extern int udi_usbdev_get_num_altsettings (udi_usb_devc * usbdev);
+extern int udi_usbdev_get_usb_version (udi_usb_devc * usbdev);
+extern unsigned char *udi_usbdev_get_altsetting (udi_usb_devc * usbdev, int n,
+ int *size);
+extern int udi_usbdev_set_interface (udi_usb_devc * usbdev, int inum,
+ int altset);
+extern int udi_usb_snd_control_msg (udi_usb_devc * usbdev,
+ unsigned int endpoint, unsigned char rq,
+ unsigned char rqtype,
+ unsigned short value,
+ unsigned short index, void *buf, int len,
+ int timeout);
+extern int udi_usb_rcv_control_msg (udi_usb_devc * usbdev,
+ unsigned int endpoint, unsigned char rq,
+ unsigned char rqtype,
+ unsigned short value,
+ unsigned short index, void *buf, int len,
+ int timeout);
+
+typedef struct udi_usb_request udi_usb_request_t; /* Opaque type */
+typedef struct _udi_endpoint_handle_t udi_endpoint_handle_t;
+
+extern udi_endpoint_handle_t *udi_open_endpoint (udi_usb_devc * usbdev,
+ void *ep_descr);
+extern void udi_close_endpoint (udi_endpoint_handle_t * eph);
+extern int udi_endpoint_get_num (udi_endpoint_handle_t * eph);
+
+#define UDI_USBXFER_ISO_WRITE 1
+#define UDI_USBXFER_ISO_READ 2
+#define UDI_USBXFER_BULK_READ 3
+#define UDI_USBXFER_BULK_WRITE 4
+#define UDI_USBXFER_INTR_READ 5
+typedef void (*udi_usb_complete_func_t) (udi_usb_request_t * request,
+ void *arg);
+
+extern udi_usb_request_t *udi_usb_alloc_request (udi_usb_devc * usbdev,
+ udi_endpoint_handle_t * eph,
+ int nframes, int xfer_type);
+extern void udi_usb_free_request (udi_usb_request_t * request);
+extern int udi_usb_submit_request (udi_usb_request_t * request,
+ udi_usb_complete_func_t callback,
+ void *callback_arg,
+ udi_endpoint_handle_t * eph, int xfer_type,
+ void *data, int data_len);
+extern void udi_usb_cancel_request (udi_usb_request_t * request);
+extern int udi_usb_request_actlen (udi_usb_request_t * request);
+extern unsigned char *udi_usb_request_actdata (udi_usb_request_t * request);
diff --git a/kernel/framework/midi/.config b/kernel/framework/midi/.config
new file mode 100644
index 0000000..101096e
--- /dev/null
+++ b/kernel/framework/midi/.config
@@ -0,0 +1,2 @@
+configcheck=MIDI
+targetcpu=any
diff --git a/kernel/framework/midi/oss_default_timer.c b/kernel/framework/midi/oss_default_timer.c
new file mode 100644
index 0000000..ee09601
--- /dev/null
+++ b/kernel/framework/midi/oss_default_timer.c
@@ -0,0 +1,204 @@
+/*
+ * Purpose: Default MIDI timer (using system clock)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+
+typedef struct
+{
+ unsigned long long start_time;
+ timeout_id_t timeout_id;
+ oss_midi_wait_callback_t timer_callback;
+ void *arg;
+} deftmr_timerc_t;
+
+static unsigned long long tick_scale = 1;
+
+static int
+deftmr_create_instance (int timer_dev, int driver_dev)
+{
+ deftmr_timerc_t *timerc;
+
+ if ((timerc = KERNEL_MALLOC (sizeof (*timerc))) == NULL)
+ return OSS_ENOMEM;
+
+ memset (timerc, 0, sizeof (*timerc));
+
+ oss_timer_devs[timer_dev]->timerc = timerc;
+
+ return 0;
+}
+
+static void
+deftmr_free_instance (int timer_dev, int driver_dev)
+{
+ deftmr_timerc_t *timerc;
+
+ timerc = oss_timer_devs[timer_dev]->timerc;
+ untimeout (timerc->timeout_id);
+
+ if (timerc != NULL)
+ KERNEL_FREE (timerc);
+ oss_timer_devs[timer_dev]->timerc = NULL;
+}
+
+static int
+deftmr_attach_client (int timer_dev, int mididev)
+{
+ return 0;
+}
+
+static void
+deftmr_detach_client (int timer_dev, int mididev)
+{
+}
+
+static int
+deftmr_ioctl (int timer_dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static int
+deftmr_set_source (int timer_dev, int source)
+{
+ return source;
+}
+
+static int
+deftmr_set_tempo (int timer_dev, int tempo)
+{
+ return tempo;
+}
+
+static int
+deftmr_set_timebase (int timer_dev, int timebase)
+{
+ return timebase;
+}
+static int
+deftmr_start (int timer_dev, oss_uint64_t tick)
+{
+ deftmr_timerc_t *timerc;
+
+ timerc = oss_timer_devs[timer_dev]->timerc;
+
+ if (timerc == NULL)
+ {
+ cmn_err (CE_WARN, "deftmr_start: timerc==NULL\n");
+ return OSS_EIO;
+ }
+
+ timerc->start_time = GET_JIFFIES ();
+ return 0;
+}
+
+static int
+deftmr_stop (int timer_dev)
+{
+ deftmr_timerc_t *timerc;
+
+ timerc = oss_timer_devs[timer_dev]->timerc;
+ untimeout (timerc->timeout_id);
+
+ return 0;
+}
+
+static int
+deftmr_cont (int timer_dev)
+{
+ return 0;
+}
+
+static int
+deftmr_wait (int timer_dev, unsigned long long time,
+ oss_midi_wait_callback_t callback, void *arg)
+{
+ deftmr_timerc_t *timerc;
+ unsigned long long t;
+
+ timerc = oss_timer_devs[timer_dev]->timerc;
+ untimeout (timerc->timeout_id);
+
+ t = ((oss_uint64_t) time + (tick_scale / 2)) / tick_scale;
+
+ t += timerc->start_time;
+
+ t -= GET_JIFFIES ();
+
+ if (t < 0)
+ {
+ return 1;
+ }
+
+ timerc->timeout_id = timeout (callback, arg, t);
+
+ return 0;
+}
+
+static unsigned long long
+deftmr_get_current_time (int timer_dev)
+{
+ unsigned long long t;
+ deftmr_timerc_t *timerc;
+
+ timerc = oss_timer_devs[timer_dev]->timerc;
+ /*
+ * Compute time in system ticks since start of the timer
+ */
+ t = GET_JIFFIES ();
+ if (t < timerc->start_time)
+ return 0;
+ t -= timerc->start_time;
+
+ return t * tick_scale; /* In microseconds */
+}
+
+oss_timer_driver_t default_midi_driver = {
+ deftmr_create_instance,
+ deftmr_free_instance,
+ deftmr_attach_client,
+ deftmr_detach_client,
+ deftmr_ioctl,
+ deftmr_wait,
+ deftmr_get_current_time,
+ deftmr_set_source,
+ deftmr_set_tempo,
+ deftmr_set_timebase,
+ deftmr_start,
+ deftmr_stop,
+ deftmr_cont
+};
+
+void
+attach_oss_default_timer (oss_device_t * osdev)
+{
+ int timer_dev;
+
+ tick_scale = 1000000 / OSS_HZ;
+ if ((timer_dev = oss_install_timer (OSS_TIMER_DRIVER_VERSION, "System timer", &default_midi_driver, sizeof (oss_timer_driver_t), 0, /* Flags */
+ 16, /* max_instances */
+ 1000000 / OSS_HZ, /* Resolution */
+ NULL, osdev)) < 0)
+ {
+ cmn_err (CE_WARN, "Failed to install default MIDI timer\n");
+ return;
+ }
+}
+
+void
+detach_oss_default_timer ()
+{
+}
diff --git a/kernel/framework/midi/oss_midi_core.c b/kernel/framework/midi/oss_midi_core.c
new file mode 100644
index 0000000..fdca69b
--- /dev/null
+++ b/kernel/framework/midi/oss_midi_core.c
@@ -0,0 +1,1733 @@
+/*
+ * Purpose: MIDI support.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+
+#define MDB(x)
+
+oss_mutex_t midi_mutex;
+static oss_device_t *osscore_osdev = NULL;
+
+/*
+ * List of MIDI devices.
+ */
+mididev_t **midi_devs = NULL;
+int num_mididevs = 0;
+
+/*
+ * List of MIDI clients (/dev/midi* device files).
+ */
+int oss_num_midi_clients = 0;
+oss_midi_client_t *oss_midi_clients[MAX_MIDI_CLIENTS] = { NULL };
+
+static int
+queue_midi_input (mididev_t * mididev, unsigned char *data, int len,
+ oss_native_word * wait_flags)
+{
+ int ret;
+
+ midi_packet_header_t hdr, *hdrp = NULL;
+
+ if (mididev->working_mode != MIDI_MODE_TRADITIONAL)
+ {
+ int use_abs = 0;
+
+ hdrp = &hdr;
+
+ memset (&hdr, 0, sizeof (hdr));
+ hdr.magic = MIDI_HDR_MAGIC;
+ hdr.event_type = MIDI_EV_WRITE;
+ hdr.options |= MIDI_OPT_TIMED;
+
+ if (mididev->working_mode == MIDI_MODE_TIMED_ABS)
+ {
+ use_abs = 1;
+ hdr.options |= MIDI_OPT_USECTIME;
+ }
+
+ hdr.time =
+ oss_timer_get_current_time (mididev->timer_dev, mididev->latency,
+ use_abs);
+ }
+
+ if ((ret = midi_queue_put (mididev->in_queue, data, len, hdrp)) < 0)
+ {
+ if (len == 1)
+ cmn_err (CE_CONT, "/dev/midi%02d: Input buffer overflow\n",
+ mididev->dev);
+ ret = 0;
+ }
+
+ oss_wakeup (mididev->in_wq, &mididev->mutex, wait_flags, POLLIN);
+
+ return ret;
+}
+
+static void
+mtc_generator (void *d)
+{
+#if 1
+ oss_native_word dev = (oss_native_word) d;
+ oss_native_word flags;
+ unsigned char data, buf[2];
+ mididev_p mididev = midi_devs[dev];
+ int t;
+ int step;
+ int h, m, s, f;
+
+ t = (int) (GET_JIFFIES () - mididev->mtc_t0);
+
+ if (mididev->mtc_timebase < 1)
+ return;
+ mididev->mtc_timeout_id =
+ timeout (mtc_generator, (void *) dev, OSS_HZ / 100);
+
+ step = OSS_HZ / (mididev->mtc_timebase * 4); /* System ticks per quarter frame */
+ if (step < 1)
+ {
+ /* System timer has too low resolution so do nothing */
+ return;
+ }
+
+ t /= step;
+ if (t <= mididev->mtc_prev_t) /* Not enough time elapsed yet (for some reason) */
+ {
+ return;
+ }
+
+ mididev->mtc_prev_t = t;
+
+ if (mididev->mtc_phase == 0)
+ mididev->mtc_current = t;
+ else
+ t = mididev->mtc_current;
+
+ t /= 4; /* Ignore quarter frames */
+ f = t % mididev->mtc_timebase;
+ t /= mididev->mtc_timebase;
+
+ s = t % 60;
+ t /= 60;
+
+ m = t % 60;
+ t /= 60;
+
+ h = t % 0x24;
+
+ data = 0x00;
+
+ switch (mididev->mtc_phase)
+ {
+ case 0:
+ data = 0x00 | (f % 0x0f);
+ break;
+ case 1:
+ data = 0x10 | ((f >> 4) % 0x0f);
+ break;
+ case 2:
+ data = 0x20 | (s % 0x0f);
+ break;
+ case 3:
+ data = 0x30 | ((s >> 4) % 0x0f);
+ break;
+ case 4:
+ data = 0x40 | (m % 0x0f);
+ break;
+ case 5:
+ data = 0x50 | ((m >> 4) % 0x0f);
+ break;
+ case 6:
+ data = 0x60 | (h % 0x0f);
+ break;
+ case 7:
+ data = 0x70 | ((h >> 4) % 0x03) | (mididev->mtc_codetype << 1);
+ break;
+ }
+
+ mididev->mtc_phase = (mididev->mtc_phase + 1) % 8;
+
+#if 0
+ cmn_err (CE_CONT, "MTC = %02d:%02d:%02d %02d.x -> %02x\n",
+ h, m, s, f, data);
+#endif
+
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+ buf[0] = 0xf1;
+ buf[1] = data;
+ queue_midi_input (mididev, buf, 2, &flags);
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+#endif
+}
+
+int
+oss_midi_input_byte (int dev, unsigned char data)
+{
+ oss_native_word flags;
+ mididev_t *mididev;
+ int ret;
+
+ if (dev < 0 || dev >= num_mididevs)
+ cmn_err (CE_PANIC, "MIDI driver bug - bad MIDI device %d\n", dev);
+
+ mididev = midi_devs[dev];
+
+ if (data == 0xf1)
+ {
+ mididev->mtc_timebase = -1;
+ }
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+ ret = queue_midi_input (mididev, &data, 1, &flags);
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+
+ return ret;
+}
+
+int
+oss_midi_input_buf (int dev, unsigned char *data, int len)
+{
+ oss_native_word flags;
+ mididev_t *mididev;
+ int ret, n = 0;
+
+ if (dev < 0 || dev >= num_mididevs)
+ cmn_err (CE_PANIC, "MIDI driver bug - bad MIDI device %d\n", dev);
+
+ mididev = midi_devs[dev];
+
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+
+ while (len > 0)
+ {
+ int i, l = len;
+
+ if (l > MIDI_PAYLOAD_SIZE)
+ l = MIDI_PAYLOAD_SIZE;
+
+
+ for (i = 0; i < l; i++)
+ {
+ /* Turn off MTC generation if MTC data is received */
+ if (data[i] == 0xf1)
+ {
+ mididev->mtc_timebase = -1;
+ }
+ }
+ ret = queue_midi_input (mididev, data, l, &flags);
+ if (ret < 0)
+ {
+ ret = 0;
+ cmn_err (CE_WARN, "MIDI input bytes dropped\n");
+ }
+
+ if (ret == 0) /* Cannot queue more bytes */
+ break;
+
+ len -= ret;
+ data += ret;
+ n += ret;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+
+ return n;
+}
+
+static void
+oss_midi_input_event (int dev, unsigned char *data, int len)
+{
+ oss_native_word flags;
+ mididev_t *mididev;
+ int ret, n = 0, i;
+
+ if (dev < 0 || dev >= num_mididevs)
+ cmn_err (CE_PANIC, "MIDI driver bug - bad MIDI device %d\n", dev);
+
+ mididev = midi_devs[dev];
+
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+
+ for (i = 0; i < len; i += 4)
+ {
+ int l;
+ unsigned char *d = data + i;
+
+ switch (d[0] & 0x0f)
+ {
+ case 0x0: /* End marker */
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return;
+ break;
+
+ case 0x2: /* Two byte real time messages TODO? */
+ l = 2;
+ break;
+
+ case 0x4: /* Sysex start/continuation */
+ l = 3;
+ break;
+
+ case 0x5: /* Sysex termination records */
+ case 0x6:
+ case 0x7:
+ l = (d[0] & 0x0f) - 4;
+ break;
+
+ case 0x8:
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ case 0xe:
+ l = 3;
+ break;
+
+ case 0x0c:
+ case 0x0d:
+ l = 2;
+ break;
+
+ case 0xf: /* System real time messages */
+ l = 1;
+ break;
+
+ default:
+ l = 3;
+ }
+
+ if (l == 0) /* Nothing to send */
+ continue;
+
+ if (l > MIDI_PAYLOAD_SIZE)
+ l = MIDI_PAYLOAD_SIZE;
+
+ /*
+ * Ignore active sensing
+ */
+ if (d[1] == 0xfe)
+ continue;
+
+ ret = queue_midi_input (mididev, d + 1, l, &flags);
+ if (ret < 0)
+ {
+ ret = 0;
+ cmn_err (CE_WARN, "MIDI input bytes dropped\n");
+ }
+
+ if (ret == 0) /* Cannot queue more bytes */
+ break;
+
+ len -= ret;
+ data += ret;
+ n += ret;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+
+ return;
+}
+
+static void oss_midi_callback (void *arg);
+static int setup_tempo (mididev_t * mididev);
+
+void
+oss_midi_copy_timer (int dev, int source_dev)
+{
+ mididev_t *mididev;
+ int err;
+
+ if (dev < 0 || dev >= num_mididevs)
+ return;
+ mididev = midi_devs[dev];
+
+ if (mididev->timer_dev >= 0) /* Detach the old client */
+ oss_timer_detach_client (mididev->timer_dev, mididev);
+
+ mididev->timer_dev = -1;
+
+ if (source_dev < 0 || source_dev >= num_mididevs)
+ return;
+
+ if (midi_devs[source_dev]->timer_dev < 0)
+ return;
+
+ if ((err =
+ oss_timer_attach_client (midi_devs[source_dev]->timer_dev,
+ mididev)) < 0)
+ {
+ cmn_err (CE_CONT, "Cannot attach timer %d to MIDI dev %d, err=%d\n",
+ midi_devs[source_dev]->timer_dev, mididev->dev, err);
+ return;
+ }
+
+ mididev->timer_dev = midi_devs[source_dev]->timer_dev;
+ mididev->timer_driver = midi_devs[source_dev]->timer_driver;
+}
+
+int
+oss_midi_output_intr_handler (int dev, int callback_flag)
+{
+ mididev_t *mididev;
+ oss_native_word flags;
+
+ unsigned char *buf;
+ int len;
+ midi_packet_header_t *hdr;
+ MDB (cmn_err (CE_CONT, "oss_midi_output_intr_handler()\n"));
+
+ if (dev < 0 || dev >= num_mididevs)
+ cmn_err (CE_PANIC, "oss_midi_output_intr: Bad device %d\n", dev);
+
+ mididev = midi_devs[dev];
+
+ if (callback_flag)
+ {
+ mididev->out_timeout = 0;
+ }
+
+ if (!(mididev->open_mode & OPEN_WRITE)) /* Device may have been closed */
+ {
+ return 0;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+
+ while ((len = midi_queue_find_buffer (mididev->out_queue, &buf, &hdr)) >= 0)
+/* TODO: Check time */
+ {
+ int i, n = 0;
+
+ if (!callback_flag) /* Called from write() handler */
+ if (hdr != NULL && (hdr->options & MIDI_OPT_BUSY))
+ {
+ /*
+ * This buffer is already playing
+ */
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return 0;
+ }
+
+ MDB (cmn_err (CE_CONT, "Bytes in buffer=%d\n", len));
+#if 0
+ if (buf != NULL)
+ MDB (cmn_err (CE_CONT, "First=%02x\n", buf[0]));
+#endif
+
+ if (hdr == NULL)
+ {
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return 0;
+ }
+
+ hdr->options |= MIDI_OPT_BUSY;
+ if (mididev->timer_dev >= 0)
+ if (hdr->options & MIDI_OPT_TIMED)
+ {
+ if (mididev->d->flush_output)
+ mididev->d->flush_output (mididev->dev);
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ /* TODO: Does releasing the mutex here cause any race conditions? */
+ if (oss_timer_wait_time
+ (mididev->timer_dev, mididev->dev, mididev->latency,
+ hdr->time, oss_midi_callback, hdr->options) <= 0)
+ {
+ /*
+ * Not the right time yet. Timer is armed
+ * and the callback function will be called
+ * at the right time. We don't remove the event
+ * so it can be retried later.
+ */
+ return 0;
+ }
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+ }
+
+ switch (hdr->event_type)
+ {
+ case MIDI_EV_TEMPO:
+ mididev->tempo = hdr->parm;
+ setup_tempo (mididev);
+ break;
+
+ case MIDI_EV_START:
+ oss_timer_start (mididev->timer_dev);
+ if (mididev->d->timer_setup)
+ mididev->d->timer_setup (mididev->dev);
+ break;
+
+ case MIDI_EV_WRITE:
+ break;
+ }
+
+ if (mididev->d->outputc == NULL
+ || (len > 1 && mididev->d->bulk_write != NULL))
+ {
+ n = mididev->d->bulk_write (mididev->dev, buf, len);
+ if (n <= 0) /* Error */
+ {
+ MDB (cmn_err
+ (CE_NOTE, "MIDI device %d - output stalled (%d).\n",
+ mididev->dev, n));
+ n = 0;
+ }
+ }
+ else
+ {
+ for (i = 0; i < len; i++)
+ {
+ MDB (cmn_err (CE_CONT, "Out %d %02x\n", mididev->dev, buf[i]));
+ if (!mididev->d->outputc (mididev->dev, buf[i]))
+ {
+ MDB (cmn_err
+ (CE_NOTE, "MIDI device %d - output stalled (%d).\n",
+ mididev->dev, n));
+ break; /* device full */
+ }
+ n++;
+ }
+ }
+
+ /* Remove the bytes sent out */
+ if (n > 0 || len == 0)
+ {
+ MDB (cmn_err (CE_CONT, "Remove %d/%d\n", n, len));
+ midi_queue_remove_chars (mididev->out_queue, n);
+ oss_wakeup (mididev->out_wq, &mididev->mutex, &flags, POLLOUT);
+ }
+
+ if (n == len)
+ {
+ if (mididev->d->flush_output)
+ mididev->d->flush_output (mididev->dev);
+ }
+
+ if (n < len)
+ {
+ /* Not everything consumed - arm a timeout */
+
+ MDB (cmn_err (CE_CONT, "Not all consumed %d/%d\n", n, len));
+ if (mididev->out_timeout == 0) /* Not armed yet */
+ {
+ oss_native_word d = dev;
+ mididev->out_timeout =
+ timeout (oss_midi_callback, (void *) d, 1);
+ }
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+
+ return 0; /* Not all buffered bytes were sent */
+ }
+ MDB (cmn_err (CE_CONT, "Everything consumed\n"));
+ }
+
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+
+ return 1; /* Everything was done */
+}
+
+int
+oss_midi_output_intr (int dev)
+{
+ MDB (cmn_err (CE_CONT, "oss_midi_output_intr\n"));
+ return oss_midi_output_intr_handler (dev, 0);
+}
+
+static void
+oss_midi_callback (void *arg)
+{
+ int dev;
+
+ dev = (oss_native_word) arg;
+
+ MDB (cmn_err (CE_CONT, "MIDI timer callback\n"));
+ oss_midi_output_intr_handler (dev, 1);
+}
+
+void
+oss_midi_set_defaults (mididev_t * mididev)
+{
+ mididev->prech_timeout = 0; /* Infinite wait */
+
+ mididev->event_input = oss_midi_input_event;
+ mididev->tempo = 120;
+ mididev->timebase = OSS_HZ;
+}
+
+static void put_output (mididev_t * mididev, unsigned char *buf, int len);
+
+int
+oss_midi_open (int dev, int no_worries, struct fileinfo *file, int recursive,
+ int open_flags, int *newdev)
+{
+/*
+ * oss_midi_open opens a MIDI client (/dev/midi##) and binds it directly to
+ * the MIDI port with the same number (dev).
+ */
+ oss_native_word flags;
+ oss_midi_client_t *client;
+ int ok, err = OSS_EBUSY;
+ int mode = file->mode & O_ACCMODE;
+
+ char *cmd;
+
+ if (dev < 0 || dev >= num_mididevs)
+ return OSS_ENXIO;
+
+ /*
+ * Don't allow read only access on playback only devices.
+ * However R/W access should be allowed so that the application can be
+ * informed about (possible) status changes.
+ */
+ if ((mode == OPEN_READ) && !(midi_devs[dev]->flags & MFLAG_INPUT))
+ {
+ return OSS_EACCES;
+ }
+
+ /*
+ * Input only devices cannot do output so don't allow it.
+ */
+ if ((mode & OPEN_WRITE) && !(midi_devs[dev]->flags & MFLAG_OUTPUT))
+ {
+ return OSS_EACCES;
+ }
+
+ if (!midi_devs[dev]->enabled)
+ return OSS_ENXIO;
+
+ if (midi_devs[dev]->unloaded)
+ return OSS_ENXIO;
+
+ client = oss_midi_clients[dev];
+ if (client == NULL)
+ return OSS_ENXIO;
+
+ MUTEX_ENTER_IRQDISABLE (midi_mutex, flags);
+
+ ok = 1;
+ if (client->open_mode != 0) /* Client busy */
+ ok = 0;
+
+ if (midi_devs[dev]->open_mode != 0) /* Device busy */
+ ok = 0;
+
+ if (ok) /* Still OK */
+ {
+ client->mididev = midi_devs[dev];
+ if (client->mididev == NULL)
+ {
+ cmn_err(CE_WARN, "client->mididev == NULL\n");
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+ return OSS_EIO;
+ }
+
+ client->open_mode = mode;
+ midi_devs[dev]->open_mode = mode;
+
+ if ((cmd = GET_PROCESS_NAME (file)) != NULL)
+ strncpy (client->mididev->cmd, cmd, 15);
+ client->mididev->pid = GET_PROCESS_PID (file);
+
+ /* Release locks before calling device open method */
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+ if ((err = midi_devs[dev]->d->open (dev, mode,
+ oss_midi_input_byte,
+ oss_midi_input_buf,
+ oss_midi_output_intr)) < 0)
+ ok = 0;
+ /* Reacquire locks */
+ MUTEX_ENTER_IRQDISABLE (midi_mutex, flags);
+ if (!ok)
+ {
+ client->open_mode = 0;
+ midi_devs[dev]->open_mode = 0;
+ }
+ }
+
+ if (!ok)
+ {
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+ return err;
+ }
+
+ oss_midi_set_defaults (client->mididev);
+
+ client->mididev->is_timing_master = 0;
+
+ client->num = dev;
+
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+
+ if (mode & OPEN_READ)
+ {
+ char name[16];
+ sprintf (name, "read%d", dev);
+ client->mididev->in_queue =
+ midi_queue_alloc (client->mididev->osdev, name);
+ if (client->mididev->in_queue == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate MIDI input queue\n");
+ midi_devs[dev]->open_mode = 0;
+ client->open_mode = 0;
+ client->mididev = NULL;
+ return OSS_ENOMEM;
+ }
+ }
+
+ if (mode & OPEN_WRITE)
+ {
+ char name[16];
+ int i;
+ unsigned char tmpbuf[4];
+ sprintf (name, "write%d", dev);
+ client->mididev->out_queue =
+ midi_queue_alloc (client->mididev->osdev, name);
+/* if (dev==0)midi_queue_debugging(client->mididev->out_queue); */
+ if (client->mididev->out_queue == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate MIDI output queue\n");
+ midi_devs[dev]->open_mode = 0;
+ client->open_mode = 0;
+ client->mididev = NULL;
+ return OSS_ENOMEM;
+ }
+
+/*
+ * Reset all MIDI controllers to their default values
+ */
+ if (!(client->mididev->flags & MFLAG_QUIET))
+ for (i = 0; i < 16; i++)
+ {
+ tmpbuf[0] = 0xb0 | i; /* Control change */
+ tmpbuf[1] = 121; /* Reset all controllers */
+ tmpbuf[2] = 127; /* Reset vol/exp/pan too */
+ put_output (client->mididev, tmpbuf, 3);
+ }
+ if (client->mididev->d->flush_output)
+ client->mididev->d->flush_output (client->mididev->dev);
+ }
+
+ if (client->mididev->d->init_device)
+ client->mididev->d->init_device (dev);
+
+ return 0;
+}
+
+int
+oss_vmidi_open (int dev, int dev_type, struct fileinfo *file, int recursive,
+ int open_flags, int *newdev);
+
+static void
+sync_output (mididev_t * mididev)
+{
+ int n = 0;
+ unsigned int status;
+ oss_native_word flags;
+
+ if (mididev->is_killed)
+ {
+ midi_queue_removeall (mididev->out_queue);
+ return;
+ }
+
+ if (mididev->timer_dev < 0 || !oss_timer_is_running (mididev->timer_dev))
+ {
+ midi_queue_removeall (mididev->out_queue);
+ return;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+ if (mididev->d->flush_output)
+ mididev->d->flush_output (mididev->dev);
+
+ while (!midi_queue_isempty (mididev->out_queue))
+ {
+ int tmout;
+
+ if (n++ > 100)
+ {
+ cmn_err (CE_NOTE, "MIDI output didn't get drained (sync).\n");
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return;
+ }
+ tmout = oss_timer_get_timeout (mididev->timer_dev, mididev->dev);
+ if (oss_sleep (mididev->out_wq, &mididev->mutex,
+ tmout, &flags, &status))
+ n = 0; /* Not timeout */
+ if (status & WK_SIGNAL)
+ {
+ mididev->is_killed = 1;
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return;
+ }
+ }
+
+ n = 0;
+ if (mididev->d->wait_output)
+ while (mididev->d->wait_output (mididev->dev))
+ {
+ MDB (cmn_err (CE_CONT, "Wait output\n"));
+ if (n++ > 10)
+ {
+ cmn_err (CE_NOTE, "MIDI output doesn't get emptied (sync).\n");
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return;
+ }
+ oss_sleep (mididev->out_wq, &mididev->mutex, OSS_HZ, &flags, &status);
+ if (status & WK_SIGNAL)
+ {
+ mididev->is_killed = 1;
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return;
+ }
+ }
+/*
+ * Give the device few moments of extra time to flush all buffers.
+ */
+ oss_sleep (mididev->out_wq, &mididev->mutex, OSS_HZ / 2, &flags, &status);
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+
+}
+
+static void
+put_output (mididev_t * mididev, unsigned char *buf, int len)
+{
+ int i, n;
+ int tmout = 1000; /* Spend here at most 1000 msec */
+
+ if (mididev->d->outputc == NULL
+ || (len > 1 && mididev->d->bulk_write != NULL))
+ {
+ int p = 0;
+
+ while (p < len && tmout-- > 0)
+ {
+ n = mididev->d->bulk_write (mididev->dev, buf + p, len - p);
+ if (n < 0) /* Error */
+ {
+ return;
+ }
+
+ if (n < (len - p)) /* Not all consumed yet */
+ oss_udelay (1000);
+
+ p += n;
+ }
+
+ return;
+ }
+
+ if (mididev->d->outputc)
+ for (i = 0; i < len; i++)
+ {
+ while (!mididev->d->outputc (mididev->dev, buf[i]) && tmout-- > 0)
+ {
+ oss_udelay (1000);
+ }
+ }
+}
+
+void
+oss_midi_release (int dev, struct fileinfo *file)
+{
+ oss_native_word flags;
+ oss_midi_client_t *client;
+ int midi_dev;
+ mididev_t *mididev;
+ int mode;
+
+ MUTEX_ENTER_IRQDISABLE (midi_mutex, flags);
+ mode = file->mode & O_ACCMODE;
+ client = oss_midi_clients[dev];
+
+ if (client->mididev == NULL) /* Not bound to a port device */
+ {
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+ return;
+ }
+
+ mididev = client->mididev;
+ midi_dev = mididev->dev;
+
+ untimeout (mididev->mtc_timeout_id);
+
+ client->open_mode = 0;
+
+ if (mididev->open_mode & OPEN_WRITE) /* Needs to sync */
+ {
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+ sync_output (mididev);
+
+ if (mididev->is_timing_master)
+ oss_timer_stop (mididev->timer_dev);
+ mididev->is_killed = 0; /* Too young to die */
+
+ /* Shut up possible hanging notes (if any) */
+ if (!(mididev->flags & MFLAG_QUIET))
+ {
+ unsigned char tmpbuf[4];
+ int i;
+
+ /* Sending one active sensing message should stop most devices */
+ tmpbuf[0] = 0xfe;
+ put_output (mididev, tmpbuf, 1);
+
+#if 1
+ /*
+ * To make sure we will also send a "all notes off" message to
+ * all MIDI channels.
+ */
+ for (i = 0; i < 16; i++)
+ {
+ tmpbuf[0] = 0xb0 | i; /* Control change */
+ tmpbuf[1] = 123; /* All notes off */
+ tmpbuf[2] = 0;
+ put_output (mididev, tmpbuf, 3);
+ }
+#endif
+ }
+
+ sync_output (mididev);
+
+ MUTEX_ENTER_IRQDISABLE (midi_mutex, flags);
+ }
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+
+ mididev->d->ioctl (midi_dev, SNDCTL_SETSONG, (ioctl_arg) "");
+ mididev->d->close (midi_dev, mode);
+ MUTEX_ENTER_IRQDISABLE (midi_mutex, flags);
+ mididev->open_mode &= ~mode;
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+
+ if (mididev->timer_dev >= 0)
+ oss_timer_detach_client (mididev->timer_dev, mididev);
+ mididev->timer_dev = -1;
+ mididev->timer_driver = 0;
+
+ if (mididev->in_queue != NULL)
+ midi_queue_free (mididev->in_queue);
+ mididev->in_queue = NULL;
+ mididev->pid = -1;
+ mididev->cmd[0] = 0;
+
+ if (mididev->out_queue != NULL)
+ midi_queue_free (mididev->out_queue);
+ mididev->out_queue = NULL;
+
+ client->mididev = NULL;
+
+ if (mididev->out_timeout != 0)
+ untimeout (mididev->out_timeout);
+ mididev->out_timeout = 0;
+}
+
+int
+oss_midi_write (int dev, struct fileinfo *file, uio_t * buf, int count)
+{
+ oss_midi_client_t *client = oss_midi_clients[dev];
+ mididev_t *mididev;
+ int ret;
+ unsigned int status;
+ int c = 0, l, loops;
+ oss_native_word flags;
+ midi_packet_header_t hdr;
+ int save_header = 0;
+ int tmout = OSS_HZ;
+
+ unsigned char *targetbuf;
+
+ MDB (cmn_err (CE_CONT, "MIDI write %d\n", count));
+ if (client->mididev == NULL)
+ if ((ret = midi_mapper_autobind (dev, client->open_mode)) < 0)
+ return ret;
+ mididev = client->mididev;
+
+ if (mididev == NULL)
+ return OSS_EBUSY;
+
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+
+ /*
+ * Since the application called write again we can ignore possible
+ * earlier received kill signals.
+ */
+ mididev->is_killed = 0;
+
+ memset (&hdr, 0, sizeof (hdr));
+ if (mididev->working_mode != MIDI_MODE_TRADITIONAL)
+ {
+ if (count < sizeof (midi_packet_header_t))
+ {
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ cmn_err (CE_WARN, "Too short MIDI write (no header)\n");
+ return OSS_EINVAL;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ if (uiomove (&hdr, sizeof (midi_packet_header_t), UIO_WRITE, buf) != 0)
+ {
+ cmn_err (CE_WARN, "uiomove (header) failed\n");
+ return OSS_EFAULT;
+ }
+
+ if (hdr.magic != MIDI_HDR_MAGIC)
+ {
+ cmn_err (CE_WARN, "Bad MIDI write packet header (%04x)\n",
+ hdr.magic);
+ return OSS_EINVAL;
+ }
+ count -= sizeof (midi_packet_header_t);
+ c += sizeof (midi_packet_header_t);
+
+ /* Force save of the header if no other data was written */
+ if (count <= 0)
+ save_header = 1;
+
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+ }
+
+ loops = 0;
+ while (save_header || count > 0)
+ {
+ MDB (cmn_err (CE_CONT, "Write bytes left %d\n", count));
+ l = count;
+ save_header = 0;
+
+ if (loops++ > 10)
+ {
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ cmn_err (CE_CONT, "MIDI Output buffer %d doesn't drain %d/%d\n",
+ mididev->dev, c, count);
+ return OSS_EIO;
+ }
+
+ if (l > MIDI_PAYLOAD_SIZE)
+ l = MIDI_PAYLOAD_SIZE;
+
+ if ((ret =
+ midi_queue_alloc_record (mididev->out_queue, &targetbuf, l,
+ &hdr)) < 0)
+ {
+ if (ret == OSS_ENOSPC) /* Buffers full */
+ {
+ MDB (cmn_err (CE_CONT, "*** Buffers full ***\n"));
+ tmout =
+ oss_timer_get_timeout (mididev->timer_dev, mididev->dev);
+ if (!oss_sleep
+ (mididev->out_wq, &mididev->mutex, tmout, &flags, &status))
+ {
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ if (c > 0)
+ return c;
+ return OSS_EIO; /* Timeout - why */
+ }
+ else
+ loops = 0; /* Restart loop limiter */
+
+ if (status & WK_SIGNAL)
+ {
+ mididev->is_killed = 1;
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return OSS_EINTR;
+ }
+
+ if (loops > 95)
+ cmn_err (CE_NOTE, "MIDI Output buffers full\n");
+ continue; /* Try again later */
+ }
+
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return ret;
+ }
+
+ if (l > ret)
+ l = ret;
+
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+/* cmn_err(CE_CONT, "Copy %08x (%d)\n", targetbuf, l); */
+
+ loops = 0;
+
+ if (l > 0)
+ {
+ MDB (cmn_err (CE_CONT, "Store %d bytes\n", l));
+ if (uiomove (targetbuf, l, UIO_WRITE, buf) != 0)
+ {
+ cmn_err (CE_WARN, "uiomove (write) failed\n");
+ return OSS_EFAULT;
+ }
+
+ count -= l;
+ c += l;
+ }
+
+ MDB (cmn_err (CE_CONT, "From oss_midi_write\n"));
+ oss_midi_output_intr_handler (mididev->dev, 0);
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+ }
+
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+
+ /* midi_queue_trace(mididev->out_queue); */
+ MDB (cmn_err (CE_CONT, "MIDI write done %d\n\n", c));
+
+ return c;
+}
+
+static int
+do_read (mididev_t * mididev, uio_t * buf, unsigned char *data, int c,
+ int max_bytes, midi_packet_header_t * hdr)
+{
+ int l = 0;
+
+ if (mididev->working_mode != MIDI_MODE_TRADITIONAL)
+ {
+ if (max_bytes <= sizeof (*hdr))
+ {
+ cmn_err (CE_WARN, "MIDI read too small for packet header\n");
+ return OSS_E2BIG;
+ }
+
+ hdr->magic = MIDI_HDR_MAGIC;
+ if (uiomove (hdr, sizeof (*hdr), UIO_READ, buf) != 0)
+ {
+ cmn_err (CE_WARN, "uiomove (read) failed\n");
+ return OSS_EFAULT;
+ }
+
+ l += sizeof (*hdr);
+ }
+
+ if (l + c > max_bytes)
+ c = max_bytes - l;
+
+ if (c <= 0)
+ return OSS_E2BIG;
+
+ if (uiomove (data, c, UIO_READ, buf) != 0)
+ {
+ cmn_err (CE_WARN, "uiomove (read) failed\n");
+ return OSS_EFAULT;
+ }
+
+ midi_queue_remove_chars (mididev->in_queue, c);
+ l += c;
+
+ return l;
+}
+
+int
+oss_midi_read (int dev, struct fileinfo *file, uio_t * buf, int count)
+{
+ oss_midi_client_t *client = oss_midi_clients[dev];
+ mididev_t *mididev;
+ oss_native_word flags;
+ unsigned char *data;
+
+ unsigned int status;
+ int c = 0;
+ midi_packet_header_t *hdr;
+
+ int err;
+
+ if (client->mididev == NULL)
+ if ((err = midi_mapper_autobind (dev, client->open_mode)) < 0)
+ return err;
+ mididev = client->mididev;
+
+ if (mididev == NULL)
+ return OSS_EBUSY;
+
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+
+ if ((c = midi_queue_find_buffer (mididev->in_queue, &data, &hdr)) < 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return c;
+ }
+
+ if (c > 0
+ || (mididev->working_mode != MIDI_MODE_TRADITIONAL && c >= 0
+ && hdr != NULL))
+ {
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return do_read (mididev, buf, data, c, count, hdr);
+ }
+
+ if (mididev->prech_timeout < 0) /* Non blocking mode */
+ {
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return OSS_EWOULDBLOCK;
+ }
+
+ if (!oss_sleep
+ (mididev->in_wq, &mididev->mutex, mididev->prech_timeout, &flags,
+ &status))
+ {
+ /* Timeout */
+
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return 0;
+ }
+
+ if (status & WK_SIGNAL)
+ {
+ mididev->is_killed = 1;
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return OSS_EINTR;
+ }
+
+ if ((c = midi_queue_get (mididev->in_queue, &data, count, &hdr)) < 0
+ || (c == 0 && hdr == NULL))
+ {
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ return c;
+ }
+
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ if (c > 0)
+ return do_read (mididev, buf, data, c, count, hdr);
+
+ return c;
+}
+
+static int
+setup_working_mode (mididev_t * mididev)
+{
+ int timer_dev;
+ int err;
+
+ if (mididev->timer_dev < 0) /* No timer yet */
+ {
+ /*
+ * Setup a timer
+ */
+
+ if (mididev->timer_driver < 0
+ || mididev->timer_driver >= oss_num_timer_drivers)
+ {
+ cmn_err (CE_WARN, "Invalid MIDI timer %d selected\n",
+ mididev->timer_driver);
+ return OSS_ENXIO;
+ }
+
+ if ((timer_dev =
+ oss_timer_create_instance (mididev->timer_driver, mididev)) < 0)
+ return timer_dev;
+ mididev->is_timing_master = 1;
+
+ if ((err = oss_timer_attach_client (timer_dev, mididev)) < 0)
+ {
+ oss_timer_detach_client (timer_dev, mididev);
+ return err;
+ }
+
+ mididev->timer_dev = timer_dev;
+ if (mididev->d->timer_setup)
+ mididev->d->timer_setup (mididev->dev);
+ }
+ else
+ timer_dev = mididev->timer_dev;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers ||
+ oss_timer_devs[timer_dev] == NULL)
+ {
+ cmn_err (CE_WARN, "Failed to allocate a timer instance\n");
+ return OSS_ENXIO;
+ }
+
+
+ return 0;
+}
+
+static int
+setup_timebase (mididev_t * mididev)
+{
+ if (mididev->timer_dev < 0) /* No timer yet */
+ return 0;
+
+ return oss_timer_set_timebase (mididev->timer_dev, mididev->timebase);
+}
+
+static int
+setup_tempo (mididev_t * mididev)
+{
+ if (mididev->timer_dev < 0) /* No timer yet */
+ return 0;
+
+ return oss_timer_set_tempo (mididev->timer_dev, mididev->tempo);
+}
+
+int
+oss_midi_ioctl (int dev, struct fileinfo *file,
+ unsigned int cmd, ioctl_arg arg)
+{
+ oss_midi_client_t *client = oss_midi_clients[dev];
+ mididev_t *mididev;
+ int err, val;
+ oss_native_word d;
+
+ if (client->mididev == NULL)
+ if ((err = midi_mapper_autobind (dev, client->open_mode)) < 0)
+ return err;
+ mididev = client->mididev;
+ if (mididev == NULL)
+ return OSS_EBUSY;
+
+ dev = mididev->dev;
+
+ switch (cmd)
+ {
+ case SNDCTL_MIDI_PRETIME:
+ val = *arg;
+ if (val < -1)
+ return OSS_EINVAL;
+
+ if (val != -1)
+ val = (OSS_HZ * val) / 100;
+ mididev->prech_timeout = val;
+ return 0;
+ break;
+
+ case SNDCTL_MIDI_MTCINPUT:
+ val = *arg;
+ switch (val)
+ {
+ case 0:
+ case -1:
+ break;
+ case 24:
+ mididev->mtc_codetype = 0;
+ break;
+ case 25:
+ mididev->mtc_codetype = 1;
+ break;
+ case 29:
+ mididev->mtc_codetype = 2;
+ break;
+ case 30:
+ mididev->mtc_codetype = 3;
+ break;
+ break;
+ default:
+ return OSS_EINVAL;
+ }
+ mididev->mtc_timebase = val;
+ mididev->mtc_t0 = GET_JIFFIES ();
+ mididev->mtc_current = 0;
+ mididev->mtc_prev_t = -1;
+ mididev->mtc_phase = 0;
+ d = dev;
+ if (mididev->mtc_timebase != -1)
+ mididev->mtc_timeout_id =
+ timeout (mtc_generator, (void *) d, OSS_HZ / 100);
+ return *arg = val;
+ break;
+
+ case SNDCTL_MIDI_SETMODE:
+ val = *arg;
+ if (val != MIDI_MODE_TRADITIONAL && val != MIDI_MODE_TIMED
+ && val != MIDI_MODE_TIMED_ABS)
+ return OSS_EINVAL;
+ mididev->working_mode = val;
+ *arg = val;
+ if ((err = setup_working_mode (mididev)) < 0)
+ return err;
+ if ((err = setup_tempo (mididev)) < 0)
+ return err;
+ if ((err = setup_timebase (mididev)) < 0)
+ return err;
+ return 0;
+ break;
+
+ case SNDCTL_MIDI_TIMEBASE:
+ val = *arg;
+ if (val < 1 || val > 1000)
+ return OSS_EINVAL;
+ mididev->timebase = val;
+ return setup_timebase (mididev);
+ break;
+
+ case SNDCTL_MIDI_TEMPO:
+ val = *arg;
+ if (val < 1 || val > 200)
+ return OSS_EINVAL;
+ mididev->tempo = val;
+ return setup_tempo (mididev);
+ break;
+
+ default:
+ return mididev->d->ioctl (mididev->dev, cmd, arg);
+ }
+}
+
+#ifdef ALLOW_SELECT
+int
+oss_midi_chpoll (int dev, struct fileinfo *file, oss_poll_event_t * ev)
+{
+ short events = ev->events;
+ oss_midi_client_t *client;
+ mididev_t *mididev;
+ oss_native_word flags;
+ int err;
+
+ if (dev < 0 || dev >= oss_num_midi_clients)
+ return OSS_ENXIO;
+ client = oss_midi_clients[dev];
+ if (client->mididev == NULL)
+ if ((err = midi_mapper_autobind (dev, client->open_mode)) < 0)
+ return err;
+ mididev = client->mididev;
+ if (mididev == NULL)
+ return OSS_EIO;
+
+ if ((events & (POLLOUT | POLLWRNORM)) && (mididev->open_mode & OPEN_WRITE))
+ {
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+ if (mididev->out_queue == NULL
+ || midi_queue_spaceleft (mididev->out_queue) < 10)
+ { /* No space yet */
+ oss_register_poll (mididev->out_wq, &mididev->mutex, &flags, ev);
+ }
+ else
+ {
+ ev->revents |= (POLLOUT | POLLWRNORM) & events;
+ }
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ }
+
+ if ((events & (POLLIN | POLLRDNORM)) && (mididev->open_mode & OPEN_READ))
+ {
+ MUTEX_ENTER_IRQDISABLE (mididev->mutex, flags);
+ if (mididev->in_queue == NULL || midi_queue_isempty (mididev->in_queue))
+ { /* No space yet */
+ oss_register_poll (mididev->in_wq, &mididev->mutex, &flags, ev);
+ }
+ else
+ {
+ ev->revents |= (POLLIN | POLLRDNORM) & events;
+ }
+ MUTEX_EXIT_IRQRESTORE (mididev->mutex, flags);
+ }
+
+ return 0;
+}
+#endif
+
+#ifdef VDEV_SUPPORT
+static oss_cdev_drv_t vmidi_cdev_drv = {
+ oss_vmidi_open,
+ oss_midi_release,
+ oss_midi_read,
+ oss_midi_write,
+ oss_midi_ioctl,
+#ifdef ALLOW_SELECT
+ oss_midi_chpoll
+#else
+ NULL
+#endif
+};
+#endif
+
+static oss_cdev_drv_t midi_cdev_drv = {
+ oss_midi_open,
+ oss_midi_release,
+ oss_midi_read,
+ oss_midi_write,
+ oss_midi_ioctl,
+#ifdef ALLOW_SELECT
+ oss_midi_chpoll
+#else
+ NULL
+#endif
+};
+
+int
+oss_vmidi_open (int dev, int dev_type, struct fileinfo *file, int recursive,
+ int open_flags, int *newdev)
+{
+/*
+ * oss_vmidi_open is another version of oss_midi_open. Instead of binding
+ * the client directly with the device port this routine creates just a
+ * client (device file). The binding operation is left to be done later
+ * using SNDCTL_MIDI_BIND. If no binding is made then the first
+ * read/write/ioctl/etc operation will automatically bind the client
+ * with the first available (lowest number) MIDI port.
+ *
+ * oss_vmidi_open() drives the /dev/midi device file.
+ */
+
+ oss_native_word flags;
+ oss_midi_client_t *client = NULL;
+ int d;
+ int mode = file->mode & O_ACCMODE;
+
+ MUTEX_ENTER_IRQDISABLE (midi_mutex, flags);
+
+/*
+ * Find the first midi client number that is free. Start from the client
+ * numbers after the last existing MIDI port.
+ */
+ for (dev = num_mididevs; dev < oss_num_midi_clients; dev++)
+ {
+ if (oss_midi_clients[dev] != NULL &&
+ oss_midi_clients[dev]->open_mode == 0)
+ {
+ client = oss_midi_clients[dev];
+ break;
+ }
+ }
+
+ if (client == NULL)
+ {
+ /*
+ * No earlier allocated clients were free so create a new entry.
+ * Also create an anonymous character device.
+ */
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+ client = PMALLOC (osdev, sizeof (*client));
+ MUTEX_ENTER_IRQDISABLE (midi_mutex, flags);
+
+ if (oss_num_midi_clients >= MAX_MIDI_CLIENTS)
+ {
+ cmn_err (CE_WARN, "Too many MIDI clients\n");
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+ return OSS_ENXIO;
+ }
+
+ if (client == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+ return OSS_ENOMEM;
+ }
+
+ memset (client, 0, sizeof (*client));
+ oss_midi_clients[dev = oss_num_midi_clients++] = client;
+
+#ifdef CONFIG_OSS_MIDI
+ MDB (cmn_err (CE_CONT, "Installing /dev/midi%02d\n", dev));
+ oss_install_chrdev (osscore_osdev, NULL, OSS_DEV_MIDI, dev,
+ &midi_cdev_drv, 0);
+#endif
+ }
+
+ client->open_mode = mode;
+ client->num = dev;
+ client->mididev = NULL; /* Not bound yet */
+ MUTEX_EXIT_IRQRESTORE (midi_mutex, flags);
+
+ if ((d = oss_find_minor (OSS_DEV_MIDI, dev)) < 0)
+ {
+ oss_midi_release (dev, file);
+ return d;
+ }
+ *newdev = d;
+
+ return dev;
+}
+
+void
+oss_midi_init (oss_device_t * osdev)
+{
+ static int already_done = 0;
+
+ if (already_done)
+ return;
+ already_done = 1;
+
+ if (sizeof (midi_packet_header_t) != 32)
+ {
+ cmn_err (CE_WARN, "sizeof(midi_packet_header_t) != 32 (%d)\n",
+ sizeof (midi_packet_header_t));
+ cmn_err (CE_CONT, "MIDI subsystem not activated\n");
+ return;
+ }
+
+ osscore_osdev = osdev;
+
+ MUTEX_INIT (osdev, midi_mutex, MH_FRAMEW);
+
+ midi_mapper_init (osdev);
+ oss_init_timers (osdev);
+ attach_oss_default_timer (osdev);
+}
+
+void
+oss_midi_uninit (void)
+{
+ int dev;
+
+ midi_mapper_uninit ();
+ detach_oss_default_timer ();
+ oss_uninit_timers ();
+
+ for (dev = 0; dev < num_mididevs; dev++)
+ {
+ oss_remove_wait_queue (midi_devs[dev]->out_wq);
+ oss_remove_wait_queue (midi_devs[dev]->in_wq);
+ MUTEX_CLEANUP (midi_devs[dev]->mutex);
+ }
+ MUTEX_CLEANUP (midi_mutex);
+}
+
+void
+install_vmidi (oss_device_t * osdev)
+{
+#ifdef CONFIG_OSS_MIDI
+#ifdef VDEV_SUPPORT
+ oss_install_chrdev (osdev, "midi", OSS_DEV_VMIDI, 0, &vmidi_cdev_drv,
+ CHDEV_VIRTUAL);
+#endif
+#endif
+}
+
+int
+oss_install_mididev (int version,
+ char *id, char *name,
+ midi_driver_t * d, int driver_size,
+ unsigned int flags, void *devc, oss_device_t * osdev)
+{
+ int curr_midi_dev;
+ mididev_t *op;
+ oss_midi_client_t *client;
+ int i;
+ int old = 0;
+
+/*
+ * Old style drivers are always input&output even they don't report that.
+ * Fix the permissions automatically.
+ */
+ if (!(flags & (MFLAG_INPUT | MFLAG_OUTPUT)))
+ flags |= MFLAG_INPUT | MFLAG_OUTPUT;
+
+ if (driver_size > sizeof (midi_driver_t))
+ driver_size = sizeof (midi_driver_t);
+
+ if (midi_devs == NULL)
+ {
+ midi_devs = PMALLOC (osdev, sizeof (mididev_p) * MAX_MIDI_DEV);
+ }
+
+ if (midi_devs == NULL)
+ {
+ cmn_err (CE_WARN, "oss_install_mididev: Out of memory\n");
+ return OSS_ENOMEM;
+ }
+
+ for (i = 0; i < num_mididevs; i++)
+ if (midi_devs[i]->unloaded && midi_devs[i]->os_id == oss_get_osid (osdev))
+ {
+ old = 1;
+ op = midi_devs[i];
+ curr_midi_dev = i;
+ MDB (cmn_err (CE_CONT, "Reincarnation of MIDI device %d\n", i));
+ break;
+ }
+
+ if (!old)
+ {
+ if (num_mididevs >= MAX_MIDI_DEV - 1)
+ {
+ cmn_err (CE_WARN, "Too many MIDI devices in the system\n");
+ return OSS_EIO;
+ }
+
+ op = midi_devs[num_mididevs] = PMALLOC (osdev, sizeof (mididev_t));
+ if (op == NULL)
+ {
+ cmn_err (CE_WARN,
+ "oss_install_mididev: Failed to allocate memory\n");
+ return OSS_ENOMEM;
+ }
+ memset (op, 0, sizeof (*op));
+ curr_midi_dev = num_mididevs++;
+ }
+
+ op->devc = devc;
+ op->dev = op->real_dev = curr_midi_dev;
+ op->pid = -1;
+ op->osdev = osdev;
+ op->os_id = oss_get_osid (osdev);
+ op->latency = -1; /* Not known */
+
+ if (!old)
+ {
+ MUTEX_INIT (op->osdev, op->mutex, MH_FRAMEW + 1);
+
+ if ((op->out_wq =
+ oss_create_wait_queue (op->osdev, "midi_out")) == NULL)
+ cmn_err (CE_PANIC, "Cannot create MIDI output wait queue\n");
+
+ if ((op->in_wq = oss_create_wait_queue (op->osdev, "midi_in")) == NULL)
+ cmn_err (CE_PANIC, "Cannot create MIDI input wait queue\n");
+
+ op->d = PMALLOC (osdev, sizeof (midi_driver_t));
+ memset (op->d, 0, sizeof (op->d));
+ memcpy (op->d, d, driver_size);
+ sprintf (op->handle, "%s-md%02d", osdev->handle, ++osdev->num_mididevs);
+ op->port_number = osdev->num_mididevs;
+ }
+
+ op->flags = flags;
+ op->enabled = 1;
+ op->unloaded = 0;
+ op->mtc_timebase = -1;
+ op->card_number = osdev->cardnum;
+ op->timer_driver = 0; /* Point to the default timer */
+ op->timer_dev = -1; /* No timer instance created yet */
+
+ strncpy (op->name, name, sizeof (op->name) - 1);
+ op->name[sizeof (op->name) - 1] = 0;
+
+ op->caps = 0;
+ if (flags & MFLAG_INPUT)
+ op->caps |= MIDI_CAP_INPUT;
+ if (flags & MFLAG_OUTPUT)
+ op->caps |= MIDI_CAP_OUTPUT;
+
+
+ if (oss_midi_clients[curr_midi_dev] == NULL)
+ {
+ client = PMALLOC (osdev, sizeof (*client));
+ if (client == NULL)
+ cmn_err (CE_PANIC, "OSS install MIDI: Out of memory.\n");
+ memset (client, 0, sizeof (*client));
+ oss_midi_clients[curr_midi_dev] = client;
+ oss_num_midi_clients = num_mididevs;
+ }
+
+
+#ifdef CONFIG_OSS_MIDI
+/*
+ * Create the device node.
+ */
+
+ {
+ char name[32];
+#ifdef NEW_DEVICE_NAMING
+# ifdef USE_DEVICE_SUBDIRS
+ sprintf (name, "oss/%s/mid%d", osdev->nick, osdev->num_mididevs - 1);
+# else
+ sprintf (name, "%s_mid%d", osdev->nick, osdev->num_mididevs - 1);
+# endif
+#else
+ sprintf (name, "midi%02d", curr_midi_dev);
+#endif
+ oss_install_chrdev (osdev, name, OSS_DEV_MIDI, curr_midi_dev,
+ &midi_cdev_drv, 0);
+ sprintf (op->devnode, "/dev/%s", name);
+ }
+#endif
+
+ return curr_midi_dev;
+}
diff --git a/kernel/framework/midi/oss_midi_mapper.c b/kernel/framework/midi/oss_midi_mapper.c
new file mode 100644
index 0000000..e99d579
--- /dev/null
+++ b/kernel/framework/midi/oss_midi_mapper.c
@@ -0,0 +1,109 @@
+/*
+ * Purpose: MIDI device mapper
+ *
+ * This code is used to bind applications using /dev/mixer to the actual
+ * MIDI input and output ports.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+
+extern oss_mutex_t midi_mutex;
+
+void
+midi_mapper_init (oss_device_t * osdev)
+{
+}
+
+void
+midi_mapper_uninit (void)
+{
+}
+
+int
+midi_mapper_autobind (int client_dev, int mode)
+{
+ int dev;
+ oss_midi_client_t *client = oss_midi_clients[client_dev];
+
+ cmn_err (CE_CONT, "MIDI autobind %d\n", client_dev);
+
+ for (dev = 0; dev < num_mididevs; dev++)
+ {
+ int err;
+
+ if (midi_devs[dev]->open_mode) /* Busy */
+ continue;
+
+ if ((mode & OPEN_WRITE) && !(midi_devs[dev]->flags & MFLAG_OUTPUT))
+ continue;
+
+ if ((mode == OPEN_READ) && !(midi_devs[dev]->flags & MFLAG_INPUT))
+ continue;
+
+ if ((err = midi_devs[dev]->d->open (dev, client->open_mode,
+ oss_midi_input_byte,
+ oss_midi_input_buf,
+ oss_midi_output_intr)) < 0)
+ {
+ /* The device seems to think it's busy */
+ continue;
+ }
+
+ if (midi_devs[dev]->open_mode == 0) /* Not busy */
+ {
+
+ midi_devs[dev]->open_mode = mode;
+ client->mididev = midi_devs[dev];
+
+ if (mode & OPEN_READ)
+ {
+ client->mididev->in_queue =
+ midi_queue_alloc (client->mididev->osdev, "qread");
+ if (client->mididev->in_queue == NULL)
+ {
+ cmn_err (CE_WARN,
+ "Failed to allocate MIDI input queue(2)\n");
+ midi_devs[dev]->d->close (dev, mode);
+ midi_devs[dev]->open_mode = 0;
+ return OSS_ENOMEM;
+
+ }
+ }
+
+ if (mode & OPEN_WRITE)
+ {
+ client->mididev->out_queue =
+ midi_queue_alloc (client->mididev->osdev, "qwrite");
+ if (client->mididev->out_queue == NULL)
+ {
+ cmn_err (CE_WARN,
+ "Failed to allocate MIDI output queue(2)\n");
+ midi_devs[dev]->d->close (dev, mode);
+ midi_devs[dev]->open_mode = 0;
+ return OSS_ENOMEM;
+
+ }
+ }
+
+ oss_midi_set_defaults (client->mididev);
+
+ cmn_err (CE_CONT, "Bound to %d/%s\n", dev, midi_devs[dev]->name);
+ return dev;
+
+ }
+ }
+
+ return OSS_EBUSY;
+}
diff --git a/kernel/framework/midi/oss_midi_parser.c b/kernel/framework/midi/oss_midi_parser.c
new file mode 100644
index 0000000..6681677
--- /dev/null
+++ b/kernel/framework/midi/oss_midi_parser.c
@@ -0,0 +1,406 @@
+/*
+ * Purpose: MIDI mesage parser
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midiparser.h"
+
+struct _mtc_state
+{
+ int prev_ix;
+ int state;
+ int offset;
+ oss_mtc_data_t mtc, mtc0;
+};
+
+typedef struct midi_input_info
+{ /* MIDI input scanner variables */
+#define MI_MAX 64
+ 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;
+ int m_f1_flag;
+} midi_input_info_t;
+
+struct midiparser_common
+{
+ midi_input_info_t inc;
+ midiparser_callback_t callback;
+ midiparser_mtc_callback_t mtc_callback;
+ void *client_context;
+ struct _mtc_state mtc_state;
+};
+
+#define CALLBACK(cat, msg, ch, p1, p2, p3) \
+ { \
+ unsigned char arr[3];arr[0]=p1;arr[1]=p2;arr[2]=p3; \
+ synth->callback(synth->client_context, cat, msg, ch, arr, 3); \
+ }
+#define CALLBACK_A(cat, msg, ch, parms, len) \
+ synth->callback(synth->client_context, cat, msg, ch, parms, len)
+
+static void
+do_system_msg (midiparser_common_p synth, unsigned char *msg, int mlen)
+{
+ CALLBACK_A (CAT_REALTIME, *msg, 0, msg, mlen);
+ return;
+}
+
+static void
+do_sysex_msg (midiparser_common_p synth, unsigned char *msg, int mlen)
+{
+ CALLBACK_A (CAT_SYSEX, 0, 0, msg, mlen);
+ return;
+}
+
+static void
+do_realtime_msg (midiparser_common_p synth, unsigned char data)
+{
+}
+
+static void
+do_midi_msg (midiparser_common_p synth, unsigned char *msg, int mlen)
+{
+ switch (msg[0] & 0xf0)
+ {
+ case 0x90:
+ if (msg[2] != 0)
+ {
+ CALLBACK (CAT_VOICE, 0x90, msg[0] & 0x0f, msg[1], msg[2], 0);
+ break;
+ }
+ msg[2] = 64;
+
+ case 0x80:
+ CALLBACK (CAT_VOICE, 0x80, msg[0] & 0x0f, msg[1], msg[2], 0);
+ break;
+
+ case 0xA0:
+ CALLBACK (CAT_VOICE, 0xA0, msg[0] & 0x0f, msg[1], msg[2], 0);
+ break;
+
+ case 0xB0:
+ CALLBACK (CAT_CHN, 0xB0, msg[0] & 0x0f, msg[1], msg[2], 0);
+ break;
+
+ case 0xC0:
+ CALLBACK (CAT_CHN, 0xC0, msg[0] & 0x0f, msg[1], 0, 0);
+ break;
+
+ case 0xD0:
+ CALLBACK (CAT_CHN, 0xD0, msg[0] & 0x0f, msg[1], 0, 0);
+ break;
+
+ case 0xE0:
+ CALLBACK (CAT_VOICE, 0xE0, msg[0] & 0x0f, msg[1], msg[2], 0);
+ break;
+
+ case 0xf0: /* System common messages */
+ do_system_msg (synth, msg, mlen);
+ break;
+
+ default:
+ ;
+ }
+}
+
+static void
+send_mtc (midiparser_common_p synth, struct _mtc_state *st)
+{
+ oss_mtc_data_t mtc;
+
+ memcpy (&mtc, &st->mtc, sizeof (mtc));
+
+ mtc.qframes += st->offset;
+ mtc.frames += mtc.qframes / 4;
+ mtc.qframes %= 4;
+
+ if (mtc.time_code_type == 0)
+ mtc.time_code_type = 30;
+ mtc.seconds += mtc.frames / mtc.time_code_type; /* TODO: Handle drop frames */
+ mtc.frames %= mtc.time_code_type;
+
+ mtc.minutes += mtc.seconds / 60;
+ mtc.seconds %= 60;
+
+ mtc.hours += mtc.minutes / 60;
+ mtc.minutes %= 60;
+
+ synth->mtc_callback (synth->client_context, &mtc);
+}
+
+static void
+mtc_message (midiparser_common_p synth, struct _mtc_state *st,
+ unsigned char b)
+{
+ static char frame_types[4] = { 24, 25, 29, 30 };
+ int ix, data;
+ int previx;
+
+ ix = b >> 4;
+ data = b & 0x0f;
+
+ previx = (st->prev_ix + 1) % 8;
+
+ if (ix == previx)
+ st->mtc0.direction = st->mtc.direction = MTC_DIR_FORWARD;
+ else if (ix == st->prev_ix)
+ st->mtc0.direction = st->mtc.direction = MTC_DIR_STOPPED;
+ else
+ st->mtc0.direction = st->mtc.direction = MTC_DIR_BACKWARD;
+ st->prev_ix = ix;
+
+ if (st->state == 0)
+ {
+ if (ix != 0) /* Not the beginning of the sequence yet */
+ return;
+ st->state = 1;
+ st->offset = -1;
+ }
+
+ switch (ix)
+ {
+ case 0: /* Frame count LS nibble */
+ st->mtc0.qframes = 0;
+ st->mtc0.frames = data;
+ break;
+
+ case 1: /* Frame count MS nibble */
+ st->mtc0.frames |= data << 4;
+ break;
+
+ case 2: /* Seconds count LS nibble */
+ st->mtc0.seconds = data;
+ break;
+
+ case 3: /* Seconds count MS nibble */
+ st->mtc0.seconds |= data << 4;
+ break;
+
+ case 4: /* Minutes count LS nibble */
+ st->mtc0.minutes = data;
+ break;
+
+ case 5: /* Minutes count MS nibble */
+ st->mtc0.minutes |= data << 4;
+ break;
+
+ case 6: /* Hours count LS nibble */
+ st->mtc0.hours = data;
+ break;
+
+ case 7: /* Hours count MS nibble */
+ st->mtc0.hours |= data << 4;
+ st->mtc0.time_code_type = frame_types[(st->mtc0.hours >> 5) & 0x03];
+ st->mtc0.hours &= 0x1f;
+ memcpy (&st->mtc, &st->mtc0, sizeof (st->mtc));
+ break;
+ }
+
+ if (ix == 7)
+ st->offset = 7;
+ else
+ st->offset++;
+ send_mtc (synth, st);
+}
+
+static void
+handle_midi_input (midiparser_common_p synth, midi_input_info_t * inc,
+ unsigned char data)
+{
+ 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 (data == 0xfe) /* Active sensing */
+ {
+ return;
+ }
+
+ if (data >= 0xf8) /* Real time message */
+ {
+ do_realtime_msg (synth, data);
+ CALLBACK (CAT_REALTIME, data, 0, 0, 0, 0);
+ return;
+ }
+
+ if (data == 0xf1) /* MTC quarter frame (1st byte) */
+ {
+ inc->m_f1_flag = 1;
+ return;
+ }
+
+ if (inc->m_f1_flag) /* MTC quarter frame (2nd byte) */
+ {
+ inc->m_f1_flag = 0;
+
+ if (synth->mtc_callback != NULL)
+ {
+ mtc_message (synth, &synth->mtc_state, data);
+ return;
+ }
+ CALLBACK (CAT_MTC, 0xf1, 0, data, 0, 0);
+ return;
+ }
+
+ 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;
+ inc->m_ptr = 1;
+ inc->m_left = MI_MAX;
+ inc->m_buf[0] = data;
+ 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: /* Other common messages */
+ inc->m_buf[0] = data;
+ inc->m_ptr = 1;
+ do_midi_msg (synth, inc->m_buf, inc->m_ptr);
+ inc->m_ptr = 0;
+ inc->m_left = 0;
+ }
+ }
+ else
+ {
+ /* Channel messages */
+ 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 /* Running status */ if (inc->m_prev_status & 0x80) /* Ignore if no previous status (yet) */
+ {
+ inc->m_state = MST_DATA;
+ inc->m_ptr = 2;
+ inc->m_left = len_tab[(inc->m_prev_status >> 4) - 8] - 1;
+ inc->m_buf[0] = inc->m_prev_status;
+ inc->m_buf[1] = data;
+ }
+ 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 (synth, inc->m_buf, inc->m_ptr);
+ inc->m_ptr = 0;
+ }
+ break; /* MST_DATA */
+
+ case MST_SYSEX:
+ inc->m_buf[inc->m_ptr++] = data;
+ if (data == 0xf7) /* Sysex end */
+ {
+ do_sysex_msg (synth, inc->m_buf, inc->m_ptr);
+ inc->m_state = MST_INIT;
+ inc->m_left = 0;
+ inc->m_ptr = 0;
+
+ }
+ else if (inc->m_ptr >= MI_MAX) /* Overflow protection */
+ {
+ do_sysex_msg (synth, inc->m_buf, inc->m_ptr);
+ inc->m_ptr = 0;
+ }
+
+ break; /* MST_SYSEX */
+
+ default:
+ inc->m_state = MST_INIT;
+ }
+}
+
+midiparser_common_p
+midiparser_create (midiparser_callback_t callback, void *context)
+{
+ midiparser_common_p synth;
+
+ if ((synth = KERNEL_MALLOC (sizeof (*synth))) == NULL)
+ return NULL;
+
+ memset (synth, 0, sizeof (*synth));
+
+ synth->callback = callback;
+ synth->client_context = context;
+ synth->mtc_state.prev_ix = -1;
+
+ return synth;
+}
+
+void
+midiparser_unalloc (midiparser_common_p common)
+{
+ KERNEL_FREE (common);
+}
+
+void
+midiparser_mtc_callback (midiparser_common_p common,
+ midiparser_mtc_callback_t callback)
+{
+ common->mtc_callback = callback;
+}
+
+void
+midiparser_input (midiparser_common_p synth, unsigned char data)
+{
+ handle_midi_input (synth, &synth->inc, data);
+}
+
+void
+midiparser_input_buf (midiparser_common_p synth, unsigned char *data, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ handle_midi_input (synth, &synth->inc, data[i]);
+}
diff --git a/kernel/framework/midi/oss_midi_queue.c b/kernel/framework/midi/oss_midi_queue.c
new file mode 100644
index 0000000..23801ae
--- /dev/null
+++ b/kernel/framework/midi/oss_midi_queue.c
@@ -0,0 +1,567 @@
+/*
+ * Purpose: MIDI message queue management
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+#define MDB(x)
+
+typedef struct
+{
+ int len;
+ midi_packet_header_t hdr;
+ int next;
+ int size;
+
+ unsigned char *data;
+ unsigned char buf[1];
+ /* Do _NOT_ add any fields after data[] */
+ /* Do _NOT_ add any fields after data[] */
+ /* Do _NOT_ add any fields after data[] */
+ /* Do _NOT_ add any fields after data[] */
+ /* Do _NOT_ add any fields after data[] */
+} midi_buf_t;
+
+#define BUF_PREFIX_SIZE (sizeof(midi_buf_t)-1)
+#define MAX_QUEUE_DEPTH 31
+#define QUEUE_BYTES ((MAX_QUEUE_DEPTH+1)*(BUF_PREFIX_SIZE+MIDI_PAYLOAD_SIZE))
+
+struct midi_queue_t
+{
+ oss_mutex_t mutex;
+ char name[16]; /* For debugging purposes */
+
+/*
+ * Memeory management variables.
+ */
+ unsigned char buffer[QUEUE_BYTES];
+ int buf_head, buf_tail;
+ int debugging;
+ int q_head, q_tail;
+ int avail;
+ int writecount, readcount;
+
+/*
+ * Message queue
+ */
+
+ midi_buf_t *buffers[MAX_QUEUE_DEPTH];
+ int dummy;
+};
+
+midi_queue_t *
+midi_queue_alloc (oss_device_t * osdev, const char *name)
+{
+ midi_queue_t *q;
+
+ if ((q = KERNEL_MALLOC (sizeof (*q))) == NULL)
+ return NULL;
+
+ memset (q, 0, sizeof (*q));
+
+ MUTEX_INIT (osdev, q->mutex, MH_FRAMEW + 2);
+ if (name != NULL)
+ strcpy (q->name, name);
+
+ q->avail = QUEUE_BYTES;
+ return q;
+}
+
+void
+midi_queue_free (midi_queue_t * queue)
+{
+ if (queue != NULL)
+ {
+ MUTEX_CLEANUP (queue->mutex);
+ KERNEL_FREE (queue);
+ }
+}
+
+static int
+queue_concat (midi_queue_t * queue, unsigned char *data, int len,
+ midi_packet_header_t * hdr)
+{
+/*
+ * Check if the MIDI event can be appended to the previous event (to improve
+ * buffering performance).
+ *
+ * This is possible if:
+ *
+ * 1) The queue is not empty.
+ * 2) The previous event has the same time stamp.
+ * 3) The previous event is not too close to the end of the allocated buffer
+ * area.
+ */
+
+ midi_buf_t *buf;
+ int p, i;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (queue->mutex, flags);
+ if (queue->buf_tail == queue->buf_head) /* Nothing in the queue */
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 0;
+ }
+
+ if (queue->avail < len)
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 0;
+ }
+
+ if (queue->q_tail == queue->q_head) /* No events in the queue */
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 0;
+ }
+
+ p = queue->q_head - 1;
+ if (p < 0)
+ p = MAX_QUEUE_DEPTH - 1;
+
+ buf = queue->buffers[p];
+
+ if (hdr == NULL || buf->hdr.time != hdr->time)
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 0;
+ }
+
+ if (buf->len + len > MIDI_PAYLOAD_SIZE) /* Event would become too long */
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 0;
+ }
+
+ if (buf->next + len >= QUEUE_BYTES - 1) /* No space to grow */
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 0;
+ }
+
+ /* Check that we are not too close to the buffer tail */
+ if (buf->next < queue->buf_tail && buf->next + len >= queue->buf_tail)
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 0;
+ }
+
+/*
+ * Ok. All checks passed. Now append the data.
+ */
+
+ queue->avail -= len;
+ queue->writecount += len;
+ buf->next += len;
+ buf->size += len;
+ for (i = 0; i < len; i++)
+ buf->data[buf->len + i] = data[i];
+ buf->len += len;
+ queue->buf_head = buf->next;
+
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 1;
+}
+
+int
+midi_queue_alloc_record (midi_queue_t * queue, unsigned char **data, int len,
+ midi_packet_header_t * hdr)
+{
+ int p;
+ int avail = 0, n, next;
+ void *ptr;
+ midi_buf_t *buf;
+ oss_native_word flags;
+
+ if (queue == NULL)
+ {
+ cmn_err (CE_WARN, "midi_queue_alloc_record: Queue==NULL\n");
+ return OSS_EIO;
+ }
+
+ if (len < 1 && hdr == NULL) /* Nothing was given */
+ {
+ cmn_err (CE_WARN, "midi_queue_alloc_record: No data\n");
+ return OSS_EIO;
+ }
+
+ if (len > MIDI_PAYLOAD_SIZE)
+ {
+ cmn_err (CE_WARN, "Too long MIDI block\n");
+ len = MIDI_PAYLOAD_SIZE;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (queue->mutex, flags);
+
+ next = (queue->q_head + 1) % MAX_QUEUE_DEPTH;
+
+ if (next == queue->q_tail)
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return OSS_ENOSPC;
+ }
+
+ if (queue->avail < BUF_PREFIX_SIZE + len)
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return OSS_ENOSPC;
+ }
+
+ n = queue->q_head - queue->q_tail;
+ if (n <= 0)
+ n += MAX_QUEUE_DEPTH;
+
+ if (n < 1)
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return OSS_ENOSPC;
+ }
+
+ if (queue->buf_tail > queue->buf_head)
+ {
+ avail = queue->buf_tail - queue->buf_head;
+
+ if (avail < BUF_PREFIX_SIZE + len)
+ {
+ queue->buf_head = 0;
+ }
+ }
+
+ if (queue->buf_tail == queue->buf_head)
+ {
+ avail = QUEUE_BYTES;
+ queue->buf_tail = queue->buf_head = 0;
+ queue->avail = QUEUE_BYTES;
+ }
+ else if (queue->buf_tail < queue->buf_head)
+ avail = QUEUE_BYTES - queue->buf_head;
+
+ if (avail < BUF_PREFIX_SIZE + len)
+ {
+#if 1
+ len = avail - BUF_PREFIX_SIZE;
+
+ if (len <= 0)
+#endif
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return OSS_ENOSPC;
+ }
+ }
+
+ if (queue->buf_head >= QUEUE_BYTES)
+ {
+ cmn_err (CE_CONT, "MIDI queue damaged (%d/%d/alloc)\n", queue->buf_head,
+ QUEUE_BYTES);
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return OSS_EIO;
+ }
+
+ if (queue->buf_head + BUF_PREFIX_SIZE + len > QUEUE_BYTES)
+ {
+ cmn_err (CE_CONT, "Potential MIDI queue overflow detected\n");
+ cmn_err (CE_CONT, "Head=%d (%d)\n", queue->buf_head, QUEUE_BYTES);
+ cmn_err (CE_CONT, "Tail=%d (%d)\n", queue->buf_tail, QUEUE_BYTES);
+ cmn_err (CE_CONT, "Avail=%d\n", avail);
+ cmn_err (CE_CONT, "Required=%d\n", len + BUF_PREFIX_SIZE);
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return OSS_EIO;
+ }
+
+ ptr = queue->buffer + queue->buf_head;
+
+ p = queue->buf_head;
+ queue->buf_head = (queue->buf_head + BUF_PREFIX_SIZE + len) % QUEUE_BYTES;
+
+ buf = ptr;
+ buf->size = BUF_PREFIX_SIZE + len;
+ queue->avail -= buf->size;
+ buf->data = buf->buf;
+ buf->next = queue->buf_head;
+ if (hdr == NULL)
+ memset (&buf->hdr, 0, sizeof (midi_packet_header_t));
+ else
+ memcpy (&buf->hdr, hdr, sizeof (midi_packet_header_t));
+ buf->len = len;
+ *data = buf->data;
+ queue->writecount += len;
+ MDB (cmn_err (CE_CONT, "%s: alloc %d bytes\n", queue->name, len));
+
+ queue->buffers[queue->q_head] = buf;
+
+ queue->q_head = (queue->q_head + 1) % MAX_QUEUE_DEPTH;
+
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return len;
+}
+
+int
+midi_queue_put (midi_queue_t * queue, unsigned char *data, int len,
+ midi_packet_header_t * hdr)
+{
+ int ret;
+ unsigned char *targetbuf;
+
+ if (queue == NULL)
+ {
+ return OSS_EIO;
+ }
+#if 0
+ {
+ char tmp[1024];
+ memcpy (tmp, data, len);
+ tmp[len] = 0;
+ cmn_err (CE_CONT, "Q Put='%s', %d\n", tmp, len);
+ }
+#endif
+
+ if (len < 1)
+ return 0;
+
+ if (len > MIDI_PAYLOAD_SIZE)
+ return OSS_E2BIG;
+
+#if 1
+ if (len == 1)
+ if (queue_concat (queue, data, len, hdr))
+ return len;
+#endif
+
+ queue->debugging = 1;
+ if ((ret = midi_queue_alloc_record (queue, &targetbuf, len, hdr)) <= 0)
+ return ret;
+ queue->debugging = 0;
+
+ if (ret < len) /* All data didn't fit */
+ len = ret;
+
+ memcpy (targetbuf, data, len);
+
+ if (queue->buf_head >= QUEUE_BYTES || queue->buf_tail >= QUEUE_BYTES)
+ {
+ cmn_err (CE_CONT, "MIDI queue damaged (%d/%d/%d/put)\n",
+ queue->buf_head, queue->buf_tail, QUEUE_BYTES);
+ return OSS_EIO;
+ }
+ return len;
+}
+
+int
+midi_queue_get (midi_queue_t * queue, unsigned char **data, int max_len,
+ midi_packet_header_t ** hdr)
+{
+ midi_buf_t *buf;
+ oss_native_word flags;
+
+ *hdr = NULL;
+ *data = NULL;
+
+ if (queue == NULL)
+ return OSS_EIO;
+
+ if (queue->buf_head >= QUEUE_BYTES || queue->buf_tail >= QUEUE_BYTES)
+ {
+ cmn_err (CE_CONT, "MIDI queue damaged (%d/%d/%d/get)\n",
+ queue->buf_head, queue->buf_tail, QUEUE_BYTES);
+ return OSS_EIO;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (queue->mutex, flags);
+
+ if (queue->q_head == queue->q_tail)
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 0;
+ }
+
+ buf = queue->buffers[queue->q_tail];
+ queue->q_tail = (queue->q_tail + 1) % MAX_QUEUE_DEPTH;
+
+ queue->buf_tail = buf->next;
+ queue->avail += buf->size;
+ queue->readcount += buf->size;
+
+ *data = buf->data;
+ *hdr = &buf->hdr;
+
+#if 0
+ if (queue->buf_tail == queue->buf_head) /* Buffer empty */
+ queue->buf_tail = queue->buf_head = 0; /* Rewind */
+
+ if (queue->q_tail == queue->q_head)
+ queue->q_tail = queue->q_head = 0;
+#endif
+
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return buf->len;
+}
+
+int
+midi_queue_find_buffer (midi_queue_t * queue, unsigned char **data,
+ midi_packet_header_t ** hdr)
+{
+ midi_buf_t *buf;
+ oss_native_word flags;
+
+ *hdr = NULL;
+ *data = NULL;
+
+ if (queue == NULL)
+ return OSS_EIO;
+
+ MUTEX_ENTER_IRQDISABLE (queue->mutex, flags);
+ if (queue->q_head == queue->q_tail)
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return 0;
+ }
+
+ buf = queue->buffers[queue->q_tail];
+
+ *data = buf->data;
+ *hdr = &buf->hdr;
+
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return buf->len;
+}
+
+void
+midi_queue_remove_chars (midi_queue_t * queue, int len)
+{
+ midi_buf_t *buf;
+ oss_native_word flags;
+
+ if (queue == NULL)
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (queue->mutex, flags);
+
+ if (queue->q_head == queue->q_tail)
+ {
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ MDB (cmn_err (CE_CONT, "%s: Q Nothing to remove\n", queue->name));
+ return;
+ }
+
+ buf = queue->buffers[queue->q_tail];
+
+ if (len < buf->len)
+ {
+ /* Buffer not completely used. Just remove len characters from the beginning */
+ /* unsigned char *data = buf->data; */
+
+ MDB (cmn_err
+ (CE_CONT, "%s: Q Remove chars %d (%02x)\n", queue->name, len,
+ buf->data[len]));
+ /* memcpy(data, data+len, buf->len-len); */
+ buf->data += len;
+ buf->len -= len;
+ queue->readcount += len;
+ MDB (cmn_err (CE_CONT, "%s: Q left %d\n", queue->name, buf->len));
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+ return;
+ }
+
+/*
+ * Remove the whole buffer
+ */
+ MDB (cmn_err (CE_CONT, "%s: Q Remove all\n", queue->name));
+ queue->q_tail = (queue->q_tail + 1) % MAX_QUEUE_DEPTH;
+ queue->buf_tail = buf->next;
+ queue->avail += buf->size;
+ queue->readcount += len;
+
+ if (queue->buf_tail == queue->buf_head) /* Buffer empty */
+ queue->buf_tail = queue->buf_head = 0; /* Rewind */
+
+ if (queue->q_tail == queue->q_head)
+ queue->q_tail = queue->q_head = 0;
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+}
+
+void
+midi_queue_removeall (midi_queue_t * queue)
+{
+/*
+ * Make the queue completely empty
+ */
+ oss_native_word flags;
+
+ if (queue == NULL)
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (queue->mutex, flags);
+
+ queue->buf_tail = queue->buf_head = 0; /* Rewind */
+ queue->q_tail = queue->q_head = 0;
+ queue->avail = QUEUE_BYTES;
+ queue->readcount = 0;
+ queue->writecount = 0;
+
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+}
+
+int
+midi_queue_isempty (midi_queue_t * queue)
+{
+ int is_empty;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (queue->mutex, flags);
+ is_empty = (queue->q_tail == queue->q_head);
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+
+ return is_empty;
+}
+
+int
+midi_queue_spaceleft (midi_queue_t * queue)
+{
+ oss_native_word flags;
+ int space = 1;
+ int next;
+
+ MUTEX_ENTER_IRQDISABLE (queue->mutex, flags);
+ next = (queue->q_head + 1) % MAX_QUEUE_DEPTH;
+ if (next == queue->q_tail)
+ space = 0;
+ else
+ {
+ if (queue->avail < BUF_PREFIX_SIZE + 1)
+ space = 0;
+ else
+ {
+ space = queue->avail;
+ if (space > MIDI_PAYLOAD_SIZE)
+ space = MIDI_PAYLOAD_SIZE;
+ }
+ }
+ MUTEX_EXIT_IRQRESTORE (queue->mutex, flags);
+
+ return space;
+}
+
+void
+midi_queue_debugging (midi_queue_t * queue)
+{
+ queue->debugging = 1;
+}
+
+void
+midi_queue_trace (midi_queue_t * queue)
+{
+ MDB (cmn_err
+ (CE_CONT, "Write %d, read %d\n", queue->writecount, queue->readcount));
+}
diff --git a/kernel/framework/midi/oss_midi_timers.c b/kernel/framework/midi/oss_midi_timers.c
new file mode 100644
index 0000000..67cb8c9
--- /dev/null
+++ b/kernel/framework/midi/oss_midi_timers.c
@@ -0,0 +1,607 @@
+/*
+ * Purpose: MIDI timer support.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+
+tdev_t *oss_timer_devs[MAX_TIMER_DEV] = { NULL };
+int oss_num_timers = 0;
+
+oss_timer_driver_t *oss_timer_drivers[MAX_TIMER_DEV] = { NULL };
+int oss_num_timer_drivers = 0;
+
+int
+oss_install_timer (int driver_version,
+ char *name,
+ oss_timer_driver_t * d, int driver_size,
+ unsigned int flags,
+ int max_instances,
+ int resolution, void *devc, oss_device_t * osdev)
+{
+ oss_timer_driver_t *op;
+ int num;
+
+ if (driver_version != OSS_TIMER_DRIVER_VERSION)
+ {
+ cmn_err (CE_WARN, "Incompatible timer driver version %d\n",
+ driver_version);
+ return OSS_EINVAL;
+ }
+
+ if (driver_size != sizeof (*op))
+ {
+ cmn_err (CE_WARN, "Incompatible timer driver size %d\n", driver_size);
+ return OSS_EINVAL;
+ }
+
+ if (oss_num_timer_drivers >= MAX_TIMER_DEV)
+ {
+ cmn_err (CE_WARN, "Too many timer drivers\n");
+ return OSS_ENOMEM;
+ }
+
+ if ((op = PMALLOC (osdev, sizeof (*op))) == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory (oss_install_timer)\n");
+ return OSS_ENOMEM;
+ }
+
+ memcpy (op, d, driver_size);
+ op->flags = flags;
+ op->devc = devc;
+ op->osdev = osdev;
+ MUTEX_INIT (op->osdev, op->mutex, MH_FRAMEW + 2);
+
+ op->max_instances = max_instances;
+ op->num_instances = 0;
+ strncpy (op->name, name, sizeof (op->name));
+ op->name[sizeof (op->name) - 1] = 0;
+ num = oss_num_timer_drivers++;
+ op->driver_dev = num;
+ op->resolution = resolution;
+ oss_timer_drivers[num] = op;
+
+ return 0;
+}
+
+int
+oss_timer_create_instance (int driver_dev, mididev_t * mididev)
+{
+ oss_timer_driver_t *drv;
+ tdev_t *tmr;
+ oss_native_word flags;
+ int num, i, err;
+
+/* TODO: Create a mutex for all timers */
+
+ if (driver_dev < 0 || driver_dev >= oss_num_timer_drivers)
+ return OSS_ENXIO;
+
+ drv = oss_timer_drivers[driver_dev];
+
+ MUTEX_ENTER_IRQDISABLE (drv->mutex, flags);
+ if (drv->num_instances >= drv->max_instances)
+ {
+ cmn_err (CE_CONT, "All instances of timer %d are in use (%d)\n",
+ driver_dev, drv->max_instances);
+
+ MUTEX_EXIT_IRQRESTORE (drv->mutex, flags);
+ return OSS_EBUSY;
+ }
+ drv->num_instances++;
+ MUTEX_EXIT_IRQRESTORE (drv->mutex, flags);
+
+ if ((tmr = KERNEL_MALLOC (sizeof (*tmr))) == NULL)
+ {
+ MUTEX_ENTER_IRQDISABLE (drv->mutex, flags);
+ drv->num_instances--;
+ MUTEX_EXIT_IRQRESTORE (drv->mutex, flags);
+ return OSS_ENOMEM;
+ }
+ memset (tmr, 0, sizeof (*tmr));
+
+ num = -1;
+
+ for (i = 0; i < oss_num_timers; i++)
+ if (oss_timer_devs[i] == NULL)
+ {
+ num = i;
+ break;
+ }
+
+ if (num == -1)
+ {
+ if (oss_num_timers >= MAX_TIMER_DEV) /* No timers available */
+ {
+ cmn_err (CE_WARN, "No free timer instances\n");
+ KERNEL_FREE (tmr);
+ MUTEX_ENTER_IRQDISABLE (drv->mutex, flags);
+ drv->num_instances--;
+ MUTEX_EXIT_IRQRESTORE (drv->mutex, flags);
+ return OSS_EBUSY;
+ }
+ num = oss_num_timers++;
+ }
+
+/*
+ * Init the timer instance
+ */
+ tmr->osdev = drv->osdev;
+ MUTEX_INIT (tmr->osdev, tmr->mutex, MH_FRAMEW + 3);
+ tmr->refcount = 0;
+ tmr->d = drv;
+ tmr->driver_dev = driver_dev;
+ tmr->timer_dev = num;
+ tmr->devc = drv->devc;
+ tmr->name = drv->name;
+
+ oss_timer_devs[num] = tmr;
+
+ if (drv->create_instance != NULL)
+ if ((err = drv->create_instance (num, driver_dev)) < 0)
+ {
+ oss_timer_devs[num] = NULL;
+ MUTEX_CLEANUP (tmr->mutex);
+ KERNEL_FREE (tmr);
+ MUTEX_ENTER_IRQDISABLE (drv->mutex, flags);
+ drv->num_instances--;
+ MUTEX_EXIT_IRQRESTORE (drv->mutex, flags);
+ return err;
+ }
+
+ return num;
+}
+
+#define BITS_PER_ENTRY (sizeof(unsigned int)*8)
+
+int
+oss_timer_attach_client (int timer_dev, mididev_t * mididev)
+{
+ tdev_t *tmr;
+ int err;
+ int mdev = mididev->dev;
+ oss_native_word flags;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return OSS_ENXIO;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL)
+ {
+ cmn_err (CE_WARN, "tmr==NULL\n");
+ return OSS_EIO;
+ }
+ if (tmr->d == NULL)
+ {
+ cmn_err (CE_WARN, "tmr->d==NULL\n");
+ return OSS_EIO;
+ }
+
+ if (tmr->d->attach_client != NULL)
+ if ((err = tmr->d->attach_client (timer_dev, mididev->dev)) < 0)
+ {
+ return err;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (tmr->mutex, flags);
+ tmr->refcount++;
+ tmr->midimap[mdev / BITS_PER_ENTRY] |= (1 << (mdev % BITS_PER_ENTRY));
+ tmr->midi_times[mdev] = 0;
+ MUTEX_EXIT_IRQRESTORE (tmr->mutex, flags);
+
+ return 0;
+}
+
+void
+oss_timer_detach_client (int timer_dev, mididev_t * mididev)
+{
+ oss_native_word flags;
+ tdev_t *tmr;
+ oss_timer_driver_t *drv;
+ int refcount;
+ int mdev;
+
+ mdev = mididev->dev;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL)
+ return;
+
+ if (tmr->d->detach_client != NULL)
+ tmr->d->detach_client (timer_dev, mididev->dev);
+
+ MUTEX_ENTER_IRQDISABLE (tmr->mutex, flags);
+ refcount = --tmr->refcount;
+ tmr->midimap[mdev / BITS_PER_ENTRY] &= ~(1 << (mdev % BITS_PER_ENTRY));
+ tmr->midi_times[mdev] = 0;
+ MUTEX_EXIT_IRQRESTORE (tmr->mutex, flags);
+
+ if (refcount <= 0)
+ {
+ drv = tmr->d;
+
+ oss_timer_stop (timer_dev);
+ if (tmr->d->free_instance != NULL)
+ tmr->d->free_instance (timer_dev, tmr->driver_dev);
+
+ oss_timer_devs[timer_dev] = NULL;
+ MUTEX_CLEANUP (tmr->mutex);
+ KERNEL_FREE (tmr);
+
+ MUTEX_ENTER_IRQDISABLE (drv->mutex, flags);
+ drv->num_instances--;
+ if (drv->num_instances < 0)
+ {
+ cmn_err (CE_WARN, "Driver instances < 0\n");
+ drv->num_instances = 0;
+ }
+ MUTEX_EXIT_IRQRESTORE (drv->mutex, flags);
+ }
+}
+
+static int update_timer_state (tdev_t * tmr);
+
+static void
+timer_callback (void *arg)
+{
+ int i, x;
+ oss_uint64_t t;
+
+ tdev_t *tmr = arg;
+
+ t = tmr->next_time;
+ tmr->prev_time = t;
+ tmr->prev_tick = tmr->next_tick;
+
+ for (x = 0; x < sizeof (tmr->midimap) / sizeof (unsigned int); x++)
+ if (tmr->midimap[x] != 0)
+ for (i = x * BITS_PER_ENTRY;
+ i < (x + 1) * BITS_PER_ENTRY && x < num_mididevs; i++)
+ if (tmr->midimap[i / BITS_PER_ENTRY] & (1 << (i % BITS_PER_ENTRY)))
+ if (tmr->midi_times[i] > 0 && tmr->midi_times[i] <= t)
+ {
+ /*
+ * Timer for this MIDI device has expired. Wake up the device.
+ */
+ tmr->midi_times[i] = 0;
+ if (tmr->callback != NULL)
+ {
+ oss_native_word d = i;
+ tmr->callback ((void *) d);
+ }
+ }
+
+ update_timer_state (tmr);
+}
+
+static int
+update_timer_state (tdev_t * tmr)
+{
+ int i, x;
+ int state;
+ oss_uint64_t t;
+ oss_midi_time_t tick = 0;
+
+ if (tmr == NULL)
+ return 0;
+
+ if (tmr->tempo < 1)
+ tmr->tempo = 60;
+ if (tmr->timebase < 1)
+ tmr->timebase = OSS_HZ;
+
+ t = 0xffffffffffffffffULL; /* Largest possible time */
+ for (x = 0; x < sizeof (tmr->midimap) / sizeof (unsigned int); x++)
+ if (tmr->midimap[x] != 0)
+ for (i = x * BITS_PER_ENTRY;
+ i < (x + 1) * BITS_PER_ENTRY && x < num_mididevs; i++)
+ if (tmr->midimap[i / BITS_PER_ENTRY] & (1 << (i % BITS_PER_ENTRY)))
+ if (tmr->midi_times[i] != 0)
+ {
+ if (tmr->midi_times[i] < t)
+ {
+ t = tmr->midi_times[i];
+ tick = tmr->midi_ticks[i];
+ }
+ }
+
+ if (t == 0xffffffffffffffffULL) /* No events queued */
+ return 1;
+
+ tmr->next_time = t;
+ tmr->next_tick = tick;
+
+ if (tmr->d->wait == NULL)
+ {
+ cmn_err (CE_WARN, "No wait method for timer\n");
+ return 1;
+ }
+
+ state = tmr->d->wait (tmr->timer_dev, t, timer_callback, tmr);
+
+ if (state == 1)
+ {
+ timer_callback (tmr);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+oss_timer_set_tempo (int timer_dev, int tempo)
+{
+ tdev_t *tmr;
+ int err;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return OSS_ENXIO;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL)
+ return OSS_ENXIO;
+ tmr->pending_tempo = tempo;
+
+ {
+ tmr->tempo = tmr->pending_tempo;
+
+ tmr->bookmark_time = tmr->prev_time;
+ tmr->bookmark_tick = tmr->prev_tick;
+ }
+
+ if (tmr->d->set_tempo != NULL)
+ if ((err = tmr->d->set_tempo (timer_dev, tempo)) < 0)
+ return err;
+
+ return 0;
+}
+
+int
+oss_timer_set_timebase (int timer_dev, int timebase)
+{
+ tdev_t *tmr;
+ int err;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return OSS_ENXIO;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL || tmr->d->set_timebase == NULL)
+ return OSS_ENXIO;
+ tmr->timebase = timebase;
+ if ((err = tmr->d->set_timebase (timer_dev, timebase)) < 0)
+ return err;
+
+ return 0;
+}
+
+int
+oss_timer_wait_time (int timer_dev, int midi_dev, int latency,
+ oss_midi_time_t time, oss_midi_wait_callback_t callback,
+ unsigned short options)
+{
+ tdev_t *tmr;
+ oss_uint64_t t;
+ unsigned int tick;
+
+ if (time == 0)
+ return 1;
+
+ if (latency < 0)
+ latency = 0;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return 0;
+
+ if (midi_dev < 0 || midi_dev >= num_mididevs)
+ return 0;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL)
+ return 0;
+
+ tmr->callback = callback;
+
+ if (!tmr->run_state)
+ oss_timer_start (timer_dev);
+
+ t = tick = time;
+
+ if (!(options & MIDI_OPT_USECTIME))
+ {
+ /*
+ * Convert MIDI time to absolute (usecs)
+ */
+ time -= tmr->bookmark_tick;
+
+ t =
+ 60000000LL * (oss_uint64_t) time / (oss_uint64_t) (tmr->tempo *
+ tmr->timebase);
+
+ t += tmr->bookmark_time;
+ }
+
+ if (t >= latency)
+ t -= latency;
+
+ if (t <= tmr->prev_time) /* Already expired */
+ {
+ return 1;
+ }
+
+ tmr->midi_times[midi_dev] = t;
+ tmr->midi_ticks[midi_dev] = tick;
+
+ return update_timer_state (tmr);
+}
+
+oss_midi_time_t
+oss_timer_get_current_time (int timer_dev, int latency, int use_abs)
+{
+ tdev_t *tmr;
+ oss_uint64_t t;
+
+ if (latency < 0)
+ latency = 0;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return 0;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL || tmr->d->get_current_time == NULL)
+ return 0;
+
+ if (tmr->run_state == 0)
+ return 0;
+
+ t = tmr->d->get_current_time (timer_dev);
+
+ if (!use_abs)
+ {
+ /*
+ * Convert from absolute (usec) time to relative (MIDI).
+ */
+
+ if (t < tmr->bookmark_time)
+ return 0;
+
+ t -= tmr->bookmark_time;
+ t = 60000000LL * t / (oss_uint64_t) (tmr->tempo * tmr->timebase);
+ t = t * (oss_uint64_t) (tmr->tempo * tmr->timebase);
+
+ t = (t + 30000000LL) / 60000000LL;
+
+ t += tmr->bookmark_tick;
+ }
+
+ return t;
+}
+
+int
+oss_timer_is_running (int timer_dev)
+{
+ tdev_t *tmr;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return 0;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL)
+ return 0;
+ return tmr->run_state;
+}
+
+void
+oss_timer_start (int timer_dev)
+{
+ tdev_t *tmr;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL)
+ return;
+ tmr->pending_tempo = tmr->tempo;
+ tmr->next_tick = 0;
+ tmr->prev_tick = 0;
+ tmr->next_time = 0;
+ tmr->prev_time = 0;
+
+ tmr->bookmark_tick = 0;
+ tmr->bookmark_time = 0LL;
+
+ tmr->run_state = 1;
+ if (tmr->d->start != NULL)
+ tmr->d->start (timer_dev, 0LL);
+}
+
+void
+oss_timer_continue (int timer_dev)
+{
+ tdev_t *tmr;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL)
+ return;
+ tmr->run_state = 1;
+}
+
+void
+oss_timer_stop (int timer_dev)
+{
+ tdev_t *tmr;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL)
+ return;
+ tmr->run_state = 0;
+ if (tmr->d->stop != NULL)
+ tmr->d->stop (timer_dev);
+ tmr->callback = NULL;
+}
+
+int
+oss_timer_get_timeout (int timer_dev, int midi_dev)
+{
+ tdev_t *tmr;
+ oss_uint64_t t, scale;
+
+ if (timer_dev < 0 || timer_dev >= oss_num_timers)
+ return OSS_HZ;
+
+ tmr = oss_timer_devs[timer_dev];
+ if (tmr == NULL)
+ return OSS_HZ;
+
+ if (tmr->prev_time >= tmr->next_time)
+ return OSS_HZ;
+
+ scale = 1000000 / OSS_HZ;
+ if (scale < 1)
+ return OSS_HZ;
+
+ t = tmr->next_time - tmr->prev_time;
+ t /= scale; /* Usecs to system clock ticks */
+
+ t += 1;
+
+ if (t > 1)
+ return t;
+
+ return OSS_HZ;
+}
+
+int
+oss_init_timers (oss_device_t * osdev)
+{
+ return 0;
+}
+
+int
+oss_uninit_timers (void)
+{
+ /* TODO: Cleanup all mutexes */
+ return 0;
+}
diff --git a/kernel/framework/midi_stubs/.config b/kernel/framework/midi_stubs/.config
new file mode 100644
index 0000000..d39c0d4
--- /dev/null
+++ b/kernel/framework/midi_stubs/.config
@@ -0,0 +1 @@
+configcheck=NO_MIDI
diff --git a/kernel/framework/midi_stubs/oss_midi_stubs.c b/kernel/framework/midi_stubs/oss_midi_stubs.c
new file mode 100644
index 0000000..21233f4
--- /dev/null
+++ b/kernel/framework/midi_stubs/oss_midi_stubs.c
@@ -0,0 +1,82 @@
+/*
+ * Purpose: Placeholder functions for MIDI support for systems that have MIDI support excluded from OSS.
+ *
+ * This source file contains empty stubs for the MIDI related functions
+ * referenced by other parts of OSS.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#ifndef CONFIG_OSS_MIDI
+#include "midi_core.h"
+#include "midiparser.h"
+
+#define MDB(x)
+
+oss_mutex_t midi_mutex;
+tdev_t *oss_timer_devs[MAX_TIMER_DEV] = { NULL };
+int oss_num_timers = 0;
+
+/*
+ * List of MIDI devices.
+ */
+mididev_t *__midi_devs[1], **midi_devs = __midi_devs;
+int num_mididevs = 0;
+
+/*
+ * List of MIDI clients (/dev/midi* device files).
+ */
+int oss_num_midi_clients = 0;
+oss_midi_client_t *oss_midi_clients[MAX_MIDI_CLIENTS] = { NULL };
+
+/*ARGSUSED*/
+void
+oss_midi_init (oss_device_t * osdev)
+{
+}
+
+/*ARGSUSED*/
+int
+oss_install_mididev (int version,
+ char *id, char *name,
+ midi_driver_t * d, int driver_size,
+ unsigned int flags, void *devc, oss_device_t * osdev)
+{
+ return 0;
+}
+
+/*ARGSUSED*/
+void
+install_vmidi (oss_device_t * osdev)
+{
+}
+
+/*ARGSUSED*/
+midiparser_common_p
+midiparser_create (midiparser_callback_t callback, void *context)
+{
+ return NULL;
+}
+
+/*ARGSUSED*/
+void
+midiparser_unalloc (midiparser_common_p common)
+{
+}
+
+/*ARGSUSED*/
+void
+midiparser_input (midiparser_common_p synth, unsigned char data)
+{
+}
+#endif
diff --git a/kernel/framework/mixer/.config b/kernel/framework/mixer/.config
new file mode 100644
index 0000000..e44f78f
--- /dev/null
+++ b/kernel/framework/mixer/.config
@@ -0,0 +1 @@
+targetcpu=any
diff --git a/kernel/framework/mixer/mixerdefs.h b/kernel/framework/mixer/mixerdefs.h
new file mode 100644
index 0000000..5c9b4de
--- /dev/null
+++ b/kernel/framework/mixer/mixerdefs.h
@@ -0,0 +1,120 @@
+/*
+ * Purpose: Mixer enum control defines for older OSS drivers.
+ *
+ * This file contains choice names for MIXT_ENUM controls defined by some
+ * older drivers. All drivers developed recently will use an embedded
+ * mechanism for setting this information.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+typedef struct
+{
+ char *name, *strings;
+} mixer_def_t;
+
+static const mixer_def_t mixer_defs[] = {
+ {"setup.mon1l", "OFF A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7"},
+ {"setup.mon1r", "OFF A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7"},
+ {"setup.mon2l", "OFF A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7"},
+ {"setup.mon2r", "OFF A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7"},
+ {"fpga.srcclock", "44.1K 48K PLL AES"},
+ {"fpga.clock", "44.1K 48K PLL AES"},
+ {"fpga.pll", "PORTA PORTB TIMER1 EXTERNAL"},
+ {"aes.mode", "CONSUMER PRO"},
+ {"aes.copy", "INHIBITED PERMITTED"},
+ {"aes.audio", "AUDIO DATA"},
+ {"aes.preemph", "NONE 50/15us"},
+ {"digi32.sync", "EXTERNAL INTERNAL"},
+ {"digi32.aesmode", "CONSUMER PRO"},
+ {"digi32.input", "OPTICAL RCA INTERNAL XLR"},
+ {"out1.src", "CODEC DSP"},
+ {"in.src", "CODEC LINE OPTICAL COAX"},
+ {"reverb.type", "ROOM1 ROOM2 ROOM3 HALL1 HALL2 PLATE DELAY PANDELAY"},
+ {"chorus.type",
+ "CHORUS1 CHORUS2 CHORUS3 CHORUS4 FBCHORUS FLANGER SHORTDELAY FBDELAY"},
+ {"digi96.sync", "EXTERNAL INTERNAL"},
+ {"digi96.input", "OPTICAL COAXIAL INTERNAL XLR"},
+ {"digi96.sel", "BYPASS NORMAL"},
+ {"digi96.mode", "SPDIF AESEBU ADAT"},
+ {"digi96.data", "AUDIO DATA"},
+ {"envy24.sync", "INTERNAL SPDIF WCLOCK"},
+ {"envy24.spdin", "COAX OPTICAL"},
+ {"gain.out1/2", "+4DB CONSUMER -10DB"},
+ {"gain.out3/4", "+4DB CONSUMER -10DB"},
+ {"gain.out5/6", "+4DB CONSUMER -10DB"},
+ {"gain.out7/8", "+4DB CONSUMER -10DB"},
+ {"gain.in1/2", "+4DB CONSUMER -10DB"},
+ {"gain.in3/4", "+4DB CONSUMER -10DB"},
+ {"gain.in5/6", "+4DB CONSUMER -10DB"},
+ {"gain.in7/8", "+4DB CONSUMER -10DB"},
+ {"gain.out1", "+4DB CONSUMER -10DB"},
+ {"gain.out2", "+4DB CONSUMER -10DB"},
+ {"gain.out3", "+4DB CONSUMER -10DB"},
+ {"gain.out4", "+4DB CONSUMER -10DB"},
+ {"gain.out5", "+4DB CONSUMER -10DB"},
+ {"gain.out6", "+4DB CONSUMER -10DB"},
+ {"gain.out7", "+4DB CONSUMER -10DB"},
+ {"gain.out8", "+4DB CONSUMER -10DB"},
+ {"gain.in1", "+4DB CONSUMER -10DB"},
+ {"gain.in2", "+4DB CONSUMER -10DB"},
+ {"gain.in3", "+4DB CONSUMER -10DB"},
+ {"gain.in4", "+4DB CONSUMER -10DB"},
+ {"gain.in5", "+4DB CONSUMER -10DB"},
+ {"gain.in6", "+4DB CONSUMER -10DB"},
+ {"gain.in7", "+4DB CONSUMER -10DB"},
+ {"gain.in8", "+4DB CONSUMER -10DB"},
+ {"route.out1/2", "DMA MONITOR IN1/2 IN3/4 IN5/6 IN7/8 SPDIF"},
+ {"route.out3/4", "DMA MONITOR IN1/2 IN3/4 IN5/6 IN7/8 SPDIF"},
+ {"route.out5/6", "DMA MONITOR IN1/2 IN3/4 IN5/6 IN7/8 SPDIF"},
+ {"route.out7/8", "DMA MONITOR IN1/2 IN3/4 IN5/6 IN7/8 SPDIF"},
+ {"route.spdif", "DMA MONITOR IN1/2 IN3/4 IN5/6 IN7/8 SPDIF"},
+ {"route.out1", "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"route.out2", "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"route.out3", "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"route.out4", "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"route.out5", "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"route.out6", "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"route.out7", "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"route.out8", "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"route.spdifl",
+ "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"route.spdifr",
+ "DMA MONITOR IN1 IN2 IN3 IN4 IN5 IN6 IN7 IN8 SPDIFL SPDIFR"},
+ {"ews88d.spdin", "OPTICAL COAX"},
+ {"ews88d.optout", "SPDIF ADAT"},
+ {"codec.recsrc", "ANALOG OPTICAL COAX CD AUX"},
+ {"route.front", "DMA ANALOGIN DIGITALIN"},
+ {"route.rear", "DMA ANALOGIN DIGITALIN"},
+ {"route.surround", "DMA ANALOGIN DIGITALIN"},
+ {"route.c/l", "DMA ANALOGIN DIGITALIN"},
+ {"route.spdifout", "DMA ANALOGIN DIGITALIN"},
+ {"lynxone.sync", "INTERNAL DIGITAL EXTW EXT27 EXT13 HDRW HDR27 HDR13"},
+ {"lynxone.format", "AESEBU SPDIF"},
+ {"lynxone.trim", "+4DB -10DB"},
+ {"spkmode", "FRONT SURR FRONT+SURR DISCRETE 3D"},
+ {"ext.recsrc", "SPDIF_OUT I2S_OUT SPDIF_IN I2S_IN AC97 SRC"},
+ {"ext.loopback", "DSP0 DSP1 DSP2 DSP3"},
+ {"3dsurround.mode", "OFF NORMAL 2X 3X"},
+ {"spdout.pro", "Consumer Professional"},
+ {"spdout.audio", "AUDIO DATA"},
+ {"spdout.rate", "48000 44100 32000"},
+ {"spdif.mode", "CONSUMER PRO"},
+ {"spdif.audio", "AUDIO DATA"},
+ {"spdif.copyright", "YES NO"},
+ {"spdif.generat", "COPY ORIGINAL"},
+ {"spdif.preemph", "OFF 50/16usec"},
+ {"mixext.spkmode", "FRONT SPREAD"},
+ {"effects.reverb.preset",
+ "SMALL_ROOM MEDIUM_ROOM LARGE_ROOM SMALL_HALL LARGE_HALL"},
+ {NULL}
+};
diff --git a/kernel/framework/mixer/oss_mixer_core.c b/kernel/framework/mixer/oss_mixer_core.c
new file mode 100644
index 0000000..44f4eff
--- /dev/null
+++ b/kernel/framework/mixer/oss_mixer_core.c
@@ -0,0 +1,2812 @@
+/*
+ * Purpose: OSS mixer core.
+ * Copyright (C) 4Front Technologies, 2002-2004. All rights reserved.
+ *
+ * Description:
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 <oss_config.h>
+#include <midi_core.h>
+#include <stdarg.h>
+oss_mutex_t oss_timing_mutex;
+
+char *oss_license_string = OSS_LICENSE;
+
+#ifdef DO_TIMINGS
+static int timing_is_active = 0; /* 1=The readtimings utility has been active */
+#endif
+
+void *mixer_devs_p = NULL;
+/*
+ * Mixer device list
+ */
+mixer_operations_t **mixer_devs = NULL;
+int num_mixers = 0;
+int mixer_port_number = 0;
+int current_mixer_card = -1;
+
+/*
+ * mix_cvt is used for scaling mixer levels by various drivers.
+ */
+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
+};
+
+static int
+get_mixer_info (int dev, ioctl_arg arg)
+{
+ mixer_info *info = (mixer_info *) arg;
+
+ memset(info, 0, sizeof(*info));
+
+ if (dev < 0 || dev >= num_mixers)
+ return OSS_ENXIO;
+
+ strcpy (info->id, mixer_devs[dev]->id);
+ strncpy (info->name, mixer_devs[dev]->name, 32);
+ info->name[31] = '\0';
+ info->modify_counter = mixer_devs[dev]->modify_counter;
+
+ return 0;
+}
+
+/*
+ * Legacy mixer handling
+ */
+
+int
+oss_legacy_mixer_ioctl (int mixdev, int audiodev, unsigned int cmd,
+ ioctl_arg arg)
+{
+ int ret;
+
+#ifdef DO_TIMINGS
+ oss_timing_printf ("oss_legacy_mixer_ioctl(%d/%d, %08x) entered", mixdev,
+ audiodev, cmd);
+#endif
+
+ if (!(cmd & SIOC_OUT) && !(cmd & SIOC_IN))
+ return OSS_EINVAL;
+
+ if (arg == 0)
+ return OSS_EINVAL;
+
+ if (((cmd >> 8) & 0xff) != 'M') /* Not a mixer ioctl */
+ return OSS_EINVAL;
+
+ if (mixdev < 0 || mixdev >= num_mixers)
+ {
+ cmn_err (CE_WARN, "Bad mixer device %d\n", mixdev);
+ return OSS_EIO;
+ }
+
+ if (cmd == SOUND_MIXER_INFO)
+ return get_mixer_info (mixdev, arg);
+
+ if (!mixer_devs[mixdev]->enabled || mixer_devs[mixdev]->unloaded)
+ return OSS_ENXIO;
+
+ if (mixer_devs[mixdev]->d->ioctl == NULL)
+ return OSS_EINVAL;
+
+ if (IOC_IS_OUTPUT (cmd))
+ mixer_devs[mixdev]->modify_counter++;
+
+ ret = mixer_devs[mixdev]->d->ioctl (mixdev, audiodev, cmd, arg);
+
+ return ret;
+}
+
+/*
+ * Handling of initial mixer volumes
+ */
+
+static int muted_mixer_levels[32] = {0};
+
+static int default_mixer_levels[32] = {
+ 0x3232, /* Master Volume */
+ 0x3232, /* Bass */
+ 0x3232, /* Treble */
+ 0x4b4b, /* FM */
+ 0x3232, /* PCM */
+ 0x1515, /* PC Speaker */
+ 0x2020, /* Ext Line */
+ 0x2020, /* 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) */
+};
+
+/*
+ * Table for configurable mixer volume handling
+ */
+static mixer_vol_table mixer_vols[MAX_MIXER_DEV];
+static int num_mixer_volumes = 0;
+
+int *
+load_mixer_volumes (char *name, int *levels, int present)
+{
+ int i, n;
+ extern int mixer_muted;
+
+ if (mixer_muted) /* Config setting from osscore.conf */
+ return muted_mixer_levels;
+
+ if (levels == NULL)
+ levels = default_mixer_levels;
+
+ for (i = 0; i < num_mixer_volumes; i++)
+ if (strcmp (name, mixer_vols[i].name) == 0)
+ {
+ if (present)
+ mixer_vols[i].num = i;
+ return mixer_vols[i].levels;
+ }
+
+ if (num_mixer_volumes >= MAX_MIXER_DEV)
+ {
+ cmn_err (CE_WARN, "Too many mixers (%s/%d/%d)\n",
+ name, num_mixer_volumes, MAX_MIXER_DEV);
+ return levels;
+ }
+
+ n = num_mixer_volumes++;
+
+ strcpy (mixer_vols[n].name, name);
+
+ 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;
+}
+
+/*
+ * Mixer "extension" handling
+ */
+
+static int
+oss_mixer_ext_info (oss_mixext * ent)
+{
+
+ int dev, ctrl;
+ int extnr;
+
+ if (ent == NULL)
+ return OSS_EFAULT;
+
+ if (ent->dev < 0 || ent->dev >= num_mixers)
+ return OSS_ENXIO;
+
+ dev = ent->dev;
+ if (!mixer_devs[dev]->enabled || mixer_devs[dev]->unloaded)
+ return OSS_ENXIO;
+ touch_mixer (dev);
+
+ ctrl = ent->ctrl;
+ if (ent->ctrl < 0 || ent->ctrl >= mixer_devs[dev]->nr_ext)
+ return OSS_EIDRM;
+ extnr = ent->ctrl;
+
+ memcpy ((char *) ent, (char *) &mixer_devs[dev]->extensions[extnr].ext,
+ sizeof (*ent));
+
+ switch (ent->type)
+ {
+ case MIXT_MONOPEAK:
+ case MIXT_STEREOPEAK:
+ case MIXT_MONOVU:
+ case MIXT_STEREOVU:
+ /* Peak meters will need to be polled */
+ ent->flags |= MIXF_POLL;
+ break;
+ }
+
+/*
+ * Read-only controls are likely to change their value spontaneously so
+ * they should be polled.
+ */
+ if (!(ent->flags & MIXF_WRITEABLE))
+ ent->flags |= MIXF_POLL;
+
+ ent->ctrl = ctrl;
+ return 0;
+}
+
+static int
+mixer_ext_get_enuminfo (oss_mixer_enuminfo * ent)
+{
+
+ int dev, ctrl;
+
+ if (ent == NULL)
+ return OSS_EFAULT;
+
+ dev = ent->dev;
+ ctrl = ent->ctrl;
+ memset (ent, 0, sizeof (*ent));
+
+ if (dev < 0 || dev >= num_mixers)
+ {
+ return OSS_ENXIO;
+ }
+
+ touch_mixer (dev);
+
+ if (ctrl < 0 || ctrl >= mixer_devs[dev]->nr_ext)
+ {
+ return OSS_EIDRM;
+ }
+
+ if (mixer_devs[dev]->extensions[ctrl].enum_info == NULL)
+ {
+ return OSS_EIO;
+ }
+
+ memcpy ((char *) ent,
+ (char *) mixer_devs[dev]->extensions[ctrl].enum_info,
+ sizeof (*ent));
+ ent->ctrl = ctrl;
+ return 0;
+}
+
+static int
+mixer_ext_get_description (oss_mixer_enuminfo * ent)
+{
+
+ int dev, ctrl;
+ char *s;
+
+ if (ent == NULL)
+ return OSS_EFAULT;
+
+ dev = ent->dev;
+ ctrl = ent->ctrl;
+ memset (ent, 0, sizeof (*ent));
+
+ if (dev < 0 || dev >= num_mixers)
+ {
+ return OSS_ENXIO;
+ }
+
+ touch_mixer (dev);
+
+ if (ctrl < 0 || ctrl >= mixer_devs[dev]->nr_ext)
+ {
+ return OSS_EIDRM;
+ }
+
+ if (mixer_devs[dev]->extensions[ctrl].description == NULL)
+ {
+ return OSS_EIO;
+ }
+
+ s = mixer_devs[dev]->extensions[ctrl].description;
+
+ strncpy (ent->strings, s, sizeof (ent->strings));
+ ent->strings [sizeof (ent->strings) - 1] = '\0';
+ ent->ctrl = ctrl;
+ return 0;
+}
+
+int
+mixer_ext_set_strings (int dev, int ctl, const char *s, int version)
+{
+/*
+ * Note! The version parameter should usually be set to 0. However if the
+ * value set can change dynamically then it must be initially set to 1
+ * and later incremented every time the value set changes.
+ * This tells the applications to poll for updated values.
+ */
+ static oss_mixer_enuminfo ent;
+
+ memset (&ent, 0, sizeof (ent));
+ ent.dev = dev;
+ ent.ctrl = ctl;
+ ent.version = version;
+ ent.nvalues = 0;
+ strcpy (ent.strings, s);
+ return mixer_ext_set_enum (&ent);
+}
+
+static int
+rebuild_list (oss_mixer_enuminfo * ent)
+{
+ int i, n, l;
+
+ n = 1;
+ ent->nvalues = 0;
+ ent->strindex[0] = 0;
+ l = strlen (ent->strings);
+
+ for (i = 0; i < l; i++)
+ if (n < OSS_ENUM_MAXVALUE)
+ {
+ if (ent->strings[i] == ' ')
+ {
+ ent->strindex[n++] = i + 1;
+ ent->strings[i] = 0;
+ }
+ }
+
+ ent->nvalues = n;
+ return 0;
+}
+
+int
+mixer_ext_set_enum (oss_mixer_enuminfo * ent)
+{
+ int dev;
+ int extnr;
+
+ if (ent == NULL)
+ return OSS_EFAULT;
+
+ if (ent->dev < 0 || ent->dev >= num_mixers)
+ return OSS_ENXIO;
+
+ dev = ent->dev;
+ touch_mixer (dev);
+
+ if (ent->ctrl < 0 || ent->ctrl >= mixer_devs[dev]->nr_ext)
+ return OSS_EIDRM;
+ extnr = ent->ctrl;
+
+ if (mixer_devs[dev]->extensions[extnr].enum_info == NULL)
+ mixer_devs[dev]->extensions[extnr].enum_info =
+ PMALLOC (mixer_devs[dev]->osdev, sizeof (*ent));
+
+ if (mixer_devs[dev]->extensions[extnr].enum_info == NULL)
+ return OSS_EIO;
+
+ memcpy ((char *) mixer_devs[dev]->extensions[extnr].enum_info,
+ (char *) ent, sizeof (*ent));
+
+ ent = mixer_devs[dev]->extensions[extnr].enum_info;
+
+ if (ent->nvalues <= 0)
+ return rebuild_list (ent);
+
+ if (ent->nvalues >= OSS_ENUM_MAXVALUE)
+ {
+ mixer_devs[dev]->extensions[extnr].enum_info = NULL;
+ return OSS_EIO;
+ }
+
+ return 0;
+}
+
+int
+mixer_ext_set_description (int dev, int ctrl, const char *desc)
+{
+ int l = strlen(desc);
+
+ if (dev < 0 || dev >= num_mixers)
+ return OSS_ENXIO;
+
+ touch_mixer (dev);
+
+ if (ctrl < 0 || ctrl >= mixer_devs[dev]->nr_ext)
+ return OSS_EIDRM;
+
+ if (l > OSS_ENUM_STRINGSIZE) l = OSS_ENUM_STRINGSIZE;
+
+ mixer_devs[dev]->extensions[ctrl].description =
+ PMALLOC (mixer_devs[dev]->osdev, l);
+
+ if (mixer_devs[dev]->extensions[ctrl].description == NULL)
+ return OSS_EIO;
+
+ strncpy (mixer_devs[dev]->extensions[ctrl].description, desc, l);
+ mixer_devs[dev]->extensions[ctrl].description[l-1] = '\0';
+
+ mixer_devs[dev]->extensions[ctrl].ext.flags |= MIXF_DESCR;
+
+ return 0;
+}
+
+static int
+mixer_ext_read (oss_mixer_value * val)
+{
+
+ int dev;
+ int extnr;
+ oss_mixext *ext;
+ oss_mixext_desc *ext_desc;
+ mixer_ext_fn func;
+
+ if (val == NULL)
+ return OSS_EFAULT;
+
+ if (val->dev < 0 || val->dev >= num_mixers)
+ return OSS_ENXIO;
+
+ dev = val->dev;
+
+ if (!mixer_devs[dev]->enabled || mixer_devs[dev]->unloaded)
+ return OSS_ENXIO;
+ touch_mixer (dev);
+
+ if (val->ctrl < 0 || val->ctrl >= mixer_devs[dev]->nr_ext)
+ return OSS_EIDRM;
+ extnr = val->ctrl;
+
+ ext_desc = &mixer_devs[dev]->extensions[extnr];
+ ext = &ext_desc->ext;
+
+ if (val->timestamp != ext->timestamp)
+ {
+ return OSS_EIDRM;
+ }
+
+ if (ext_desc->handler == NULL || !(ext->flags & MIXF_READABLE))
+ return OSS_EFAULT;
+
+ func = (mixer_ext_fn) ext_desc->handler;
+ return (val->value = func (dev, ext->ctrl, SNDCTL_MIX_READ, val->value));
+}
+
+static int
+mixer_ext_write (oss_mixer_value * val)
+{
+
+ int dev;
+ int extnr;
+ int err;
+ oss_mixext *ext;
+ oss_mixext_desc *ext_desc;
+ mixer_ext_fn func;
+
+ if (val == NULL)
+ {
+ cmn_err (CE_WARN, "NULL argument in mixer call\n");
+ return OSS_EFAULT;
+ }
+
+ if (val->dev < 0 || val->dev >= num_mixers)
+ return OSS_ENXIO;
+
+ dev = val->dev;
+ if (!mixer_devs[dev]->enabled || mixer_devs[dev]->unloaded)
+ return OSS_ENXIO;
+ touch_mixer (dev);
+
+ if (val->ctrl < 0 || val->ctrl >= mixer_devs[dev]->nr_ext)
+ return OSS_EIDRM;
+ extnr = val->ctrl;
+
+ ext_desc = &mixer_devs[dev]->extensions[extnr];
+ ext = &ext_desc->ext;
+
+ if (ext_desc->handler == NULL || !(ext->flags & MIXF_WRITEABLE))
+ {
+ cmn_err (CE_WARN, "NULL handler or control not writeable\n");
+ return OSS_EFAULT;
+ }
+
+ if (val->timestamp != ext->timestamp)
+ {
+ return OSS_EIDRM;
+ }
+
+ func = (mixer_ext_fn) ext_desc->handler;
+ mixer_devs[dev]->modify_counter++;
+ err = val->value = func (dev, ext->ctrl, SNDCTL_MIX_WRITE, val->value);
+
+ if (err >= 0)
+ ext->update_counter++;
+ return err;
+}
+
+int
+mixer_ext_create_device (int dev, int maxentries)
+{
+ oss_mixext_root *mixroot;
+ oss_mixext *mixext;
+ oss_mixext_desc *mixext_desc;
+ char *name = mixer_devs[dev]->name;
+ char *id = mixer_devs[dev]->id;
+ int i;
+
+ maxentries++; /* Needs space for the device root node */
+
+ if (mixer_devs[dev]->max_ext == 0)
+ {
+ mixext_desc =
+ PMALLOC (mixer_devs[dev]->osdev, sizeof (*mixext_desc) * maxentries);
+ mixer_devs[dev]->max_ext = maxentries;
+ mixer_devs[dev]->extensions = mixext_desc;
+ }
+ else
+ {
+ mixext_desc = mixer_devs[dev]->extensions;
+ }
+
+ if (mixext_desc == NULL)
+ {
+ cmn_err (CE_CONT, "Not enough memory for mixer%d (ext)\n", dev);
+ return OSS_EIO;
+ }
+
+ mixer_devs[dev]->nr_ext = 1;
+ mixer_devs[dev]->timestamp = GET_JIFFIES ();
+
+ mixext = &mixext_desc->ext;
+ mixext->dev = dev;
+ mixext->ctrl = -1; /* Undefined */
+ mixext->type = MIXT_DEVROOT;
+ mixext->maxvalue = 0;
+ mixext->minvalue = 0;
+ mixext->flags = 0;
+ strcpy (mixext->id, "DEVROOT");
+ mixext->parent = 0; /* Link to itself */
+ mixext->timestamp = mixer_devs[dev]->timestamp;
+ mixext_desc->handler = NULL;
+ memset (mixext->data, 0, sizeof (mixext->data));
+
+ mixroot = (oss_mixext_root *) & mixext->data;
+
+ for (i = 0; i < 15 && id[i]; i++)
+ mixroot->id[i] = id[i];
+ mixroot->id[15] = 0;
+
+ for (i = 0; i < 47 && name[i]; i++)
+ mixroot->name[i] = name[i];
+ mixroot->name[47] = 0;
+
+ return 0;
+}
+
+int
+mixer_ext_create_group_flags (int dev, int parent, const char *id,
+ unsigned int flags)
+{
+ oss_mixext *mixext;
+ oss_mixext_desc *mixext_desc, *parent_desc;
+ int enumber;
+
+ flags &= ~MIXF_DESCR;
+
+ if (mixer_devs[dev]->extensions == NULL)
+ {
+ cmn_err (CE_WARN, "Mixer extensions not initialized for device %d\n",
+ dev);
+ return OSS_EFAULT;
+ }
+
+ /*
+ * Ensure that the parent node number is valid.
+ */
+ if (parent < 0 || parent >= mixer_devs[dev]->nr_ext)
+ parent = 0;
+
+ parent_desc =
+ &mixer_devs[dev]->extensions[parent];
+ mixext = &parent_desc->ext;
+
+ if (mixext->type != MIXT_DEVROOT && mixext->type != MIXT_GROUP)
+ parent = 0; /* Point to the root group */
+
+ if (mixer_devs[dev]->nr_ext >= mixer_devs[dev]->max_ext)
+ {
+ cmn_err (CE_WARN, "Out of mixer controls for device %d/%s (%d)\n", dev,
+ mixer_devs[dev]->name, mixer_devs[dev]->max_ext);
+ return OSS_ENOSPC;
+ }
+
+ mixext_desc =
+ &mixer_devs[dev]->extensions[(enumber = mixer_devs[dev]->nr_ext++)];
+ mixext = &mixext_desc->ext;
+ mixext->dev = dev;
+ mixext->ctrl = -1; /* Undefined */
+ mixext->type = MIXT_GROUP;
+ mixext->maxvalue = 0;
+ mixext->minvalue = 0;
+ mixext->flags = flags | MIXF_FLAT; /* Will be unflattened later if required */
+ strcpy (mixext->id, id);
+ mixext->parent = parent;
+ mixext_desc->handler = NULL;
+ mixext_desc->enum_info = NULL;
+ memset (mixext->enum_present, 0xff, sizeof (mixext->enum_present));
+ mixext->timestamp = mixer_devs[dev]->timestamp;
+ mixext->control_no = -1;
+ mixext->desc = 0;
+ memset (mixext->data, 0, sizeof (mixext->data));
+
+ return enumber;
+}
+
+int
+mixer_ext_create_group (int dev, int parent, const char *id)
+{
+ return mixer_ext_create_group_flags (dev, parent, id, 0);
+}
+
+int
+mixer_ext_truncate (int dev, int index)
+{
+ if (index < mixer_devs[dev]->nr_ext)
+ {
+ mixer_devs[dev]->nr_ext = index;
+ mixer_devs[dev]->modify_counter++;
+ mixer_devs[dev]->timestamp++;
+ }
+ return 0;
+}
+
+static void expand_names (int dev);
+static void unflatten_group (int dev, int group);
+static void touch_parents (int dev, int group);
+
+int
+mixer_ext_create_control (int dev, int parent, int ctrl, mixer_ext_fn func,
+ int type, const char *id, int maxvalue, int flags)
+{
+ oss_mixext *mixext;
+ oss_mixext_desc *mixext_desc, *parent_desc;
+ int enumber;
+
+ flags &= ~MIXF_DESCR;
+
+ if (mixer_devs[dev]->extensions == NULL)
+ {
+ cmn_err (CE_WARN, "Mixer extensions not initialized for device %d\n",
+ dev);
+ return OSS_EFAULT;
+ }
+
+ if (mixer_devs[dev]->nr_ext >= mixer_devs[dev]->max_ext)
+ {
+ cmn_err (CE_WARN, "Out of mixer controls for device %d/%s (%d)\n", dev,
+ mixer_devs[dev]->name, mixer_devs[dev]->max_ext);
+ return OSS_ENOSPC;
+ }
+
+ if (func == NULL) /* No access function */
+ flags &= ~(MIXF_READABLE | MIXF_WRITEABLE);
+
+ /*
+ * Ensure that the parent node number is valid.
+ */
+ if (parent < 0 || parent >= mixer_devs[dev]->nr_ext)
+ parent = 0;
+
+ parent_desc =
+ &mixer_devs[dev]->extensions[parent];
+ mixext = &parent_desc->ext;
+
+ if (mixext->type != MIXT_DEVROOT && mixext->type != MIXT_GROUP)
+ parent = 0; /* Point to the root group */
+
+
+ mixext_desc =
+ &mixer_devs[dev]->extensions[(enumber = mixer_devs[dev]->nr_ext++)];
+ mixext = &mixext_desc->ext;
+ mixext->dev = dev;
+ mixext->ctrl = ctrl;
+ mixext->type = type;
+ mixext->maxvalue = maxvalue;
+ mixext->minvalue = 0;
+ mixext->flags = flags;
+ strncpy (mixext->id, id, sizeof (mixext->id));
+ mixext->id[sizeof (mixext->id) - 1] = 0;
+ mixext->parent = parent;
+ mixext->timestamp = mixer_devs[dev]->timestamp;
+ mixext_desc->handler = (mixer_ext_fn) func;
+ mixext_desc->enum_info = NULL;
+ memset (mixext->data, 0, sizeof (mixext->data));
+ memset (mixext->enum_present, 0xff, sizeof (mixext->enum_present));
+ mixext->control_no = -1;
+ mixext->desc = 0;
+
+/*
+ * Perform name expansion too if it has already been done for the
+ * earlier controls. Note that this only gets done with rare devices
+ * that add/remove controls on fly.
+ *
+ * TODO: Optimize this to expand only the current control. Scanning through
+ * all the controls may be bit time consuming with future devices having 100s
+ * of controls.
+ */
+ if (mixer_devs[dev]->names_checked)
+ expand_names (dev);
+ else
+ strcpy(mixext->extname, mixext->id);
+
+/*
+ * Mark groups with tall controls such as peak meters and sliders as
+ * non-flat
+ */
+
+ switch (type)
+ {
+ case MIXT_SLIDER:
+ case MIXT_MONOSLIDER:
+ case MIXT_STEREOSLIDER:
+ case MIXT_MONOSLIDER16:
+ case MIXT_STEREOSLIDER16:
+ case MIXT_MONOVU:
+ case MIXT_STEREOVU:
+ case MIXT_MONOPEAK:
+ case MIXT_STEREOPEAK:
+ case MIXT_MONODB:
+ case MIXT_STEREODB:
+ case MIXT_3D:
+ unflatten_group (dev, parent);
+ break;
+ }
+
+ touch_parents(dev, parent);
+
+ return enumber;
+}
+
+
+oss_mixext *
+mixer_find_ext (int dev, int enumber)
+{
+ oss_mixext_desc *mixext;
+
+ if (dev < 0 || dev >= num_mixers)
+ {
+ return NULL;
+ }
+ touch_mixer (dev);
+
+ if (enumber < 0 || enumber >= mixer_devs[dev]->nr_ext)
+ {
+ return NULL;
+ }
+
+ mixext = &mixer_devs[dev]->extensions[enumber];
+
+ return &mixext->ext;
+}
+
+/*
+ * Default read/write access functions
+ */
+int
+mixer_ext_rw (int dev, int ctrl, unsigned int cmd, int value)
+{
+ int err;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ if ((err =
+ oss_legacy_mixer_ioctl (dev, -1, MIXER_READ (ctrl),
+ (ioctl_arg) & value)) < 0)
+ return err;
+ return value;
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ if ((err =
+ oss_legacy_mixer_ioctl (dev, -1, MIXER_WRITE (ctrl),
+ (ioctl_arg) & value)) < 0)
+ return err;
+ return value;
+ }
+
+ return OSS_EINVAL;
+}
+
+int
+mixer_ext_recrw (int dev, int ctrl, unsigned int cmd, int value)
+{
+ int caps, recmask, err;
+
+ if ((err =
+ oss_legacy_mixer_ioctl (dev, -1, SOUND_MIXER_READ_CAPS,
+ (ioctl_arg) & caps)) < 0)
+ caps = SOUND_CAP_EXCL_INPUT; /* Default */
+
+ if ((err =
+ oss_legacy_mixer_ioctl (dev, -1, SOUND_MIXER_READ_RECSRC,
+ (ioctl_arg) & recmask)) < 0)
+ return err;
+
+ if (cmd == SNDCTL_MIX_READ)
+ return (recmask & (1 << ctrl)) ? 1 : 0;
+
+ if (caps & SOUND_CAP_EXCL_INPUT) /* Single recording source */
+ recmask = 0;
+
+ if (value)
+ recmask |= (1 << ctrl);
+ else
+ recmask &= ~(1 << ctrl);
+
+ if (recmask == 0)
+ return 1; /* Can't remove the only recording source */
+
+ if ((err =
+ oss_legacy_mixer_ioctl (dev, -1, SOUND_MIXER_WRITE_RECSRC,
+ (ioctl_arg) & recmask)) < 0)
+ return err;
+
+
+ return (recmask & (1 << ctrl)) ? 1 : 0;
+}
+
+/*
+ * Mixer extension initialization
+ */
+
+static void
+store_name (oss_mixext * thisrec, char *name)
+{
+ int i;
+
+ while (*name == '.')
+ name++;
+ strncpy (thisrec->extname, name, 32);
+ thisrec->extname[31] = '\0';
+
+ name = thisrec->extname;
+ for (i = 0; i < strlen (name); i++)
+ if (name[i] >= 'A' && name[i] <= 'Z')
+ name[i] += 32;
+}
+
+static char *
+cut_name (char *name)
+{
+ char *s = name;
+ while (*s)
+ if (*s++ == '_')
+ return s;
+
+ if (name[0] == '@')
+ return &name[1];
+
+ return name;
+}
+
+#include "mixerdefs.h"
+
+static void
+find_enum_defs (oss_mixext * thisrec, int dev, int ctl)
+{
+ int i;
+
+ for (i = 0; mixer_defs[i].name != NULL; i++)
+ if (strcmp (thisrec->extname, mixer_defs[i].name) == 0)
+ {
+ mixer_ext_set_strings (dev, ctl, mixer_defs[i].strings, 0);
+ return;
+ }
+}
+
+static void
+expand_names (int dev)
+{
+ int i, n;
+ oss_mixext_desc *mixext_desc;
+
+ n = mixer_devs[dev]->nr_ext;
+ mixer_devs[dev]->names_checked = 1;
+
+ if (n < 1)
+ return;
+
+ for (i = 0; i < n; i++)
+ {
+ char tmp[100], *name;
+ int parent = 0;
+ oss_mixext *thisrec = NULL, *parentrec = NULL;
+
+ mixext_desc = &mixer_devs[dev]->extensions[i];
+ thisrec = &mixext_desc->ext;
+
+ switch (thisrec->type)
+ {
+ case MIXT_DEVROOT:
+ thisrec->extname[0] = 0;
+ break;
+
+ case MIXT_GROUP:
+ parent = thisrec->parent;
+ mixext_desc = &mixer_devs[dev]->extensions[parent];
+ parentrec = &mixext_desc->ext;
+ name = cut_name (thisrec->id);
+ if (parentrec->extname[0] == 0)
+ strcpy (tmp, name);
+ else
+ sprintf (tmp, "%s.%s", parentrec->extname, name);
+ store_name (thisrec, tmp);
+ break;
+
+ case MIXT_STEREOSLIDER:
+ case MIXT_STEREOSLIDER16:
+ case MIXT_STEREODB:
+ case MIXT_STEREOVU:
+ case MIXT_MONODB:
+ case MIXT_MONOSLIDER:
+ case MIXT_MONOSLIDER16:
+ case MIXT_SLIDER:
+ case MIXT_MONOVU:
+ case MIXT_MONOPEAK:
+ case MIXT_STEREOPEAK:
+ case MIXT_ONOFF:
+ case MIXT_MUTE:
+ case MIXT_ENUM:
+ case MIXT_VALUE:
+ case MIXT_HEXVALUE:
+ case MIXT_3D:
+ parent = thisrec->parent;
+ mixext_desc = &mixer_devs[dev]->extensions[parent];
+ parentrec = &mixext_desc->ext;
+ name = cut_name (thisrec->id);
+ if (*thisrec->id == 0 || *thisrec->id == '-') /* Special (hidden) names */
+ strcpy (thisrec->extname, parentrec->extname);
+ else
+ {
+ sprintf (tmp, "%s.%s", parentrec->extname, name);
+ store_name (thisrec, tmp);
+
+ if (thisrec->type == MIXT_ENUM)
+ find_enum_defs (thisrec, dev, i);
+ }
+ break;
+
+ case MIXT_MARKER:
+ break;
+
+ default:;
+ }
+ }
+/*
+ * Fix duplicate names.
+ */
+
+ for (i = 0; i < n; i++)
+ {
+ char tmp[100];
+ int j, dupes = 0;
+ oss_mixext *thisrec = NULL;
+
+ mixext_desc = &mixer_devs[dev]->extensions[i];
+ thisrec = &mixext_desc->ext;
+
+ if (thisrec->type == MIXT_GROUP)
+ continue;
+
+ strcpy (tmp, thisrec->extname);
+
+ for (j = i + 1; j < n; j++)
+ {
+ oss_mixext_desc *mixext_desc2;
+ oss_mixext *thisrec2 = NULL;
+ mixext_desc2 = &mixer_devs[dev]->extensions[j];
+ thisrec2 = &mixext_desc2->ext;
+
+ if (thisrec2->type == MIXT_GROUP)
+ continue;
+
+ if (strcmp (thisrec2->extname, tmp) == 0)
+ dupes++;
+ }
+
+ if (dupes > 0) /* Need to fix duplicates */
+ {
+ int count = 1, len;
+ char tmp2[32];
+
+ for (j = i; j < n; j++)
+ {
+ oss_mixext_desc *mixext_desc2;
+ oss_mixext *thisrec2 = NULL;
+ mixext_desc2 = &mixer_devs[dev]->extensions[j];
+ thisrec2 = &mixext_desc2->ext;
+
+ if (thisrec2->type != MIXT_GROUP)
+ if (strcmp (thisrec2->extname, tmp) == 0)
+ {
+ sprintf (tmp2, "%d", count++);
+ tmp2[31] = '\0';
+ len = strlen (thisrec2->extname);
+ if (len >= sizeof (thisrec2->extname) - strlen (tmp2))
+ len = sizeof (thisrec2->extname) - strlen (tmp2) - 1;
+ strcpy (thisrec2->extname + len, tmp2);
+ }
+ }
+ }
+ }
+}
+
+static void
+unflatten_group (int dev, int group)
+{
+/*
+ * Clear the MIXF_FLAT flags from all parent groups (recursively):
+ */
+ int n;
+ oss_mixext_desc *mixext_desc;
+ oss_mixext *thisrec = NULL;
+
+ n = mixer_devs[dev]->nr_ext;
+
+ if (n < 1)
+ return;
+
+ if (group <= 0 || group >= n)
+ return;
+
+ mixext_desc = &mixer_devs[dev]->extensions[group];
+ thisrec = &mixext_desc->ext;
+
+ if (thisrec->type != MIXT_GROUP) /* Not a group */
+ return;
+
+ if (!(thisrec->flags & MIXF_FLAT)) /* Already unflattened */
+ return;
+
+ thisrec->flags &= ~MIXF_FLAT;
+
+ if (thisrec->parent >= group) /* Broken link */
+ return;
+
+ unflatten_group (dev, thisrec->parent); /* Unflatten the parent */
+}
+
+static void
+touch_parents (int dev, int group)
+{
+ int n;
+ oss_mixext_desc *mixext_desc;
+ oss_mixext *thisrec = NULL;
+
+ n = mixer_devs[dev]->nr_ext;
+
+ if (n < 1)
+ return;
+
+ if (group <= 0 || group >= n)
+ return;
+
+ mixext_desc = &mixer_devs[dev]->extensions[group];
+ thisrec = &mixext_desc->ext;
+
+ while (thisrec->type != MIXT_DEVROOT)
+ {
+ if (thisrec->type != MIXT_GROUP) /* Not a group */
+ return;
+
+ thisrec->update_counter++;
+
+ if (thisrec->parent >= group) /* Broken link */
+ return;
+
+ unflatten_group (dev, thisrec->parent); /* Unflatten the parent */
+
+ mixext_desc = &mixer_devs[dev]->extensions[thisrec->parent];
+ thisrec = &mixext_desc->ext;
+ }
+
+ thisrec->update_counter++;
+}
+
+#define INPUT_MASK (SOUND_MASK_RECLEV|SOUND_MASK_IGAIN)
+#define OUTPUT_MASK (SOUND_MASK_PCM|SOUND_MASK_ALTPCM|SOUND_MASK_VOLUME| \
+ SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_SYNTH| \
+ SOUND_MASK_IMIX|SOUND_MASK_REARVOL|SOUND_MASK_CENTERVOL| \
+ SOUND_MASK_SIDEVOL)
+#define MONITOR_MASK (SOUND_MASK_SPEAKER|SOUND_MASK_LINE|SOUND_MASK_LINE| \
+ SOUND_MASK_MIC|SOUND_MASK_CD|SOUND_MASK_LINE1|SOUND_MASK_LINE2| \
+ SOUND_MASK_LINE3|SOUND_MASK_DIGITAL1|SOUND_MASK_DIGITAL2| \
+ SOUND_MASK_DIGITAL3|SOUND_MASK_MONO|SOUND_MASK_PHONE| \
+ SOUND_MASK_RADIO|SOUND_MASK_VIDEO)
+
+void
+touch_mixer (int dev)
+{
+ int i, n, devmask, recmask, stereomask, grp, root = 0, caps = 0;
+ static char *id[] = SOUND_DEVICE_NAMES;
+ int created = 0;
+
+ if (mixer_devs[dev] == NULL || mixer_devs[dev]->unloaded
+ || !mixer_devs[dev]->enabled)
+ {
+ return;
+ }
+
+/*
+ * Create default mixer extension records if required.
+ */
+ if (mixer_devs[dev]->nr_ext > 0) /* Already initialized */
+ return;
+
+/*
+ * Compute number of required mixer extension entries
+ */
+
+ n = mixer_devs[dev]->nr_extra_ext; /* Reserve space for the actual driver */
+ if (n < 20)
+ n = 20;
+
+ if (oss_legacy_mixer_ioctl
+ (dev, -1, SOUND_MIXER_READ_CAPS, (ioctl_arg) & caps) < 0)
+ caps = 0; /* Error */
+
+ if (oss_legacy_mixer_ioctl
+ (dev, -1, SOUND_MIXER_READ_DEVMASK, (ioctl_arg) & devmask) < 0)
+ goto skip; /* Error */
+
+ /* Remove devices that are handled otherwise */
+ devmask &= ~mixer_devs[dev]->ignore_mask;
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if (devmask & (1 << i)) /* This control is supported */
+ n++;
+
+ n = n * 2;
+
+ if (oss_legacy_mixer_ioctl
+ (dev, -1, SOUND_MIXER_READ_RECMASK, (ioctl_arg) & recmask) < 0)
+ goto skip; /* Error */
+
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if (recmask & (1 << i)) /* This control is also recording device */
+ n++;
+
+ root = 0;
+
+#ifdef CONFIG_OSSD
+ n += 20; /* Space for OSSD use */
+#endif
+
+ n = n + 5; /* The marker entry and some spare space */
+ if ((root = mixer_ext_create_device (dev, n)) < 0)
+ return; /* Error */
+ created = 1;
+
+ if (oss_legacy_mixer_ioctl (dev, -1, SOUND_MIXER_READ_STEREODEVS,
+ (ioctl_arg) & stereomask) < 0)
+ stereomask = -1; /* Assume all stereo */
+
+ if (!(caps & SOUND_CAP_NOLEGACY)) /* Don't (re)export the legacy mixer */
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ if (devmask & (1 << i))
+ {
+ if ((grp =
+ mixer_ext_create_group_flags (dev, root, id[i],
+ MIXF_LEGACY)) > 0)
+ {
+ int cnum;
+ oss_mixext *ent;
+ int flags = 0;
+
+ /*
+ * Set the type hints for main and PCM volume controls
+ */
+
+ switch (i)
+ {
+ case SOUND_MIXER_VOLUME:
+ case SOUND_MIXER_MONO:
+ case SOUND_MIXER_REARVOL:
+ case SOUND_MIXER_CENTERVOL:
+ case SOUND_MIXER_SIDEVOL:
+ flags |= MIXF_MAINVOL;
+ break;
+
+ case SOUND_MIXER_PCM:
+ case SOUND_MIXER_ALTPCM:
+ flags |= MIXF_PCMVOL;
+ break;
+
+ case SOUND_MIXER_RECLEV:
+ case SOUND_MIXER_IGAIN:
+ flags |= MIXF_RECVOL;
+ break;
+
+ case SOUND_MIXER_SYNTH:
+ case SOUND_MIXER_SPEAKER:
+ case SOUND_MIXER_LINE:
+ case SOUND_MIXER_LINE1:
+ case SOUND_MIXER_LINE2:
+ case SOUND_MIXER_LINE3:
+ case SOUND_MIXER_MIC:
+ case SOUND_MIXER_CD:
+ case SOUND_MIXER_DIGITAL1:
+ case SOUND_MIXER_DIGITAL2:
+ case SOUND_MIXER_DIGITAL3:
+ case SOUND_MIXER_PHONE:
+ case SOUND_MIXER_VIDEO:
+ case SOUND_MIXER_RADIO:
+ flags |= MIXF_MONVOL;
+ break;
+ }
+
+ if (stereomask & (1 << i))
+ cnum = mixer_ext_create_control (dev, grp, i, mixer_ext_rw,
+ MIXT_STEREOSLIDER,
+ "", 100,
+ flags | MIXF_READABLE |
+ MIXF_WRITEABLE);
+ else
+ cnum = mixer_ext_create_control (dev, grp, i, mixer_ext_rw,
+ MIXT_MONOSLIDER,
+ "", 100,
+ flags | MIXF_READABLE |
+ MIXF_WRITEABLE);
+
+ if ((ent = mixer_find_ext (dev, cnum)) != NULL)
+ {
+ ent->control_no = i;
+
+ if ((1 << i) & INPUT_MASK)
+ ent->desc &= MIXEXT_SCOPE_INPUT;
+ if ((1 << i) & OUTPUT_MASK)
+ ent->desc &= MIXEXT_SCOPE_OUTPUT;
+ if ((1 << i) & MONITOR_MASK)
+ ent->desc &= MIXEXT_SCOPE_MONITOR;
+
+ /*
+ * Set the RGB color for some of the controls
+ * to match the usual jack color.
+ */
+
+ switch (i)
+ {
+ case SOUND_MIXER_MIC: ent->rgbcolor=OSS_RGB_PINK; break;
+ case SOUND_MIXER_LINE: ent->rgbcolor=OSS_RGB_BLUE; break;
+ case SOUND_MIXER_VOLUME: ent->rgbcolor=OSS_RGB_GREEN; break;
+ case SOUND_MIXER_REARVOL: ent->rgbcolor=OSS_RGB_BLACK; break;
+ case SOUND_MIXER_SIDEVOL: ent->rgbcolor=OSS_RGB_GRAY; break;
+ case SOUND_MIXER_CENTERVOL: ent->rgbcolor=OSS_RGB_ORANGE; break;
+ }
+ }
+
+ if (recmask & (1 << i))
+ {
+ cnum =
+ mixer_ext_create_control (dev, grp, i, mixer_ext_recrw,
+ MIXT_ONOFF, "REC", 1,
+ MIXF_READABLE | MIXF_WRITEABLE | MIXF_RECVOL);
+ if ((ent = mixer_find_ext (dev, cnum)) != NULL)
+ {
+ ent->desc &= MIXEXT_SCOPE_RECSWITCH;
+ }
+ }
+ }
+ }
+
+skip:
+ if (!created)
+ if ((root = mixer_ext_create_device (dev, n)) < 0)
+ return; /* Error */
+ mixer_ext_create_control (dev, root, 0, NULL, MIXT_MARKER, "", 0, 0);
+
+ if (mixer_devs[dev]->create_controls != NULL)
+ mixer_devs[dev]->create_controls (dev);
+ expand_names (dev);
+}
+
+int
+mixer_ext_set_init_fn (int dev, mixer_create_controls_t func, int nextra)
+{
+/*
+ * Set device dependent mixer extension initialization function and
+ * reserve some extension entries for device dependent use.
+ *
+ * This initialization function will be called later when/if the
+ * extended mixer is actually used.
+ */
+ if (dev < 0 || dev >= num_mixers)
+ return OSS_ENXIO;
+
+ mixer_devs[dev]->nr_extra_ext = nextra;
+ mixer_devs[dev]->create_controls = func;
+ return 0;
+}
+
+int
+mixer_ext_rebuild_all (int dev, mixer_create_controls_t func, int nextra)
+{
+/*
+ * Throw away all existing mixer controls and recreate the mixer.
+ */
+ if (dev < 0 || dev >= num_mixers)
+ return OSS_ENXIO;
+ mixer_devs[dev]->nr_ext = 0;
+
+ mixer_devs[dev]->nr_extra_ext = nextra;
+ mixer_devs[dev]->create_controls = func;
+
+ touch_mixer (dev);
+ if (mixer_devs[dev]->create_vmix_controls != NULL)
+ {
+ mixer_devs[dev]->create_vmix_controls(dev);
+ }
+
+ return 0;
+}
+
+int
+mixer_ext_set_vmix_init_fn (int dev, mixer_create_controls_t func, int nextra,
+ void *devc)
+{
+/*
+ * Set device dependent mixer extension initialization function and
+ * reserve some extension entries for device dependent use.
+ *
+ * This initialization function will be called later when/if the
+ * extended mixer is actually used.
+ */
+ if (dev < 0 || dev >= num_mixers)
+ return OSS_ENXIO;
+
+ mixer_devs[dev]->nr_extra_ext += nextra;
+ mixer_devs[dev]->create_vmix_controls = func;
+ mixer_devs[dev]->vmix_devc = devc;
+ touch_mixer (dev);
+ func (dev);
+ expand_names (dev);
+ return 0;
+}
+
+#ifdef VDEV_SUPPORT
+static void
+ainfo_combine_caps (oss_audioinfo * ainfo, adev_p adev)
+{
+ if (!(adev->flags & ADEV_NOOUTPUT))
+ ainfo->caps |= DSP_CAP_OUTPUT;
+ else
+ ainfo->caps &= ~DSP_CAP_OUTPUT;
+
+ if (!(adev->flags & ADEV_NOINPUT))
+ ainfo->caps |= DSP_CAP_INPUT;
+ else
+ ainfo->caps &= ~DSP_CAP_INPUT;
+
+ if (adev->flags & ADEV_DUPLEX)
+ ainfo->caps |= DSP_CAP_DUPLEX;
+ else
+ ainfo->caps &= ~DSP_CAP_DUPLEX;
+
+#ifdef ALLOW_BUFFER_MAPPING
+ if (!(adev->flags & ADEV_NOMMAP))
+ ainfo->caps |= DSP_CAP_MMAP;
+#endif
+}
+#endif
+
+#if 0
+/*
+ * Device list support is currently not used
+ */
+static int
+check_list (oss_devlist_t * oldlist, oss_devlist_t * newlist)
+{
+/*
+ * Check that the same devices are present in both lists. Any difference
+ * indicates that the device configuration has changed (invalidates the list).
+ */
+#if MAX_AUDIO_DEVFILES > 64
+#error Too many audio devices - fix this algorithm
+#endif
+ unsigned long long mask1, mask2;
+ int i;
+
+ if (newlist->ndevs != oldlist->ndevs)
+ return 0;
+
+ mask1 = 0LL;
+ mask2 = 0LL;
+
+ for (i = 0; i < oldlist->ndevs; i++)
+ mask1 |= 1LL << oldlist->devices[i];
+ for (i = 0; i < newlist->ndevs; i++)
+ mask1 |= 1LL << newlist->devices[i];
+
+ if (mask1 != mask2)
+ return 0;
+
+ return 1;
+}
+#endif
+
+static int
+get_engineinfo (int dev, oss_audioinfo * info, int combine_slaves)
+{
+ int dev_present = 0;
+ int i;
+ oss_native_word flags;
+
+ adev_p adev, next;
+
+ flags = 0;
+ memset ((char *) info, 0, sizeof (*info));
+
+ if (dev < 0 || dev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ adev = audio_engines[dev];
+ if (adev == NULL)
+ {
+ cmn_err (CE_WARN, "Internal error - adev==NULL (%d)\n", dev);
+ return OSS_ENXIO;
+ }
+
+ if (!adev->unloaded && adev->enabled)
+ dev_present = 1;
+
+ if (dev_present)
+ {
+ MUTEX_ENTER_IRQDISABLE (adev->mutex, flags);
+ }
+ info->dev = dev;
+ strcpy (info->name, adev->name);
+ strcpy (info->handle, adev->handle);
+ info->busy = adev->open_mode;
+ info->caps = adev->caps;
+ if (!(adev->flags & ADEV_NOINPUT))
+ info->caps |= PCM_CAP_INPUT;
+ if (!(adev->flags & ADEV_NOOUTPUT))
+ info->caps |= PCM_CAP_OUTPUT;
+ if (adev->flags & ADEV_SPECIAL)
+ info->caps |= PCM_CAP_SPECIAL;
+ if (adev->flags & ADEV_VIRTUAL)
+ info->caps |= PCM_CAP_VIRTUAL;
+
+ if (adev->flags & (ADEV_HIDDEN | ADEV_SHADOW))
+ {
+ info->caps |= PCM_CAP_HIDDEN;
+ }
+
+ if (adev->flags & ADEV_DUPLEX)
+ {
+ info->caps |= PCM_CAP_DUPLEX;
+ }
+ if (adev->d->adrv_trigger) /* Supports SETTRIGGER */
+ info->caps |= PCM_CAP_TRIGGER;
+#ifdef ALLOW_BUFFER_MAPPING
+ if (!(adev->flags & ADEV_NOMMAP))
+ info->caps |= PCM_CAP_MMAP;
+#endif
+
+ info->oformats = adev->oformat_mask;
+ info->iformats = adev->iformat_mask;
+ info->pid = adev->pid;
+ info->latency = adev->latency;
+ *info->cmd = 0;
+ strncpy (info->cmd, adev->cmd, sizeof (info->cmd));
+ info->cmd[sizeof (info->cmd) - 1] = 0;
+
+ strcpy (info->devnode, adev->devnode);
+
+ if (!adev->unloaded && adev->enabled)
+ {
+ if (audio_engines[dev]->d->adrv_ioctl (dev, SNDCTL_GETSONG,
+ (ioctl_arg) info->song_name) ==
+ OSS_EINVAL)
+ strcpy (info->song_name, adev->song_name);
+ if (audio_engines[dev]->d->adrv_ioctl (dev, SNDCTL_GETLABEL,
+ (ioctl_arg) info->label) ==
+ OSS_EINVAL)
+ strcpy (info->label, adev->label);
+ }
+
+ if (*info->label == 0)
+ {
+ strncpy (info->label, info->cmd, sizeof (info->label));
+ info->label[sizeof (info->label) - 1] = 0;
+ }
+
+ info->magic = adev->magic;
+ info->card_number = adev->card_number;
+ info->port_number = adev->port_number;
+ info->mixer_dev = adev->mixer_dev;
+ info->legacy_device = adev->real_dev;
+ info->rate_source = adev->rate_source;
+ info->enabled = (adev->enabled && !adev->unloaded);
+ info->flags = adev->flags;
+ info->min_rate = adev->min_rate;
+ info->max_rate = adev->max_rate;
+ info->min_channels = adev->min_channels;
+ info->max_channels = adev->max_channels;
+ info->binding = adev->binding;
+ info->nrates = adev->nrates;
+ for (i = 0; i < info->nrates; i++)
+ info->rates[i] = adev->rates[i];
+
+ if (adev->next_out == NULL || !dev_present)
+ info->next_play_engine = 0;
+ else
+ {
+ info->next_play_engine = adev->next_out->engine_num;
+ next = adev->next_out;
+
+#ifdef VDEV_SUPPORT
+ i = 0;
+ while (combine_slaves && next != NULL && i++ < num_audio_engines)
+ {
+ ainfo_combine_caps (info, next);
+ next = next->next_out;
+ }
+#endif
+ }
+
+ if (adev->next_in == NULL || !dev_present)
+ info->next_rec_engine = 0;
+ else
+ {
+ info->next_rec_engine = adev->next_in->engine_num;
+ next = adev->next_in;
+
+#ifdef VDEV_SUPPORT
+ i=0;
+ while (combine_slaves && next != NULL && i++ < num_audio_engines)
+ {
+ ainfo_combine_caps (info, next);
+ next = next->next_in;
+ }
+#endif
+ }
+
+ if (dev_present)
+ {
+ MUTEX_EXIT_IRQRESTORE (adev->mutex, flags);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_OSS_VMIX
+static int
+vmixctl_attach(vmixctl_attach_t *att)
+{
+ int err;
+ oss_device_t *osdev;
+
+ if (att->masterdev<0 || att->masterdev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ if (att->inputdev != -1)
+ if (att->inputdev<0 || att->inputdev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ osdev=audio_engines[att->masterdev]->master_osdev;
+
+ if ((err=vmix_attach_audiodev(osdev, att->masterdev, att->inputdev, att->attach_flags))<0)
+ return err;
+
+ return 0;
+}
+
+static int
+vmixctl_detach(vmixctl_attach_t *att)
+{
+ int err;
+ oss_device_t *osdev;
+
+ if (att->masterdev<0 || att->masterdev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ osdev=audio_engines[att->masterdev]->master_osdev;
+
+ if ((err=vmix_detach_audiodev(att->masterdev))<0)
+ return err;
+
+ return 0;
+}
+
+static int
+vmixctl_rate(vmixctl_rate_t *rate)
+{
+ int err;
+
+ if (rate->masterdev<0 || rate->masterdev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ if ((err=vmix_set_master_rate(rate->masterdev, rate->rate))<0)
+ return err;
+
+ return 0;
+}
+
+static int
+vmixctl_map_channels(vmixctl_map_t *map)
+{
+ int err;
+
+ if (map->masterdev < 0 || map->masterdev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ if ((err = vmix_set_channel_map (map->masterdev, &map->map)) < 0)
+ return err;
+
+ return 0;
+}
+#endif
+
+int
+oss_mixer_ext (int orig_dev, int class, unsigned int cmd, ioctl_arg arg)
+{
+ int val;
+ int combine_slaves = 0;
+#ifdef MANAGE_DEV_DSP
+#ifdef VDEV_SUPPORT
+ extern void oss_combine_write_lists (void);
+#endif
+#endif
+
+ switch (cmd)
+ {
+ case SNDCTL_SYSINFO: /* Formerly OSS_SYSINFO */
+ {
+ oss_sysinfo *info = (oss_sysinfo *) arg;
+ int i;
+
+ memset (info, 0, sizeof (*info));
+ strcpy (info->product, "OSS");
+ strncpy (info->version, OSS_VERSION_STRING, sizeof (info->version));
+ info->version [sizeof (info->version) - 1] = '\0';
+ strcpy (info->license, oss_license_string);
+ info->versionnum = OSS_VERSION;
+
+#ifdef OSS_HG_INFO
+ /* Detailed Mercurial version */
+ strncpy (info->revision_info, OSS_HG_INFO, sizeof(info->revision_info));
+ info->revision_info[sizeof(info->revision_info)-1]=0;
+#endif
+
+ memset (info->options, 0, sizeof (info->options));
+
+ info->numaudios = num_audio_devfiles;
+ info->numaudioengines = num_audio_engines;
+ for (i = 0; i < 8; i++)
+ info->openedaudio[i] = 0;
+ for (i = 0; i < num_audio_engines; i++)
+ if (audio_engines[i] != NULL)
+ {
+ if (audio_engines[i]->flags & ADEV_OPENED)
+ if (audio_engines[i]->next_out != NULL)
+ {
+ int x = audio_engines[i]->real_dev;
+ info->openedaudio[x / 32] |= 1 << (x % 32);
+ }
+ }
+ for (i = 0; i < 8; i++)
+ info->openedmidi[i] = 0;
+ for (i = 0; i < num_mididevs; i++)
+ if (midi_devs[i]->open_mode != 0)
+ info->openedmidi[i / 32] |= 1 << (i % 32);
+
+ info->numsynths = 0;
+#ifdef CONFIG_OSS_MIDI
+ info->nummidis = num_mididevs;
+#endif
+ info->numtimers = oss_num_timers;
+ info->nummixers = num_mixers;
+ info->numcards = oss_num_cards;
+
+ return 0;
+ }
+ break;
+
+ case SNDCTL_MIX_NRMIX:
+ return *arg = num_mixers;
+ break;
+
+ case SNDCTL_MIX_NREXT: /* Return # of mixer extensions for device */
+ val = *arg;
+ *arg = 0;
+ if (val==-1)
+ val=orig_dev;
+ if (val < 0 || val >= num_mixers)
+ return OSS_ENXIO;
+ if (mixer_devs[val] == NULL || mixer_devs[val]->unloaded
+ || !mixer_devs[val]->enabled)
+ {
+ return OSS_ENXIO;
+ }
+
+
+ touch_mixer (val);
+ return *arg = mixer_devs[val]->nr_ext;
+ break;
+
+ case SNDCTL_MIX_EXTINFO:
+ return oss_mixer_ext_info ((oss_mixext *) arg);
+ break;
+
+ case SNDCTL_MIX_ENUMINFO:
+ return mixer_ext_get_enuminfo ((oss_mixer_enuminfo *) arg);
+ break;
+
+ case SNDCTL_MIX_DESCRIPTION:
+ return mixer_ext_get_description ((oss_mixer_enuminfo *) arg);
+ break;
+
+ case SNDCTL_MIX_READ:
+ return mixer_ext_read ((oss_mixer_value *) arg);
+ break;
+
+ case SNDCTL_MIX_WRITE:
+ return mixer_ext_write ((oss_mixer_value *) arg);
+ break;
+
+ case OSS_GETVERSION:
+ return *arg = OSS_VERSION;
+ break;
+
+ case SNDCTL_AUDIOINFO:
+ case SNDCTL_AUDIOINFO_EX:
+ {
+ int dev;
+ oss_audioinfo *info = (oss_audioinfo *) arg;
+
+ if (info == NULL)
+ return OSS_EFAULT;
+
+ dev = info->dev;
+
+ if (dev == -1) /* Request for the current device */
+ {
+ oss_audio_set_error (orig_dev, E_PLAY,
+ OSSERR (1022,
+ "SNDCTL_AUDIOINFO called with dev=-1.."),
+ 0);
+ /*
+ * Errordesc:
+ * Applications that try to obtain audio device information about
+ * the current device should call SNDCTL_ENGINEINFO instead of
+ * SNDCTL_AUDIOINFO.
+ *
+ * Audio file descriptors returned by open(2) are bound
+ * directly to specific audio engine instead of the
+ * device file.
+ */
+ return OSS_EINVAL;
+ }
+
+ if (dev < 0 || dev >= num_audio_devfiles)
+ {
+ return OSS_EINVAL;
+ }
+
+ if (audio_devfiles[dev] == NULL)
+ {
+ return OSS_EIO;
+ }
+
+ if (dev >= 0)
+ {
+ dev = audio_devfiles[dev]->engine_num; /* Get the engine number */
+ if (cmd == SNDCTL_AUDIOINFO && info->dev != -1)
+ combine_slaves = 1;
+ }
+ return get_engineinfo (dev, info, combine_slaves);
+ }
+ break;
+
+ case SNDCTL_ENGINEINFO:
+ {
+ int dev;
+ oss_audioinfo *info = (oss_audioinfo *) arg;
+
+ if (info == NULL)
+ return OSS_EFAULT;
+
+ dev = info->dev;
+
+ if (dev == -1) /* Request for the current device */
+ switch (class)
+ {
+ case OSS_DEV_DSP:
+ case OSS_DEV_DSP_ENGINE:
+ dev = orig_dev;
+ break;
+
+ default:
+ cmn_err(CE_WARN, "Unrecognized device class %d for dev %d\n", class, orig_dev);
+ return OSS_EINVAL;
+ }
+
+ if (dev < 0 || dev >= num_audio_engines)
+ {
+ return OSS_EINVAL;
+ }
+
+ return get_engineinfo (dev, info, 0);
+ }
+ break;
+
+#ifdef CONFIG_OSS_MIDI
+ case SNDCTL_MIDIINFO:
+ {
+ int dev;
+ oss_native_word flags;
+ extern int oss_num_midi_clients; /* midi.c */
+
+ oss_midi_info *info = (oss_midi_info *) arg;
+ mididev_t *mdev;
+
+ dev = info->dev;
+
+ if (dev == -1) /* Request for the current device */
+ switch (class)
+ {
+ case OSS_DEV_MIDI:
+ /*
+ * Figure out the HW device connected to this client (orig_dev).
+ */
+ dev = orig_dev;
+ if (dev < 0 || dev >= oss_num_midi_clients)
+ return OSS_ENXIO;
+ if (oss_midi_clients[dev]->mididev == NULL)
+ return OSS_EBUSY; /* No binding established (yet) */
+ dev = oss_midi_clients[dev]->mididev->dev;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ if (dev < 0 || dev >= num_mididevs)
+ {
+ return OSS_EINVAL;
+ }
+
+ memset ((char *) info, 0, sizeof (*info));
+
+ mdev = midi_devs[dev];
+ MUTEX_ENTER_IRQDISABLE (mdev->mutex, flags);
+ info->dev = dev;
+ strcpy (info->name, mdev->name);
+ strcpy (info->handle, mdev->handle);
+ info->pid = mdev->pid;
+ info->busy = mdev->open_mode;
+ *info->cmd = 0;
+ strncpy (info->cmd, mdev->cmd, sizeof (info->cmd));
+ info->cmd[sizeof (info->cmd) - 1] = 0;
+ info->magic = mdev->magic;
+ info->card_number = mdev->card_number;
+ strcpy (info->devnode, mdev->devnode);
+ info->legacy_device = mdev->real_dev;
+ info->port_number = mdev->port_number;
+ info->enabled = mdev->enabled;
+ info->flags = mdev->flags;
+ info->caps = mdev->caps;
+ info->latency = mdev->latency;
+ if (!(info->caps & MIDI_CAP_INOUT))
+ info->caps |= MIDI_CAP_INOUT;
+ if (mdev->flags & MFLAG_VIRTUAL)
+ info->caps |= MIDI_CAP_VIRTUAL;
+ if (mdev->flags & MFLAG_CLIENT)
+ info->caps |= MIDI_CAP_CLIENT;
+ if (mdev->flags & MFLAG_SERVER)
+ info->caps |= MIDI_CAP_SERVER;
+ if (mdev->flags & MFLAG_INTERNAL)
+ info->caps |= MIDI_CAP_INTERNAL;
+ if (mdev->flags & MFLAG_EXTERNAL)
+ info->caps |= MIDI_CAP_EXTERNAL;
+ if (mdev->flags & MFLAG_MTC)
+ info->caps |= MIDI_CAP_MTC;
+ if (midi_devs[dev]->enabled && !midi_devs[dev]->unloaded)
+ if (midi_devs[dev]->d->ioctl)
+ {
+ midi_devs[dev]->d->ioctl (dev, SNDCTL_GETSONG,
+ (ioctl_arg) info->song_name);
+ midi_devs[dev]->d->ioctl (dev, SNDCTL_GETLABEL,
+ (ioctl_arg) info->label);
+ }
+ if (*info->label == 0)
+ {
+ strncpy (info->label, info->cmd, sizeof (info->label));
+ info->label[sizeof (info->label) - 1] = 0;
+ }
+ MUTEX_EXIT_IRQRESTORE (mdev->mutex, flags);
+ }
+ return 0;
+ break;
+#endif
+
+ case SNDCTL_CARDINFO:
+ {
+ int card, err;
+
+ oss_card_info *info = (oss_card_info *) arg;
+ card = info->card;
+
+ if (card < 0 || card >= oss_num_cards)
+ {
+ return OSS_ENXIO;
+ }
+
+ memset ((char *) info, 0, sizeof (*info));
+ if ((err = oss_get_cardinfo (card, info)) < 0)
+ return err;
+ info->card = card;
+ }
+ return 0;
+ break;
+
+ case SNDCTL_MIXERINFO:
+ {
+ int dev;
+
+ oss_mixerinfo *info = (oss_mixerinfo *) arg;
+ mixer_operations_t *mdev;
+
+ dev = info->dev;
+
+ if (dev == -1) /* Request for the current device */
+ switch (class)
+ {
+ case OSS_DEV_MIXER:
+ dev = orig_dev;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+
+ if (dev < 0 || dev >= num_mixers)
+ {
+ return OSS_ENXIO;
+ }
+
+ if (mixer_devs[dev] == NULL)
+ return OSS_ENXIO;
+
+ memset ((char *) info, 0, sizeof (*info));
+ touch_mixer (dev);
+
+ mdev = mixer_devs[dev];
+ info->dev = dev;
+ strncpy (info->name, mdev->name, sizeof (info->name));
+ info->name[sizeof (info->name) - 1] = '\0';
+ strcpy (info->id, mdev->id);
+ strcpy (info->handle, mdev->handle);
+ info->card_number = mdev->card_number;
+ info->port_number = mdev->port_number;
+ info->enabled = (mdev->enabled && !mdev->unloaded);
+ info->magic = mdev->magic;
+ info->caps = mdev->caps;
+ info->flags = mdev->flags;
+ info->modify_counter = mdev->modify_counter;
+ info->nrext = mdev->nr_ext;
+ info->priority = mdev->priority;
+ strcpy (info->devnode, mdev->devnode);
+ info->legacy_device = mdev->real_dev;
+ }
+ return 0;
+ break;
+
+ case OSSCTL_RENUM_AUDIODEVS:
+ {
+ oss_renumber_t *r = (oss_renumber_t *) arg;
+ int i;
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+
+ if (r->n != num_audio_devfiles) /* Wrong map size? */
+ {
+ cmn_err (CE_NOTE, "Legacy audio map size mismatch %d/%d\n",
+ r->n, num_audio_devfiles);
+ return OSS_EINVAL;
+ }
+
+ for (i = 0; i < r->n; i++)
+ {
+ adev_p adev = audio_devfiles[i];
+
+ if (r->map[i] >= HARD_MAX_AUDIO_DEVFILES) /* May be unnecessary check */
+ return OSS_EINVAL;
+
+ if (r->map[i] < -1)
+ r->map[i] = -1;
+
+ adev->real_dev = r->map[i];
+ }
+ }
+ return 0;
+ break;
+
+ case OSSCTL_RENUM_MIXERDEVS:
+ {
+ oss_renumber_t *r = (oss_renumber_t *) arg;
+ int i;
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+
+ if (r->n != num_mixers) /* Wrong map size? */
+ return OSS_EINVAL;
+
+ for (i = 0; i < r->n; i++)
+ {
+ mixdev_p mdev = mixer_devs[i];
+
+ if (r->map[i] >= HARD_MAX_AUDIO_DEVFILES) /* May be unnecessary check */
+ return OSS_EINVAL;
+
+ mdev->real_dev = r->map[i];
+ }
+ }
+ return 0;
+ break;
+
+ case OSSCTL_RENUM_MIDIDEVS:
+ {
+ oss_renumber_t *r = (oss_renumber_t *) arg;
+ int i;
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+
+ if (r->n != num_mididevs) /* Wrong map size? */
+ return OSS_EINVAL;
+
+ for (i = 0; i < r->n; i++)
+ {
+ mididev_p mdev = midi_devs[i];
+
+ if (r->map[i] >= HARD_MAX_AUDIO_DEVFILES) /* May be unnecessary check */
+ return OSS_EINVAL;
+
+ mdev->real_dev = r->map[i];
+ }
+ }
+ return 0;
+ break;
+
+#ifdef CONFIG_OSS_VMIX
+ case VMIXCTL_ATTACH:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ return vmixctl_attach((vmixctl_attach_t*)arg);
+ break;
+
+ case VMIXCTL_DETACH:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ return vmixctl_detach((vmixctl_attach_t*)arg);
+ break;
+
+ case VMIXCTL_RATE:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ return vmixctl_rate((vmixctl_rate_t*)arg);
+ break;
+
+ case VMIXCTL_REMAP:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+ return vmixctl_map_channels((vmixctl_map_t *)arg);
+ break;
+
+#endif
+
+#if 0
+/*
+ * These calls are obsolete and disabled in current OSS version.
+ */
+ case OSSCTL_GET_REROUTE:
+ {
+ oss_reroute_t *r = (oss_reroute_t *) arg;
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ {
+ return OSS_EINVAL;
+ }
+#endif
+
+ switch (r->mode)
+ {
+ case OPEN_READ:
+ memcpy (&r->devlist, &dspinlist, sizeof (oss_devlist_t));
+ break;
+
+ case OPEN_WRITE:
+#ifdef MANAGE_DEV_DSP
+#ifdef VDEV_SUPPORT
+ oss_combine_write_lists ();
+#endif
+#endif
+ memcpy (&r->devlist, &dspoutlist, sizeof (oss_devlist_t));
+ break;
+
+ case OPEN_WRITE | OPEN_READ:
+ memcpy (&r->devlist, &dspinoutlist, sizeof (oss_devlist_t));
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+ }
+ return 0;
+ break;
+
+#if 0
+ case OSSCTL_SET_REROUTE:
+ {
+ oss_reroute_t *r = (oss_reroute_t *) arg;
+ int i, d;
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+
+ for (i = 0; i < r->devlist.ndevs; i++)
+ {
+ if ((d = r->devlist.devices[i]) < 0 || d >= num_audio_devfiles)
+ return OSS_EINVAL;
+ }
+
+ switch (r->mode)
+ {
+ case OPEN_READ:
+ /* Refuse if number of devices has changed */
+ if (!check_list (&r->devlist, &dspinlist))
+ {
+ return OSS_EINVAL;
+ }
+ memcpy (&dspinlist, &r->devlist, sizeof (oss_devlist_t));
+ break;
+
+ case OPEN_WRITE:
+#ifdef MANAGE_DEV_DSP
+#ifdef VDEV_SUPPORT
+ oss_combine_write_lists ();
+#endif
+#endif
+ /* Refuse if number of devices has changed */
+ if (!check_list (&r->devlist, &dspoutlist))
+ {
+ return OSS_EINVAL;
+ }
+ memcpy (&dspoutlist, &r->devlist, sizeof (oss_devlist_t));
+ dspoutlist2.ndevs = 0;
+ break;
+
+ case OPEN_WRITE | OPEN_READ:
+ /* Refuse if number of devices has changed */
+ if (!check_list (&r->devlist, &dspinoutlist))
+ {
+ return OSS_EINVAL;
+ }
+ memcpy (&dspinoutlist, &r->devlist, sizeof (oss_devlist_t));
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+ }
+ return 0;
+ break;
+#endif
+
+#ifdef APPLIST_SUPPORT
+ case OSSCTL_RESET_APPLIST:
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+
+ oss_applist_size = 0;
+ return 0;
+ break;
+
+ case OSSCTL_ADD_APPLIST:
+ {
+ app_routing_t *def, *parm = (app_routing_t *) arg;
+
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () != 0) /* Not root */
+ return OSS_EINVAL;
+#endif
+
+ if (oss_applist_size >= APPLIST_SIZE)
+ return OSS_ENOSPC;
+
+ if (parm->dev < -1 || parm->dev >= num_audio_devfiles)
+ return OSS_ENXIO;
+
+ def = &oss_applist[oss_applist_size];
+
+ memset (def, 0, sizeof (*def));
+ strcpy (def->name, parm->name);
+ def->mode = parm->mode & (OPEN_READ | OPEN_WRITE);
+ def->dev = parm->dev;
+ def->open_flags = parm->open_flags;
+ oss_applist_size++;
+ return 0;
+ }
+ break;
+
+#endif
+#endif
+ default:
+#if 0
+ if (mixer_devs[orig_dev]->d->ioctl != NULL)
+ return mixer_devs[orig_dev]->d->ioctl (orig_dev, -1, cmd, arg);
+#endif
+
+ return OSS_EINVAL;
+ }
+}
+
+/*ARGSUSED*/
+static int
+oss_mixer_open (int dev, int dev_type, struct fileinfo *file, int recursive,
+ int open_flags, int *newdev)
+{
+/*
+ * Permit opening nonexistent mixer so that certain mixer ioctl calls
+ * can be called. Other code must check that the devices really exist
+ * before permitting the calls.
+ */
+ if (dev >= 0 && dev < num_mixers)
+ return 0;
+
+ if (mixer_devs == NULL)
+ return 0;
+
+ if (mixer_devs[dev]->unloaded)
+ return OSS_ENODEV;
+
+ if (!mixer_devs[dev]->enabled)
+ return OSS_ENXIO;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+oss_mixer_release (int dev, struct fileinfo *file)
+{
+}
+
+/*ARGSUSED*/
+int
+oss_mixer_ioctl (int dev, struct fileinfo *bogus,
+ unsigned int cmd, ioctl_arg arg)
+{
+ int ret;
+
+ if (cmd == OSS_GETVERSION)
+ return *arg = OSS_VERSION;
+
+/*
+ * Handle SNDCTL_SYSINFO/CARDINFO/etc even if there are no mixer devices in the
+ * system.
+ */
+ switch (cmd)
+ {
+ case OSS_GETVERSION:
+ case SNDCTL_SYSINFO:
+ case SNDCTL_CARDINFO:
+ case SNDCTL_MIXERINFO:
+ case SNDCTL_MIDIINFO:
+ case SNDCTL_AUDIOINFO:
+ case SNDCTL_AUDIOINFO_EX:
+ case SNDCTL_ENGINEINFO:
+ case OSSCTL_RENUM_AUDIODEVS:
+ case OSSCTL_RENUM_MIXERDEVS:
+ case OSSCTL_RENUM_MIDIDEVS:
+ case SNDCTL_MIX_EXTINFO:
+ case SNDCTL_MIX_ENUMINFO:
+ case SNDCTL_MIX_READ:
+ case SNDCTL_MIX_WRITE:
+ case SNDCTL_MIX_NRMIX:
+ case SNDCTL_MIX_MATRIX_WRITE:
+ case SNDCTL_MIX_MATRIX_READ:
+ case VMIXCTL_ATTACH:
+ case VMIXCTL_DETACH:
+ case VMIXCTL_RATE:
+ return oss_mixer_ext (dev, OSS_DEV_MIXER, cmd, arg);
+ break;
+ }
+
+ if (dev < 0 || dev >= num_mixers)
+ {
+ return OSS_ENXIO;
+ }
+
+ if (mixer_devs == NULL)
+ {
+ return OSS_ENXIO;
+ }
+
+ if (!mixer_devs[dev]->enabled || mixer_devs[dev]->unloaded)
+ {
+ return OSS_ENODEV;
+ }
+
+ if ((ret = oss_legacy_mixer_ioctl (dev, -1, cmd, arg)) != OSS_EINVAL)
+ {
+ return ret;
+ }
+
+ return oss_mixer_ext (dev, OSS_DEV_MIXER, cmd, arg);
+}
+
+#ifdef DO_TIMINGS
+
+static char timing_buf[256 * 1024] = { 0 }, *timing_ptr = timing_buf;
+static int timing_prev_time = 0;
+int timing_flags = 0x7fffffff;
+
+#define TM_SCALE 256
+static oss_timing_timer_func tmfunc = NULL;
+static void *tmfunc_arg = NULL;
+
+void
+timing_install_timer (oss_timing_timer_func f, void *x)
+{
+ tmfunc = f;
+ tmfunc_arg = x;
+}
+
+static void
+oss_do_timing_ (char *txt)
+{
+ int l = strlen (txt) + 20;
+ oss_native_word flags;
+ oss_native_word this_time;
+
+ if (!timing_is_active) /* Nobody is listening */
+ return;
+
+ MUTEX_ENTER_IRQDISABLE (oss_timing_mutex, flags);
+ if ((long) (&timing_buf[sizeof (timing_buf)] - timing_ptr - 8) <= l)
+ {
+ MUTEX_EXIT_IRQRESTORE (oss_timing_mutex, flags);
+ return;
+ }
+
+ if (tmfunc != NULL)
+ {
+ this_time = tmfunc (tmfunc_arg);
+ }
+ else
+ {
+ this_time = 0; /* TODO: Get the actual audio pointer */
+
+ if (this_time == 0)
+ this_time = GET_JIFFIES ();
+ }
+
+ sprintf (timing_ptr, "%ld/%d: %s\n", this_time,
+ this_time - timing_prev_time, txt);
+ l = strlen (timing_ptr);
+ timing_ptr += l;
+ timing_prev_time = this_time;
+ MUTEX_EXIT_IRQRESTORE (oss_timing_mutex, flags);
+}
+
+typedef struct
+{
+ oss_native_word sum;
+ oss_native_word open_time;
+}
+timing_entry;
+
+static timing_entry timing_bins[DF_NRBINS];
+static oss_native_word timing_start = 0;
+
+static char *bin_names[DF_NRBINS] = {
+ "Iddle",
+ "Write",
+ "Read",
+ "Interrupt",
+ "Write sleep",
+ "Read sleep",
+ "Write SRC",
+ "Read SRC"
+};
+
+void
+timing_open (void)
+{
+ int i;
+
+ if (tmfunc == NULL)
+ return;
+ timing_start = tmfunc (tmfunc_arg) / TM_SCALE;
+
+ for (i = 0; i < DF_NRBINS; i++)
+ {
+ timing_bins[i].sum = 0;
+ timing_bins[i].open_time = 0xffffffff;
+ }
+
+}
+
+void
+timing_close (void)
+{
+ char tmp[64];
+ int i;
+ oss_native_word t, sum, pc;
+ if (tmfunc == NULL)
+ return;
+
+ t = tmfunc (tmfunc_arg) / TM_SCALE - timing_start;
+
+ sprintf (tmp, "Timing close, elapsed=%d", t);
+ oss_do_timing2 (DFLAG_PROFILE, tmp);
+
+ sum = 0;
+
+ for (i = 0; i < DF_NRBINS; i++)
+ {
+ sum += timing_bins[i].sum;
+ pc = (timing_bins[i].sum * 1000) / t;
+ sprintf (tmp, "Bin %s: %d/%d (%d.%d%%)", bin_names[i],
+ timing_bins[i].sum, pc, pc / 10, pc % 10);
+ oss_do_timing2 (DFLAG_PROFILE, tmp);
+ }
+
+ /* sum = sum-timing_bins[DF_SLEEPWRITE].sum-timing_bins[DF_SLEEPREAD].sum; */
+ pc = (sum * 10000) / t;
+
+ sprintf (tmp, "OSS Total: %d (%d.%d%%)", sum, pc / 100, pc % 100);
+ oss_do_timing2 (DFLAG_PROFILE, tmp);
+}
+
+void
+oss_timing_enter (int bin)
+{
+ if (tmfunc == NULL)
+ return;
+
+ timing_bins[bin].open_time = tmfunc (tmfunc_arg) / TM_SCALE;
+}
+
+void
+oss_timing_leave (int bin)
+{
+ oss_native_word t;
+
+ if (tmfunc == NULL)
+ return;
+
+ if (timing_bins[bin].open_time >= 0xfffffffe)
+ return;
+
+ t = tmfunc (tmfunc_arg) / TM_SCALE - timing_bins[bin].open_time;
+ timing_bins[bin].sum += t;
+ timing_bins[bin].open_time = 0xfffffffe;
+}
+
+void
+oss_do_timing (char *txt)
+{
+ if (!timing_is_active) /* Nobody is listening */
+ return;
+
+ if (timing_flags & DFLAG_ALL)
+ oss_do_timing_ (txt);
+}
+
+void
+oss_do_timing2 (int mask, char *txt)
+{
+ if (!timing_is_active) /* Nobody is listening */
+ return;
+
+ if ((timing_flags & DFLAG_ALL) || (timing_flags & mask))
+ oss_do_timing_ (txt);
+}
+
+void
+oss_timing_printf (char *s, ...)
+{
+ char tmp[1024], *a[6];
+ va_list ap;
+ int i, n = 0;
+
+ if (!timing_is_active) /* Nobody is listening */
+ return;
+
+ va_start (ap, s);
+
+ for (i = 0; i < strlen (s); i++)
+ if (s[i] == '%')
+ n++;
+
+ for (i = 0; i < n && i < 6; i++)
+ a[i] = va_arg (ap, char *);
+
+ for (i = n; i < 6; i++)
+ a[i] = NULL;
+
+ sprintf (tmp, s, a[0], a[1], a[2], a[3], a[4], a[5], NULL,
+ NULL, NULL, NULL);
+ oss_do_timing(tmp);
+
+ va_end (ap);
+}
+
+static int
+timing_read (int dev, struct fileinfo *file, uio_t * buf, int count)
+{
+ /*
+ * Return at most 'count' bytes from the status_buf.
+ */
+ int l;
+ oss_native_word flags;
+
+ timing_is_active = 1;
+
+ MUTEX_ENTER_IRQDISABLE (oss_timing_mutex, flags);
+
+ l = timing_ptr - timing_buf;
+ if (l <= 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (oss_timing_mutex, flags);
+ return 0;
+ }
+
+ if (l > count)
+ l = count;
+
+ timing_ptr = timing_buf;
+
+ MUTEX_EXIT_IRQRESTORE (oss_timing_mutex, flags);
+
+ if (uiomove (timing_buf, l, UIO_READ, buf) != 0)
+ cmn_err (CE_WARN, "audio: uiomove(UIO_READ) failed\n");
+
+ return l;
+}
+#else
+/*
+ * Dummy wrappers
+ */
+
+/*ARGSUSED*/
+void
+oss_timing_enter (int bin)
+{
+}
+
+/*ARGSUSED*/
+void
+oss_timing_leave (int bin)
+{
+}
+
+/*ARGSUSED*/
+void
+oss_do_timing (char *txt)
+{
+}
+
+/*ARGSUSED*/
+void
+oss_do_timing2 (int mask, char *txt)
+{
+}
+
+/*ARGSUSED*/
+void
+oss_timing_printf (char *s, ...)
+{
+}
+#endif
+
+static oss_cdev_drv_t mixer_cdev_drv = {
+ oss_mixer_open,
+ oss_mixer_release,
+#ifdef DO_TIMINGS
+ timing_read,
+#else
+ NULL, /* read */
+#endif
+ NULL, /* write */
+ oss_mixer_ioctl
+};
+
+int
+oss_install_mixer (int vers,
+ oss_device_t * osdev,
+ oss_device_t * master_osdev,
+ const char *name,
+ mixer_driver_t * driver, int driver_size, void *devc)
+{
+ mixer_operations_t *op = NULL;
+ mixer_driver_t *d;
+
+ int i, num;
+ char handle[32];
+
+ if (master_osdev == NULL)
+ master_osdev = osdev;
+
+ if (mixer_devs == NULL)
+ {
+ mixer_devs = PMALLOC (osdev, sizeof (mixdev_p) * MAX_MIXER_DEV);
+ memset (mixer_devs, 0, sizeof (mixdev_p) * MAX_MIXER_DEV);
+ mixer_devs_p = mixer_devs;
+ }
+
+ if (num_mixers >= MAX_MIXER_DEV - 1)
+ {
+ static int nnn = 0;
+ cmn_err (CE_WARN, "Too many mixer devices %d/%d (%s)\n",
+ num_mixers, MAX_MIXER_DEV, name);
+ /*
+ * In some special situations a driver may keep trying to install a mixer
+ * in infinite loop if the request fails. Stop this by panicking after
+ * this has continued for more than 50 times. In this case we can get an
+ * error message instead of having the system to lock up foreever.
+ */
+ if (nnn++ > 50)
+ cmn_err (CE_PANIC, "Killing runaway system.\n");
+ return OSS_EIO;
+ }
+
+ if (vers != OSS_MIXER_DRIVER_VERSION)
+ {
+ cmn_err (CE_WARN, "Incompatible mixer driver for %s\n", name);
+ return OSS_EIO;
+ }
+
+ if (driver_size > sizeof (mixer_driver_t))
+ driver_size = sizeof (mixer_driver_t);
+
+/*
+ * Check if this device was earlier unloaded and now returning back.
+ */
+ num = -1;
+ for (i = 0; i < num_mixers; i++)
+ {
+ if (mixer_devs[i]->unloaded
+ && mixer_devs[i]->os_id == oss_get_osid (osdev))
+ {
+ op = mixer_devs[i];
+ num = i;
+ break;
+ }
+ }
+
+ if ((d = PMALLOC (osdev, sizeof (*d))) == NULL)
+ {
+ cmn_err (CE_WARN, "Can't allocate mixer driver for (%s)\n", name);
+ return OSS_ENOSPC;
+ }
+
+ if (num == -1)
+ {
+ op = PMALLOC (osdev, sizeof (mixer_operations_t));
+ if (op == NULL)
+ {
+ cmn_err (CE_WARN, "Can't allocate mixer driver for (%s)\n", name);
+ return OSS_ENOSPC;
+ }
+
+ memset ((char *) op, 0, sizeof (mixer_operations_t));
+ num = num_mixers++;
+ sprintf (handle, "%s-mx%02d", osdev->handle, osdev->num_mixerdevs+1);
+ op->port_number = osdev->num_mixerdevs++;
+ }
+ else
+ {
+ strcpy (handle, op->handle); /* Preserve the previous handle */
+ }
+
+ memset ((char *) d, 0, sizeof (mixer_driver_t));
+ memcpy ((char *) d, (char *) driver, driver_size);
+ strcpy (op->handle, handle);
+ strcpy (op->id, osdev->nick);
+ op->d = d;
+
+ strncpy (op->name, name, sizeof (op->name));
+ op->name[sizeof (op->name) - 1] = 0;
+ op->devc = devc;
+ op->osdev = osdev;
+ op->os_id = oss_get_osid (osdev);
+ op->master_osdev = master_osdev;
+ op->hw_devc = NULL;
+ op->max_ext = op->nr_ext = 0;
+ op->names_checked = 0;
+ op->extensions = NULL;
+ op->timestamp = GET_JIFFIES ();
+ op->ignore_mask = 0;
+ op->card_number = osdev->cardnum;
+ op->enabled = 1;
+ op->unloaded = 0;
+ op->flags = 0;
+ op->caps = 0;
+ op->priority = 0; /* Normal (low) priority */
+ op->real_dev = num;
+
+ if (osdev->first_mixer == -1) /* Not defined yet */
+ osdev->first_mixer = num;
+
+ mixer_devs[num] = op;
+/*
+ * Create the device node
+ */
+
+ {
+ oss_devnode_t name;
+
+#ifdef NEW_DEVICE_NAMING
+# ifdef USE_DEVICE_SUBDIRS
+ sprintf (name, "oss/%s/mix%d", osdev->nick, osdev->num_mixerdevs - 1);
+# else
+ sprintf (name, "%s_mix%d", osdev->nick, osdev->num_mixerdevs - 1);
+# endif
+#else
+ sprintf (name, "mixer%d", num);
+#endif
+ oss_install_chrdev (osdev, name, OSS_DEV_MIXER, num, &mixer_cdev_drv, 0);
+ sprintf (op->devnode, "/dev/%s", name);
+
+#if 0
+ /*
+ * Moved to install_dev_mixer()
+ */
+ if (num == 0)
+ {
+ oss_install_chrdev (osdev, "mixer", OSS_DEV_MIXER, num,
+ &mixer_cdev_drv, 0);
+ }
+#endif
+ }
+
+ return num;
+}
+
+void
+install_dev_mixer (oss_device_t * osdev)
+{
+/*
+ * Install the default mixer node if necessary
+ */
+ oss_install_chrdev (osdev, "mixer", OSS_DEV_MIXER, 0, &mixer_cdev_drv, 0);
+}
diff --git a/kernel/framework/osscore/.config b/kernel/framework/osscore/.config
new file mode 100644
index 0000000..c10d582
--- /dev/null
+++ b/kernel/framework/osscore/.config
@@ -0,0 +1 @@
+bus=VIRTUAL
diff --git a/kernel/framework/osscore/oss_core_options.c b/kernel/framework/osscore/oss_core_options.c
new file mode 100644
index 0000000..9cbce31
--- /dev/null
+++ b/kernel/framework/osscore/oss_core_options.c
@@ -0,0 +1,73 @@
+/*
+ * Purpose: Configuration options for OSS (osscore.conf)
+ *
+ * Description:
+ * This file contains various configuration options for the osscore module.
+ * They can be set in the osscore.conf configuration file.
+ *
+ * Each option variable must also be defined as extern in the proper header
+ * file (of the subsystem that uses them) or in the source file that uses them.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 <oss_config.h>
+
+#ifndef NO_GLOBAL_OPTIONS
+/***********************************************************************************
+ ***********************************************************************************
+ ***********************************************************************************
+ ***********************************************************************************
+ * Core settings
+ *
+ * Remember to update kernel/drv/osscore/.params when adding, removing or
+ * changing the following options. The .params file is used when generating the
+ * driver.conf files. Also don't forget to update osscore.man.
+ *
+ * For Linux it's also necessary to add a module_param() line to Linux/osscore.c
+ * For FreeBSD it's also necessary to add a TUNABLE_INT() line to FreeBSD/osscore.c
+ ***********************************************************************************
+ ***********************************************************************************
+ ***********************************************************************************
+ ***********************************************************************************/
+
+int max_intrate = 100; /* 10 msec minimum interrupt interval */
+int src_quality = 3; /* Sample rate conversion quality (0-5) */
+int ac97_amplifier = -1; /* External amplifier enable for AC97 */
+int ac97_recselect = 0; /* Enables independent L/R ch rec source selection */
+int cooked_enable = 1;
+int dma_buffsize = 0; /* Size of the DMA buffer in kbytes (0=use default) */
+int flat_device_model = 0; /* 0=new audio device model, 1=old model */
+int detect_trace = 0; /* Se to 1 if detection tracing is required */
+int vmix_disabled = 0; /* 1=disable virtual mixer, 0=enable */
+int vmix_loopdevs = 0; /* Number of vmix loopback devices for all instances (0 to 2) */
+int vmix_no_autoattach = 0; /* Do not attach vmix devices during boot */
+int excl_policy = 0; /* Allow O_EXCL to occupy soundcard */
+int mixer_muted = 0; /* Set all mixer controls to a low level when OSS modules are loaded */
+
+oss_option_map_t oss_global_options[] = {
+ {"max_intrate", &max_intrate},
+ {"detect_trace", &detect_trace},
+ {"src_quality", &src_quality},
+ {"ac97_amplifier", &ac97_amplifier},
+ {"ac97_recselect", &ac97_recselect},
+ {"cooked_enable", &cooked_enable},
+ {"dma_buffsize", &dma_buffsize},
+ {"flat_device_model", &flat_device_model},
+ {"vmix_disabled", &vmix_disabled},
+ {"vmix_loopdevs", &vmix_loopdevs},
+ {"vmix_no_autoattach", &vmix_no_autoattach},
+ {"excl_policy", &excl_policy},
+ {"mixer_muted", &mixer_muted},
+ {NULL, NULL}
+};
+#endif
diff --git a/kernel/framework/osscore/oss_core_services.c b/kernel/framework/osscore/oss_core_services.c
new file mode 100644
index 0000000..f049b57
--- /dev/null
+++ b/kernel/framework/osscore/oss_core_services.c
@@ -0,0 +1,84 @@
+/*
+ * Purpose: Various global services for OSS.
+ *
+ * This source file contains some initialization and cleanup code
+ * that is called by the OS modules for all operating systems.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 <oss_config.h>
+#include "midi_core.h"
+
+#ifdef DO_TIMINGS
+extern oss_mutex_t oss_timing_mutex;
+#endif
+
+oss_history_t oss_history[OSS_HISTORY_SIZE] = { {0} };
+int oss_history_p = 0;
+
+int oss_num_cdevs = 0;
+oss_cdev_t **oss_cdevs = NULL;
+int oss_max_cdevs = 0;
+
+static int drivers_loaded = 0;
+
+void
+oss_unload_drivers (void)
+{
+
+ if (!drivers_loaded)
+ return;
+ drivers_loaded = 0;
+
+#ifdef CONFIG_OSS_VMIX
+ vmix_core_uninit ();
+#endif
+
+ oss_audio_uninit ();
+
+ /* oss_midi_uninit(); *//* TODO: This causes crashes */
+#ifdef DO_TIMINGS
+ MUTEX_CLEANUP (oss_timing_mutex);
+#endif
+
+ /*
+ * Release all global memory
+ */
+ oss_memblk_unalloc(&oss_global_memblk);
+}
+
+/*ARGSUSED*/
+void
+create_new_card (char *shortname, char *longname)
+{
+}
+
+void
+oss_common_init (oss_device_t * osdev)
+{
+ if (drivers_loaded)
+ return;
+#ifdef DO_TIMINGS
+ MUTEX_INIT (osdev, oss_timing_mutex, MH_TOP);
+#endif
+ drivers_loaded = 1;
+ oss_audio_init (osdev);
+ install_sndstat (osdev);
+ install_vdsp (osdev);
+ oss_midi_init (osdev);
+ install_vmidi (osdev);
+ install_dev_mixer (osdev);
+#ifdef CONFIG_OSS_VMIX
+ vmix_core_init (osdev);
+#endif
+}
diff --git a/kernel/framework/osscore/oss_memblk.c b/kernel/framework/osscore/oss_memblk.c
new file mode 100644
index 0000000..57da1d0
--- /dev/null
+++ b/kernel/framework/osscore/oss_memblk.c
@@ -0,0 +1,100 @@
+/*
+ * Purpose: OSS memory block allocation and management routines.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 <oss_config.h>
+
+struct _oss_memblk_t
+{
+ oss_memblk_t *next;
+ void *addr;
+};
+
+oss_memblk_t *oss_global_memblk=NULL;
+
+void
+*oss_memblk_malloc(oss_memblk_t **blk, int size)
+{
+ oss_memblk_t *newblk;
+
+ newblk = KERNEL_MALLOC (sizeof(oss_memblk_t) + size);
+
+ newblk->addr = newblk +1;
+ newblk->next = NULL;
+
+ if (*blk == NULL)
+ {
+ /*
+ * No earlier memory blocks in the chain.
+ */
+ *blk = newblk;
+ return newblk->addr;
+ }
+
+/*
+ * Add this block to the chain.
+ */
+ newblk->next = *blk;
+ *blk = newblk;
+
+ return newblk->addr;
+}
+
+void
+oss_memblk_free(oss_memblk_t **blk, void *addr)
+{
+ oss_memblk_t *this_one = *blk, *prev = NULL;
+
+ while (this_one != NULL)
+ {
+ if (this_one->addr == addr)
+ {
+ if (prev == NULL) /* First one in the chain */
+ {
+ *blk = this_one->next;
+ KERNEL_FREE (this_one);
+ }
+ else
+ {
+ prev->next = this_one->next;
+ KERNEL_FREE (this_one);
+ }
+
+ return;
+ }
+
+ this_one = this_one->next;
+ }
+}
+
+void
+oss_memblk_unalloc(oss_memblk_t **blk)
+{
+/*
+ * Free all memory allocations on the chain.
+ */
+ oss_memblk_t *this_one = *blk;
+
+ while (this_one != NULL)
+ {
+ oss_memblk_t *next_one;
+
+ next_one = this_one->next;
+
+ KERNEL_FREE(this_one);
+ this_one = next_one;
+ }
+
+ *blk = NULL;
+}
diff --git a/kernel/framework/remux/.config b/kernel/framework/remux/.config
new file mode 100644
index 0000000..46b59d2
--- /dev/null
+++ b/kernel/framework/remux/.config
@@ -0,0 +1 @@
+endian=LITTLE
diff --git a/kernel/framework/remux/oss_remux.c b/kernel/framework/remux/oss_remux.c
new file mode 100644
index 0000000..30dca71
--- /dev/null
+++ b/kernel/framework/remux/oss_remux.c
@@ -0,0 +1,544 @@
+/*
+ * Purpose: Multi channel playback support for devices with multiple stereo engines.
+ *
+ * Some sound cards don't provide single multi channel output engine. Instead
+ * they have multiple stereo output pairs connected to the front, side,
+ * center/LFE and rear speakers. The remux driver is used by such drivers to
+ * redistribute multi channel streams to the individual stereo engines.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+
+#ifndef USE_REMUX
+#error remux.c is not compatible with this architecture (endianess)
+#endif
+
+#ifdef OSS_BIG_ENDIAN
+void
+remux_install (char *name, oss_device_t * osdev, int frontdev, int reardev,
+ int center_lfe_dev, int surrounddev)
+{
+ /* Not compatible with big endian yet */
+}
+
+#else
+
+#include "remux.h"
+
+static char *chnames[MAX_SUBDEVS] = {
+ "Front",
+ "Surr",
+ "C&L",
+ "Rear"
+};
+
+static const int bindings[MAX_SUBDEVS] = {
+ DSP_BIND_FRONT,
+ DSP_BIND_SURR,
+ DSP_BIND_CENTER_LFE,
+ DSP_BIND_REAR
+};
+
+static remux_devc dev_info = { 0 }, *devc = &dev_info;
+
+/*
+ * Audio routines
+ */
+/*ARGSUSED*/
+static void
+remux_callback (int dev, int parm)
+{
+ oss_audio_outputintr (devc->audio_dev, 1);
+}
+
+static int
+remux_set_rate (int dev, int arg)
+{
+ remux_devc *devc = audio_engines[dev]->devc;
+
+ return devc->speed =
+ audio_engines[devc->physdev[0]]->d->adrv_set_rate (devc->physdev[0], arg);
+}
+
+static short
+remux_set_channels (int dev, short arg)
+{
+ remux_devc *devc = audio_engines[dev]->devc;
+
+ if (arg == 0)
+ return devc->channels;
+
+ arg &= ~1; /* Make sure we have even number of channels */
+
+ if (arg < 2)
+ return devc->channels = 2;
+ if (arg > devc->maxchannels)
+ return devc->channels = devc->maxchannels;
+
+ return devc->channels = arg;
+}
+
+/*ARGSUSED*/
+static unsigned int
+remux_set_format (int dev, unsigned int arg)
+{
+ return AFMT_S16_NE;
+}
+
+/*ARGSUSED*/
+static int
+remux_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static void remux_trigger (int dev, int state);
+
+static void
+remux_reset (int dev)
+{
+ remux_trigger (dev, 0);
+}
+
+/*ARGSUSED*/
+static int
+remux_open (int dev, int mode, int open_flags)
+{
+ remux_devc *devc = audio_engines[dev]->devc;
+ adev_p adev = audio_engines[devc->audio_dev];
+ oss_native_word flags;
+ int i, j, err;
+
+ if (mode & OPEN_READ)
+ {
+ cmn_err (CE_WARN, "Audio device %d cannot do recording\n", dev);
+ /* return OSS_ENOTSUP; */
+ }
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (devc->open_mode != 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return OSS_EBUSY;
+ }
+ devc->open_mode = mode;
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ for (i = 0; i < devc->n_physdevs; i++)
+ {
+ adev_p pdev = audio_engines[devc->physdev[i]];
+
+ devc->finfo[i].mode = OPEN_WRITE;
+ devc->finfo[i].acc_flags = 0;
+ if ((err =
+ oss_audio_open_engine (devc->physdev[i], OSS_DEV_DSP,
+ &devc->finfo[i], 1, OF_SMALLFRAGS,
+ NULL)) < 0)
+ {
+ for (j = 0; j < i; j++)
+ {
+ oss_audio_release (devc->physdev[j], &devc->finfo[j]);
+ }
+
+ devc->open_mode = 0;
+ return err;
+ }
+
+
+ strcpy (pdev->cmd, chnames[i]);
+ pdev->pid = 0;
+ pdev->cooked_enable = 0;
+
+ if (pdev->d->adrv_bind != NULL)
+ {
+ int b = bindings[i];
+ pdev->d->adrv_bind (pdev->engine_num, SNDCTL_DSP_BIND_CHANNEL,
+ (ioctl_arg) & b);
+ }
+
+ if (pdev->flags & ADEV_FIXEDRATE)
+ {
+ adev->flags |= ADEV_FIXEDRATE;
+ adev->fixed_rate = pdev->fixed_rate;
+ }
+ else
+ adev->flags &= ~(ADEV_FIXEDRATE);
+
+ }
+
+ devc->speed = 48000;
+ devc->channels = 2;
+ adev->cooked_enable = 0;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+remux_close (int dev, int mode)
+{
+ int i;
+ remux_devc *devc = audio_engines[dev]->devc;
+
+ for (i = 0; i < devc->n_physdevs; i++)
+ oss_audio_release (devc->physdev[i], &devc->finfo[i]);
+ devc->open_mode = 0;
+}
+
+#if 0
+static int sinebuf[48] = {
+
+ 0, 4276, 8480, 12539, 16383, 19947, 23169, 25995,
+ 28377, 30272, 31650, 32486, 32767, 32486, 31650, 30272,
+ 28377, 25995, 23169, 19947, 16383, 12539, 8480, 4276,
+ 0, -4276, -8480, -12539, -16383, -19947, -23169, -25995,
+ -28377, -30272, -31650, -32486, -32767, -32486, -31650, -30272,
+ -28377, -25995, -23169, -19947, -16383, -12539, -8480, -4276
+};
+#endif
+
+/*ARGSUSED*/
+static void
+remux_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+/*
+ * This routine does the actual de-interleaving of stereo pairs to the
+ * individual devices. All data movement is done based on sample pairs
+ * 2*16=32 bit (2*short=int). Native endianess (AFMT_S16_NE) is assumed.
+ */
+ adev_p adev = audio_engines[dev], pdev = audio_engines[devc->physdev[0]];
+ remux_devc *devc = adev->devc;
+ dmap_p dmap = adev->dmap_out, pdmap = pdev->dmap_out;
+
+ int ch, nc, nf = pdmap->nfrags;
+
+ int *inbuf;
+ int ptr, pos = 0;
+
+ ptr = ((unsigned long) dmap->byte_counter) % dmap->bytes_in_use;
+
+ inbuf = (int *) (dmap->dmabuf + ptr);
+
+ nc = devc->channels / 2;
+
+ for (ch = 0; ch < nc; ch++)
+ {
+ int *outbuf;
+ int i, ns;
+
+ pdev = audio_engines[devc->physdev[ch]];
+ pdmap = pdev->dmap_out;
+ if (ch == 0)
+ pos =
+ (pdmap->user_counter + pdmap->fragment_size) % pdmap->bytes_in_use;
+
+ outbuf = (int *) (pdmap->dmabuf + pos);
+
+ ns = dmap->fragment_size / (4 * nc);
+
+ for (i = 0; i < ns; i++)
+ {
+#if 0
+ static int p[MAX_SUBDEVS] = { 0 };
+
+ short *s = (short *) &outbuf[i];
+ s[0] = s[1] = sinebuf[p[ch]];
+ p[ch] = (p[ch] + 1) % 48;
+#else
+ outbuf[i] = inbuf[(i * nc) + ch];
+#endif
+ }
+
+ pdmap->user_counter += ns * 4;
+ }
+
+ if (pdmap->user_counter - pdmap->byte_counter <
+ pdmap->fragment_size * (nf / 2))
+ {
+ oss_audio_outputintr (devc->audio_dev, 1);
+ }
+}
+
+/*ARGSUSED*/
+static void
+remux_start_input (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+}
+
+static void
+remux_trigger (int dev, int state)
+{
+ remux_devc *devc = audio_engines[dev]->devc;
+
+ int i;
+
+ for (i = 0; i < devc->n_physdevs; i++)
+ {
+ int pd = devc->physdev[i];
+ adev_p pdev = audio_engines[pd];
+
+ pdev->d->adrv_trigger (pd, state);
+ if (state & PCM_ENABLE_OUTPUT)
+ pdev->dmap_out->flags |= DMAP_STARTED;
+ else
+ pdev->dmap_out->flags &= ~DMAP_STARTED;
+ }
+}
+
+/*ARGSUSED*/
+static int
+remux_prepare_for_input (int dev, int bsize, int bcount)
+{
+ return OSS_EIO;
+}
+
+static int
+remux_prepare_for_output (int dev, int bsize, int bcount)
+{
+ remux_devc *devc = audio_engines[dev]->devc;
+ adev_p adev = audio_engines[dev];
+ int i, err, tmp, nd;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ nd = devc->channels / 2;
+ bsize = 240; /* Must be divisible by 3*4 and 4*4 */
+
+ for (i = 0; i < devc->n_physdevs; i++)
+ {
+ int pd = devc->physdev[i];
+ adev_p pdev = audio_engines[pd];
+ dmap_p dmap = pdev->dmap_out;
+
+ tmp = pdev->d->adrv_set_format (pd, AFMT_S16_NE);
+ if (tmp != AFMT_S16_NE)
+ {
+ cmn_err (CE_NOTE, "remux: Bad sample format %x\n", tmp);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EIO;
+ }
+
+ tmp = pdev->d->adrv_set_channels (pd, 2);
+ if (tmp != 2)
+ {
+ cmn_err (CE_NOTE, "remux: Bad number of channels %d\n", tmp);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EIO;
+ }
+
+ tmp = pdev->d->adrv_set_rate (pd, devc->speed);
+ if (tmp != devc->speed)
+ {
+ cmn_err (CE_NOTE, "remux: Bad sample rate %d\n", tmp);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_EIO;
+ }
+
+ if (pdev->min_block > 0 && bsize < pdev->min_block)
+ bsize = pdev->min_block;
+ if (pdev->max_block > 0 && bsize > pdev->max_block)
+ bsize = pdev->max_block;
+
+ dmap->fragment_size = bsize;
+
+ bcount = dmap->buffsize / bsize;
+
+ dmap->bytes_in_use = bcount * bsize;
+ dmap->nfrags = bcount;
+
+ if ((err = pdev->d->adrv_prepare_for_output (pd, bsize, bcount)) < 0)
+ {
+ cmn_err (CE_WARN,
+ "remux: Preparing device #%d failed, error %d\n", pd, err);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return err;
+ }
+
+ if (dmap->dmabuf == NULL)
+ {
+ cmn_err (CE_WARN, "dmabuf==NULL\n");
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return OSS_ENOMEM;
+ }
+
+ memset (dmap->dmabuf, 0, dmap->buffsize);
+
+ if (i == 0)
+ dmap->audio_callback = remux_callback;
+ dmap->dma_mode = PCM_ENABLE_OUTPUT;
+ dmap->flags |= DMAP_PREPARED;
+ dmap->data_rate = devc->speed * 4;
+ }
+
+ adev->dmap_out->fragment_size = bsize * nd;
+ adev->dmap_out->nfrags =
+ adev->dmap_out->bytes_in_use / adev->dmap_out->fragment_size;
+ adev->dmap_out->nfrags &= ~1;
+
+ if (adev->dmap_out->nfrags < 2)
+ adev->dmap_out->nfrags = 2;
+ adev->dmap_out->bytes_in_use =
+ adev->dmap_out->fragment_size * adev->dmap_out->nfrags;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ return 0;
+}
+
+static audiodrv_t remux_driver = {
+ remux_open,
+ remux_close,
+ remux_output_block,
+ remux_start_input,
+ remux_ioctl,
+ remux_prepare_for_input,
+ remux_prepare_for_output,
+ remux_reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ remux_trigger,
+ remux_set_rate,
+ remux_set_format,
+ remux_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* remux_alloc_buffer */
+ NULL, /* remux_free_buffer */
+ NULL,
+ NULL,
+ NULL
+};
+
+static int
+check_physdev (int dev)
+{
+ adev_p adev = audio_engines[dev];
+
+ if (!(adev->oformat_mask & AFMT_S16_NE))
+ {
+ cmn_err (CE_NOTE,
+ "remux: Audio device %d doesn't support the 16 bit format\n",
+ dev);
+ return 0;
+ }
+
+ if (adev->flags & (ADEV_NOOUTPUT))
+ {
+ cmn_err (CE_NOTE, "remux: Audio device %d doesn't support output\n",
+ dev);
+ return 0;
+ }
+
+#if 0
+ if (!(adev->flags & ADEV_AUTOMODE))
+ {
+ cmn_err (CE_NOTE, "remux: Audio device %d doesn't support auto-mode\n",
+ dev);
+ return 0;
+ }
+#endif
+
+ return 1;
+}
+
+static int
+countdevs (int frontdev, int reardev, int center_lfe_dev, int surrounddev)
+{
+ if (frontdev < 0 || frontdev >= num_audio_engines)
+ return 0;
+ if (reardev < 0 || reardev >= num_audio_engines)
+ return 2;
+ if (center_lfe_dev < 0 || center_lfe_dev >= num_audio_engines)
+ return 4;
+ if (surrounddev < 0 || surrounddev >= num_audio_engines)
+ return 6;
+
+ return 8;
+}
+
+void
+remux_install (char *name, oss_device_t * osdev, int frontdev, int reardev,
+ int center_lfe_dev, int surrounddev)
+{
+ adev_p adev, pdev;
+ int n, i;
+
+ DDB (cmn_err (CE_CONT, "remux install %s: %d, %d, %d, %d\n",
+ name, frontdev, reardev, center_lfe_dev, surrounddev));
+
+ devc->osdev = osdev;
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV + 2);
+
+ n = countdevs (frontdev, reardev, center_lfe_dev, surrounddev);
+
+ if (n < 4)
+ {
+ cmn_err (CE_WARN, "remux: Bad devices (%d, %d, %d, %d)\n",
+ frontdev, reardev, center_lfe_dev, surrounddev);
+ return;
+ }
+
+ devc->maxchannels = n;
+ devc->n_physdevs = n / 2;
+ devc->physdev[0] = frontdev;
+ devc->physdev[1] = reardev;
+ devc->physdev[2] = center_lfe_dev;
+ devc->physdev[3] = surrounddev;
+
+ for (i = 0; i < devc->n_physdevs; i++)
+ if (!check_physdev (devc->physdev[i]))
+ return;
+
+ pdev = audio_engines[frontdev];
+
+ if ((devc->audio_dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ devc->osdev,
+ devc->osdev,
+ name,
+ &remux_driver,
+ sizeof (audiodrv_t),
+ ADEV_NOINPUT | ADEV_SPECIAL |
+ ADEV_DISABLE_VIRTUAL |
+ ADEV_NOSRC, AFMT_S16_NE, devc,
+ -1)) < 0)
+ {
+ devc->audio_dev = -1;
+ return;
+ }
+
+ adev = audio_engines[devc->audio_dev];
+
+ adev->devc = devc;
+ adev->min_channels = 2;
+ adev->max_channels = devc->maxchannels;
+ adev->min_rate = pdev->min_rate;
+ adev->max_rate = pdev->max_rate;
+ adev->rate_source = frontdev;
+ adev->caps |= DSP_CH_MULTI;
+ if (pdev->caps & PCM_CAP_FREERATE)
+ adev->caps |= PCM_CAP_FREERATE;
+
+ devc->open_mode = 0;
+}
+
+#endif
diff --git a/kernel/framework/sndstat/.config b/kernel/framework/sndstat/.config
new file mode 100644
index 0000000..e44f78f
--- /dev/null
+++ b/kernel/framework/sndstat/.config
@@ -0,0 +1 @@
+targetcpu=any
diff --git a/kernel/framework/sndstat/oss_sndstat.c b/kernel/framework/sndstat/oss_sndstat.c
new file mode 100644
index 0000000..82f4ff5
--- /dev/null
+++ b/kernel/framework/sndstat/oss_sndstat.c
@@ -0,0 +1,693 @@
+/*
+ * Purpose: /dev/sndstat driver
+ *
+ * Description:
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 <oss_config.h>
+#include <midi_core.h>
+
+static char *sndstat_buf = NULL;
+static int sndstat_len, sndstat_ptr;
+static volatile int sndstat_busy = 0;
+int riptide_notice = 0; /* The Riptide driver will set this to 1 */
+
+/*
+ * All kind of status messages
+ */
+#define MAX_MESSAGE 50
+static char *messages[MAX_MESSAGE];
+static int nmessages; /* # of display messages (/dev/sndstat) */
+
+static int
+put_status (const char *s)
+{
+ int l = strlen (s);
+
+ if (sndstat_len + l >= 4000)
+ return 0;
+
+ memcpy (&sndstat_buf[sndstat_len], s, l);
+ sndstat_len += l;
+
+ return 1;
+}
+
+static int
+put_status_int (unsigned int val, int radix)
+{
+ char buf[11], *rx = "%d";
+
+ if (!val)
+ return put_status ("0");
+
+ if (radix == 16)
+ rx = "%x";
+ sprintf (buf, rx, val);
+
+ return put_status (buf);
+}
+
+static void
+init_status (void)
+{
+ /*
+ * Write the status information to the sndstat_buf and update sndstat_len.
+ * There is a limit of 4000 bytes for the data.
+ */
+
+ int i, p, missing_devs = 0;
+ int notify = 0;
+ extern char *oss_license_string;
+
+ sndstat_ptr = 0;
+
+ put_status ("OSS " OSS_VERSION_STRING);
+ put_status (oss_license_string);
+ put_status (" (C) 4Front Technologies 1996-2011\n");
+
+ if (riptide_notice)
+ put_status ("RipTide Driver (C) 2000, Conexant Systems, Inc.\n");
+
+#ifdef LICENSED_VERSION
+ oss_print_license (put_status, put_status_int);
+#endif
+
+#ifdef OSS_CONFIG_OPTIONS
+ put_status ("\nSource configration options: ");
+ put_status (OSS_CONFIG_OPTIONS);
+ put_status ("\n");
+#endif
+
+#ifdef OSS_HG_INFO
+ put_status ("\nHg revision: ");
+ put_status (OSS_HG_INFO);
+ put_status ("\n");
+#endif
+
+ if (nmessages > 0)
+ {
+ put_status ("\n");
+
+ for (i = 0; i < nmessages; i++)
+ {
+ if (!put_status (messages[i]))
+ return;
+ }
+
+ put_status ("\n");
+ }
+
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+ {
+#if defined(__FreeBSD__)
+ extern char version[];
+#endif
+
+ put_status ("Kernel: ");
+ put_status (version);
+ put_status ("\n");
+ }
+#endif
+
+#if 0
+/*
+ * This code is obsolete and not functional at this moment.
+ */
+ if (!put_status ("\nDevice objects:\n"))
+ return;
+
+ for (i = 0; i < oss_num_cards; i++)
+ {
+ char tmp[256];
+
+ oss_get_cardinfo (i, tmp, sizeof (tmp) - 1);
+ if (!put_status (tmp))
+ return;
+ if (!put_status ("\n"))
+ return;
+ }
+
+#endif
+
+ if (!put_status ("\nAudio devices:\n"))
+ return;
+
+ missing_devs = 0;
+
+ if (audio_devfiles != NULL)
+ for (i = 0; i < MAX_AUDIO_DEVFILES +100 && missing_devs < 40; i++)
+ {
+ int j, d;
+#if 0
+ if (i < num_audio_devfiles)
+ if (audio_devfiles[i]->card_number != cardno)
+ {
+ put_status (" \n");
+ cardno = audio_devfiles[i]->card_number;
+ }
+#endif
+/*
+ * New device numbering scheme may have /dev/dsp# devices in different
+ * order than the order of devices in audio_devices[]. Find the right device
+ * based on the adev->real_dev number. Note that device numbering may have
+ * holes if devices have been removed after running ossdevlinks -f last time.
+ */
+ d = -1;
+ for (j = 0; j < num_audio_devfiles; j++)
+ {
+ if (audio_devfiles[j]->real_dev == i)
+ {
+ if (j != i)
+ notify = 1;
+ d = audio_devfiles[j]->audio_devfile;
+ break;
+ }
+ }
+
+ if (d == -1)
+ {
+ missing_devs++;
+ continue;
+ }
+
+ if (missing_devs > 0) /* There is a hole in numbering */
+ for (j = i - missing_devs; j < i; j++)
+ {
+ notify = 1;
+ if (!put_status_int (j, 10))
+ return;
+ if (!put_status (": (Undefined or removed device)\n"))
+ return;
+ }
+ missing_devs = 0;
+
+ if (!put_status_int (i, 10))
+ return;
+ if (!put_status (": "))
+ return;
+ if (!audio_devfiles[d]->enabled || audio_devfiles[d]->unloaded)
+ put_status ("(");
+
+ if (!put_status (audio_devfiles[d]->name))
+ return;
+ if (!audio_devfiles[d]->enabled || audio_devfiles[d]->unloaded)
+ put_status (")");
+
+ if ((audio_devfiles[d]->flags & ADEV_DUPLEX)
+ || (audio_devfiles[d]->flags & ADEV_NOINPUT)
+ || (audio_devfiles[d]->flags & ADEV_NOOUTPUT))
+ {
+ int nn = 0;
+
+ if (!put_status (" ("))
+ return;
+
+ if (audio_devfiles[d]->flags & ADEV_NOINPUT)
+ {
+ if (nn++)
+ put_status (",");
+ if (!put_status ("OUTPUT"))
+ return;
+ }
+
+ if (audio_devfiles[d]->flags & ADEV_NOOUTPUT)
+ {
+ if (nn++)
+ put_status (",");
+ if (!put_status ("INPUT"))
+ return;
+ }
+
+ if (audio_devfiles[d]->flags & ADEV_DUPLEX)
+ {
+ if (nn++)
+ put_status (",");
+ if (!put_status ("DUPLEX"))
+ return;
+ }
+ if (!put_status (")"))
+ return;
+ }
+
+ if (!put_status ("\n"))
+ return;
+
+ {
+ adev_t *adev = audio_devfiles[d];
+ int n = 0, single = 0;
+ if (adev->next_out == NULL)
+ single = 1;
+
+ while (adev != NULL)
+ {
+ if (adev->open_mode != 0)
+ {
+ if (i < 10)
+ {
+ if (!put_status (" "))
+ return;
+ }
+ else
+ {
+ if (!put_status (" "))
+ return;
+ }
+
+ if (single)
+ {
+ put_status ("Opened ");
+ if (adev->open_mode & OPEN_READ)
+ put_status ("IN");
+ if (adev->open_mode & OPEN_WRITE)
+ put_status ("OUT");
+ put_status (" by ");
+ }
+ else
+ {
+ put_status ("Engine ");
+ put_status_int (n + 1, 10);
+ put_status (" opened ");
+ if (adev->open_mode & OPEN_READ)
+ put_status ("IN");
+ if (adev->open_mode & OPEN_WRITE)
+ put_status ("OUT");
+ put_status (" by ");
+ }
+
+ if (adev->pid != -1 || *adev->label != 0)
+ {
+ if (*adev->label != 0)
+ {
+ if (!put_status (adev->label))
+ return;
+ if (!put_status ("/"))
+ return;
+ }
+
+ put_status_int (adev->pid, 10);
+ }
+ else
+ {
+ if (!put_status ("unknown application"))
+ return;
+ }
+
+ if (!put_status (" @ "))
+ return;
+ if (!put_status_int (adev->user_parms.rate, 10))
+ return;
+ if (!put_status ("/"))
+ return;
+ if (!put_status_int (adev->hw_parms.rate, 10))
+ return;
+ if (!put_status (" Hz"))
+ return;
+
+#if 1
+ if (!put_status (" Fragment: "))
+ return;
+
+ if (!put_status (audio_show_latency (adev->engine_num)))
+ return;
+#endif
+
+ if (!put_status ("\n"))
+ return;
+
+ if (*adev->song_name != 0)
+ {
+ if (i < 10)
+ {
+ if (!put_status (" "))
+ return;
+ }
+ else
+ {
+ if (!put_status (" "))
+ return;
+ }
+
+ if (!put_status ("Song name: "))
+ return;
+ if (!put_status (adev->song_name))
+ return;
+ if (!put_status ("\n"))
+ return;
+ }
+ }
+
+ adev = adev->next_out;
+ n++;
+ }
+ }
+ }
+
+#ifdef CONFIG_OSS_MIDI
+ if (!put_status ("\nMIDI devices:\n"))
+ return;
+
+ missing_devs = 0;
+ for (i = 0; i < MAX_MIDI_DEV * 2 && missing_devs < 16; i++)
+ {
+ int j, d = -1;
+
+ for (j = 0; j < num_mididevs; j++)
+ if (midi_devs[j]->real_dev == i)
+ {
+ d = j;
+ if (j != i)
+ notify = 1;
+ }
+
+ if (d == -1)
+ {
+ missing_devs++;
+ continue;
+ }
+
+ for (j = i - missing_devs; j < i; j++)
+ {
+ notify = 1;
+ if (!put_status_int (j, 10))
+ return;
+ if (!put_status (": (Unknown or removed device)\n"))
+ return;
+ }
+ missing_devs = 0;
+
+ if (!put_status_int (i, 10))
+ return;
+ if (!put_status (": "))
+ return;
+ if (!midi_devs[d]->enabled || midi_devs[d]->unloaded)
+ put_status ("(");
+ if (!put_status (midi_devs[d]->name))
+ return;
+ if (!midi_devs[d]->enabled || midi_devs[d]->unloaded)
+ put_status (")");
+ if (!put_status ("\n"))
+ return;
+
+ if (midi_devs[d]->pid != -1)
+ {
+ if (i < 10)
+ {
+ if (!put_status (" "))
+ return;
+ }
+ else
+ {
+ if (!put_status (" "))
+ return;
+ }
+ if (!put_status ("Open by "))
+ return;
+ if (!put_status_int (midi_devs[d]->pid, 10))
+ return;
+ if (*midi_devs[d]->cmd != 0)
+ {
+ if (!put_status ("/"))
+ return;
+ if (!put_status (midi_devs[d]->cmd))
+ return;
+ }
+ if (!put_status ("\n"))
+ return;
+ if (midi_devs[d]->d->ioctl)
+ {
+ oss_longname_t song_name;
+
+ if (midi_devs[d]->d->ioctl (d, SNDCTL_GETSONG,
+ (ioctl_arg) song_name) >= 0
+ && *song_name != 0)
+ {
+ if (!put_status (" Song name: "))
+ return;
+ if (!put_status (song_name))
+ return;
+ if (!put_status ("\n"))
+ return;
+ }
+ }
+ }
+ }
+#endif
+
+#if 0
+ /* TODO: No timer available at this moment */
+ if (!put_status ("\nTimers:\n"))
+ return;
+
+ for (i = 0; i < oss_num_timers; i++)
+ {
+ if (!put_status_int (i, 10))
+ return;
+ if (!put_status (": "))
+ return;
+ if (!put_status (oss_timer_devs[i]->info.name))
+ return;
+ if (!put_status ("\n"))
+ return;
+ }
+#endif
+
+ if (!put_status ("\nMixers:\n"))
+ return;
+
+ missing_devs = 0;
+
+ for (i = 0; i < MAX_MIXER_DEV * 2 && missing_devs < 10; i++)
+ {
+ int j, d = -1;
+
+ for (j = 0; j < num_mixers; j++)
+ if (mixer_devs[j]->real_dev == i)
+ {
+ if (j != i)
+ notify = 1;
+ d = j;
+ }
+
+ if (d == -1)
+ {
+ missing_devs++;
+ continue;
+ }
+
+ for (j = i - missing_devs; j < i; j++)
+ {
+ notify = 1;
+ if (!put_status_int (j, 10))
+ return;
+ if (!put_status (": (Uninstalled or removed device\n"))
+ return;
+ }
+ missing_devs = 0;
+
+ if (!put_status_int (i, 10))
+ return;
+ if (!put_status (": "))
+ return;
+
+ if (!mixer_devs[d]->enabled || mixer_devs[d]->unloaded)
+ if (!put_status ("("))
+ return;
+
+ if (!put_status (mixer_devs[d]->name))
+ return;
+
+ if (!mixer_devs[d]->enabled || mixer_devs[d]->unloaded)
+ if (!put_status (")"))
+ return;
+
+ if (!put_status ("\n"))
+ return;
+ }
+
+#if 1
+ p = 0;
+ for (i = 0; i < OSS_HISTORY_SIZE; i++)
+ if (*oss_history[i] != 0)
+ p++;
+
+ if (p > 0)
+#ifdef GET_PROCESS_UID
+ if (GET_PROCESS_UID () == 0)
+#endif
+ {
+ if (!put_status ("\nHistory:\n"))
+ return;
+
+ p = oss_history_p;
+
+ for (i = 0; i < OSS_HISTORY_SIZE; i++)
+ {
+ int ix = (p + i) % OSS_HISTORY_SIZE;
+
+ if (*oss_history[ix] == 0)
+ continue;
+
+ if (!put_status (oss_history[ix]))
+ return;
+ if (!put_status ("\n"))
+ return;
+ }
+ }
+#endif
+#if 0
+ if (!put_status
+ ("\n\nNOTICE! This /dev/sndstat file is obsolete - use the ossinfo command instead\n"))
+ return;
+#endif
+ if (notify)
+ {
+ if (!put_status
+ ("\n\nWARNING! Legacy device numbering in /dev/sndstat is different from actual device numbering\n"))
+ return;
+ }
+
+ put_status ("\n\nNOTICE! Device numbers shown above may be wrong.\n");
+ put_status (" Use the ossinfo command to find out the correct device names.\n");
+
+ sndstat_buf[sndstat_len] = 0;
+}
+
+void
+store_msg (char *msg)
+{
+ char *s;
+
+ if (strlen (msg) > 100 || nmessages >= MAX_MESSAGE)
+ return;
+
+ s = PMALLOC (NULL, strlen (msg) + 1);
+ if (s == NULL)
+ {
+ return;
+ }
+ strcpy (s, msg);
+ messages[nmessages++] = s;
+}
+
+static int
+read_status (uio_t * buf, int count)
+{
+ /*
+ * Return at most 'count' bytes from the sndstat_buf.
+ */
+ int l, c;
+
+ l = count;
+ c = sndstat_len - sndstat_ptr;
+
+ if (l > c)
+ l = c;
+ if (l <= 0)
+ return 0;
+
+ if (uiomove (&sndstat_buf[sndstat_ptr], l, UIO_READ, buf) != 0)
+ return OSS_EFAULT;
+ sndstat_ptr += l;
+
+ return l;
+}
+
+/*ARGSUSED*/
+static int
+sndstat_open (int dev, int dev_class, struct fileinfo *file,
+ int recursive, int open_flags, int *redirect)
+{
+ /* TODO: Concurrency control */
+ if (sndstat_busy)
+ return OSS_EBUSY;
+ sndstat_busy = 1;
+
+ if ((sndstat_buf = KERNEL_MALLOC (4096)) == NULL)
+ {
+ sndstat_busy = 0;
+ return OSS_ENOMEM;
+ }
+
+ sndstat_len = 0;
+ init_status ();
+ sndstat_ptr = 0;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+sndstat_close (int dev, struct fileinfo *file)
+{
+ KERNEL_FREE (sndstat_buf);
+ sndstat_buf = NULL;
+ sndstat_busy = 0;
+}
+
+/*ARGSUSED*/
+static int
+sndstat_read (int dev, struct fileinfo *file, uio_t * buf, int count)
+{
+ int l;
+ l = read_status (buf, count);
+ return l;
+}
+
+/*ARGSUSED*/
+static int
+sndstat_write (int dev, struct fileinfo *file, uio_t * buf, int count)
+{
+/*
+ * This dummy write routine will be used for some internal management purposes
+ * in the future. At this moment it just tells the osscore module that it
+ * should permit detaching itself.
+ */
+#ifdef sun
+ extern int oss_detach_enabled;
+ oss_detach_enabled = 1;
+ return count;
+#else
+ return OSS_EIO;
+#endif
+}
+
+/*ARGSUSED*/
+static int
+sndstat_ioctl (int dev, struct fileinfo *bogus,
+ unsigned int cmd, ioctl_arg arg)
+{
+ if (cmd == OSS_GETVERSION)
+ return *arg = OSS_VERSION;
+
+ return OSS_EINVAL;
+}
+
+static oss_cdev_drv_t sndstat_cdev_drv = {
+ sndstat_open,
+ sndstat_close,
+ sndstat_read,
+ sndstat_write,
+ sndstat_ioctl
+};
+
+void
+install_sndstat (oss_device_t * osdev)
+{
+ //static int already_installed=0;
+
+ // if (!already_installed++) // TODO: Is it necessaary to prevent loading sndstat multiple times?
+ oss_install_chrdev (osdev, "sndstat", OSS_DEV_STATUS, 0, &sndstat_cdev_drv,
+ 0);
+}
diff --git a/kernel/framework/uart401/.config b/kernel/framework/uart401/.config
new file mode 100644
index 0000000..4e00504
--- /dev/null
+++ b/kernel/framework/uart401/.config
@@ -0,0 +1 @@
+forgetcpu=armv5tel
diff --git a/kernel/framework/uart401/oss_uart401.c b/kernel/framework/uart401/oss_uart401.c
new file mode 100644
index 0000000..58945af
--- /dev/null
+++ b/kernel/framework/uart401/oss_uart401.c
@@ -0,0 +1,340 @@
+/*
+ * Purpose: MPU-401 (UART mode) driver
+ *
+ * This driver/library can be used by the drivers for devices that provide
+ * MPU-401 (UART) compatible interface.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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 "oss_config.h"
+#include "midi_core.h"
+
+#include "uart401.h"
+
+#define DATAPORT (devc->base)
+#define COMDPORT (devc->base+1)
+#define STATPORT (devc->base+1)
+
+static int
+uart401_status (uart401_devc * devc)
+{
+ return INB (devc->osdev, 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 (devc->osdev, cmd, COMDPORT);
+}
+static int
+uart401_read (uart401_devc * devc)
+{
+ return INB (devc->osdev, DATAPORT);
+}
+static void
+uart401_write (uart401_devc * devc, unsigned char byte)
+{
+ OUTB (devc->osdev, 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)
+{
+ unsigned char buf[128];
+ int l = 0;
+
+ while (input_avail (devc))
+ {
+ int dev;
+ unsigned char c;
+
+ c = uart401_read (devc);
+
+ dev = devc->my_dev;
+ if (midi_devs[dev]->input_callback != NULL)
+ midi_devs[dev]->input_callback (dev, c);
+
+ if (c == MPU_ACK)
+ devc->input_byte = c;
+ else if ((devc->opened & OPEN_READ))
+ {
+ buf[l++] = c;
+
+ if (l >= sizeof (buf)) /* Buffer full */
+ {
+ if (devc->save_input_buffer != NULL)
+ devc->save_input_buffer (devc->my_dev, buf, l);
+ l = 0;
+ }
+ }
+
+ if (l > 0)
+ {
+ if (devc->save_input_buffer != NULL)
+ devc->save_input_buffer (devc->my_dev, buf, l);
+ }
+ }
+}
+
+void
+uart401_irq (uart401_devc * devc)
+{
+ if (devc->base == 0)
+ {
+ /* cmn_err(CE_CONT, "uart401_irq: Bad base address\n"); */
+ return;
+ }
+
+ if (input_avail (devc))
+ {
+ uart401_input_loop (devc);
+ }
+}
+
+/*ARGSUSED*/
+static int
+uart401_open (int dev, int mode, oss_midi_inputbyte_t inputbyte,
+ oss_midi_inputbuf_t inputbuf, oss_midi_outputintr_t outputintr)
+{
+ uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
+
+ if (devc->opened)
+ {
+ return OSS_EBUSY;
+ }
+
+ while (input_avail (devc))
+ uart401_read (devc);
+
+ devc->save_input_buffer = inputbuf;
+ devc->opened = mode;
+ enter_uart_mode (devc);
+ devc->disabled = 0;
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+uart401_close (int dev, int mode)
+{
+ uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
+
+ reset_uart401 (devc);
+ oss_udelay (10);
+ enter_uart_mode (devc);
+ reset_uart401 (devc);
+ devc->save_input_buffer = NULL;
+ devc->opened = 0;
+}
+
+static int
+uart401_out (int dev, unsigned char midi_byte)
+{
+ int timeout;
+ uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
+ oss_native_word flags;
+
+ if (devc->disabled)
+ return 1;
+ /*
+ * Test for input since pending input seems to block the output.
+ */
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+
+ if (input_avail (devc))
+ uart401_input_loop (devc);
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+
+ /*
+ * Sometimes it takes about 130000 loops before the output becomes ready
+ * (After reset). Normally it takes just about 10 loops.
+ */
+
+ for (timeout = 13000; timeout > 0 && !output_ready (devc); timeout--);
+
+ if (!output_ready (devc))
+ {
+ return 0;
+ }
+
+ uart401_write (devc, midi_byte);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+uart401_ioctl (int dev, unsigned cmd, ioctl_arg arg)
+{
+ return OSS_EINVAL;
+}
+
+static midi_driver_t uart401_driver = {
+ uart401_open,
+ uart401_close,
+ uart401_ioctl,
+ uart401_out
+};
+
+static void
+enter_uart_mode (uart401_devc * devc)
+{
+ int ok, timeout;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, 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;
+
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+}
+
+static int
+reset_uart401 (uart401_devc * devc)
+{
+ int ok, timeout, n;
+ oss_native_word flags;
+
+ /*
+ * Send the RESET command. Try again if no success at the first time.
+ */
+ MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
+ 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)
+ uart401_input_loop (devc); /*
+ * Flush input before enabling interrupts
+ */
+ MUTEX_EXIT_IRQRESTORE (devc->mutex, flags);
+ return ok;
+}
+
+int
+uart401_init (uart401_devc * devc, oss_device_t * osdev, int base, char *name)
+{
+ int ok = 0;
+
+ DDB (cmn_err (CE_CONT, "Entered uart401_init(%x)\n", base));
+
+ devc->base = base;
+ devc->irq = 0;
+ devc->osdev = osdev;
+ MUTEX_INIT (devc->osdev, devc->mutex, MH_DRV + 3);
+ devc->running = 1;
+
+ devc->save_input_buffer = NULL;
+ devc->opened = 0;
+ devc->input_byte = 0;
+ devc->my_dev = 0;
+ devc->share_irq = 0;
+
+ ok = reset_uart401 (devc);
+
+ if (ok)
+ {
+ DDB (cmn_err (CE_CONT, "Reset UART401 OK\n"));
+ }
+ else
+ {
+ DDB (cmn_err
+ (CE_CONT, "Reset UART401 failed (no hardware present?).\n"));
+ DDB (cmn_err (CE_CONT, "mpu401 status %02x\n", uart401_status (devc)));
+ }
+
+ if (!ok)
+ {
+ return 0;
+ }
+
+ DDB (cmn_err (CE_CONT, "uart401 detected OK\n"));
+
+ enter_uart_mode (devc);
+
+ devc->my_dev = oss_install_mididev (OSS_MIDI_DRIVER_VERSION, "UART401", name, &uart401_driver, sizeof (midi_driver_t),
+ 0, devc, devc->osdev);
+ devc->opened = 0;
+#ifdef USE_POLLING
+ if (!timer_armed)
+ {
+ timer_armed = 1;
+ poll_interval = OSS_HZ / 10;
+ if (poll_interval < 1)
+ poll_interval = 1;
+ INIT_TIMER (uart401_timer, uart401_poll);
+ ACTIVATE_TIMER (uart401_timer, uart401_poll, poll_interval);
+ }
+#endif
+ return 1;
+}
+
+void
+uart401_disable (uart401_devc * devc)
+{
+#ifdef USE_POLLING
+ if (timer_armed)
+ {
+ timer_armed = 0;
+ REMOVE_TIMER (uart401_timer, uart401_poll);
+ }
+ else;
+#endif
+ if (!devc->running)
+ return;
+ reset_uart401 (devc);
+ devc->running = 0;
+}
diff --git a/kernel/framework/vmix_core/.config b/kernel/framework/vmix_core/.config
new file mode 100644
index 0000000..f6f2c2e
--- /dev/null
+++ b/kernel/framework/vmix_core/.config
@@ -0,0 +1 @@
+configcheck=VMIX
diff --git a/kernel/framework/vmix_core/db_scale.h b/kernel/framework/vmix_core/db_scale.h
new file mode 100644
index 0000000..3b23edd
--- /dev/null
+++ b/kernel/framework/vmix_core/db_scale.h
@@ -0,0 +1,45 @@
+/*
+ * Purpose: dB to linear conversion tables for vmix
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * Attenuation table for dB->linear conversion. Indexed in steps of 0.5 dB.
+ * Table size is 25 dB (first entry is handled as mute).
+ */
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+const float vmix_db_table[DB_SIZE + 1] = {
+ 0.0 /* MUTE */ , 0.0035481, 0.0039811, 0.0044668, 0.0050119,
+ 0.0056234, 0.0063096, 0.0070795, 0.0079433, 0.0089125,
+ 0.01, 0.01122, 0.012589, 0.014125, 0.015849,
+ 0.017783, 0.019953, 0.022387, 0.025119, 0.028184,
+ 0.031623, 0.035481, 0.039811, 0.044668, 0.050119,
+ 0.056234, 0.063096, 0.070795, 0.079433, 0.089125,
+ 0.1, 0.1122, 0.12589, 0.14125, 0.15849,
+ 0.17783, 0.19953, 0.22387, 0.25119, 0.28184,
+ 0.31623, 0.35481, 0.39811, 0.44668, 0.50119,
+ 0.56234, 0.63096, 0.70795, 0.79433, 0.89125,
+ 1.0 /* Full level */
+};
+#else
+/* #define VMIX_VOL_SCALE moved to vmix.h */
+const int vmix_db_table[DB_SIZE + 1] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3,
+ 4, 4, 5, 5, 6, 7, 8, 9, 10, 11,
+ 12, 14, 16, 18, 20, 22, 25, 28, 32, 36,
+ 40, 45, 50, 57, 64, 71, 80, 90, 101, 114,
+ 128
+};
+#endif
diff --git a/kernel/framework/vmix_core/outexport.inc b/kernel/framework/vmix_core/outexport.inc
new file mode 100644
index 0000000..6a28b3c
--- /dev/null
+++ b/kernel/framework/vmix_core/outexport.inc
@@ -0,0 +1,83 @@
+#ifdef CONFIG_OSS_VMIX_FLOAT
+/*
+ * Purpose: Local output buffer to device export routine for vmix (FP version)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+int i, ch, och;
+double vol;
+
+vol = vmix_db_table[eng->outvol / 5];
+
+for (ch = 0; ch < channels; ch++)
+ {
+ double vu;
+ float *chbuf;
+
+ och = eng->channel_order[ch];
+ op = (SAMPLE_TYPE *) outbuf;
+ op += och;
+
+ chbuf = chbufs[ch];
+
+ vu = eng->vu[och % 2];
+ vu = vu / 255.0;
+
+ for (i = 0; i < samples; i++)
+ {
+ double tmp;
+
+#if 0 && defined(SINE_DEBUG)
+ tmp = sine_table[sine_phase[ch]];
+ sine_phase[ch] = (sine_phase[ch] + 1 + ch / 2) % SINE_SIZE;
+#else
+ tmp = *chbuf++;
+#endif
+
+ tmp *= vol;
+
+/*
+ * Check for clipping. Decrease volume if necessary.
+ */
+ if (tmp < -1.0)
+ {
+ vol /= -tmp;
+ eng->outvol--;
+ tmp = -1.0;
+ }
+ else if (tmp > 1.0)
+ {
+ vol /= tmp;
+ eng->outvol--;
+ tmp = 1.0;
+ }
+
+ *op = VMIX_BYTESWAP ((SAMPLE_TYPE) (tmp * SAMPLE_RANGE));
+ op += channels;
+
+ /* VU meter */
+ if (tmp < 0.0)
+ tmp = -tmp;
+ if (tmp > vu)
+ vu = tmp;
+ }
+
+ if (och < 2)
+ {
+ vu = vu * 255.0;
+ eng->vu[och] = (int)vu;
+ }
+ }
+#else
+#include "outexport_int.inc"
+#endif
diff --git a/kernel/framework/vmix_core/outexport_int.inc b/kernel/framework/vmix_core/outexport_int.inc
new file mode 100644
index 0000000..074705f
--- /dev/null
+++ b/kernel/framework/vmix_core/outexport_int.inc
@@ -0,0 +1,78 @@
+/*
+ * Purpose: Local output buffer to device export routine for vmix (int)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+int i, ch, och;
+int vol;
+
+#define RANGE_MAX ((1<<24)-1)
+#define RANGE_MIN -(1<<24)
+
+vol = vmix_db_table[eng->outvol / 5];
+
+for (ch = 0; ch < channels; ch++)
+ {
+ int vu;
+ int *chbuf;
+
+ och = eng->channel_order[ch];
+ op = (SAMPLE_TYPE *) outbuf;
+ op += och;
+
+ chbuf = chbufs[ch];
+
+ vu = eng->vu[och % 2];
+ vu = vu * 65536;
+
+ for (i = 0; i < samples; i++)
+ {
+ int tmp;
+
+ tmp = *chbuf++;
+
+ tmp = (tmp * vol) / VMIX_VOL_SCALE;
+
+/*
+ * Check for clipping. Decrease volume if necessary.
+ */
+ if (tmp<RANGE_MIN)
+ {
+ tmp=RANGE_MIN;
+ eng->outvol -= 1;
+ vol /= 2;
+ }
+ else
+ if (tmp>RANGE_MAX)
+ {
+ tmp=RANGE_MAX;
+ eng->outvol -= 1;
+ vol /= 2;
+ }
+
+ *op = VMIX_BYTESWAP(INT_EXPORT(tmp));
+ op += channels;
+
+ /* VU meter */
+ if (tmp < 0)
+ tmp = -tmp;
+ if (tmp > vu)
+ vu = tmp;
+ }
+
+ if (och < 2)
+ {
+ vu = vu / 65536;
+ eng->vu[och] = vu;
+ }
+ }
diff --git a/kernel/framework/vmix_core/playmix.inc b/kernel/framework/vmix_core/playmix.inc
new file mode 100644
index 0000000..50d07f5
--- /dev/null
+++ b/kernel/framework/vmix_core/playmix.inc
@@ -0,0 +1,115 @@
+#ifdef CONFIG_OSS_VMIX_FLOAT
+/*
+ * Purpose: Application to local playback buffer import routine for vmix (FP)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * Mixing function for virtual devices
+ */
+
+vmix_mixer_t *mixer = portc->mixer;
+vmix_engine_t *eng = &mixer->play_engine;
+
+dmap_t *dmap = audio_engines[portc->audio_dev]->dmap_out;
+
+int frame_size;
+
+int inptr, inmax;
+int used_channels;
+int i, ch, nch;
+double vol;
+
+/*
+ * Initial setup
+ */
+
+frame_size = sizeof (*inp);
+
+inmax = dmap->bytes_in_use / frame_size;
+inptr = portc->play_dma_pointer / frame_size;
+
+inp = (BUFFER_TYPE) dmap->dmabuf;
+
+used_channels = portc->channels;
+if (used_channels > eng->channels)
+ used_channels = eng->channels;
+
+/* ignored_channels = portc->channels - used_channels; */
+
+/*
+ * Handle mono playback by playing the mono stream twice (for left and right ch)
+ */
+nch=used_channels;
+if (nch<2)nch=2;
+
+/*
+ * Do the mixing
+ */
+for (ch = 0; ch < nch; ch++)
+ {
+ int ip = inptr + (ch%used_channels);
+ double vu = portc->vu[ch % 2];
+ float *chbuf = eng->chbufs[ch+portc->play_choffs];
+
+ i = portc->volume[ch%2];
+ vol = vmix_db_table[i / 5];
+
+ vu = vu / 255.0;
+
+ for (i = 0; i < nsamples; i++)
+ {
+ double tmp;
+
+#if 0 && defined(SINE_DEBUG)
+ if (ch > 1)
+ tmp = 0.0;
+ else
+ tmp = sine_table[sine_phase[ch]];
+ sine_phase[ch] = (sine_phase[ch] + 1) % SINE_SIZE;
+#else
+ /*
+ * Convert the sample to right endianess.
+ */
+ tmp = VMIX_BYTESWAP (inp[ip]);
+ tmp = tmp * range;
+#endif
+ tmp = tmp * vol;
+
+ *chbuf++ += tmp;
+ ip = (ip + portc->channels) % inmax;
+
+ /* VU meter */
+ if (tmp < 0.0)
+ tmp = -tmp;
+ if (tmp > vu)
+ vu = tmp;
+ }
+
+ if (ch < 2)
+ { /* Save left/right VU meters */
+ vu = vu * 255.0;
+ portc->vu[ch] = (int)vu;
+ }
+ }
+
+/*
+ * Finally save the state variables
+ */
+
+portc->play_dma_pointer =
+ (portc->play_dma_pointer +
+ nsamples * frame_size * portc->channels) % dmap->bytes_in_use;
+#else
+#include "playmix_int.inc"
+#endif
diff --git a/kernel/framework/vmix_core/playmix_int.inc b/kernel/framework/vmix_core/playmix_int.inc
new file mode 100644
index 0000000..18e4815
--- /dev/null
+++ b/kernel/framework/vmix_core/playmix_int.inc
@@ -0,0 +1,102 @@
+/*
+ * Purpose: Application to local playback buffer import routine for vmix (int)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * Mixing function for virtual devices
+ */
+
+vmix_mixer_t *mixer = portc->mixer;
+vmix_engine_t *eng = &mixer->play_engine;
+
+dmap_t *dmap = audio_engines[portc->audio_dev]->dmap_out;
+
+int frame_size;
+
+int inptr, inmax;
+int used_channels;
+int i, ch, nch;
+int vol;
+
+/*
+ * Initial setup
+ */
+
+frame_size = sizeof (*inp);
+
+inmax = dmap->bytes_in_use / frame_size;
+inptr = portc->play_dma_pointer / frame_size;
+
+inp = (BUFFER_TYPE) dmap->dmabuf;
+
+used_channels = portc->channels;
+if (used_channels > eng->channels)
+ used_channels = eng->channels;
+
+/* ignored_channels = portc->channels - used_channels; */
+
+/*
+ * Handle mono playback by playing the mono stream twice (for left and right ch)
+ */
+nch=used_channels;
+if (nch<2)nch=2;
+
+/*
+ * Do the mixing
+ */
+for (ch = 0; ch < nch; ch++)
+ {
+ int ip = inptr + (ch%used_channels);
+ int vu = portc->vu[ch % 2];
+ int *chbuf = eng->chbufs[ch+portc->play_choffs];
+
+ i = portc->volume[ch%2];
+ vol = vmix_db_table[i / 5];
+
+ vu = vu * 65536;
+
+ for (i = 0; i < nsamples; i++)
+ {
+ int tmp;
+
+ /*
+ * Convert the sample to right endianess.
+ */
+ tmp = INT_OUTMIX(VMIX_BYTESWAP (inp[ip]));
+ tmp = (tmp * vol) / VMIX_VOL_SCALE;
+
+ *chbuf++ += tmp;
+ ip = (ip + portc->channels) % inmax;
+
+ /* VU meter */
+ if (tmp < 0)
+ tmp = -tmp;
+ if (tmp > vu)
+ vu = tmp;
+ }
+
+ if (ch < 2)
+ { /* Save left/right VU meters */
+ vu = vu / 65536;
+ portc->vu[ch] = vu;
+ }
+ }
+
+/*
+ * Finally save the state variables
+ */
+
+portc->play_dma_pointer =
+ (portc->play_dma_pointer +
+ nsamples * frame_size * portc->channels) % dmap->bytes_in_use;
diff --git a/kernel/framework/vmix_core/playmix_src.inc b/kernel/framework/vmix_core/playmix_src.inc
new file mode 100644
index 0000000..1877c34
--- /dev/null
+++ b/kernel/framework/vmix_core/playmix_src.inc
@@ -0,0 +1,152 @@
+/*
+ * Purpose: Application to local playback buffer resampling routine for vmix
+ *
+ * This file is almost the same than playmix.inc but uses simple
+ * linear interpolation algorithm for sample rate conversion.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+/*
+ * Mixing function for virtual devices
+ */
+
+vmix_mixer_t *mixer = portc->mixer;
+vmix_engine_t *eng = &mixer->play_engine;
+
+dmap_t *dmap = audio_engines[portc->audio_dev]->dmap_out;
+
+int frame_size;
+
+int inptr, inmax;
+int used_channels;
+int i, ch, nch;
+double vol, step;
+double tmp;
+
+/*
+ * Initial setup
+ */
+step = (double) portc->rate / (double) mixer->play_engine.rate;
+
+#if 1
+/*
+ * TODO:
+ * For some reason "trivial" conversion rations such as 4:1, 2:1, 1:2 and 1:4
+ * don't work properly. As a workaround we add a tiny error to break the
+ * evil ratio. Need to find out why the algorithm doesn't work with such ratios.
+ */
+ if (step==4.0)step=4.0001;
+ if (step==2.0)step=2.0001;
+ if (step==0.5)step=0.5001;
+ if (step==0.25)step=0.25001;
+#endif
+
+frame_size = sizeof (*inp);
+
+inmax = dmap->bytes_in_use / frame_size / portc->channels;
+inptr = (int)(portc->play_dma_pointer_src / frame_size / portc->channels);
+
+used_channels = portc->channels;
+if (used_channels > eng->channels)
+ used_channels = eng->channels;
+
+/* ignored_channels = portc->channels - used_channels; */
+
+/*
+ * Handle mono playback by playing the mono stream twice (for left and right ch)
+ */
+nch=used_channels;
+if (nch<2)nch=2;
+
+/*
+ * Do the mixing
+ */
+for (ch = 0; ch < nch; ch++)
+ {
+ double ip = inptr + (ch%used_channels);
+ double vu = portc->vu[ch % 2];
+ float *chbuf = eng->chbufs[ch+portc->play_choffs];
+
+ inp = (BUFFER_TYPE) dmap->dmabuf;
+ inp += ch;
+
+ i = portc->volume[ch%2];
+ vol = vmix_db_table[i / 5];
+
+ vu = vu / 255.0;
+
+ for (i = 0; i < nsamples; i++)
+ {
+ double frag, tmp_next;
+ int ip_next;
+
+#if 0 && defined(SINE_DEBUG)
+ if (ch > 1)
+ tmp = 0.0;
+ else
+ tmp = sine_table[sine_phase[ch]];
+ sine_phase[ch] = (sine_phase[ch] + 1) % SINE_SIZE;
+#else
+ /*
+ * Convert the sample to right endianess.
+ */
+ tmp = VMIX_BYTESWAP (inp[((int) ip) * portc->channels]);
+
+ /* perform linear interpolation */
+ ip_next = (((int) ip) + 1) % inmax;
+ tmp_next = VMIX_BYTESWAP (inp[ip_next * portc->channels]);
+ frag = ip - (int) ip; /* Pointer fraction */
+ tmp += (tmp_next - tmp) * frag;
+ tmp /= 2.0;
+
+ tmp = tmp * range;
+#endif
+ tmp = tmp * vol;
+
+ *chbuf++ += tmp;
+ ip = ip + step;
+ if (ip > inmax)
+ ip -= inmax;
+
+ /* VU meter */
+ if (tmp < 0.0)
+ tmp = -tmp;
+ if (tmp > vu)
+ vu = tmp;
+ }
+
+ if (ch < 2)
+ { /* Save left/right VU meters */
+ vu = vu * 255.0;
+ portc->vu[ch] = (int)vu;
+ }
+ }
+
+/*
+ * Finally save the state variables
+ */
+tmp = (nsamples * frame_size * portc->channels);
+
+tmp *= step;
+
+portc->play_dma_pointer_src = portc->play_dma_pointer_src + tmp;
+
+if (portc->play_dma_pointer_src > dmap->bytes_in_use)
+ portc->play_dma_pointer_src -= dmap->bytes_in_use;
+
+portc->play_dma_pointer = (int)portc->play_dma_pointer_src;
+
+frame_size *= portc->channels;
+
+portc->play_dma_pointer = (portc->play_dma_pointer / frame_size) * frame_size;
+
diff --git a/kernel/framework/vmix_core/rec_export.inc b/kernel/framework/vmix_core/rec_export.inc
new file mode 100644
index 0000000..a8ac880
--- /dev/null
+++ b/kernel/framework/vmix_core/rec_export.inc
@@ -0,0 +1,76 @@
+#ifdef CONFIG_OSS_VMIX_FLOAT
+/*
+ * Purpose: Local input buffer to application export routine for vmix (FP version)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+vmix_mixer_t *mixer = portc->mixer;
+vmix_engine_t *eng = &mixer->record_engine;
+
+dmap_t *dmap = audio_engines[portc->audio_dev]->dmap_in;
+
+int frame_size;
+
+int outptr, outmax;
+int used_channels;
+int i, ch;
+
+/*
+ * Initial setup
+ */
+
+frame_size = sizeof (*outp);
+
+outmax = dmap->bytes_in_use / frame_size;
+outptr = portc->rec_dma_pointer / frame_size;
+
+outp = (BUFFER_TYPE) dmap->dmabuf;
+
+used_channels = portc->channels;
+if (used_channels > eng->channels)
+ used_channels = eng->channels;
+
+/* ignored_channels = portc->channels - used_channels; */
+
+/*
+ * Do the mixing
+ */
+for (ch = 0; ch < used_channels; ch++)
+ {
+ int op = outptr + ch;
+ float *chbuf = eng->chbufs[ch+portc->rec_choffs];
+
+ for (i = 0; i < nsamples; i++)
+ {
+ float tmp;
+
+ tmp = *chbuf++;
+ /*
+ * Convert the sample to right endianess.
+ */
+ outp[op] = VMIX_BYTESWAP ((int)(tmp * range));
+
+ op = (op + portc->channels) % outmax;
+ }
+ }
+
+/*
+ * Finally save the state variables
+ */
+
+portc->rec_dma_pointer =
+ (portc->rec_dma_pointer +
+ nsamples * frame_size * portc->channels) % dmap->bytes_in_use;
+#else
+#include "rec_export_int.inc"
+#endif
diff --git a/kernel/framework/vmix_core/rec_export_int.inc b/kernel/framework/vmix_core/rec_export_int.inc
new file mode 100644
index 0000000..3a9953d
--- /dev/null
+++ b/kernel/framework/vmix_core/rec_export_int.inc
@@ -0,0 +1,72 @@
+/*
+ * Purpose: Local input buffer to application export routine for vmix (int)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+vmix_mixer_t *mixer = portc->mixer;
+vmix_engine_t *eng = &mixer->record_engine;
+
+dmap_t *dmap = audio_engines[portc->audio_dev]->dmap_in;
+
+int frame_size;
+
+int outptr, outmax;
+int used_channels;
+int i, ch;
+
+/*
+ * Initial setup
+ */
+
+frame_size = sizeof (*outp);
+
+outmax = dmap->bytes_in_use / frame_size;
+outptr = portc->rec_dma_pointer / frame_size;
+
+outp = (BUFFER_TYPE) dmap->dmabuf;
+
+used_channels = portc->channels;
+if (used_channels > eng->channels)
+ used_channels = eng->channels;
+
+/* ignored_channels = portc->channels - used_channels; */
+
+/*
+ * Do the mixing
+ */
+for (ch = 0; ch < used_channels; ch++)
+ {
+ int op = outptr + ch;
+ int *chbuf = eng->chbufs[ch+portc->rec_choffs];
+
+ for (i = 0; i < nsamples; i++)
+ {
+ int tmp;
+
+ tmp = *chbuf++;
+ /*
+ * Convert the sample to right endianess.
+ */
+ outp[op] = VMIX_BYTESWAP (INT_EXPORT(tmp));
+
+ op = (op + portc->channels) % outmax;
+ }
+ }
+
+/*
+ * Finally save the state variables
+ */
+
+portc->rec_dma_pointer =
+ (portc->rec_dma_pointer +
+ nsamples * frame_size * portc->channels) % dmap->bytes_in_use;
diff --git a/kernel/framework/vmix_core/vmix.h b/kernel/framework/vmix_core/vmix.h
new file mode 100644
index 0000000..a01c722
--- /dev/null
+++ b/kernel/framework/vmix_core/vmix.h
@@ -0,0 +1,242 @@
+/*
+ * Purpose: Definitions for the vmix driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define SUPPORTED_FORMATS (AFMT_S16_NE | AFMT_S16_OE | AFMT_S32_NE | AFMT_S32_OE)
+
+/*
+ * Maximum number of clients per "real" device is defined by MAX_CLIENTS. Limit of 4 would be good for 95% of systems.
+ * For each client there will be a mixer volume control and peak meter in the mixer interface. Raising the
+ * client limit will make the mixer interface larger and larger. Something like 8 is probably the practical limit
+ * for number of clients.
+ *
+ * Mixing more than 16 streams together doesn't make much sense since the result is likely to be
+ * just noise. Mixing a stream will cause some overhead so it's not a good idea to let large number of iddle
+ * applications running muted or playing silence.
+ */
+
+#define MAX_CLIENTS 9
+
+#define MAX_LOOPDEVS 2 /* Maximum number of vmix loopback devices */
+
+/*
+ * 8 play channels and 2 rec channels might be OK for most devices. However envy24 requires 10 play and 12 rec
+ * channels for the "raw devices". Some professional (ADAT) cards like Digi96 requires 8+8 channels.
+ */
+#define MAX_PLAY_CHANNELS 12
+/* MAX_REC_CHANNELS must be less or equal than MAX_PLAY_CHANNELS */
+#define MAX_REC_CHANNELS 12
+
+#define CHBUF_SAMPLES 2048 /* Max samples (frames) per fragment */
+
+typedef struct _vmix_mixer_t vmix_mixer_t;
+typedef struct _vmix_portc_t vmix_portc_t;
+typedef struct _vmix_engine_t vmix_engine_t;
+typedef unsigned char vmix_channel_map_t[MAX_PLAY_CHANNELS];
+
+struct _vmix_portc_t /* Audio device specific data */
+{
+ int num;
+ vmix_mixer_t *mixer;
+ vmix_portc_t *next; /* Linked list for all portc structures */
+ int dev_type;
+#define DT_IN 1
+#define DT_OUT 2
+#define DT_LOOP 3
+
+ int disabled_modes;
+
+ int fmt, bits;
+ int channels;
+ int rate;
+
+ int audio_dev;
+ int open_mode;
+ int trigger_bits;
+
+ int open_pending; /* Set to 1 by vmix_create_client() and cleared by vmix_open() */
+
+ int play_dma_pointer;
+ int play_choffs; /* Index of the first channel on multich play engines */
+ int rec_choffs; /* Index of the first channel on multich rec engines */
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ double play_dma_pointer_src;
+#endif
+ int rec_dma_pointer;
+ int volume[2]; /* Left and right ch volumes */
+ int vu[2];
+
+ void (*play_mixing_func) (vmix_portc_t * portc, int nsamples);
+ void (*rec_mixing_func) (vmix_portc_t * portc, int nsamples);
+ int do_src;
+ vmix_channel_map_t channel_order;
+};
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ typedef float vmix_sample_t;
+#else
+ typedef int vmix_sample_t;
+#endif
+
+typedef void (*converter_t) (vmix_engine_t * engine, void *outbuf,
+ vmix_sample_t * chbufs[], int channels,
+ int samples);
+
+struct _vmix_engine_t
+{
+ int rate, channels, fmt, bits;
+ int max_playahead;
+ int fragsize;
+ int samples_per_frag;
+
+ converter_t converter;
+ vmix_sample_t *chbufs[MAX_PLAY_CHANNELS];
+ unsigned int limiter_statevar;
+
+/*
+ * Mixer volumes, etc.
+ */
+ int outvol;
+ int vu[2];
+ int num_active_outputs;
+ vmix_channel_map_t channel_order;
+};
+
+struct _vmix_mixer_t /* Instance specific data */
+{
+ vmix_mixer_t *next; /* Pointer to the next vmix instance */
+ int instance_num;
+ int disabled;
+ oss_device_t *osdev;
+ oss_device_t *master_osdev;
+ oss_mutex_t mutex;
+ unsigned int attach_flags;
+
+ int installed_ok;
+
+ int open_devices, open_inputs;
+ struct fileinfo master_finfo, input_finfo;
+ int masterdev_opened;
+
+ int vmix_flags; /* Copy of adev[master]->vmix_flags */
+
+/*
+ * Config options for this instance
+ */
+ int masterdev;
+ int inputdev;
+ int rate;
+
+ int src_quality; /* Control panel setting */
+ int multich_enable; /* Enable multi channel mode */
+ int max_channels;
+
+ vmix_engine_t play_engine, record_engine;
+
+ vmix_portc_t *client_portc[MAX_CLIENTS];
+ vmix_portc_t *loop_portc[MAX_LOOPDEVS];
+ int num_clientdevs, num_loopdevs;
+
+/*
+ * Mixer interface
+ *
+ * Mixer device numbers for the master audio devices
+ */
+ int output_mixer_dev;
+ int input_mixer_dev;
+ int first_input_mixext;
+ int first_output_mixext;
+ int client_mixer_group; /* Create the client controls under this mixer group */
+};
+
+extern void vmix_setup_play_engine (vmix_mixer_t * mixer, adev_t * adev,
+ dmap_t * dmap);
+extern void vmix_setup_record_engine (vmix_mixer_t * mixer, adev_t * adev,
+ dmap_t * dmap);
+extern void finalize_record_engine (vmix_mixer_t * mixer, int fmt,
+ adev_t * adev, dmap_p dmap);
+
+extern void vmix_outmix_16ne (vmix_portc_t * portc, int nsamples);
+extern void vmix_outmix_16oe (vmix_portc_t * portc, int nsamples);
+extern void vmix_outmix_32ne (vmix_portc_t * portc, int nsamples);
+extern void vmix_outmix_32oe (vmix_portc_t * portc, int nsamples);
+#ifdef CONFIG_OSS_VMIX_FLOAT
+extern void vmix_outmix_float (vmix_portc_t * portc, int nsamples);
+#endif
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+/*
+ * For the time being these routines will only work in floating point.
+ */
+extern void vmix_outmix_16ne_src (vmix_portc_t * portc, int nsamples);
+extern void vmix_outmix_16oe_src (vmix_portc_t * portc, int nsamples);
+extern void vmix_outmix_32ne_src (vmix_portc_t * portc, int nsamples);
+extern void vmix_outmix_32oe_src (vmix_portc_t * portc, int nsamples);
+extern void vmix_outmix_float_src (vmix_portc_t * portc, int nsamples);
+#endif
+
+extern void vmix_rec_export_16ne (vmix_portc_t * portc, int nsamples);
+extern void vmix_rec_export_16oe (vmix_portc_t * portc, int nsamples);
+extern void vmix_rec_export_32ne (vmix_portc_t * portc, int nsamples);
+extern void vmix_rec_export_32oe (vmix_portc_t * portc, int nsamples);
+#ifdef CONFIG_OSS_VMIX_FLOAT
+extern void vmix_rec_export_float (vmix_portc_t * portc, int nsamples);
+#endif
+
+#define DB_SIZE 50
+#define VMIX_VOL_SCALE 127
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ extern const float vmix_db_table[DB_SIZE + 1];
+#else
+ extern const int vmix_db_table[DB_SIZE + 1];
+#endif
+
+#ifdef VMIX_MAIN
+#include "db_scale.h"
+#endif
+
+#ifdef SWAP_SUPPORT
+/*
+ * Endianess swapping functions
+ */
+static __inline__ short
+bswap16 (short x)
+{
+ short y = 0;
+ unsigned char *a = ((unsigned char *) &x) + 1;
+ unsigned char *b = (unsigned char *) &y;
+
+ *b++ = *a--;
+ *b++ = *a--;
+
+ return y;
+}
+
+static __inline__ int
+bswap32 (int x)
+{
+
+ int y = 0;
+ unsigned char *a = ((unsigned char *) &x) + 3;
+ unsigned char *b = (unsigned char *) &y;
+
+ *b++ = *a--;
+ *b++ = *a--;
+ *b++ = *a--;
+ *b++ = *a--;
+
+ return y;
+}
+#endif
diff --git a/kernel/framework/vmix_core/vmix_core.c b/kernel/framework/vmix_core/vmix_core.c
new file mode 100644
index 0000000..d74499f
--- /dev/null
+++ b/kernel/framework/vmix_core/vmix_core.c
@@ -0,0 +1,2352 @@
+/*
+ * Purpose: Viartual audio mixing framework
+ *
+ * This subsystem makes it possible to share one physical audio between
+ * multiple applications at the same time.
+ *
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define VMIX_MAIN
+#include <oss_config.h>
+#include "vmix.h"
+
+extern int vmix_disabled; /* Configuration option (osscore.conf) */
+extern int vmix_loopdevs; /* Configuration option (osscore.conf) */
+extern int flat_device_model;
+extern int vmix_no_autoattach;
+static vmix_mixer_t *mixer_list = NULL; /* List of all currently installed mixer instances */
+static int num_instances = 0;
+
+static const unsigned char peak_cnv[256] = {
+ 0, 18, 29, 36, 42, 47, 51, 54, 57, 60, 62, 65, 67, 69, 71, 72,
+ 74, 75, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 89, 90,
+ 91, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 100, 101,
+ 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108,
+ 108,
+ 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 113, 113, 113, 114, 114,
+ 114,
+ 115, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 118, 119,
+ 119,
+ 119, 119, 120, 120, 120, 121, 121, 121, 121, 122, 122, 122, 122, 122, 123,
+ 123,
+ 123, 123, 124, 124, 124, 124, 125, 125, 125, 125, 125, 126, 126, 126, 126,
+ 126,
+ 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 129, 129, 129, 129, 129,
+ 130,
+ 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132,
+ 132,
+ 132, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 135,
+ 135,
+ 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 137, 137, 137,
+ 137,
+ 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139,
+ 139,
+ 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141,
+ 141,
+ 141, 141, 141, 141, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143,
+ 143,
+ 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, 144, 144, 144,
+ 144,
+};
+
+/*
+ * Mixer/control panel interface
+ */
+static int
+vmix_outvol (int dev, int ctrl, unsigned int cmd, int value)
+{
+ vmix_mixer_t *mixer = mixer_devs[dev]->vmix_devc;
+ int vol;
+
+ if (mixer == NULL)
+ return OSS_ENXIO;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ switch (ctrl)
+ {
+ case 0: /* Main output volume */
+ return mixer->play_engine.outvol | (mixer->play_engine.
+ outvol << 16);
+ break;
+
+ case 1: /* Peak meter */
+ vol =
+ peak_cnv[mixer->play_engine.
+ vu[0]] | (peak_cnv[mixer->play_engine.vu[1]] << 8);
+ mixer->play_engine.vu[0] = 0;
+ mixer->play_engine.vu[1] = 0;
+ return vol;
+ break;
+
+ case 509: /* Curren sample rate */
+ return mixer->rate;
+ break;
+
+ case 510: /* Enable/disable */
+ return !mixer->disabled;
+ break;
+
+ case 511: /* Multi channel enable */
+ return mixer->multich_enable;
+ break;
+
+ case 512: /* grc3<->interpolation selector */
+ return mixer->src_quality;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ vol = value & 0xffff; /* Left/mono channel volume */
+ if (vol > DB_SIZE * 5)
+ vol = DB_SIZE * 5;
+
+ switch (ctrl)
+ {
+ case 0:
+ mixer->play_engine.outvol = vol;
+
+ mixer_devs[dev]->modify_counter++;
+ return vol | (vol << 16);
+ break;
+
+ case 510: /* Enable/disable */
+ mixer->disabled = !value;
+ return !!value;
+ break;
+
+ case 511: /* Multich enable */
+ mixer->multich_enable = !!value;
+ mixer_devs[dev]->modify_counter++;
+ return mixer->multich_enable;
+ break;
+
+ case 512: /* grc3<->interpolation selector */
+ mixer->src_quality = value & 0xff;
+ mixer_devs[dev]->modify_counter++;
+ return mixer->src_quality;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+vmix_invol (int dev, int ctrl, unsigned int cmd, int value)
+{
+ vmix_mixer_t *mixer = mixer_devs[dev]->vmix_devc;
+ int vol;
+
+ if (mixer == NULL)
+ return OSS_ENXIO;
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ switch (ctrl)
+ {
+ case 0: /* Main input volume */
+ return mixer->record_engine.outvol | (mixer->record_engine.
+ outvol << 16);
+ break;
+
+ case 1: /* recording peak meter */
+ vol =
+ peak_cnv[mixer->record_engine.
+ vu[0]] | (peak_cnv[mixer->record_engine.vu[1]] << 8);
+ mixer->record_engine.vu[0] = 0;
+ mixer->record_engine.vu[1] = 0;
+ return vol & 0x7fffffff;
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ vol = value & 0xffff; /* Left/mono channel volume */
+ if (vol > DB_SIZE * 5)
+ vol = DB_SIZE * 5;
+
+ switch (ctrl)
+ {
+ case 0:
+ mixer->record_engine.outvol = vol;
+ mixer_devs[mixer->input_mixer_dev]->modify_counter++;
+ return vol | (vol << 16);
+ break;
+
+ default:
+ return OSS_EINVAL;
+ }
+ }
+
+ return OSS_EINVAL;
+}
+
+static int
+vmix_outportc_vol (int dev, int ctrl, unsigned int cmd, int value)
+{
+ vmix_mixer_t *mixer = mixer_devs[dev]->vmix_devc;
+ vmix_portc_t *portc;
+ int vol, rvol;
+
+ if (mixer == NULL)
+ return OSS_ENXIO;
+
+ if (ctrl < 0)
+ return OSS_ENXIO;
+
+ if (ctrl >= mixer->num_clientdevs) /* Client engine not created yet */
+ return (DB_SIZE * 5) | ((DB_SIZE * 5) << 16); /* Force to maximum level */
+
+ portc = mixer->client_portc[ctrl];
+
+ if (cmd == SNDCTL_MIX_READ)
+ {
+ return portc->volume[0] | (portc->volume[1] << 16);
+ }
+
+ if (cmd == SNDCTL_MIX_WRITE)
+ {
+ vol = (value) & 0xffff; /* Left/mono channel volume */
+ rvol = (value >> 16) & 0xffff; /* Right channel volume */
+ if (vol > DB_SIZE * 5)
+ vol = DB_SIZE * 5;
+ if (rvol > DB_SIZE * 5)
+ rvol = DB_SIZE * 5;
+ portc->volume[0] = vol;
+ portc->volume[1] = rvol;
+ return vol | (rvol << 16);
+ }
+
+ return OSS_EINVAL;
+}
+
+/*ARGSUSED*/
+static int
+vmix_outportc_vu (int dev, int ctrl, unsigned int cmd, int value)
+{
+ vmix_mixer_t *mixer = mixer_devs[dev]->vmix_devc;
+ vmix_portc_t *portc;
+ int val;
+
+ if (mixer == NULL)
+ return OSS_ENXIO;
+
+ if (cmd != SNDCTL_MIX_READ)
+ return OSS_EINVAL;
+
+ if (ctrl < 0 || ctrl >= mixer->num_clientdevs)
+ return OSS_ENXIO;
+
+ portc = mixer->client_portc[ctrl];
+
+ val = peak_cnv[portc->vu[0]] | (peak_cnv[portc->vu[1]] << 8);
+ portc->vu[0] = portc->vu[1] = 0;
+
+ return val;
+}
+
+static void
+create_client_controls (void *vmix_mixer, int client_num)
+{
+ /*
+ * Create the pcmN sliders
+ */
+ int group, err;
+ vmix_mixer_t *mixer = vmix_mixer;
+ int mixer_dev;
+ char name[32];
+
+ mixer_dev = mixer->output_mixer_dev;
+ group = mixer->client_mixer_group;
+
+ if (mixer_dev < 0 || mixer_dev >= num_mixers)
+ return;
+
+ sprintf (name, "@pcm%d", mixer->client_portc[client_num]->audio_dev);
+ if ((err =
+ mixer_ext_create_control (mixer_dev, group, client_num, vmix_outportc_vol,
+ MIXT_STEREOSLIDER16, name, DB_SIZE * 5,
+ MIXF_READABLE | MIXF_WRITEABLE |
+ MIXF_CENTIBEL | MIXF_PCMVOL)) < 0)
+ return;
+
+ if ((err =
+ mixer_ext_create_control (mixer_dev, group, client_num, vmix_outportc_vu,
+ MIXT_STEREOPEAK, "", 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return;
+}
+
+static int
+create_output_controls (int mixer_dev)
+{
+ int ctl;
+ oss_mixext *ext;
+ vmix_mixer_t *mixer = mixer_devs[mixer_dev]->vmix_devc;
+ char tmp[32];
+
+ /*
+ * Misc vmix related mixer settings.
+ */
+ sprintf (tmp, "vmix%d-enable", mixer->instance_num);
+ if ((ctl = mixer_ext_create_control (mixer_dev, 0, 510, vmix_outvol,
+ MIXT_ONOFF,
+ tmp, 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return ctl;
+
+ sprintf (tmp, "vmix%d-rate", mixer->instance_num);
+ if ((ctl = mixer_ext_create_control (mixer_dev, 0, 509, vmix_outvol,
+ MIXT_VALUE,
+ tmp, 500000,
+ MIXF_READABLE | MIXF_HZ)) <
+ 0)
+ return ctl;
+ mixer_ext_set_description(mixer_dev, ctl, "Sample rate currently used by virtual mixer on this device.\n"
+ "Use vmixctl(1) command to change the rate.");
+
+ if (mixer->max_channels>2)
+ {
+ sprintf (tmp, "vmix%d-channels", mixer->instance_num);
+ if ((ctl = mixer_ext_create_control (mixer_dev, 0, 511, vmix_outvol,
+ MIXT_ENUM,
+ tmp, 2,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return ctl;
+
+ mixer_ext_set_strings (mixer_dev, ctl,
+ "Stereo Multich", 0);
+ }
+
+ sprintf (tmp, "vmix%d-src", mixer->instance_num);
+ if ((ctl = mixer_ext_create_control (mixer_dev, 0, 512, vmix_outvol,
+ MIXT_ENUM,
+ tmp, 7,
+ MIXF_READABLE | MIXF_WRITEABLE)) <
+ 0)
+ return ctl;
+
+ mixer_ext_set_strings (mixer_dev, ctl,
+ "Fast Low Medium High High+ Production OFF", 0);
+ mixer_ext_set_description(mixer_dev, ctl, "Sample rate conversion quality used by the virtual mixer.\n"
+ "\n"
+ "Virtual mixer uses internally a fixed sampling rate that can be set\n"
+ "using the 'vmixctl rate' command (usually 48 kHz by default). Applications\n"
+ "that want to use different rates will be handled by performing automatic\n"
+ "sample rate conversions (SRC) in software. This operation will consume\n"
+ "some additional CPU time depending on the quality. The following\n"
+ "alternatives are availabe:\n"
+ "\n"
+ "Fast: Use fast linear interpolation algorithm (low quality).\n"
+ "Low: Use slightly better linear interpolation\n"
+ "Medium: Use an algorithm that provides good quality with moderate CPU load.\n"
+ "High/High+/Production: Higher quality algorithms that consume more CPU resources.\n"
+ "OFF: No sample rate conversions. Sample rate locked to the master rate.\n"
+ "\n"
+ "'Fast' will work best in most cases. Only users with high end audio\n"
+ "cards and speakers should use the other settings.\n"
+ );
+ ext = mixer_find_ext (mixer_dev, ctl);
+ if (ext != NULL)
+ {
+ int i;
+
+ memset (ext->enum_present, 0, sizeof (ext->enum_present));
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ ext->enum_present[0] |= 0x01; // "Fast" is always present
+#endif
+ ext->enum_present[0] |= 0x040; // As well as "OFF"
+#if CONFIG_OSS_GRC_MAX_QUALITY > 7
+#error CONFIG_OSS_GRC_MAX_QUALITY is out of range
+#endif
+
+ for (i=CONFIG_OSS_GRC_MIN_QUALITY; i <= CONFIG_OSS_GRC_MAX_QUALITY; i++)
+ ext->enum_present[0] |= (1 << i);
+ }
+
+ /*
+ * Create the vmix volume slider and peak meter to the top panel.
+ */
+ if (!(mixer->vmix_flags & VMIX_NOMAINVOL))
+ {
+ sprintf (tmp, "vmix%d-outvol", mixer->instance_num);
+ if ((ctl = mixer_ext_create_control (mixer_dev, 0, 0, vmix_outvol,
+ MIXT_MONOSLIDER16,
+ tmp, DB_SIZE * 5,
+ MIXF_READABLE | MIXF_WRITEABLE |
+ MIXF_CENTIBEL | MIXF_PCMVOL)) < 0)
+ return ctl;
+
+ if (mixer->first_output_mixext == -1)
+ mixer->first_output_mixext = ctl;
+ }
+ else
+ mixer->play_engine.outvol = DB_SIZE * 5;
+
+ sprintf (tmp, "vmix%d-outvu", mixer->instance_num);
+ if ((ctl = mixer_ext_create_control (mixer_dev, 0, 1, vmix_outvol,
+ MIXT_STEREOPEAK,
+ tmp, 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return ctl;
+
+ if (mixer->first_output_mixext == -1)
+ mixer->first_output_mixext = ctl;
+
+ sprintf (tmp, "vmix%d", mixer->instance_num);
+ if ((mixer->client_mixer_group = mixer_ext_create_group (mixer_dev, 0, tmp)) < 0)
+ return mixer->client_mixer_group;
+
+ return 0;
+}
+
+static int
+create_input_controls (int mixer_dev)
+{
+ int err;
+ vmix_mixer_t *mixer = mixer_devs[mixer_dev]->vmix_devc;
+ char name[32];
+
+ if (!(mixer->vmix_flags & VMIX_NOMAINVOL))
+ {
+ sprintf (name, "vmix%d-invol", mixer->instance_num);
+
+ if ((err = mixer_ext_create_control (mixer_dev, 0, 0, vmix_invol,
+ MIXT_MONOSLIDER16,
+ name, DB_SIZE * 5,
+ MIXF_READABLE | MIXF_WRITEABLE |
+ MIXF_CENTIBEL | MIXF_PCMVOL)) < 0)
+ return err;
+
+ sprintf (name, "vmix%d-invu", mixer->instance_num);
+ if ((err = mixer_ext_create_control (mixer_dev, 0, 1, vmix_invol,
+ MIXT_STEREOPEAK,
+ name, 144,
+ MIXF_READABLE | MIXF_DECIBEL)) < 0)
+ return err;
+
+ if (mixer->first_input_mixext == -1)
+ mixer->first_input_mixext = err;
+ }
+
+ return 0;
+}
+
+static int
+create_duplex_controls (int mixer_dev)
+{
+ int err;
+
+ if ((err=create_output_controls (mixer_dev)) < 0)
+ return err;
+
+ return create_input_controls (mixer_dev);
+}
+
+static int
+vmix_process_chninfo (vmix_channel_map_t * output, oss_chninfo * input,
+ int maxchan)
+{
+ int i, val;
+
+ for (i=0; i < sizeof (vmix_channel_map_t); i++)
+ {
+ val = (*input)[i];
+ if ((val <= 0) || (val > maxchan) || (val == i+1))
+ {
+ (*input)[i] = 0;
+ (*output)[i] = i;
+ }
+ else
+ {
+ (*output)[i] = val-1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Audio virtual device routines
+ */
+
+static int
+vmix_set_rate (int dev, int arg)
+{
+ vmix_mixer_t *mixer = audio_engines[dev]->devc;
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+
+ if (arg == 0)
+ return portc->rate;
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ if (portc->do_src)
+ {
+ /*
+ * Stick with the master device rate if the requested rate is
+ * not inside the range supported by the simple interpolation algorithm.
+ * In that way the rate conversion will be handled by the audio core
+ * with better quality.
+ */
+ if (arg > (mixer->play_engine.rate * 5) / 4) /* At most 1.25*master_rate */
+ arg = mixer->play_engine.rate;
+
+/*
+ * The simple linear interpolation algorithm cannot handle more than 2x rate
+ * boosts reliably so don't permit them.
+ */
+ if (arg < mixer->play_engine.rate / 2)
+ arg = mixer->play_engine.rate;
+
+ return portc->rate = arg;
+ }
+#endif
+
+ return portc->rate = mixer->play_engine.rate;
+}
+
+static short
+vmix_set_channels (int dev, short arg)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+
+ if (portc->dev_type == DT_LOOP)
+ {
+ return portc->mixer->play_engine.channels;
+ }
+
+ if (arg == 0)
+ {
+ return portc->channels;
+ }
+
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ if (arg > portc->mixer->play_engine.channels)
+ arg = portc->mixer->play_engine.channels;
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ if (arg > portc->mixer->record_engine.channels)
+ arg = portc->mixer->record_engine.channels;
+ }
+ return portc->channels = arg;
+}
+
+/*ARGSUSED*/
+static unsigned int
+vmix_set_format (int dev, unsigned int arg)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+
+ if (portc->dev_type == DT_LOOP)
+ return portc->mixer->play_engine.fmt;
+
+ return portc->fmt = AFMT_S16_NE;
+}
+
+static int
+export_names (oss_mixer_enuminfo * ei, char *names)
+{
+ int n = 1, p = 0;
+
+ strcpy (ei->strings, names);
+ names = ei->strings;
+
+ ei->strindex[0] = 0;
+
+ while (names[p] != 0)
+ {
+ if (names[p] == ' ')
+ {
+ names[p] = 0;
+ ei->strindex[n++] = p + 1;
+ }
+ p++;
+ }
+
+ ei->nvalues = n;
+
+ return 0;
+}
+
+static int
+vmix_ioctl_override (int dev, unsigned int cmd, ioctl_arg arg)
+{
+/*
+ * Redirect all mixer (also legacy) ioctl calls to the master device
+ * if the master device driver has exported its ioctl override method.
+ *
+ * All other ioctl calls will be processed in normal way (by oss_audio_core.c)
+ * because we return OSS_EAGAIN.
+ */
+
+ if ((((cmd >> 8) & 0xff) == 'M') || (((cmd >> 8) & 0xff) == 'X'))
+ {
+ vmix_mixer_t *mixer = audio_engines[dev]->devc;
+ adev_t *adev;
+
+ adev=audio_engines[mixer->masterdev];
+
+ if (adev->d->adrv_ioctl_override == NULL)
+ return OSS_EAGAIN;
+
+ return adev->d->adrv_ioctl_override(adev->engine_num, cmd, arg);
+ }
+
+ return OSS_EAGAIN;
+}
+
+static int
+vmix_ioctl (int dev, unsigned int cmd, ioctl_arg arg)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+ vmix_mixer_t *mixer = audio_engines[dev]->devc;
+ int val, left, right;
+
+ switch (cmd)
+ {
+ case SNDCTL_DSP_SETPLAYVOL:
+ left = (*arg) & 0xff;
+ if (left > 100)
+ left = 100;
+ left = (left * DB_SIZE * 5) / 100;
+ portc->volume[0] = left;
+
+ right = (*arg >> 8) & 0xff;
+ if (right > 100)
+ right = 100;
+ right = (right * DB_SIZE * 5) / 100;
+ portc->volume[1] = right;
+
+ if (mixer->output_mixer_dev >= 0
+ && mixer->output_mixer_dev < num_mixers)
+ mixer_devs[mixer->output_mixer_dev]->modify_counter++;
+ return 0;
+ break;
+
+ case SNDCTL_DSP_GETPLAYVOL:
+ left = (portc->volume[0] * 100) / (DB_SIZE * 5);
+ right = (portc->volume[1] * 100) / (DB_SIZE * 5);
+ *arg = left | (right << 8);
+ return 0;
+ break;
+
+ case SNDCTL_DSP_GET_PLAYTGT:
+ return *arg = portc->play_choffs / 2;
+ break;
+
+ case SNDCTL_DSP_SET_PLAYTGT:
+ val = (*arg) * 2;
+ if (val < 0)
+ return OSS_EIO;
+ if (val >= mixer->play_engine.channels)
+ return OSS_EIO;
+ portc->play_choffs = val;
+ return *arg = val / 2;
+ break;
+
+ case SNDCTL_DSP_GET_PLAYTGT_NAMES:
+ {
+ oss_mixer_enuminfo *ei = (oss_mixer_enuminfo *) arg;
+ int n, p, i;
+ char *names = NULL;
+
+ names = audio_engines[mixer->masterdev]->outch_names;
+
+ memset (ei, 0, sizeof (*ei));
+
+ n = mixer->play_engine.channels / 2;
+ if (n < 1)
+ n = 1;
+ ei->nvalues = n;
+ p = 0;
+
+ if (n <= 1) /* Only one alternative */
+ {
+ ei->nvalues = 1;
+ ei->strindex[0] = 0;
+ sprintf (ei->strings, "default");
+
+ }
+ else
+ {
+ /* Multiple alternatives */
+
+ if (names != NULL)
+ return export_names (ei, names);
+
+ for (i = 0; i < n; i++)
+ {
+ ei->strindex[i] = p;
+
+ sprintf (&ei->strings[p], "CH%d/%d", i * 2 + 1, i * 2 + 2);
+
+ p += strlen (&ei->strings[p]) + 1;
+ }
+ }
+
+ return 0;
+ }
+ break;
+
+/*
+ * Bypass the recording source and level calls to the master device if only one
+ * recording client is active and if the master device is not a multi channel
+ * one (probably professional device).
+ */
+ case SNDCTL_DSP_GETRECVOL:
+ case SNDCTL_DSP_SETRECVOL:
+
+ if (mixer->inputdev == -1) /* No input device */
+ return OSS_EINVAL;
+ if (mixer->open_inputs < 2 && mixer->record_engine.channels <= 2)
+ return oss_audio_ioctl (mixer->inputdev, NULL, cmd, arg);
+
+ return OSS_EINVAL;
+ break;
+
+/*
+ * Recording source selection. This can be done in two different ways depending
+ * on the hardware capabilities:
+ *
+ * 1) If the input master device has multiple channels then select one of
+ * the stereo pairs. It is likely that such device is a professional
+ * audio card that uses fixed inputs anyway.
+ * 2) For stereo input only devices bypass the RECSRC ioctl calls to the
+ * actual hardware driver. However this cannot be done when multiple
+ * client applications have the same device opened for recording. In
+ * such situation switching the recording source would disturb other
+ * applications that already have recording going on.
+ */
+
+ case SNDCTL_DSP_GET_RECSRC:
+
+ if (mixer->inputdev == -1) /* No input device */
+ return OSS_EINVAL;
+ if (mixer->open_inputs < 2 && mixer->record_engine.channels <= 2)
+ return oss_audio_ioctl (mixer->inputdev, NULL, cmd, arg);
+
+ return *arg = portc->rec_choffs / 2;
+ break;
+
+ case SNDCTL_DSP_SET_RECSRC:
+
+ if (mixer->inputdev == -1) /* No input device */
+ return OSS_EINVAL;
+
+ if (mixer->open_inputs < 2 && mixer->record_engine.channels <= 2)
+ return oss_audio_ioctl (mixer->inputdev, NULL, cmd, arg);
+
+ val = (*arg) * 2;
+ if (val < 0)
+ return OSS_EIO;
+ if (val >= mixer->record_engine.channels)
+ return OSS_EIO;
+ portc->rec_choffs = val;
+ return *arg = val / 2;
+ break;
+
+ case SNDCTL_DSP_GET_RECSRC_NAMES:
+ {
+ oss_mixer_enuminfo *ei = (oss_mixer_enuminfo *) arg;
+ int n, p, i;
+ char *names = NULL;
+
+ if (mixer->inputdev == -1)
+ return OSS_EINVAL;
+
+ if (mixer->open_inputs < 2 && mixer->record_engine.channels <= 2)
+ return oss_audio_ioctl (mixer->inputdev, NULL, cmd, arg);
+
+ names = audio_engines[mixer->inputdev]->inch_names;
+
+ memset (ei, 0, sizeof (*ei));
+
+ n = mixer->record_engine.channels / 2;
+ if (n < 1)
+ n = 1;
+ ei->nvalues = n;
+ p = 0;
+
+ if (n <= 1) /* Only one alternative */
+ {
+ /*
+ * It might be better to get the name of the current recording
+ * source from the master device. However for the time being
+ * we will return just "default".
+ */
+ ei->nvalues = 1;
+ ei->strindex[0] = 0;
+ sprintf (ei->strings, "default");
+ }
+ else
+ {
+ /* Multiple alternatives */
+
+ if (names != NULL)
+ return export_names (ei, names);
+
+ for (i = 0; i < n; i++)
+ {
+ ei->strindex[i] = p;
+
+ sprintf (&ei->strings[p], "CH%d/%d", i * 2 + 1, i * 2 + 2);
+
+ p += strlen (&ei->strings[p]) + 1;
+ }
+ }
+
+ return 0;
+ }
+ break;
+ }
+ return OSS_EINVAL;
+}
+
+static void
+vmix_halt_input (int dev)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+ vmix_mixer_t *mixer = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+ portc->trigger_bits &= PCM_ENABLE_INPUT;
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+}
+
+static void
+vmix_halt_output (int dev)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+ vmix_mixer_t *mixer = audio_engines[dev]->devc;
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+ portc->trigger_bits &= PCM_ENABLE_OUTPUT;
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+}
+
+static void
+vmix_reset (int dev)
+{
+ vmix_halt_input (dev);
+ vmix_halt_output (dev);
+}
+
+static int
+start_engines (vmix_mixer_t * mixer)
+{
+ int err;
+ int trig;
+
+ adev_t *adev_in, *adev_out;
+ dmap_t *dmap_in, *dmap_out;
+
+ if (mixer->masterdev_opened)
+ {
+ return 0;
+ }
+
+ mixer->master_finfo.mode = OPEN_WRITE;
+ if (mixer->inputdev == mixer->masterdev)
+ mixer->master_finfo.mode |= OPEN_READ;
+ mixer->master_finfo.acc_flags = 0;
+
+ adev_out = adev_in = audio_engines[mixer->masterdev];
+
+ if (mixer->inputdev > -1)
+ adev_in = audio_engines[mixer->inputdev];
+
+ adev_out->cooked_enable = 0;
+
+ if ((err =
+ oss_audio_open_engine (mixer->masterdev, OSS_DEV_DSP,
+ &mixer->master_finfo, 1, OF_SMALLBUF,
+ NULL)) < 0)
+ {
+ return err;
+ }
+
+ dmap_out = adev_out->dmap_out;
+ dmap_in = adev_in->dmap_in;
+ adev_out->cooked_enable = 0;
+
+ if (mixer->inputdev > -1 && mixer->inputdev != mixer->masterdev)
+ {
+ /*
+ * Open input device
+ */
+ adev_in->cooked_enable = 0;
+ mixer->input_finfo.mode = OPEN_READ;
+ mixer->input_finfo.acc_flags = 0;
+ if ((err =
+ oss_audio_open_engine (mixer->inputdev, OSS_DEV_DSP,
+ &mixer->input_finfo, 1, OF_SMALLBUF,
+ NULL)) < 0)
+ {
+ oss_audio_release (mixer->masterdev, &mixer->master_finfo);
+ return err;
+ }
+ strcpy (adev_in->cmd, "VMIX_IN");
+ strcpy (adev_in->label, "VMIX_IN");
+ dmap_in = adev_in->dmap_in;
+ adev_out->pid = 0;
+ adev_out->cooked_enable = 0;
+
+ vmix_setup_record_engine (mixer, adev_in, dmap_in);
+
+ dmap_in->dma_mode = PCM_ENABLE_INPUT;
+ trig = 0;
+ oss_audio_ioctl (mixer->inputdev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & trig);
+ }
+
+ mixer->masterdev_opened = 1;
+ strcpy (adev_out->cmd, "VMIX");
+ strcpy (adev_out->label, "VMIX");
+ adev_out->pid = 0;
+ adev_out->cooked_enable = 0;
+
+ vmix_setup_play_engine (mixer, adev_out, dmap_out);
+
+ trig = 0;
+ dmap_out->dma_mode = PCM_ENABLE_OUTPUT;
+
+ oss_audio_ioctl (mixer->masterdev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & trig);
+ trig = PCM_ENABLE_OUTPUT;
+ if (mixer->masterdev == mixer->inputdev)
+ trig |= PCM_ENABLE_INPUT;
+ else
+ {
+ int trig2 = PCM_ENABLE_INPUT;
+ if (mixer->inputdev > -1)
+ if (oss_audio_ioctl (mixer->inputdev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & trig2) < 0)
+ {
+ cmn_err (CE_WARN, "Trigger (input) failed\n");
+ }
+ }
+
+ if (oss_audio_ioctl (mixer->masterdev, NULL, SNDCTL_DSP_SETTRIGGER,
+ (ioctl_arg) & trig) < 0)
+ {
+ cmn_err (CE_WARN, "Trigger failed\n");
+ }
+
+ return 0;
+}
+
+static void
+stop_engines (vmix_mixer_t * mixer)
+{
+ oss_native_word flags;
+
+ if (mixer->masterdev_opened)
+ {
+ adev_t *adev;
+ dmap_t *dmap;
+
+ adev = audio_engines[mixer->masterdev];
+ dmap = adev->dmap_out;
+
+ oss_audio_ioctl (mixer->masterdev, NULL, SNDCTL_DSP_HALT, 0);
+
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+ dmap->audio_callback = NULL;
+
+ dmap = adev->dmap_in;
+ if (dmap != NULL)
+ {
+ dmap->audio_callback = NULL;
+ }
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+
+ oss_audio_release (mixer->masterdev, &mixer->master_finfo);
+
+ if (mixer->inputdev > -1 && mixer->inputdev != mixer->masterdev)
+ {
+ adev = audio_engines[mixer->inputdev];
+ dmap = adev->dmap_in;
+
+ oss_audio_ioctl (mixer->inputdev, NULL, SNDCTL_DSP_HALT, 0);
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+ dmap->audio_callback = NULL;
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+ oss_audio_release (mixer->inputdev, &mixer->input_finfo);
+ }
+
+ mixer->masterdev_opened = 0;
+ }
+}
+
+/*ARGSUSED*/
+static int
+vmix_open (int dev, int mode, int open_flags)
+{
+ adev_t *adev = audio_engines[dev];
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+ vmix_mixer_t *mixer = portc->mixer;
+ oss_native_word flags;
+ int start = 0;
+
+ if (mode & portc->disabled_modes)
+ return OSS_EACCES;
+
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+
+ portc->open_pending = 0; /* Was set to 1 by vmix_create_client */
+
+ if (portc->open_mode != 0)
+ {
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+ return OSS_EBUSY;
+ }
+
+ portc->open_mode = mode;
+ portc->trigger_bits = 0;
+ portc->play_mixing_func = NULL;
+ portc->rec_mixing_func = NULL;
+ portc->do_src = 0;
+ portc->play_choffs = 0; /* Left align */
+ portc->rec_choffs = 0; /* Left align */
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ /*
+ * For the time being always enable local linear interpolation to make
+ * vmix devices to work faster.
+ */
+ if (mixer->src_quality == 0)
+ portc->do_src = 1;
+ else
+#endif
+ {
+ adev->src_quality = mixer->src_quality;
+ if (mixer->src_quality == 6) /* SRC=OFF */
+ adev->cooked_enable = 0;
+ else
+ {
+ if (adev->src_quality < 1)
+ adev->src_quality = 1;
+ else if (adev->src_quality > 5)
+ adev->src_quality = 5;
+ }
+ }
+#ifdef CONFIG_OSS_VMIX_FLOAT
+/*
+ * Enable local src (linear interpolation) for mmap applications and SADA
+ * support (sadasupport.c).
+ */
+ if (open_flags & (OF_DEVAUDIO | OF_MMAP))
+ portc->do_src = 1;
+#endif
+
+ /*
+ * However SRC is not supported for input
+ */
+ if (mode == PCM_ENABLE_INPUT)
+ portc->do_src = 0;
+
+ if (mixer->open_devices++ == 0)
+ start = 1;
+
+ if (mode & PCM_ENABLE_INPUT)
+ mixer->open_inputs++;
+
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+
+ if (start)
+ {
+ int err;
+
+ if ((err = start_engines (mixer)) < 0)
+ {
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+ mixer->open_devices = 0;
+ mixer->open_inputs=0;
+ portc->open_mode = 0;
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static void
+vmix_close (int dev, int mode)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+ vmix_mixer_t *mixer = portc->mixer;
+ oss_native_word flags;
+ int stop = 0;
+
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+ if (mixer->open_devices-- == 1)
+ stop = 1;
+
+ if (mode & PCM_ENABLE_INPUT)
+ mixer->open_inputs--;
+
+ portc->open_mode = 0;
+ portc->trigger_bits = 0;
+ portc->play_mixing_func = NULL;
+ portc->rec_mixing_func = NULL;
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+
+ if (stop)
+ {
+ stop_engines (mixer);
+ }
+
+}
+
+/*ARGSUSED*/
+static void
+vmix_output_block (int dev, oss_native_word buf, int count,
+ int fragsize, int intrflag)
+{
+}
+
+/*ARGSUSED*/
+static void
+vmix_start_input (int dev, oss_native_word buf, int count, int fragsize,
+ int intrflag)
+{
+}
+
+static void
+vmix_trigger (int dev, int state)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+ vmix_mixer_t *mixer = audio_engines[dev]->devc;
+
+ oss_native_word flags;
+
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+ if (portc->open_mode & OPEN_WRITE)
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_OUTPUT;
+ portc->trigger_bits |= state & PCM_ENABLE_OUTPUT;
+ }
+
+ if (portc->open_mode & OPEN_READ)
+ {
+ portc->trigger_bits &= ~PCM_ENABLE_INPUT;
+ portc->trigger_bits |= state & PCM_ENABLE_INPUT;
+ }
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+}
+
+/*ARGSUSED*/
+static int
+vmix_prepare_for_input (int dev, int bsize, int bcount)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+ /* int bytes; */
+
+ switch (portc->fmt)
+ {
+ case AFMT_S16_NE:
+ portc->rec_mixing_func = vmix_rec_export_16ne;
+ /* bytes = 2; */
+ break;
+
+ case AFMT_S16_OE:
+ portc->rec_mixing_func = vmix_rec_export_16oe;
+ /* bytes = 2; */
+ break;
+
+ case AFMT_S32_NE:
+ portc->rec_mixing_func = vmix_rec_export_32ne;
+ /* bytes = 4; */
+ break;
+
+ case AFMT_S32_OE:
+ portc->rec_mixing_func = vmix_rec_export_32oe;
+ /* bytes = 4; */
+ break;
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ case AFMT_FLOAT:
+ portc->rec_mixing_func = vmix_rec_export_float;
+ /* bytes = 4; */
+ break;
+#endif
+ }
+
+ portc->rec_dma_pointer = 0;
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+vmix_prepare_for_output (int dev, int bsize, int bcount)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+ /* int bytes; */
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ vmix_mixer_t *mixer = audio_engines[dev]->devc;
+
+ memset (&portc->play_dma_pointer_src, 0, sizeof (portc->play_dma_pointer_src)); /* 0.0 */
+
+ if (portc->rate != mixer->play_engine.rate) /* Sample rate conversions needed */
+ {
+ switch (portc->fmt)
+ {
+ case AFMT_S16_NE:
+ portc->play_mixing_func = vmix_outmix_16ne_src;
+ /* bytes = 2; */
+ break;
+
+ case AFMT_S16_OE:
+ portc->play_mixing_func = vmix_outmix_16oe_src;
+ /* bytes = 2; */
+ break;
+
+ case AFMT_S32_NE:
+ portc->play_mixing_func = vmix_outmix_32ne_src;
+ /* bytes = 4; */
+ break;
+
+ case AFMT_S32_OE:
+ portc->play_mixing_func = vmix_outmix_32oe_src;
+ /* bytes = 4; */
+ break;
+
+ case AFMT_FLOAT:
+ portc->play_mixing_func = vmix_outmix_float_src;
+ /* bytes = 4; */
+ break;
+ }
+ }
+ else
+#endif
+ {
+ switch (portc->fmt)
+ {
+ case AFMT_S16_NE:
+ portc->play_mixing_func = vmix_outmix_16ne;
+ /* bytes = 2; */
+ break;
+
+ case AFMT_S16_OE:
+ portc->play_mixing_func = vmix_outmix_16oe;
+ /* bytes = 2; */
+ break;
+
+ case AFMT_S32_NE:
+ portc->play_mixing_func = vmix_outmix_32ne;
+ /* bytes = 4; */
+ break;
+
+ case AFMT_S32_OE:
+ portc->play_mixing_func = vmix_outmix_32oe;
+ /* bytes = 4; */
+ break;
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ case AFMT_FLOAT:
+ portc->play_mixing_func = vmix_outmix_float;
+ /* bytes = 4; */
+ break;
+#endif
+ }
+ }
+
+ portc->play_dma_pointer = 0;
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+vmix_alloc_buffer (int dev, dmap_t * dmap, int direction)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+
+ /* Loopback devices share the DMA buffer of the master device */
+ if (portc->dev_type == DT_LOOP)
+ {
+ adev_t *adev;
+ adev = audio_engines[portc->mixer->masterdev];
+
+ dmap->dmabuf_phys = 0;
+ dmap->dmabuf = adev->dmap_out->dmabuf;
+ dmap->buffsize = adev->dmap_out->buffsize;
+ dmap->buffer_protected = 1; /* Write protect flag for audio core */
+
+ return 0;
+ }
+
+ if (dmap->dmabuf != NULL)
+ return 0;
+
+#ifdef ALLOW_BUFFER_MAPPING
+ /*
+ * Apps may use mmap() so allocate a buffer that is
+ * suitable for it.
+ */
+ {
+ int err;
+
+ if ((err = oss_alloc_dmabuf (dev, dmap, direction)) < 0)
+ return err;
+ }
+#else
+#define MY_BUFFSIZE (64*1024)
+ dmap->dmabuf_phys = 0;
+ dmap->dmabuf = KERNEL_MALLOC (MY_BUFFSIZE);
+ if (dmap->dmabuf == NULL)
+ return OSS_ENOSPC;
+ dmap->buffsize = MY_BUFFSIZE;
+#endif
+
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+vmix_free_buffer (int dev, dmap_t * dmap, int direction)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+
+ /* Loopback devices share the DMA buffer of the master device so don't free it */
+ if (portc->dev_type == DT_LOOP)
+ {
+ dmap->dmabuf_phys = 0;
+ dmap->dmabuf = NULL;
+ dmap->buffsize = 0;
+ return 0;
+ }
+
+ if (dmap->dmabuf == NULL)
+ return 0;
+#ifdef ALLOW_BUFFER_MAPPING
+ oss_free_dmabuf (dev, dmap);
+#else
+ KERNEL_FREE (dmap->dmabuf);
+#endif
+
+ dmap->dmabuf = NULL;
+ dmap->dmabuf_phys = 0;
+ return 0;
+}
+
+/*ARGSUSED*/
+static int
+vmix_get_output_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+
+ return portc->play_dma_pointer;
+}
+
+/*ARGSUSED*/
+static int
+vmix_get_input_buffer_pointer (int dev, dmap_t * dmap, int direction)
+{
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+
+ if (portc->dev_type == DT_LOOP)
+ {
+ int p;
+ /* Return the write pointer of the master side */
+ adev_t *adev;
+ adev = audio_engines[portc->mixer->masterdev];
+
+ p = (int) (adev->dmap_out->user_counter % adev->dmap_out->bytes_in_use);
+
+ return p;
+ }
+
+ return portc->rec_dma_pointer;
+}
+
+static int
+vmix_local_qlen (int dev)
+{
+ vmix_portc_t *portc;
+ vmix_mixer_t *mixer;
+ int samplesize;
+ int len = 0;
+
+ portc = audio_engines[dev]->portc;
+ mixer = audio_engines[dev]->devc;
+
+ samplesize = 1;
+ if (portc->bits == AFMT_S16_NE)
+ samplesize *= 2;
+ samplesize *= portc->channels;
+
+ /* Compute the number of samples in the physical device */
+ oss_audio_ioctl (mixer->masterdev, NULL, SNDCTL_DSP_GETODELAY,
+ (ioctl_arg) & len);
+
+ if (mixer->play_engine.bits == 16)
+ len /= 2; /* 16 bit samples */
+ else
+ len /= 4; /* 32 bit samples */
+ len /= mixer->play_engine.channels;
+
+ /* Convert # of samples to local bytes */
+
+ len *= portc->channels;
+
+ if (portc->bits == AFMT_S16_NE)
+ len *= 2;
+
+ return len;
+}
+
+/*ARGSUSED*/
+static void
+vmix_setup_fragments (int dev, dmap_t * dmap, int direction)
+{
+/*
+ * vmix_setup_fragments is used to force fragment/buffer parameters of
+ * loopback devices to match the DMA buffer of the physical device.
+ */
+ vmix_portc_t *portc = audio_engines[dev]->portc;
+ adev_t *adev;
+
+ if (portc->dev_type != DT_LOOP)
+ return;
+
+ adev = audio_engines[portc->mixer->masterdev];
+
+ /* Copy the buffering parameters */
+ dmap->fragment_size = adev->dmap_out->fragment_size;
+ dmap->nfrags = adev->dmap_out->nfrags;
+ dmap->bytes_in_use = adev->dmap_out->bytes_in_use;
+}
+
+static audiodrv_t vmix_driver = {
+ vmix_open,
+ vmix_close,
+ vmix_output_block,
+ vmix_start_input,
+ vmix_ioctl,
+ vmix_prepare_for_input,
+ vmix_prepare_for_output,
+ vmix_reset,
+ vmix_local_qlen,
+ NULL,
+ vmix_halt_input,
+ vmix_halt_output,
+ vmix_trigger,
+ vmix_set_rate,
+ vmix_set_format,
+ vmix_set_channels,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ vmix_alloc_buffer,
+ vmix_free_buffer,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ vmix_get_input_buffer_pointer,
+ vmix_get_output_buffer_pointer,
+ NULL,
+ vmix_setup_fragments
+};
+
+/*
+ * Initialization support
+ */
+
+static void
+relink_masterdev (vmix_mixer_t * mixer)
+{
+/*
+ * Insert the VMIX devices to the engine search list of the master device.
+ */
+ adev_t *first_adev, *last_adev, *master_adev;
+ int i, n = mixer->num_clientdevs;
+
+ n = n - 1;
+ if (n < 1)
+ return;
+
+ first_adev = audio_engines[mixer->client_portc[0]->audio_dev];
+ last_adev = audio_engines[mixer->client_portc[n]->audio_dev];
+ master_adev = audio_engines[mixer->masterdev];
+
+/*
+ * Relink client devices in the proper way.
+ */
+
+ for (i=0;i<mixer->num_clientdevs;i++)
+ {
+ adev_t *adev = audio_engines[mixer->client_portc[i]->audio_dev];
+
+ if (i==mixer->num_clientdevs-1)
+ adev->next_out = NULL;
+ else
+ adev->next_out = audio_engines[mixer->client_portc[i+1]->audio_dev];
+ }
+
+ if (master_adev == NULL || master_adev->unloaded || !master_adev->enabled)
+ {
+ cmn_err (CE_WARN, "vmix: master_adev %d is not available\n", mixer->masterdev);
+ cmn_err (CE_CONT, "master_adev=%p, unloaded=%d, enabled=%d\n", master_adev, master_adev->unloaded, master_adev->enabled);
+ return;
+ }
+
+ last_adev->next_out = NULL;
+ master_adev->next_out = first_adev;
+}
+
+static void
+unlink_masterdev (vmix_mixer_t * mixer)
+{
+/*
+ * Remove the VMIX devices from the engine search list of the master device.
+ */
+ adev_t *last_adev, *master_adev;
+ int i, n = mixer->num_clientdevs;
+
+ if (n < 1)
+ return;
+
+ if (n > MAX_CLIENTS)
+ n = MAX_CLIENTS;
+
+ for (i=0;i<n;i++)
+ {
+ /*
+ * Mark all client engines as unloaded
+ */
+ adev_t *adev = audio_engines[mixer->client_portc[i]->audio_dev];
+
+ adev->unloaded = 1;
+ }
+
+ last_adev = audio_engines[mixer->client_portc[n-1]->audio_dev];
+ master_adev = audio_engines[mixer->masterdev];
+
+ if (master_adev == NULL)
+ {
+ cmn_err (CE_WARN, "master_adev == NULL\n");
+ return;
+ }
+
+ master_adev->vmix_mixer=NULL;
+
+ master_adev->next_out = last_adev->next_out;
+ last_adev->next_out = NULL;
+}
+
+static void
+relink_inputdev (vmix_mixer_t * mixer)
+{
+/*
+ * Insert the VMIX devices to the engine search list of the input device.
+ */
+ adev_t *first_adev, *last_adev, *input_adev;
+ int i, n = mixer->num_clientdevs;
+
+/*
+ * Relink client devices in the proper way.
+ */
+
+ for (i=0;i<mixer->num_clientdevs;i++)
+ {
+ adev_t *adev = audio_engines[mixer->client_portc[i]->audio_dev];
+
+ if (i==mixer->num_clientdevs-1)
+ adev->next_in = NULL;
+ else
+ adev->next_in = audio_engines[mixer->client_portc[i+1]->audio_dev];
+ }
+
+ if (n < 1)
+ return;
+
+ n = n - 1;
+
+ first_adev = audio_engines[mixer->client_portc[0]->audio_dev];
+ last_adev = audio_engines[mixer->client_portc[n]->audio_dev];
+ input_adev = audio_engines[mixer->inputdev];
+
+ last_adev->next_in = NULL;
+ input_adev->next_in = first_adev;
+}
+
+static void
+unlink_inputdev (vmix_mixer_t * mixer)
+{
+/*
+ * Remove the VMIX devices from the engine search list of the input device.
+ */
+ adev_t *last_adev, *input_adev;
+ int n = mixer->num_clientdevs;
+
+ if (n < 1)
+ return;
+
+ if (n > MAX_CLIENTS)
+ n = MAX_CLIENTS;
+
+ n = n - 1;
+
+ last_adev = audio_engines[mixer->client_portc[n]->audio_dev];
+ input_adev = audio_engines[mixer->inputdev];
+ input_adev->vmix_mixer=NULL;
+
+ input_adev->next_in = last_adev->next_in;
+ last_adev->next_in = NULL;
+}
+
+static int
+create_vmix_engine (vmix_mixer_t * mixer)
+{
+ vmix_portc_t *portc;
+ int n;
+ char tmp[128];
+ adev_t *adev, *master_adev;
+ int opts = ADEV_VIRTUAL | ADEV_DEFAULT | ADEV_VMIX;
+
+ n = mixer->num_clientdevs;
+
+ /*
+ * ADEV_HIDDEN is used for the VMIX devices because they should not be
+ * made visible to applications. The audio core will automatically
+ * redirect applications opening the master device to use the
+ * VMIX devices.
+ *
+ * However make the client devices visible if requested by vmixctl
+ */
+ if (!(mixer->attach_flags & VMIX_INSTALL_VISIBLE))
+ {
+ opts |= ADEV_HIDDEN;
+
+ if (n > 0)
+ opts |= ADEV_SHADOW;
+ }
+
+ if (mixer->masterdev == -1)
+ return OSS_ENXIO;
+
+ if (n + 1 >= MAX_CLIENTS) /* Cannot create more client engines */
+ return OSS_EBUSY;
+
+ /*
+ * Other than the first instance are unlikely to be default the default
+ * audio device of the system.
+ */
+ if (mixer->instance_num > 0)
+ opts |= ADEV_SPECIAL;
+
+ if ((portc = PMALLOC (mixer->osdev, sizeof (*portc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate portc structure\n");
+ return OSS_ENOMEM;
+ }
+ memset (portc, 0, sizeof (*portc));
+ portc->open_pending = 1; /* Reserve this engine to the client it was created for */
+
+ mixer->num_clientdevs++;
+
+ portc->num = n;
+
+ mixer->client_portc[n] = portc;
+
+ if (mixer->inputdev == -1)
+ opts |= ADEV_NOINPUT;
+ else
+ opts |= ADEV_DUPLEX;
+
+ master_adev = audio_engines[mixer->masterdev];
+
+ sprintf (tmp, "%s (vmix)", master_adev->name);
+
+ if ((portc->audio_dev = oss_install_audiodev (OSS_AUDIO_DRIVER_VERSION,
+ mixer->osdev,
+ mixer->master_osdev,
+ tmp,
+ &vmix_driver,
+ sizeof (audiodrv_t),
+ opts,
+ AFMT_S16_NE | AFMT_S32_NE |
+ AFMT_FLOAT, mixer, -1)) < 0)
+ {
+ return portc->audio_dev;
+ }
+
+ adev = audio_engines[portc->audio_dev];
+
+ if (master_adev->d->adrv_ioctl_override != NULL)
+ adev->d->adrv_ioctl_override = vmix_ioctl_override;
+
+ adev->mixer_dev = mixer->output_mixer_dev;
+ adev->portc = portc;
+ adev->min_rate = mixer->play_engine.rate;
+ adev->max_rate = mixer->play_engine.rate;
+ adev->caps |= PCM_CAP_FREERATE | PCM_CAP_BATCH | PCM_CAP_MULTI;
+ adev->min_channels = 2;
+ adev->max_channels = mixer->play_engine.channels;
+
+ adev->rate_source = audio_engines[mixer->masterdev]->rate_source;
+ portc->dev_type = DT_OUT;
+ portc->mixer = mixer;
+ portc->volume[0] = DB_SIZE * 5;
+ portc->volume[1] = DB_SIZE * 5;
+ if (mixer->inputdev == -1)
+ portc->disabled_modes = OPEN_READ;
+
+ portc->fmt = AFMT_S16_NE;
+ portc->bits = 16;
+ portc->channels = 2;
+
+#ifdef VDEV_SUPPORT
+ /* Report device node of the master device */
+ if (opts & ADEV_HIDDEN)
+ strcpy (adev->devnode, master_adev->devnode);
+ oss_add_audio_devlist (OPEN_READ | OPEN_WRITE, master_adev->audio_devfile);
+#endif
+
+ if (n == 0 && mixer->masterdev < num_audio_engines
+ && audio_engines[mixer->masterdev] != NULL)
+ {
+ audio_engines[mixer->masterdev]->redirect_out = portc->audio_dev;
+
+ if (mixer->inputdev > -1)
+ {
+ audio_engines[mixer->inputdev]->redirect_in = portc->audio_dev;
+ audio_engines[mixer->masterdev]->redirect_in = portc->audio_dev;
+ }
+ }
+
+ relink_masterdev (mixer);
+
+ if (mixer->inputdev > -1)
+ relink_inputdev (mixer);
+
+
+ return portc->audio_dev;
+}
+
+static void
+create_loopdev (vmix_mixer_t * mixer)
+{
+ vmix_portc_t *portc;
+ int n;
+ char tmp[128], nick[16];
+ adev_t *adev;
+ int opts = ADEV_VIRTUAL | ADEV_NOOUTPUT;
+
+ if (mixer->masterdev == -1)
+ return;
+
+ if ((portc = PMALLOC (mixer->osdev, sizeof (*portc))) == NULL)
+ {
+ cmn_err (CE_WARN, "Cannot allocate portc structure\n");
+ return;
+ }
+ memset (portc, 0, sizeof (*portc));
+
+ n = mixer->num_loopdevs++;
+ portc->num = n;
+ mixer->loop_portc[n] = portc;
+
+ if (n > 0)
+ opts |= ADEV_SHADOW;
+
+ adev = audio_engines[mixer->masterdev];
+
+ sprintf (tmp, "%s (vmix) loopback record", adev->name);
+ sprintf (nick, "loop%d", n);
+
+ if ((portc->audio_dev = oss_install_audiodev_with_devname (OSS_AUDIO_DRIVER_VERSION,
+ mixer->osdev,
+ mixer->master_osdev,
+ tmp,
+ &vmix_driver,
+ sizeof (audiodrv_t),
+ opts,
+ mixer->play_engine.fmt,
+ mixer, -1,
+ nick)) < 0)
+ {
+ return;
+ }
+
+ adev = audio_engines[portc->audio_dev];
+
+ adev->mixer_dev = mixer->output_mixer_dev;
+ adev->portc = portc;
+ adev->min_rate = mixer->play_engine.rate;
+ adev->max_rate = mixer->play_engine.rate;
+ adev->min_channels = mixer->play_engine.channels;
+ adev->max_channels = mixer->play_engine.channels;
+ adev->caps |= PCM_CAP_FREERATE | PCM_CAP_HIDDEN | PCM_CAP_BATCH | PCM_CAP_MULTI;
+ portc->mixer = mixer;
+ portc->dev_type = DT_LOOP;
+ portc->disabled_modes = OPEN_WRITE;
+ portc->fmt = AFMT_S16_NE;
+ portc->bits = 16;
+ portc->channels = 2;
+ portc->volume[0] = DB_SIZE * 5;
+ portc->volume[1] = DB_SIZE * 5;
+}
+
+static int
+uninit_vmix_instance(vmix_mixer_t *mixer)
+{
+ if (mixer->master_osdev != NULL)
+ {
+ MUTEX_CLEANUP (mixer->mutex);
+ }
+
+ if (mixer->masterdev < 0 || mixer->masterdev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ if (!mixer->installed_ok)
+ {
+ return OSS_EIO;
+ }
+
+ if (audio_engines[mixer->masterdev] == NULL)
+ return OSS_ENXIO;
+
+/*
+ * Cleanup the engine redirection links
+ */
+
+ audio_engines[mixer->masterdev]->redirect_out = -1;
+
+ if (mixer->inputdev > -1)
+ {
+ audio_engines[mixer->inputdev]->redirect_in = -1;
+ audio_engines[mixer->masterdev]->redirect_in = -1;
+ }
+ unlink_masterdev (mixer);
+
+ if (mixer->inputdev > -1 && mixer->inputdev != mixer->masterdev)
+ {
+ unlink_inputdev (mixer);
+ }
+
+ return 0;
+}
+
+static int
+check_masterdev (void *mx, int reattach)
+{
+ vmix_mixer_t *mixer = mx;
+ adev_t *adev;
+
+ if (mixer->masterdev < 0 || mixer->masterdev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ adev = audio_engines[mixer->masterdev];
+ DDB (cmn_err
+ (CE_CONT, "Check masterdev eng=%d/%s\n", adev->engine_num,
+ adev->name));
+
+ /* Don't accept virtual devices other than loopback ones */
+ if (adev->flags & ADEV_VIRTUAL && !(adev->flags & ADEV_LOOP))
+ return OSS_EIO;
+
+ if (adev->vmix_mixer != NULL) /* Already attached */
+ {
+ cmn_err(CE_CONT, "Vmix already attached to %s\n", adev->devnode);
+ return OSS_EBUSY;
+ }
+
+ if (adev->flags & ADEV_NOOUTPUT)
+ return OSS_EIO;
+
+ if (adev->flags & ADEV_DISABLE_VIRTUAL) /* Not compatible */
+ return OSS_EIO;
+
+ if (adev->vmix_flags & VMIX_DISABLED) /* Not compatible */
+ return OSS_EIO;
+
+ if (adev->max_channels < 2)
+ return OSS_EIO;
+
+ if (!(adev->oformat_mask & SUPPORTED_FORMATS))
+ return OSS_EIO;
+
+ if (mixer->inputdev != -1 && mixer->inputdev != mixer->masterdev)
+ if (audio_engines[mixer->inputdev]->vmix_mixer != NULL) /* Input master already driven */
+ {
+ cmn_err(CE_CONT, "Vmix already attached to %s\n", audio_engines[mixer->inputdev]->devnode);
+ return OSS_EBUSY;
+ }
+
+/*
+ * Good. Initialize all per-mixer variables
+ */
+ mixer->master_osdev = adev->master_osdev;
+ adev->vmix_mixer = mixer;
+ adev->prev_vmix_mixer = mixer;
+//cmn_err(CE_CONT, "Calling MUTEX_INIT mast=%p, mixer=%p, mutex=%p\n", mixer->master_osdev, mixer,mixer->mutex);
+ MUTEX_INIT (mixer->master_osdev, mixer->mutex, MH_DRV + 4);
+//cmn_err(CE_CONT, "OK\n");
+
+ DDB (cmn_err (CE_CONT, "Vmix masterdev=%d\n", mixer->masterdev));
+
+/*
+ * The device is OK. Next check for the input/duplex capability.
+ */
+
+ mixer->vmix_flags = adev->vmix_flags;
+ mixer->max_channels = adev->max_channels;
+
+ if (mixer->attach_flags & VMIX_INSTALL_NOINPUT)
+ mixer->vmix_flags |= VMIX_NOINPUT;
+
+ if (mixer->vmix_flags & VMIX_NOINPUT)
+ mixer->inputdev = -1;
+ else if (!(adev->flags & ADEV_NOINPUT) && (adev->flags & ADEV_DUPLEX))
+ {
+ mixer->inputdev = mixer->masterdev;
+ DDB (cmn_err
+ (CE_CONT, "Vmix masterdev=%d shared for input\n",
+ mixer->masterdev));
+ }
+
+/*
+ * At this point we know the input and output master devices so it's the time
+ * to create the virtual audio devices.
+ */
+
+ adev = audio_engines[mixer->masterdev];
+
+ if (mixer->osdev->first_mixer >= 0)
+ {
+ mixer->output_mixer_dev = mixer->osdev->first_mixer;
+ mixer->input_mixer_dev = mixer->osdev->first_mixer;
+ }
+
+ if (mixer->inputdev != -1 && mixer->inputdev != mixer->masterdev)
+ {
+ adev = audio_engines[mixer->inputdev];
+
+ adev->vmix_mixer = mixer;
+ adev->prev_vmix_mixer = mixer;
+
+ if (adev->mixer_dev != -1)
+ {
+ mixer->input_mixer_dev = adev->mixer_dev;
+ }
+ }
+
+ /*
+ * Warm up the engines so that client device creation knows the defaults
+ */
+ start_engines (mixer);
+ stop_engines (mixer);
+
+ mixer->installed_ok = 1;
+
+
+ if (!reattach)
+ {
+ if (mixer->output_mixer_dev > -1)
+ {
+ if (mixer->output_mixer_dev == mixer->input_mixer_dev)
+ {
+ mixer_ext_set_vmix_init_fn (mixer->output_mixer_dev,
+ create_duplex_controls, 20, mixer);
+ }
+ else
+ {
+ mixer_ext_set_vmix_init_fn (mixer->output_mixer_dev,
+ create_output_controls, 20, mixer);
+ }
+ }
+
+ if (mixer->output_mixer_dev != mixer->input_mixer_dev)
+ if (mixer->inputdev >= 0 &&
+ mixer->input_mixer_dev > -1)
+ {
+ mixer_ext_set_vmix_init_fn (mixer->input_mixer_dev,
+ create_input_controls, 10, mixer);
+ }
+ }
+/*
+ * Crate one client in advance so that that SNDCTL_AUDIOINFO can provide proper info.
+ */
+ if (!(mixer->attach_flags & VMIX_INSTALL_NOPREALLOC))
+ {
+ int cl, n=4;
+
+ if ((mixer->attach_flags & 0xff) != 0) /* Number of clients given */
+ {
+ n = mixer->attach_flags & 0xff;
+ if (n<1) n=1;
+ if (n>=MAX_CLIENTS) n=MAX_CLIENTS-1; /* TODO: Why n=MAX_CLIENTS doesn't work? */
+ }
+
+ for (cl=0;cl<n;cl++)
+ vmix_create_client (mixer);
+
+ /*
+ * Mark the engines to be free for use
+ */
+ for (cl=0;cl<mixer->num_clientdevs;cl++)
+ mixer->client_portc[cl]->open_pending = 0;
+ }
+
+ if (vmix_loopdevs>0)
+ {
+ int i;
+
+ for (i=0;i<vmix_loopdevs;i++)
+ create_loopdev (mixer);
+ }
+
+ DDB (cmn_err (CE_CONT, "Master dev %d is OK\n", adev->engine_num));
+
+ return 0;
+}
+
+int
+vmix_attach_audiodev(oss_device_t *osdev, int masterdev, int inputdev, unsigned int attach_flags)
+{
+/*
+ * Purpose: Create a vmix instance for an audio device.
+ *
+ * This function will be called by OSS drivers after installing the audio devices. It will create
+ * an vmix instance for the device.
+ *
+ * Parameters:
+ *
+ * osdev: The osdev structure of the actual hardware device.
+ * masterdev: The audio engine number of the master (playback or duplex) device.
+ * inputdev: Input master device (if different than masterdev). Value of -1 means that the
+ * masterdev device should also be used as the input master device (if it supports
+ * input).
+ * attach_flags: Flags like VMIX_INSTALL_NOPREALLOC.
+ */
+
+ vmix_mixer_t *mixer=NULL;
+ int reattach=0;
+ int err;
+ int i;
+
+ if (vmix_disabled) /* Vmix not available in the system */
+ return OSS_EIO;
+
+ /*
+ * If the vmix_no_autoattach option is set in osscore.conf then attach
+ * vmix only when 'vmixctl attach' is executed manually (VMIX_INSTALL_MANUAL).
+ */
+ if (vmix_no_autoattach && !(attach_flags & VMIX_INSTALL_MANUAL))
+ return 0;
+
+ if (flat_device_model)
+ {
+ attach_flags |= VMIX_INSTALL_VISIBLE;
+ attach_flags = (attach_flags & ~0xff) | 8; /* Precreate 8 client engines */
+ }
+
+ if (audio_engines[masterdev]->prev_vmix_mixer != NULL)
+ {
+ mixer = audio_engines[masterdev]->prev_vmix_mixer;
+
+ if (mixer->attach_flags != attach_flags) /* Not compatible */
+ mixer=NULL;
+ }
+
+ if (mixer == NULL)
+ {
+ if ((mixer = PMALLOC (osdev, sizeof (*mixer))) == NULL)
+ {
+ cmn_err (CE_CONT, "Cannot allocate memory for instance descriptor\n");
+ return OSS_ENOMEM;
+ }
+
+ memset (mixer, 0, sizeof (*mixer));
+ mixer->instance_num = num_instances++;
+ if (mixer->instance_num > 0)
+ mixer->osdev = osdev_clone (osdev, mixer->instance_num);
+ }
+ else
+ {
+ relink_masterdev (mixer);
+
+ if (mixer->inputdev > -1)
+ relink_inputdev (mixer);
+
+ reattach=1;
+ }
+
+ mixer->osdev = osdev;
+ mixer->first_input_mixext = -1;
+ mixer->first_output_mixext = -1;
+ mixer->src_quality = 0;
+
+ mixer->output_mixer_dev = -1;
+ mixer->input_mixer_dev = -1;
+
+ /*
+ * Mixer default levels
+ */
+ mixer->play_engine.outvol = DB_SIZE * 5;
+ mixer->record_engine.outvol = DB_SIZE * 5;
+#ifndef CONFIG_OSS_VMIX_FLOAT
+ mixer->play_engine.outvol -= 3; /* For overflow protection */
+#endif
+ for (i = 0; i < sizeof (vmix_channel_map_t); i++)
+ mixer->play_engine.channel_order[i] = i;
+
+ mixer->masterdev = masterdev;
+ mixer->inputdev = inputdev;
+ mixer->rate = 48000;
+ mixer->attach_flags = attach_flags;
+
+ DDB (cmn_err (CE_CONT, "Create instance %d\n", num_instances));
+ DDB (cmn_err (CE_CONT, "vmix_masterdev=%d\n", masterdev));
+ DDB (cmn_err (CE_CONT, "vmix_inputdev=%d\n", inputdev));
+ DDB (cmn_err (CE_CONT, "vmix_rate=%d\n", mixer->rate));
+ DDB (cmn_err (CE_CONT, "\n"));
+
+ /*
+ * Insert the newly created mixer to the mixer list.
+ */
+ mixer->next = mixer_list;
+ mixer_list = mixer;
+
+ if (masterdev >= 0)
+ {
+ if (masterdev >= num_audio_engines)
+ {
+ return OSS_ENXIO;
+ }
+
+ masterdev = mixer->masterdev;
+
+ if (mixer->inputdev >= 0)
+ {
+ if (inputdev >= num_audio_engines)
+ inputdev = mixer->inputdev = -1;
+ }
+
+ if ((err=check_masterdev (mixer, reattach))<0)
+ {
+ cmn_err (CE_CONT, "Vmix instance %d: Master device %d is not compatible with vmix (error %d)\n",
+ mixer->instance_num + 1, mixer->masterdev, err);
+ return err;
+ }
+
+ return 0;
+ }
+
+ return OSS_EIO;
+}
+
+int
+vmix_detach_audiodev(int masterdev)
+{
+/*
+ * Purpose: Detach the vmix subsystem from the audio device.
+ *
+ * Most drivers don't call this since vmix instances will be automatically detached when the
+ * master device is removed. However drivers that support dynamically created/deleted devices must
+ * call this when a device is deleted.
+ *
+ * Paramaters:
+ *
+ * masterdev: The audio engine number of the master device (same as in vmix_attach_audiodev).
+ */
+
+ vmix_mixer_t *mixer;
+
+ if (masterdev<0 || masterdev>=num_audio_engines)
+ return OSS_ENXIO;
+
+ mixer = audio_engines[masterdev]->vmix_mixer;
+
+ if (mixer==NULL) /* Not attached */
+ return 0;
+
+ return uninit_vmix_instance(mixer);
+}
+
+int
+vmix_set_master_rate(int masterdev, int rate)
+{
+/*
+ * Purpose: Set the master sampling rate of given vmix instance.
+ *
+ * Paramaters:
+ *
+ * masterdev: The audio engine number of the master device (same as in vmix_attach_audiodev).
+ * rate: The requested new sampling rate.
+ */
+
+ vmix_mixer_t *mixer;
+
+ if (rate < 4000 || rate > 200000)
+ return OSS_EDOM;
+
+ if (masterdev<0 || masterdev>=num_audio_engines)
+ return OSS_ENXIO;
+
+ mixer = audio_engines[masterdev]->vmix_mixer;
+
+ if (mixer==NULL)
+ return OSS_ENXIO;
+
+ mixer->rate = rate;
+
+ return 0;
+}
+
+int
+vmix_set_channel_map (int masterdev, void * map)
+{
+ vmix_mixer_t *mixer;
+
+ if (masterdev < 0 || masterdev >= num_audio_engines)
+ return OSS_ENXIO;
+
+ mixer = audio_engines[masterdev]->vmix_mixer;
+
+ if (mixer == NULL)
+ return OSS_EPERM;
+
+ return vmix_process_chninfo (&mixer->play_engine.channel_order, map,
+ mixer->play_engine.channels);
+}
+
+int
+vmix_create_client(void *mixer_)
+{
+ int engine_num=-1, i;
+ oss_native_word flags;
+ vmix_portc_t *portc;
+ vmix_mixer_t *mixer = mixer_;
+
+ if (mixer->disabled) /* Vmix is disabled for the time being */
+ return OSS_ENXIO;
+
+/*
+ * First check if any of the already created engines is free and available for use.
+ */
+
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+ for (i=0;i<mixer->num_clientdevs;i++)
+ {
+ portc = mixer->client_portc[i];
+
+ if (portc->open_mode != 0 || portc->open_pending)
+ continue;
+
+ portc->open_pending = 1;
+ engine_num = portc->audio_dev;
+ break;
+ }
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+
+/*
+ * Create a new engine and use it
+ */
+
+ if (engine_num < 0) /* Engine not allocated yet */
+ {
+ if ((engine_num = create_vmix_engine (mixer))<0)
+ {
+ cmn_err(CE_WARN, "Failed to create a vmix engine, error=%d\n", engine_num);
+ return engine_num;
+ }
+
+ portc = audio_engines[engine_num]->portc;
+ create_client_controls (mixer, portc->num);
+ }
+
+ portc = audio_engines[engine_num]->portc;
+
+ /* portc->open_pending = 1; // This was done already by create_vmix_engine() */
+ return engine_num;
+}
+
+void
+vmix_core_init (oss_device_t *osdev)
+{
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ int check;
+/*
+ * Check that the processor is compatible with vmix (has proper FP support).
+ */
+
+ if ((check = oss_fp_check ()) <= 0)
+ {
+ vmix_disabled = 1;
+ cmn_err (CE_WARN,
+ "This processor architecture is not compatible with vmix (info=%d) - Not enabled.\n",
+ check);
+ return;
+ }
+#endif
+}
+
+void
+vmix_core_uninit (void)
+{
+ vmix_mixer_t *mixer = mixer_list;
+ int n = 0;
+
+ while (mixer != NULL && n++ < num_instances)
+ {
+ uninit_vmix_instance(mixer);
+ mixer = mixer->next;
+ }
+
+ mixer_list = NULL; /* Everything removed */
+}
+
+void
+vmix_change_devnames(void *vmix_mixer, const char *name)
+{
+/*
+ * Change audio device names of all client engines.
+ */
+ vmix_mixer_t *mixer = vmix_mixer;
+ int i;
+
+ for (i=0;i<mixer->num_clientdevs;i++)
+ {
+ adev_t *adev = audio_engines[mixer->client_portc[i]->audio_dev];
+
+ sprintf(adev->name, "%s (vmix)", name);
+ }
+}
diff --git a/kernel/framework/vmix_core/vmix_import.inc b/kernel/framework/vmix_core/vmix_import.inc
new file mode 100644
index 0000000..dc4a965
--- /dev/null
+++ b/kernel/framework/vmix_core/vmix_import.inc
@@ -0,0 +1,77 @@
+#ifdef CONFIG_OSS_VMIX_FLOAT
+/*
+ * Purpose: Recording device to local input buffer import routine for vmix
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+int i, ch;
+float vol;
+
+vol = vmix_db_table[eng->outvol / 5];
+
+for (ch = 0; ch < channels; ch++)
+ {
+ float vu;
+ float *chbuf;
+
+ vu = eng->vu[ch % 2];
+ vu = vu / 255.0;
+
+ op = (SAMPLE_TYPE *) inbuf;
+ op += ch;
+
+ chbuf = chbufs[ch];
+
+ for (i = 0; i < samples; i++)
+ {
+ float tmp;
+
+#if 0 && defined(SINE_DEBUG)
+ /* Generate internal sine wave test signal */
+ tmp = 0;
+ if (ch < 2)
+ {
+ tmp = sine_table[sine_phase[ch]];
+ sine_phase[ch] = (sine_phase[ch] + 1) % SINE_SIZE;
+ }
+#else
+ tmp = VMIX_BYTESWAP (*op);
+ tmp /= SAMPLE_RANGE;
+ tmp *= vol;
+
+ if (tmp < -1.0)
+ tmp = -1.0;
+ else if (tmp > 1.0)
+ tmp = 1.0;
+
+#endif
+ op += channels;
+
+ *chbuf++ = tmp;
+
+ /* VU meter */
+ if (tmp < 0.0)
+ tmp = -tmp;
+ if (tmp > vu)
+ vu = tmp;
+ }
+
+ if (ch < 2)
+ {
+ vu = vu * 255.0;
+ eng->vu[ch] = (int)vu;
+ }
+ }
+#else
+#include "vmix_import_int.inc"
+#endif
diff --git a/kernel/framework/vmix_core/vmix_import_int.inc b/kernel/framework/vmix_core/vmix_import_int.inc
new file mode 100644
index 0000000..338078d
--- /dev/null
+++ b/kernel/framework/vmix_core/vmix_import_int.inc
@@ -0,0 +1,56 @@
+/*
+ * Purpose: Recording device to local input buffer import routine for vmix (int)
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+int i, ch;
+int vol;
+
+vol = vmix_db_table[eng->outvol / 5];
+
+for (ch = 0; ch < channels; ch++)
+ {
+ int vu;
+ int *chbuf;
+
+ vu = eng->vu[ch % 2] * 65536;
+
+ op = (SAMPLE_TYPE *) inbuf;
+ op += ch;
+
+ chbuf = chbufs[ch];
+
+ for (i = 0; i < samples; i++)
+ {
+ int tmp;
+
+ tmp = INT_IMPORT (VMIX_BYTESWAP (*op));
+ tmp = (tmp * vol) / VMIX_VOL_SCALE;
+
+ op += channels;
+
+ *chbuf++ = tmp;
+
+ /* VU meter */
+ if (tmp < 0)
+ tmp = -tmp;
+ if (tmp > vu)
+ vu = tmp;
+ }
+
+ if (ch < 2)
+ {
+ vu = vu / 65536;
+ eng->vu[ch] = vu;
+ }
+ }
diff --git a/kernel/framework/vmix_core/vmix_input.c b/kernel/framework/vmix_core/vmix_input.c
new file mode 100644
index 0000000..0e90b48
--- /dev/null
+++ b/kernel/framework/vmix_core/vmix_input.c
@@ -0,0 +1,505 @@
+/*
+ * Purpose: Virtual mixing audio driver recording routines
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define SWAP_SUPPORT
+#include <oss_config.h>
+#include "vmix.h"
+
+#if 0
+/* Debugging macros */
+extern unsigned char tmp_status;
+# define UP_STATUS(v) OUTB(NULL, (tmp_status=tmp_status|(v)), 0x378)
+# define DOWN_STATUS(v) OUTB(NULL, (tmp_status=tmp_status&~(v)), 0x378)
+#else
+# define UP_STATUS(v)
+# define DOWN_STATUS(v)
+#endif
+
+#undef SINE_DEBUG
+
+#ifndef CONFIG_OSS_VMIX_FLOAT
+#undef SINE_DEBUG
+#endif
+
+#ifdef SINE_DEBUG
+#define SINE_SIZE 48
+static const float sine_table[SINE_SIZE] = {
+ 0.000000, 0.130526, 0.258819, 0.382683,
+ 0.500000, 0.608761, 0.707107, 0.793353,
+ 0.866025, 0.923880, 0.965926, 0.991445,
+ 1.000000, 0.991445, 0.965926, 0.923880,
+ 0.866025, 0.793353, 0.707107, 0.608761,
+ 0.500000, 0.382683, 0.258819, 0.130526,
+ 0.000000, -0.130526, -0.258819, -0.382683,
+ -0.500000, -0.608761, -0.707107, -0.793353,
+ -0.866025, -0.923880, -0.965926, -0.991445,
+ -1.000000, -0.991445, -0.965926, -0.923880,
+ -0.866025, -0.793353, -0.707107, -0.608761,
+ -0.500000, -0.382683, -0.258819, -0.130526
+};
+static int sine_phase[2] = { 0 };
+#endif
+
+/*
+ * Recording import functions (from the physical devices)
+ */
+#undef INT_IMPORT
+#define INT_IMPORT(x) (x * 256)
+
+static void
+import16ne (vmix_engine_t * eng, void *inbuf, vmix_sample_t * chbufs[],
+ int channels, int samples)
+{
+ short *op;
+#define SAMPLE_TYPE short
+#define SAMPLE_RANGE 32768.0
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+
+#include "vmix_import.inc"
+}
+
+static void
+import16oe (vmix_engine_t * eng, void *inbuf, vmix_sample_t * chbufs[],
+ int channels, int samples)
+{
+ short *op;
+#undef SAMPLE_TYPE
+#undef SAMPLE_RANGE
+#define SAMPLE_TYPE short
+#define SAMPLE_RANGE 32768.0
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap16(x)
+
+#include "vmix_import.inc"
+}
+
+#undef INT_IMPORT
+#define INT_IMPORT(x) (x / 256)
+
+static void
+import32ne (vmix_engine_t * eng, void *inbuf, vmix_sample_t * chbufs[],
+ int channels, int samples)
+{
+ int *op;
+#undef SAMPLE_TYPE
+#undef SAMPLE_RANGE
+#define SAMPLE_TYPE int
+#define SAMPLE_RANGE 2147483648.0
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+
+#include "vmix_import.inc"
+}
+
+static void
+import32oe (vmix_engine_t * eng, void *inbuf, vmix_sample_t * chbufs[],
+ int channels, int samples)
+{
+ int *op;
+#define SAMPLE_TYPE int
+#define SAMPLE_RANGE 2147483648.0
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap32(x)
+
+#include "vmix_import.inc"
+}
+
+/*
+ * recording export functions to virtual devices
+ */
+#undef BUFFER_TYPE
+#define BUFFER_TYPE short *
+
+#undef INT_EXPORT
+#define INT_EXPORT(x) (x / 256)
+
+void
+vmix_rec_export_16ne (vmix_portc_t * portc, int nsamples)
+{
+ short *outp;
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ double range = 32767.0;
+#endif
+#include "rec_export.inc"
+}
+
+void
+vmix_rec_export_16oe (vmix_portc_t * portc, int nsamples)
+{
+ short *outp;
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap16(x)
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ double range = 32767.0;
+#endif
+#include "rec_export.inc"
+}
+
+#undef BUFFER_TYPE
+#define BUFFER_TYPE int *
+#undef INT_EXPORT
+#define INT_EXPORT(x) (x * 256)
+
+void
+vmix_rec_export_32ne (vmix_portc_t * portc, int nsamples)
+{
+ int *outp;
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ double range = 2147483647.0;
+#endif
+#include "rec_export.inc"
+}
+
+void
+vmix_rec_export_32oe (vmix_portc_t * portc, int nsamples)
+{
+ int *outp;
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap32(x)
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ double range = 2147483647.0;
+#endif
+#include "rec_export.inc"
+}
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+void
+vmix_rec_export_float (vmix_portc_t * portc, int nsamples)
+{
+ float *outp;
+#undef BUFFER_TYPE
+#define BUFFER_TYPE float *
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+ double range = 1.0;
+#include "rec_export.inc"
+}
+#endif
+
+static void
+vmix_record_callback (int dev, int parm)
+{
+ int i, n;
+ int do_input = 0;
+
+ adev_t *adev = audio_engines[dev];
+ dmap_t *dmap = adev->dmap_in;
+ oss_native_word flags;
+
+ vmix_mixer_t *mixer = adev->vmix_mixer;
+ vmix_engine_t *eng = &mixer->record_engine;
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ fp_env_t fp_buf;
+ short *fp_env = fp_buf;
+ fp_flags_t fp_flags;
+#endif
+
+ if (mixer == NULL) /* Houston, we have a problem. */
+ return;
+
+ /*
+ * Check if any input applications are active. Skip input processing
+ * if it's not needed (to save CPU cycles).
+ */
+
+ for (i = 0; i < mixer->num_clientdevs; i++)
+ if (mixer->client_portc[i]->trigger_bits & PCM_ENABLE_INPUT)
+ do_input = 1;
+
+ if (!do_input) /* Skip all input processing */
+ {
+ n = 0;
+ while (n++ < dmap->nfrags
+ && (int) (dmap->byte_counter - dmap->user_counter) >=
+ dmap->fragment_size)
+ {
+ dmap->user_counter += dmap->fragment_size;
+ }
+ return;
+ }
+
+ UP_STATUS (0x02);
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ {
+ /*
+ * Align the FP save buffer to 16 byte boundary
+ */
+ oss_native_word p;
+ p = (oss_native_word) fp_buf;
+
+ p = ((p + 15ULL) / 16) * 16;
+ fp_env = (short *) p;
+ }
+
+ FP_SAVE (fp_env, fp_flags);
+#endif
+
+ n = 0;
+ while (n++ < dmap->nfrags
+ && (int) (dmap->byte_counter - dmap->user_counter) >=
+ dmap->fragment_size)
+ {
+ int i, p;
+ unsigned char *inbuf;
+
+ if (!do_input)
+ {
+ /*
+ * Just skip the recorded data becaus nobody needs it.
+ */
+ dmap->user_counter += dmap->fragment_size;
+ continue;
+ }
+
+ for (i = 0; i < eng->channels; i++)
+ {
+ memset (eng->chbufs[i], 0, CHBUF_SAMPLES * sizeof (vmix_sample_t));
+ }
+
+ p = (int) (dmap->user_counter % dmap->bytes_in_use);
+ inbuf = dmap->dmabuf + p;
+
+ eng->converter (eng, inbuf, eng->chbufs, eng->channels,
+ eng->samples_per_frag);
+
+ for (i = 0; i < mixer->num_clientdevs; i++)
+ {
+ vmix_portc_t *portc = mixer->client_portc[i];
+
+ if (portc->trigger_bits & PCM_ENABLE_INPUT)
+ {
+ if (portc->rec_mixing_func == NULL)
+ continue;
+ if (portc->rec_choffs + portc->channels >
+ mixer->record_engine.channels)
+ portc->rec_choffs = 0;
+ portc->rec_mixing_func (portc,
+ mixer->record_engine.samples_per_frag);
+ }
+ }
+
+ dmap->user_counter += dmap->fragment_size;
+ }
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ FP_RESTORE (fp_env, fp_flags);
+#endif
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+
+/*
+ * Call oss_audio_inputintr outside FP mode because it may
+ * cause a task switch (under Solaris). Task switch may turn on CR0.TS under
+ * x86 which in turn will cause #nm exception.
+ */
+ for (i = 0; i < mixer->num_clientdevs; i++)
+ if (mixer->client_portc[i]->trigger_bits & PCM_ENABLE_INPUT)
+ {
+ vmix_portc_t *portc = mixer->client_portc[i];
+ oss_audio_inputintr (portc->audio_dev, 0);
+ }
+ DOWN_STATUS (0x02);
+}
+
+void
+finalize_record_engine (vmix_mixer_t * mixer, int fmt, adev_t * adev,
+ dmap_p dmap)
+{
+ int i;
+
+ switch (fmt)
+ {
+ case AFMT_S16_NE:
+ mixer->record_engine.bits = 16;
+ mixer->record_engine.converter = import16ne;
+ break;
+
+ case AFMT_S16_OE:
+ mixer->record_engine.bits = 16;
+ mixer->record_engine.converter = import16oe;
+ break;
+
+ case AFMT_S32_NE:
+ mixer->record_engine.bits = 32;
+ mixer->record_engine.converter = import32ne;
+ break;
+
+ case AFMT_S32_OE:
+ mixer->record_engine.bits = 32;
+ mixer->record_engine.converter = import32oe;
+ break;
+
+ default:
+ cmn_err (CE_CONT, "Unrecognized recording sample format %x\n", fmt);
+ return;
+ }
+
+ mixer->record_engine.fragsize = dmap->fragment_size;
+
+ mixer->record_engine.samples_per_frag =
+ mixer->record_engine.fragsize / mixer->record_engine.channels /
+ (mixer->record_engine.bits / 8);
+
+ if (mixer->record_engine.samples_per_frag > CHBUF_SAMPLES)
+ {
+ cmn_err (CE_WARN, "Too many samples per fragment (%d,%d)\n",
+ mixer->record_engine.samples_per_frag, CHBUF_SAMPLES);
+ return;
+ }
+
+ for (i = 0; i < mixer->record_engine.channels; i++)
+ if (mixer->record_engine.chbufs[i] == NULL) /* Not allocated yet */
+ {
+ mixer->record_engine.chbufs[i] =
+ PMALLOC (mixer->master_osdev,
+ CHBUF_SAMPLES * sizeof (vmix_sample_t));
+ if (mixer->record_engine.chbufs[i] == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return;
+ }
+ }
+
+ dmap->audio_callback = vmix_record_callback; /* Enable conversions */
+ dmap->callback_parm = mixer->instance_num;
+ dmap->dma_mode = PCM_ENABLE_INPUT;
+
+ if (mixer->num_clientdevs > 1)
+ {
+ adev->redirect_out = mixer->client_portc[0]->audio_dev;
+ adev->vmix_mixer = mixer;
+ }
+ vmix_record_callback (mixer->inputdev, mixer->instance_num);
+}
+
+void
+vmix_setup_record_engine (vmix_mixer_t * mixer, adev_t * adev, dmap_t * dmap)
+{
+ int fmt;
+ int old_min;
+ int frags = 0x7fff0007; /* fragment size of 128 bytes */
+
+/*
+ * Sample format (and endianess) setup
+ *
+ */
+
+ // First make sure a sane format is selected before starting to probe
+ fmt = adev->d->adrv_set_format (mixer->inputdev, AFMT_S16_LE);
+ fmt = adev->d->adrv_set_format (mixer->inputdev, AFMT_S16_NE);
+
+ // Find out the "best" sample format supported by the device
+
+ if (adev->iformat_mask & AFMT_S16_OE)
+ fmt = AFMT_S16_OE;
+ if (adev->iformat_mask & AFMT_S16_NE)
+ fmt = AFMT_S16_NE;
+ if (mixer->multich_enable)
+ {
+ if (adev->iformat_mask & AFMT_S32_OE)
+ fmt = AFMT_S32_OE;
+ if (adev->iformat_mask & AFMT_S32_NE)
+ fmt = AFMT_S32_NE;
+ }
+
+ fmt = adev->d->adrv_set_format (mixer->inputdev, fmt);
+ mixer->record_engine.fmt = fmt;
+
+/*
+ * Number of channels
+ */
+ mixer->record_engine.channels = mixer->max_channels;
+
+ if (mixer->record_engine.channels > MAX_REC_CHANNELS)
+ mixer->record_engine.channels = MAX_REC_CHANNELS;
+
+ if (!mixer->multich_enable)
+ mixer->record_engine.channels = 2;
+
+ /* Force the device to stereo before trying with (possibly) imultiple channels */
+ adev->d->adrv_set_channels (mixer->inputdev, 2);
+
+ mixer->record_engine.channels =
+ adev->d->adrv_set_channels (mixer->inputdev,
+ mixer->record_engine.channels);
+
+ if (mixer->record_engine.channels > MAX_REC_CHANNELS)
+ {
+ cmn_err (CE_WARN,
+ "Number of channels (%d) is larger than maximum (%d)\n",
+ mixer->record_engine.channels, MAX_REC_CHANNELS);
+ return;
+ }
+
+ /*
+ * Try to set the same rate than for playback.
+ */
+ mixer->record_engine.rate =
+ oss_audio_set_rate (mixer->inputdev, mixer->play_engine.rate);
+
+ if (mixer->record_engine.rate <= 22050)
+ frags = 0x7fff0004; /* Use smaller fragments */
+
+ audio_engines[mixer->inputdev]->hw_parms.channels =
+ mixer->record_engine.channels;
+ audio_engines[mixer->inputdev]->hw_parms.rate = mixer->record_engine.rate;
+ audio_engines[mixer->inputdev]->dmap_in->data_rate =
+ mixer->record_engine.rate * mixer->record_engine.channels *
+ mixer->record_engine.bits / 8;
+ audio_engines[mixer->inputdev]->dmap_in->frame_size =
+ mixer->record_engine.channels * mixer->record_engine.bits / 8;
+
+ old_min = adev->min_fragments;
+
+#if 0
+ if ((adev->max_fragments == 0 || adev->max_fragments >= 4)
+ && adev->min_block == 0)
+ adev->min_fragments = 4;
+#endif
+
+ oss_audio_ioctl (mixer->inputdev, NULL, SNDCTL_DSP_SETFRAGMENT,
+ (ioctl_arg) & frags);
+ oss_audio_ioctl (mixer->inputdev, NULL, SNDCTL_DSP_GETBLKSIZE,
+ (ioctl_arg) & mixer->record_engine.fragsize);
+
+ dmap->bytes_in_use = dmap->fragment_size * dmap->nfrags;
+
+ oss_audio_ioctl (mixer->inputdev, NULL, SNDCTL_DSP_GETBLKSIZE,
+ (ioctl_arg) & mixer->record_engine.fragsize);
+ mixer->record_engine.fragsize = dmap->fragment_size;
+ adev->min_fragments = old_min;
+
+ if (mixer->record_engine.channels > 2)
+ {
+ DDB (cmn_err
+ (CE_CONT, "Enabling multi channel rec mode, %d hw channels\n",
+ mixer->record_engine.channels));
+ }
+ else if (mixer->record_engine.channels != 2)
+ {
+ cmn_err (CE_WARN,
+ "Master device doesn't support suitable channel configuration\n");
+
+ return;
+ }
+
+ finalize_record_engine (mixer, fmt, adev, dmap);
+}
diff --git a/kernel/framework/vmix_core/vmix_output.c b/kernel/framework/vmix_core/vmix_output.c
new file mode 100644
index 0000000..47e10ab
--- /dev/null
+++ b/kernel/framework/vmix_core/vmix_output.c
@@ -0,0 +1,687 @@
+/*
+ * Purpose: Virtual mixing audio driver output mixing routines
+ *
+ * This file contains the actual mixing and resampling engine for output.
+ * The actual algorithms are implemented in outexport.inc and playmix.inc.
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This 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.
+ *
+ */
+
+#define SWAP_SUPPORT
+#include <oss_config.h>
+#include "vmix.h"
+
+#if 0
+/* Debugging macros*/
+extern unsigned char tmp_status;
+# define UP_STATUS(v) OUTB(NULL, (tmp_status=tmp_status|(v)), 0x378)
+# define DOWN_STATUS(v) OUTB(NULL, (tmp_status=tmp_status&~(v)), 0x378)
+#else
+# define UP_STATUS(v)
+# define DOWN_STATUS(v)
+#endif
+
+#undef SINE_DEBUG
+
+#ifndef CONFIG_OSS_VMIX_FLOAT
+#undef SINE_DEBUG
+#endif
+
+#ifdef SINE_DEBUG
+#define SINE_SIZE 48
+static const float sine_table[SINE_SIZE] = {
+ 0.000000, 0.130526, 0.258819, 0.382683,
+ 0.500000, 0.608761, 0.707107, 0.793353,
+ 0.866025, 0.923880, 0.965926, 0.991445,
+ 1.000000, 0.991445, 0.965926, 0.923880,
+ 0.866025, 0.793353, 0.707107, 0.608761,
+ 0.500000, 0.382683, 0.258819, 0.130526,
+ 0.000000, -0.130526, -0.258819, -0.382683,
+ -0.500000, -0.608761, -0.707107, -0.793353,
+ -0.866025, -0.923880, -0.965926, -0.991445,
+ -1.000000, -0.991445, -0.965926, -0.923880,
+ -0.866025, -0.793353, -0.707107, -0.608761,
+ -0.500000, -0.382683, -0.258819, -0.130526
+};
+static int sine_phase[MAX_PLAY_CHANNELS] = { 0 };
+#endif
+
+#ifndef CONFIG_OSS_VMIX_FLOAT
+/*
+ * Simple limiter to prevent overflows when using fixed point computations
+ */
+void
+process_limiter (unsigned int *statevar, int *chbufs[], int nchannels,
+ int nsamples)
+{
+#define Abs(x) ((x) < 0 ? -(x) : (x))
+
+ int k, t;
+ unsigned int q, amp, amp2;
+
+ for (t = 0; t < nsamples; t++)
+ {
+ amp = (unsigned) Abs (chbufs[0][t]);
+
+ for (k = 1; k < nchannels; k++)
+ {
+ amp2 = (unsigned) Abs (chbufs[k][t]);
+ if (amp2 > amp)
+ amp = amp2;
+ }
+
+ amp >>= 8;
+ q = 0x10000;
+
+ if (amp > 0x7FFF)
+ q = 0x7FFF0000 / amp;
+
+ if (*statevar > q)
+ *statevar = q;
+ else
+ {
+ q = *statevar;
+
+ /*
+ * Simplier (linear) tracking algo
+ * (gives less distortion, but more pumping)
+ */
+ *statevar += 2;
+ if (*statevar > 0x10000)
+ *statevar = 0x10000;
+
+ /*
+ * Classic tracking algo
+ * gives more distortion with no-lookahead
+ * *statevar=0x10000-((0x10000-*statevar)*0xFFF4>>16);
+ */
+ }
+
+ for (k = 0; k < nchannels; k++)
+ {
+ int in = chbufs[k][t];
+ int out = 0;
+ unsigned int p;
+
+ if (in >= 0)
+ {
+ p = in;
+ p = ((p & 0xFFFF) * (q >> 4) >> 12) + (p >> 16) * q;
+ out = p;
+ }
+ else
+ {
+ p = -in;
+ p = ((p & 0xFFFF) * (q >> 4) >> 12) + (p >> 16) * q;
+ out = -p;
+ }
+ /* safety code */
+ /* if output after limiter is clamped, then it can be dropped */
+ if (out > 0x7FFFFF)
+ out = 0x7FFFFF;
+ else if (out < -0x7FFFFF)
+ out = -0x7FFFFF;
+
+ chbufs[k][t] = out;
+ }
+ }
+}
+#endif
+
+/*
+ * Output export functions
+ */
+
+#undef INT_EXPORT
+#define INT_EXPORT(x) (x / 256)
+
+static void
+export16ne (vmix_engine_t * eng, void *outbuf, vmix_sample_t * chbufs[],
+ int channels, int samples)
+{
+ short *op;
+#define SAMPLE_TYPE short
+#define SAMPLE_RANGE 32768.0
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+
+#include "outexport.inc"
+}
+
+static void
+export16oe (vmix_engine_t * eng, void *outbuf, vmix_sample_t * chbufs[],
+ int channels, int samples)
+{
+ short *op;
+#undef SAMPLE_TYPE
+#undef SAMPLE_RANGE
+#define SAMPLE_TYPE short
+#define SAMPLE_RANGE 32768.0
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap16(x)
+
+#include "outexport.inc"
+}
+
+#undef INT_EXPORT
+#define INT_EXPORT(x) (x * 256)
+
+static void
+export32ne (vmix_engine_t * eng, void *outbuf, vmix_sample_t * chbufs[],
+ int channels, int samples)
+{
+ int *op;
+#undef SAMPLE_TYPE
+#undef SAMPLE_RANGE
+#define SAMPLE_TYPE int
+#define SAMPLE_RANGE 2147483648.0
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+
+#include "outexport.inc"
+}
+
+static void
+export32oe (vmix_engine_t * eng, void *outbuf, vmix_sample_t * chbufs[],
+ int channels, int samples)
+{
+ int *op;
+#define SAMPLE_TYPE int
+#define SAMPLE_RANGE 2147483648.0
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap32(x)
+
+#include "outexport.inc"
+}
+
+/*
+ * Mixing functions
+ */
+#undef BUFFER_TYPE
+#define BUFFER_TYPE short *
+
+#undef INT_OUTMIX
+#define INT_OUTMIX(x) (x * 256)
+
+void
+vmix_outmix_16ne (vmix_portc_t * portc, int nsamples)
+{
+ short *inp;
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ double range = 3.0517578125e-5; /* 1.0 / 32768.0 */
+#endif
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+#include "playmix.inc"
+}
+
+void
+vmix_outmix_16oe (vmix_portc_t * portc, int nsamples)
+{
+ short *inp;
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ double range = 3.0517578125e-5; /* 1.0 / 32768.0 */
+#endif
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap16(x)
+#include "playmix.inc"
+}
+
+#undef BUFFER_TYPE
+#define BUFFER_TYPE int *
+#undef INT_OUTMIX
+#define INT_OUTMIX(x) (x / 256)
+
+void
+vmix_outmix_32ne (vmix_portc_t * portc, int nsamples)
+{
+ int *inp;
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ double range = 4.65661287308e-10; /* 1.0 / 2147483648.0 */
+#endif
+#include "playmix.inc"
+}
+
+void
+vmix_outmix_32oe (vmix_portc_t * portc, int nsamples)
+{
+ int *inp;
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap32(x)
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ double range = 4.65661287308e-10; /* 1.0 / 2147483648.0 */
+#endif
+#include "playmix.inc"
+}
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+void
+vmix_outmix_float (vmix_portc_t * portc, int nsamples)
+{
+ float *inp;
+ double range = 1.0;
+#undef BUFFER_TYPE
+#define BUFFER_TYPE float *
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+#include "playmix.inc"
+}
+#endif
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+/*
+ * Mixing functions (with sample rate conversions)
+ */
+#undef BUFFER_TYPE
+#define BUFFER_TYPE short *
+
+#undef INT_OUTMIX
+#define INT_OUTMIX(x) (x * 256)
+
+void
+vmix_outmix_16ne_src (vmix_portc_t * portc, int nsamples)
+{
+ short *inp;
+ double range = 3.0517578125e-5; /* 1.0 / 32768.0 */
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+#include "playmix_src.inc"
+}
+
+void
+vmix_outmix_16oe_src (vmix_portc_t * portc, int nsamples)
+{
+ short *inp;
+ double range = 3.0517578125e-5; /* 1.0 / 32768.0 */
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap16(x)
+#include "playmix_src.inc"
+}
+
+#undef BUFFER_TYPE
+#define BUFFER_TYPE int *
+
+#undef INT_OUTMIX
+#define INT_OUTMIX(x) (x / 256)
+
+void
+vmix_outmix_32ne_src (vmix_portc_t * portc, int nsamples)
+{
+ int *inp;
+ double range = 4.65661287308e-10; /* 1.0 / 2147483648.0 */
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+#include "playmix_src.inc"
+}
+
+void
+vmix_outmix_32oe_src (vmix_portc_t * portc, int nsamples)
+{
+ int *inp;
+ double range = 4.65661287308e-10; /* 1.0 / 2147483648.0 */
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) bswap32(x)
+#include "playmix_src.inc"
+}
+
+void
+vmix_outmix_float_src (vmix_portc_t * portc, int nsamples)
+{
+ float *inp;
+ double range = 1.0;
+#undef BUFFER_TYPE
+#define BUFFER_TYPE float *
+#undef VMIX_BYTESWAP
+#define VMIX_BYTESWAP(x) x
+#include "playmix_src.inc"
+}
+#endif
+
+static void
+vmix_play_callback (int dev, int parm)
+{
+ int n;
+
+ adev_t *adev = audio_engines[dev];
+ dmap_t *dmap = adev->dmap_out;
+ oss_native_word flags;
+ int i;
+
+ vmix_mixer_t *mixer = adev->vmix_mixer;
+ vmix_engine_t *eng = &mixer->play_engine;
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ fp_env_t fp_buf;
+ short *fp_env = fp_buf;
+ fp_flags_t fp_flags;
+#endif
+
+ UP_STATUS (0x04);
+ if (dmap == NULL || dmap->dmabuf == NULL)
+ return;
+
+ if (dmap->bytes_in_use == 0)
+ {
+ cmn_err (CE_WARN, "Bytes in use=0, eng=%d\n", adev->engine_num);
+ return;
+ }
+
+ MUTEX_ENTER_IRQDISABLE (mixer->mutex, flags);
+
+ if (dmap->dmabuf == NULL)
+ {
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+ return;
+ }
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+
+ {
+ /*
+ * Align the FP save buffer to 16 byte boundary
+ */
+ oss_native_word p;
+ p = (oss_native_word) fp_buf;
+
+ p = ((p + 15ULL) / 16) * 16;
+ fp_env = (short *) p;
+ }
+ FP_SAVE (fp_env, fp_flags);
+#endif
+
+ n = 0;
+ while (n++ < eng->max_playahead
+ && dmap_get_qlen (dmap) < eng->max_playahead)
+ {
+ int p;
+ unsigned char *outbuf;
+ int nstreams = 0;
+
+ for (i = 0; i < eng->channels; i++)
+ memset (eng->chbufs[i], 0, CHBUF_SAMPLES * sizeof (vmix_sample_t));
+ for (i = 0; i < mixer->num_clientdevs; i++)
+ if (mixer->client_portc[i]->trigger_bits & PCM_ENABLE_OUTPUT)
+ {
+ vmix_portc_t *portc = mixer->client_portc[i];
+
+ if (portc->play_mixing_func == NULL)
+ continue;
+ if (portc->play_choffs + portc->channels >
+ mixer->play_engine.channels)
+ portc->play_choffs = 0;
+ portc->play_mixing_func (portc,
+ mixer->play_engine.samples_per_frag);
+ nstreams++; /* Count the number of active output streams */
+ }
+
+ eng->num_active_outputs = (nstreams > 0) ? nstreams : 1;
+
+ /* Export the output mix to the device */
+ p = (int) (dmap->user_counter % dmap->bytes_in_use);
+ outbuf = dmap->dmabuf + p;
+ if (dmap->dmabuf != NULL)
+ {
+#ifndef CONFIG_OSS_VMIX_FLOAT
+ process_limiter (&eng->limiter_statevar, eng->chbufs, eng->channels,
+ eng->samples_per_frag);
+#endif
+ eng->converter (eng, outbuf, eng->chbufs, eng->channels,
+ eng->samples_per_frag);
+ }
+
+ dmap->user_counter += dmap->fragment_size;
+
+ }
+
+#ifdef CONFIG_OSS_VMIX_FLOAT
+ FP_RESTORE (fp_env, fp_flags);
+#endif
+ MUTEX_EXIT_IRQRESTORE (mixer->mutex, flags);
+/*
+ * Call oss_audio_outputintr outside FP mode because it may
+ * cause a task switch (under Solaris). Task switch may turn on CR0.TS under
+ * x86 which in turn will cause #nm exception.
+ */
+ for (i = 0; i < mixer->num_clientdevs; i++)
+ if (mixer->client_portc[i]->trigger_bits & PCM_ENABLE_OUTPUT)
+ {
+ vmix_portc_t *portc = mixer->client_portc[i];
+ oss_audio_outputintr (portc->audio_dev, 1);
+ }
+
+ for (i = 0; i < mixer->num_loopdevs; i++)
+ {
+ if (mixer->loop_portc[i]->trigger_bits & PCM_ENABLE_INPUT)
+ {
+ oss_audio_inputintr (mixer->loop_portc[i]->audio_dev, 0);
+ }
+ }
+ DOWN_STATUS (0x04);
+}
+
+void
+vmix_setup_play_engine (vmix_mixer_t * mixer, adev_t * adev, dmap_t * dmap)
+{
+ int fmt;
+ int frags = 0x7fff0007; /* fragment size of 128 bytes */
+ int i;
+ int old_min;
+
+/*
+ * Sample format (and endianess) setup
+ *
+ */
+
+ /* First make sure a sane format is selected before starting to probe */
+ fmt = adev->d->adrv_set_format (mixer->masterdev, AFMT_S16_LE);
+ fmt = adev->d->adrv_set_format (mixer->masterdev, AFMT_S16_NE);
+
+ /* Find out the "best" sample format supported by the device */
+
+ if (adev->oformat_mask & AFMT_S16_OE)
+ fmt = AFMT_S16_OE;
+ if (adev->oformat_mask & AFMT_S16_NE)
+ fmt = AFMT_S16_NE;
+
+ if (mixer->multich_enable) /* Better quality enabled */
+ {
+ if (adev->oformat_mask & AFMT_S32_OE)
+ fmt = AFMT_S32_OE;
+ if (adev->oformat_mask & AFMT_S32_NE)
+ fmt = AFMT_S32_NE;
+ }
+
+ fmt = adev->d->adrv_set_format (mixer->masterdev, fmt);
+ mixer->play_engine.fmt = fmt;
+
+ switch (fmt)
+ {
+ case AFMT_S16_NE:
+ mixer->play_engine.bits = 16;
+ mixer->play_engine.converter = export16ne;
+ break;
+
+ case AFMT_S16_OE:
+ mixer->play_engine.bits = 16;
+ mixer->play_engine.converter = export16oe;
+ break;
+
+ case AFMT_S32_NE:
+ mixer->play_engine.bits = 32;
+ mixer->play_engine.converter = export32ne;
+ break;
+
+ case AFMT_S32_OE:
+ mixer->play_engine.bits = 32;
+ mixer->play_engine.converter = export32oe;
+ break;
+
+ default:
+ cmn_err (CE_CONT, "Unrecognized sample format %x\n", fmt);
+ return;
+ }
+/*
+ * Number of channels
+ */
+ mixer->play_engine.channels = mixer->max_channels;
+
+ if (mixer->play_engine.channels > MAX_PLAY_CHANNELS)
+ mixer->play_engine.channels = MAX_PLAY_CHANNELS;
+
+ if (!mixer->multich_enable)
+ mixer->play_engine.channels = 2;
+
+ /* Force the device to stereo before trying with (possibly) multiple channels */
+ adev->d->adrv_set_channels (mixer->masterdev, 2);
+
+ mixer->play_engine.channels =
+ adev->d->adrv_set_channels (mixer->masterdev,
+ mixer->play_engine.channels);
+
+ if (mixer->play_engine.channels > MAX_PLAY_CHANNELS)
+ {
+ cmn_err (CE_WARN,
+ "Number of channels (%d) is larger than maximum (%d)\n",
+ mixer->play_engine.channels, MAX_PLAY_CHANNELS);
+ return;
+ }
+
+ if (mixer->play_engine.channels > 2)
+ {
+ DDB (cmn_err
+ (CE_CONT, "Enabling multi channel play mode, %d hw channels\n",
+ mixer->play_engine.channels));
+ }
+ else if (mixer->play_engine.channels != 2)
+ {
+ cmn_err (CE_WARN,
+ "Master device doesn't support suitable channel configuration\n");
+
+ return;
+ }
+
+ mixer->play_engine.rate =
+ oss_audio_set_rate (mixer->masterdev, mixer->rate);
+ mixer->rate = mixer->play_engine.rate;
+
+ if (mixer->play_engine.rate <= 22050)
+ frags = 0x7fff0004; /* Use smaller fragments */
+
+ audio_engines[mixer->masterdev]->hw_parms.channels =
+ mixer->play_engine.channels;
+ audio_engines[mixer->masterdev]->hw_parms.rate = mixer->play_engine.rate;
+ audio_engines[mixer->masterdev]->dmap_out->data_rate =
+ mixer->play_engine.rate * mixer->play_engine.channels *
+ mixer->play_engine.bits / 8;
+ audio_engines[mixer->masterdev]->dmap_out->frame_size =
+ mixer->play_engine.channels * mixer->play_engine.bits / 8;
+
+ old_min = adev->min_fragments;
+#if 0
+ if ((adev->max_fragments == 0 || adev->max_fragments >= 4)
+ && adev->min_block == 0)
+ adev->min_fragments = 4;
+#endif
+
+ oss_audio_ioctl (mixer->masterdev, NULL, SNDCTL_DSP_SETFRAGMENT,
+ (ioctl_arg) & frags);
+ oss_audio_ioctl (mixer->masterdev, NULL, SNDCTL_DSP_GETBLKSIZE,
+ (ioctl_arg) & mixer->play_engine.fragsize);
+
+ dmap->bytes_in_use = dmap->fragment_size * dmap->nfrags;
+
+ oss_audio_ioctl (mixer->masterdev, NULL, SNDCTL_DSP_GETBLKSIZE,
+ (ioctl_arg) & mixer->play_engine.fragsize);
+ adev->min_fragments = old_min;
+
+ mixer->play_engine.fragsize = dmap->fragment_size;
+
+/*
+ * Determine how many fragments we need to keep filled.
+ */
+ if (adev->vmix_flags & VMIX_MULTIFRAG)
+ mixer->play_engine.max_playahead = 32;
+ else
+ mixer->play_engine.max_playahead = 4;
+
+ if (mixer->play_engine.max_playahead >
+ audio_engines[mixer->masterdev]->dmap_out->nfrags)
+ mixer->play_engine.max_playahead =
+ audio_engines[mixer->masterdev]->dmap_out->nfrags;
+
+/*
+ * Try to keep one empty fragment after the one currently being played
+ * by the device. Writing too close to the playback point may cause
+ * massive clicking with some devices.
+ */
+ if (dmap->nfrags > 2 && mixer->play_engine.max_playahead == dmap->nfrags)
+ mixer->play_engine.max_playahead--;
+
+ mixer->play_engine.samples_per_frag =
+ mixer->play_engine.fragsize / mixer->play_engine.channels /
+ (mixer->play_engine.bits / 8);
+
+ if (mixer->play_engine.samples_per_frag > CHBUF_SAMPLES)
+ {
+ cmn_err (CE_WARN, "Too many samples per fragment (%d,%d)\n",
+ mixer->play_engine.samples_per_frag, CHBUF_SAMPLES);
+ return;
+ }
+
+ for (i = 0; i < mixer->play_engine.channels; i++)
+ {
+ if (mixer->play_engine.chbufs[i] == NULL) /* Not allocated yet */
+ {
+ mixer->play_engine.chbufs[i] =
+ PMALLOC (mixer->master_portc,
+ CHBUF_SAMPLES * sizeof (vmix_sample_t));
+ if (mixer->play_engine.chbufs[i] == NULL)
+ {
+ cmn_err (CE_WARN, "Out of memory\n");
+ return;
+ }
+ }
+
+ if (mixer->play_engine.channel_order[i] >= mixer->play_engine.channels)
+ mixer->play_engine.channel_order[i] = i;
+ }
+
+ dmap->audio_callback = vmix_play_callback; /* Enable conversions */
+ dmap->callback_parm = mixer->instance_num;
+ dmap->dma_mode = PCM_ENABLE_OUTPUT;
+
+ if (mixer->inputdev == mixer->masterdev)
+ {
+ mixer->record_engine.rate = mixer->play_engine.rate;
+ mixer->record_engine.bits = mixer->play_engine.bits;
+ mixer->record_engine.fragsize = mixer->play_engine.fragsize;
+ mixer->record_engine.channels = mixer->play_engine.channels;
+ mixer->record_engine.samples_per_frag =
+ mixer->play_engine.samples_per_frag;
+ }
+
+ if (mixer->num_clientdevs > 1)
+ {
+ adev->redirect_out = mixer->client_portc[0]->audio_dev;
+ }
+
+ /*
+ * Fill in the initial playback data (silence) to avoid underruns
+ */
+ vmix_play_callback (mixer->masterdev, mixer->instance_num);
+
+ if (mixer->masterdev == mixer->inputdev)
+ finalize_record_engine (mixer, fmt, audio_engines[mixer->inputdev],
+ audio_engines[mixer->inputdev]->dmap_in);
+}