== M-Audio Project-Mix IO == This page is to help with developing support for the Project-Mix I/O and similar devices. -- Update -- This device is now usable under Linux using Takashi Sakamoto's snd-bebob drivers and ffado-mixer. The following is a guide on how to set it up. This will likely also work for the FW1814 and any other devices covered by Takashi's driver: [https://wornwinter.wordpress.com/2015/02/05/how-to-get-your-m-audio-projectmix-io-working-in-linux/ How to Get Your ProjectMix working in Linux] For more information, see: - [wiki:MaudioBebob] I've been working with Bus Hound, and identified the following information: {{{ ProjectMix Notes ------------------- (Dashes added in hex for readability) Initialisation procedure ------------------------- -Show light pattern. -Initialise internal routing/volume. -Set spdif port to coaxial. -Set sample rate to 44100hz. (This happens twice) -Set clock source to internal with digital inputs muted. -Set sample rate to 44100hz. ------------------------- Base address 0xfffff0000000 Register Function 0b00 Control. Used for selecting clocks and setting the sample rate. Also controls digital ports. Misc --------- 00 ff 00 02 - 00 00 00 00 : Show light pattern on interface. Probably aesthetic. Visual feedback. Clocking --------- 00 ff 00 04 - 00 04 00 00 : Set clock source to internal with digital inputs muted. 00 ff 00 04 - 00 04 03 00 : Set clock source to internal with digital inputs unmuted. 00 ff 00 04 - 00 04 01 00 : Set clock source to external (digital). 00 ff 00 04 - 00 04 02 00 : Word clock. Sample Rate (Not exactly sure why there are two writes) ------------ 00 ff 18 00 - 90 01 ff ff : Set samplerate to 44100Hz 00 ff 19 00 - 90 01 ff ff 00 ff 18 00 - 90 02 ff ff : Set samplerate to 48000Hz 00 ff 19 00 - 90 02 ff ff 00 ff 18 00 - 90 03 ff ff : Set samplerate to 96000Hz 00 ff 19 00 - 90 03 ff ff Digital Port Selection ------------ 00 ff 00 04 - 00 04 00 00 : Set digital input to spdif. 00 ff 00 04 - 00 04 00 01 : Set digital input to ADAT. 00 08 b8 80 - 04 10 02 01 : Set spdif input port to coaxial. 00 08 b8 80 - 04 10 02 00 : Set spdif input port to optical. ------------------------------------------------------------------------------------------------------------ Base Address 0xffc700000000 Register Function 0070 0010 Internal mixing and volume. Seems to be set to "80 00 80 00 - 80 00 80 00" before some routing commands. Zeroing out this register initialises the internal routing/volume to their default settings. Firmware Information The device uses modified bridgeCo firmware. The details are as follows: $ firewire-request /dev/fw1 read 0xffffc8020000 70 result: 000: 62 72 69 64 67 65 43 6f 01 00 00 00 00 00 00 00 bridgeCo........ result: 010: 0c 6c 0d 00 cb 80 b1 00 91 00 01 00 01 00 00 00 .l.............. result: 020: 32 30 30 37 30 37 31 33 30 38 30 35 34 34 00 00 20070713080544.. result: 030: 00 00 00 00 00 00 00 00 00 00 08 20 00 00 18 00 ........... .... result: 040: 32 30 30 35 30 33 31 34 31 38 32 38 34 35 00 00 20050314182845.. result: 050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ result: 060: 00 00 00 00 00 00 00 00 78 56 34 12 20 0b ea 21 ........xV4. ..! $ cat /proc/asound/ProjectMix/firewire/firmware Manufacturer: bridgeCo Protocol Ver: 1 Build Ver: 0 GUID: 0x000D6C0C00B180CB Model ID: 0x10091 Model Rev: 1 Firmware Date: 20070713 Firmware Time: 080544 Firmware ID: 0x0 Firmware Ver: 0 Base Addr: 0x20080000 Max Size: 1572864 Loader Date: 20050314 Loader Time: 182845 ------------------------ Rotary encoder protocol ------------------------ Idle: ffc1 ffc7 0060 0000 <- 00 00 00 00 00 01 00 00 Level up: ffc1 ffc7 0060 0000 <- 00 00 00 01 00 01 00 00 Level down: ffc1 ffc7 0060 0000 <- 00 00 00 02 00 01 00 01 Headphone 1 up: ffc1 ffc7 0060 0000 <- 00 01 00 00 00 01 00 00 Headphone 1 down: ffc1 ffc7 0060 0000 <- 00 02 00 00 00 01 00 01 Headphone 2 up: ffc1 ffc7 0060 0000 <- 00 00 01 00 00 01 00 00 Headphone 2 down: ffc1 ffc7 0060 0000 <- 00 00 02 00 00 01 00 01 Note that the last byte seems to be changeable. Sometimes it is 00, othertimes it is 01. I'm not 100% sure why, however, the important thing seems to be the first 4 bytes. In general 01 = up, 02 = down. With each encoder having its own byte. ------------------------ }}} Additionally, some firewire dumps are here: [https://www.dropbox.com/s/tmyidxjjypqqoeg/projectmix-dump.zip] == Implementation == Below are my current definitions: {{{ #define PROJECTMIX_BASE_ADDR_A 0xfffff0000000ULL #define PROJECTMIX_CONTROL_REG 0x0b00 #define PROJECTMIX_BASE_ADDR_ROUTING 0xffc700000000ULL #define PROJECTMIX_ROUTE_REG 0x0700000 #define OPERATION_CONTROL 0 #define OPERATION_ROUTE 1 #define SAMPLERATE_44_A 0x00ff18009001ffff #define SAMPLERATE_48_A 0x00ff18009002ffff #define SAMPLERATE_96_A 0x00ff18009003ffff #define SAMPLERATE_44_B 0x00ff19009001ffff #define SAMPLERATE_48_B 0x00ff19009002ffff #define SAMPLERATE_96_B 0x00ff19009003ffff #define CLOCK_INTERNAL_DM 0x00ff000400040000 #define CLOCK_INTERNAL_DU 0x00ff000400040300 #define CLOCK_EXTERNAL 0x00ff000400040100 #define CLOCK_WORD 0x00ff000400040200 #define ROUTE_DEFAULT 0x0000000000000000 }}} I'm currently initializing the device in the following way: {{{ WriteRegister(OPERATION_CONTROL, PROJECTMIX_CONTROL_REG, 0x00ff0002); //Show lights on mixer. WriteRegisterOct(OPERATION_ROUTE, PROJECTMIX_ROUTE_REG, ROUTE_DEFAULT); //Set internal volume/routing to default. WriteRegisterOct(OPERATION_CONTROL, PROJECTMIX_CONTROL_REG, CLOCK_INTERNAL_DM); //Set clock source to internal with digital inputs muted. WriteRegisterOct(OPERATION_CONTROL, PROJECTMIX_CONTROL_REG, SAMPLERATE_44_A); //Set samplerate to 44100Hz. WriteRegisterOct(OPERATION_CONTROL, PROJECTMIX_CONTROL_REG, SAMPLERATE_44_B); }}} == Current Progress == I have managed to create a new (non-functional) driver within FFADO. It can currently initialize the device, set the clock source and the sample rate. If someone could help me out with this project, that'd be great! I'm unsure of the audio streaming protocol. You can see an example of it here using the 3-4 stereo output, unfortunately, the free version of Bus Hound only captures the first 8 bytes of each transaction :( {{{ 45 1h 11520 ISOC 01 0b 00 98 90 01 c3 d2 ........ 1.1.0 45 1h 11520 ISOC 01 0b 00 48 90 01 c2 f3 ...H.... 2.1.0 45 1h 11520 ISOC 01 0b 00 f8 90 01 c2 14 ........ 3.1.0 45 1h 11520 ISOC 01 0b 00 a8 90 01 c1 35 .......5 4.1.0 45 1h 11520 ISOC 01 0b 00 58 90 01 c0 56 ...X...V 5.1.0 45 1h 11520 ISOC 01 0b 00 08 90 01 bb 77 .......w 6.1.0 45 1h 11520 ISOC 01 0b 00 b8 90 01 ba 98 ........ 7.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 8.1.0 45 1h 11520 ISOC 01 0b 00 68 90 01 b9 b9 ...h.... 9.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 10.1.0 45 1h 11520 ISOC 01 0b 00 18 90 01 b8 da ........ 11.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 12.1.0 45 1h 11520 ISOC 01 0b 00 c8 90 01 b7 fb ........ 13.1.0 45 1h 11520 ISOC 01 0b 00 78 90 01 b7 1c ...x.... 14.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 15.1.0 45 1h 11520 ISOC 01 0b 00 28 90 01 b6 3d ...(...= 16.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 17.1.0 45 1h 11520 ISOC 01 02 00 e0 90 01 ff ff ........ 18.1.0 45 1h 11520 ISOC 01 02 00 90 90 01 ff ff ........ 19.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 20.1.0 45 1h 11520 ISOC 01 02 00 40 90 01 ff ff ...@.... 21.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 22.1.0 45 1h 11520 ISOC 01 02 00 f0 90 01 ff ff ........ 23.1.0 45 1h 11520 ISOC 01 02 00 a0 90 01 ff ff ........ 24.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 25.1.0 45 1h 11520 ISOC 01 02 00 50 90 01 ff ff ...P.... 26.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 27.1.0 45 1h 11520 ISOC 01 0b 00 00 90 01 c5 8f ........ 28.1.0 45 1h 11520 ISOC 01 0b 00 b0 90 01 c4 b1 ........ 29.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 30.1.0 45 1h 11520 ISOC 01 0b 00 60 90 01 c3 d2 ...`.... 31.1.0 45 0h 7168 ISOC 40 00 00 00 40 00 00 00 @...@... 32.1.0 }}}