Changeset 1828
- Timestamp:
- 05/10/10 07:44:28 (2 years ago)
- Files:
-
- trunk/libffado/doc/motu_firewire_protocol-mk3.txt (modified) (2 diffs)
- trunk/libffado/src/motu/motu_avdevice.cpp (modified) (10 diffs)
- trunk/libffado/src/motu/motu_avdevice.h (modified) (5 diffs)
- trunk/libffado/src/motu/motu_controls.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/doc/motu_firewire_protocol-mk3.txt
r1818 r1828 2 2 using an 828 Mk 3. 3 3 4 Version: 20100 426-14 Version: 20100510-1 5 5 Author: Jonathan Woithe 6 6 … … 126 126 127 127 The clock source is set with a quadlet write to bits 0, 3 and 4 of register 128 0xfffff0000b14. Values for bits 4-3- 1:128 0xfffff0000b14. Values for bits 4-3-0: 129 129 0-0-0 = internal / SMTPE 130 130 0-0-1 = Word clock trunk/libffado/src/motu/motu_avdevice.cpp
r1818 r1828 657 657 // port if the sample rate is set to a 1x or 2x rate later. 658 658 if (cancel_adat) { 659 setOpticalMode( MOTU_CTRL_DIR_INOUT, MOTU_OPTICAL_MODE_OFF);659 setOpticalMode(0, MOTU_CTRL_DIR_INOUT, MOTU_OPTICAL_MODE_OFF); 660 660 } 661 661 … … 714 714 break; 715 715 case MOTU_CLKSRC_SPDIF_TOSLINK: 716 if (getOpticalMode( MOTU_DIR_IN) == MOTU_OPTICAL_MODE_TOSLINK)716 if (getOpticalMode(0, MOTU_DIR_IN) == MOTU_OPTICAL_MODE_TOSLINK) 717 717 src_name = "TOSLink "; 718 718 else … … 895 895 896 896 int samp_freq = getSamplingFrequency(); 897 unsigned int optical_in_mode = getOpticalMode( MOTU_DIR_IN);898 unsigned int optical_out_mode = getOpticalMode( MOTU_DIR_OUT);897 unsigned int optical_in_mode = getOpticalMode(0, MOTU_DIR_IN); 898 unsigned int optical_out_mode = getOpticalMode(0, MOTU_DIR_OUT); 899 899 unsigned int event_size_in = getEventSize(MOTU_DIR_IN); 900 900 unsigned int event_size_out= getEventSize(MOTU_DIR_OUT); … … 907 907 // up without this set to anything sensible. In this case, writes to 908 908 // MOTU_REG_ISOCTRL fail more often than not, which is bad. 909 setOpticalMode( MOTU_DIR_IN, optical_in_mode);910 setOpticalMode( MOTU_DIR_OUT, optical_out_mode);909 setOpticalMode(0, MOTU_DIR_IN, optical_in_mode); 910 setOpticalMode(0, MOTU_DIR_OUT, optical_out_mode); 911 911 912 912 // Allocate bandwidth if not previously done. … … 1221 1221 } 1222 1222 1223 unsigned int MotuDevice::getOpticalMode(unsigned int dir) { 1223 signed int MotuDevice::getDeviceGeneration(void) { 1224 if (m_motu_model == MOTU_MODEL_828MkI) 1225 return MOTU_DEVICE_G1; 1226 if (m_motu_model==MOTU_MODEL_828mk3 || 1227 m_motu_model==MOTU_MODEL_ULTRALITEmk3) 1228 return MOTU_DEVICE_G3; 1229 return MOTU_DEVICE_G2; 1230 } 1231 1232 unsigned int MotuDevice::getOpticalMode(unsigned int port, unsigned int dir) { 1233 // Only the "Mark 3" (aka G3) MOTU devices had more than one optical port. 1234 // Therefore the "port" parameter is ignored for all devices other than 1235 // the Mark 3 devices. 1224 1236 unsigned int reg; 1237 unsigned int mask, shift; 1225 1238 1226 1239 if (m_motu_model == MOTU_MODEL_828MkI) { 1227 1240 // The early devices used a different register layout. 1228 unsigned int mask, shift;1229 1241 reg = ReadRegister(MOTU_G1_REG_CONFIG); 1230 1242 mask = (dir==MOTU_DIR_IN)?MOTU_G1_OPT_IN_MODE_MASK:MOTU_G1_OPT_OUT_MODE_MASK; 1231 1243 shift = (dir==MOTU_DIR_IN)?MOTU_G1_OPT_IN_MODE_BIT0:MOTU_G1_OPT_OUT_MODE_BIT0; 1232 switch ( reg & mask) {1244 switch ((reg & mask) >> shift) { 1233 1245 case MOTU_G1_OPTICAL_OFF: return MOTU_OPTICAL_MODE_OFF; 1234 1246 case MOTU_G1_OPTICAL_TOSLINK: return MOTU_OPTICAL_MODE_TOSLINK; … … 1241 1253 } 1242 1254 1255 if (getDeviceGeneration() == MOTU_DEVICE_G3) { 1256 debugOutput(DEBUG_LEVEL_INFO, "Optical mode control not implemented for Mark3/G3 devices yet"); 1257 return 0; 1258 } 1259 1243 1260 reg = ReadRegister(MOTU_REG_ROUTE_PORT_CONF); 1244 1245 if (dir == MOTU_DIR_IN) 1246 return (reg & MOTU_OPTICAL_IN_MODE_MASK) >> 8; 1247 else 1248 return (reg & MOTU_OPTICAL_OUT_MODE_MASK) >> 10; 1249 } 1250 1251 signed int MotuDevice::setOpticalMode(unsigned int dir, unsigned int mode) { 1252 unsigned int reg; 1261 mask = (dir==MOTU_DIR_IN)?MOTU_G2_OPTICAL_IN_MODE_MASK:MOTU_G2_OPTICAL_OUT_MODE_MASK; 1262 shift = (dir==MOTU_DIR_IN)?MOTU_G2_OPTICAL_IN_MODE_BIT0:MOTU_G2_OPTICAL_OUT_MODE_BIT0; 1263 1264 switch ((reg & mask) >> shift) { 1265 case MOTU_G2_OPTICAL_MODE_OFF: return MOTU_OPTICAL_MODE_OFF; 1266 case MOTU_G2_OPTICAL_MODE_ADAT: return MOTU_OPTICAL_MODE_ADAT; 1267 case MOTU_G2_OPTICAL_MODE_TOSLINK: return MOTU_OPTICAL_MODE_TOSLINK; 1268 } 1269 1270 return 0; 1271 } 1272 1273 signed int MotuDevice::setOpticalMode(unsigned int port, unsigned int dir, 1274 unsigned int mode) { 1275 // Only the "Mark 3" (aka G3) MOTU devices had more than one optical port. 1276 // Therefore the "port" parameter is ignored for all devices other than 1277 // the Mark 3 devices. 1278 unsigned int reg, g2mode; 1253 1279 unsigned int opt_ctrl = 0x0000002; 1254 1280 … … 1275 1301 } 1276 1302 1303 if (getDeviceGeneration() == MOTU_DEVICE_G3) { 1304 debugOutput(DEBUG_LEVEL_INFO, "Optical mode control not implemented for Mark3/G3 devices yet"); 1305 return 0; 1306 } 1307 1277 1308 reg = ReadRegister(MOTU_REG_ROUTE_PORT_CONF); 1309 1310 // Map from user mode to values sent to the device registers. 1311 g2mode = 0; 1312 switch (mode) { 1313 case MOTU_OPTICAL_MODE_OFF: g2mode = MOTU_G2_OPTICAL_MODE_OFF; break; 1314 case MOTU_OPTICAL_MODE_ADAT: g2mode = MOTU_G2_OPTICAL_MODE_ADAT; break; 1315 case MOTU_OPTICAL_MODE_TOSLINK: g2mode = MOTU_G2_OPTICAL_MODE_TOSLINK; break; 1316 } 1278 1317 1279 1318 // Set up the optical control register value according to the current … … 1281 1320 // what the "Optical control" register does, so the values it's set to 1282 1321 // are more or less "magic" numbers. 1283 if ((reg & MOTU_ OPTICAL_IN_MODE_MASK) != (MOTU_OPTICAL_MODE_ADAT<<8))1322 if ((reg & MOTU_G2_OPTICAL_IN_MODE_MASK) != (MOTU_G2_OPTICAL_MODE_ADAT<<MOTU_G2_OPTICAL_IN_MODE_BIT0)) 1284 1323 opt_ctrl |= 0x00000080; 1285 if ((reg & MOTU_ OPTICAL_OUT_MODE_MASK) != (MOTU_OPTICAL_MODE_ADAT<<10))1324 if ((reg & MOTU_G2_OPTICAL_OUT_MODE_MASK) != (MOTU_G2_OPTICAL_MODE_ADAT<<MOTU_G2_OPTICAL_OUT_MODE_BIT0)) 1286 1325 opt_ctrl |= 0x00000040; 1287 1326 1288 1327 if (dir & MOTU_DIR_IN) { 1289 reg &= ~MOTU_ OPTICAL_IN_MODE_MASK;1290 reg |= ( mode << 8) & MOTU_OPTICAL_IN_MODE_MASK;1291 if ( mode != MOTU_OPTICAL_MODE_ADAT)1328 reg &= ~MOTU_G2_OPTICAL_IN_MODE_MASK; 1329 reg |= (g2mode << MOTU_G2_OPTICAL_IN_MODE_BIT0) & MOTU_G2_OPTICAL_IN_MODE_MASK; 1330 if (g2mode != MOTU_G2_OPTICAL_MODE_ADAT) 1292 1331 opt_ctrl |= 0x00000080; 1293 1332 else … … 1295 1334 } 1296 1335 if (dir & MOTU_DIR_OUT) { 1297 reg &= ~MOTU_ OPTICAL_OUT_MODE_MASK;1298 reg |= (mode << 10) & MOTU_OPTICAL_OUT_MODE_MASK;1299 if ( mode != MOTU_OPTICAL_MODE_ADAT)1336 reg &= ~MOTU_G2_OPTICAL_OUT_MODE_MASK; 1337 reg |= (mode << MOTU_G2_OPTICAL_OUT_MODE_BIT0) & MOTU_G2_OPTICAL_OUT_MODE_MASK; 1338 if (g2mode != MOTU_G2_OPTICAL_MODE_ADAT) 1300 1339 opt_ctrl |= 0x00000040; 1301 1340 else 1302 1341 opt_ctrl &= ~0x00000040; 1303 1342 } 1343 1344 /* Setting bit 25 in the route/port configuration register enables the 1345 * setting of the optical mode. Bit 24 allows the phones assign to be 1346 * set using the lower 8 bits of the register. This function has no 1347 * business setting that, so make sure bit 24 is masked off. 1348 */ 1349 reg |= 0x02000000; 1350 reg &= ~0x01000000; 1304 1351 1305 1352 // FIXME: there seems to be more to it than this, but for … … 1323 1370 // Note that all audio channels are sent using 3 bytes. 1324 1371 signed int sample_rate = getSamplingFrequency(); 1325 signed int optical_mode = getOpticalMode( direction);1372 signed int optical_mode = getOpticalMode(0, direction); 1326 1373 signed int size = 4+6; 1327 1374 trunk/libffado/src/motu/motu_avdevice.h
r1812 r1828 39 39 #define MOTU_BASE_ADDR 0xfffff0000000ULL 40 40 41 /* Bitmasks and values used when setting MOTU device registers */ 41 /* Bitmasks and values used when setting MOTU device registers. Note that 42 * the only "generation 1" device presently supported is the original 828. 43 * "Generation 2" devices include the original Traveler, the 828Mk2, the 44 * original Ultralite, the 896/896HD and so forth. "Generation 3" devices 45 * are all those which carry the "Mark 3" moniker. 46 */ 42 47 #define MOTU_RATE_BASE_44100 (0<<3) 43 48 #define MOTU_RATE_BASE_48000 (1<<3) … … 48 53 #define MOTU_RATE_MULTIPLIER_MASK (0x00000030) 49 54 50 #define MOTU_OPTICAL_MODE_OFF 0x00 51 #define MOTU_OPTICAL_MODE_ADAT 0x01 52 #define MOTU_OPTICAL_MODE_TOSLINK 0x02 53 #define MOTU_OPTICAL_IN_MODE_MASK (0x00000300) 54 #define MOTU_OPTICAL_OUT_MODE_MASK (0x00000c00) 55 #define MOTU_OPTICAL_MODE_MASK (MOTU_OPTICAL_IN_MODE_MASK|MOTU_OPTICAL_MODE_MASK) 55 #define MOTU_G2_OPTICAL_MODE_OFF 0x00 56 #define MOTU_G2_OPTICAL_MODE_ADAT 0x01 57 #define MOTU_G2_OPTICAL_MODE_TOSLINK 0x02 58 #define MOTU_G2_OPTICAL_IN_MODE_MASK (0x00000300) 59 #define MOTU_G2_OPTICAL_IN_MODE_BIT0 8 60 #define MOTU_G2_OPTICAL_OUT_MODE_MASK (0x00000c00) 61 #define MOTU_G2_OPTICAL_OUT_MODE_BIT0 10 62 #define MOTU_G2_OPTICAL_MODE_MASK (MOTU_G2_OPTICAL_IN_MODE_MASK|MOTU_G2_OPTICAL_MODE_MASK) 56 63 57 64 #define MOTU_CLKSRC_MASK 0x00000007 … … 138 145 139 146 /* Mark3 device registers - these don't have MOTU_BASE_ADDR as the base 140 * address so for now we'll define them as absolute addresses. 147 * address so for now we'll define them as absolute addresses. The "Mark 3" 148 * (aka G3) devices share a number of control registers with the G2 devices. 149 * Where this occurs we just use the G2 definitions since there's little to 150 * be gained by adding duplicate defines. 141 151 */ 142 152 #define MOTU_MARK3_REG_MIXER 0xffff00010000LL 153 154 /* Mark3 (aka G3) register constants for cases where the G3 devices differ 155 * from the G2s. 156 */ 157 #define MOTU_G3_CLKSRC_MASK 0x00000019 158 #define MOTU_G3_CLKSRC_INTERNAL 0x00000000 159 #define MOTU_G3_CLKSRC_WORDCLOCK 0x00000001 160 #define MOTU_G3_CLKSRC_SPDIR 0x00000010 161 #define MOTU_G3_CLKSRC_ADAT_A 0x00000018 162 #define MOTU_G3_CLKSRC_ADAT_B 0x00000019 163 164 /* The following values are used when defining configuration structures and 165 * calling driver functions. They are generally not raw values written to 166 * registers. 167 */ 143 168 144 169 /* Port Active Flags (ports declaration) */ … … 179 204 #define MOTU_DIR_INOUT (MOTU_DIR_IN | MOTU_DIR_OUT) 180 205 206 /* Optical port mode settings/flags */ 207 #define MOTU_OPTICAL_MODE_OFF 0x0000 208 #define MOTU_OPTICAL_MODE_ADAT 0x0001 209 #define MOTU_OPTICAL_MODE_TOSLINK 0x0002 210 #define MOTU_OPTICAL_PORT_A 0x0001 211 #define MOTU_OPTICAL_PORT_B 0x0002 212 #define MOTU_OPTICAL_PORT_ALL (MOTU_OPTICAL_PORT_A|MOTU_OPTICAL_PORT_B) 213 214 /* Device generation identifiers */ 215 #define MOTU_DEVICE_G1 0x0001 216 #define MOTU_DEVICE_G2 0x0002 217 #define MOTU_DEVICE_G3 0x0003 218 181 219 class ConfigRom; 182 220 class Ieee1394Service; … … 300 338 virtual bool stopStreamByIndex(int i); 301 339 340 signed int getDeviceGeneration(void); 341 302 342 signed int getIsoRecvChannel(void); 303 343 signed int getIsoSendChannel(void); 304 unsigned int getOpticalMode(unsigned int dir);305 signed int setOpticalMode(unsigned int dir, unsigned int mode);344 unsigned int getOpticalMode(unsigned int port, unsigned int dir); 345 signed int setOpticalMode(unsigned int port, unsigned int dir, unsigned int mode); 306 346 307 347 signed int getEventSize(unsigned int dir); trunk/libffado/src/motu/motu_controls.cpp
r1763 r1828 685 685 OpticalMode::setValue(int v) 686 686 { 687 unsigned int val ;687 unsigned int val, dir; 688 688 debugOutput(DEBUG_LEVEL_VERBOSE, "setValue for optical mode %d to %d\n", m_register, v); 689 689 690 // Need to get current optical modes so we can preserve the one we're 691 // not setting. Input mode is in bits 9-8, output is in bits 11-10. 692 val = m_parent.ReadRegister(MOTU_REG_ROUTE_PORT_CONF) & 0x00000f00; 693 694 // Set mode as requested. An invalid setting is effectively ignored. 695 if (v>=0 && v<=3) { 696 if (m_register == MOTU_CTRL_DIR_IN) { 697 val = (val & ~0x0300) | ((v & 0x03) << 8); 698 } else { 699 val = (val & ~0x0c00) | ((v & 0x03) << 10); 700 } 701 } 702 // Bit 25 indicates that optical modes are being set 703 val |= 0x02000000; 704 m_parent.WriteRegister(MOTU_REG_ROUTE_PORT_CONF, val); 705 690 /* Assume v is 0 for "off", 1 for "ADAT" and 2 for "Toslink" */ 691 switch (v) { 692 case 0: val = MOTU_OPTICAL_MODE_OFF; break; 693 case 1: val = MOTU_OPTICAL_MODE_ADAT; break; 694 case 2: val = MOTU_OPTICAL_MODE_TOSLINK; break; 695 default: return true; 696 } 697 dir = (m_register==MOTU_CTRL_DIR_IN)?MOTU_DIR_IN:MOTU_DIR_OUT; 698 m_parent.setOpticalMode(0, dir, val); 706 699 return true; 707 700 } … … 710 703 OpticalMode::getValue() 711 704 { 712 unsigned int val;705 unsigned int dir; 713 706 debugOutput(DEBUG_LEVEL_VERBOSE, "getValue for optical mode %d\n", m_register); 714 707 715 708 // FIXME: we could just read the appropriate mixer status field from the 716 709 // receive stream processor once we work out an efficient way to do this. 717 val = m_parent.ReadRegister(MOTU_REG_ROUTE_PORT_CONF); 718 if (m_register == MOTU_CTRL_DIR_IN) 719 val = (val >> 8) & 0x03; 720 else 721 val = (val >> 10) & 0x03; 722 return val; 710 dir = (m_register==MOTU_CTRL_DIR_IN)?MOTU_DIR_IN:MOTU_DIR_OUT; 711 switch (m_parent.getOpticalMode(0, dir)) { 712 case MOTU_OPTICAL_MODE_OFF: return 0; 713 case MOTU_OPTICAL_MODE_ADAT: return 1; 714 case MOTU_OPTICAL_MODE_TOSLINK: return 2; 715 default: return 0; 716 } 717 return 0; 723 718 } 724 719
