55 | | // GenericAVC::AvDevice::showDevice(); |
---|
56 | | |
---|
| 58 | GenericAVC::AvDevice::showDevice(); |
---|
| 59 | } |
---|
| 60 | |
---|
| 61 | |
---|
| 62 | bool |
---|
| 63 | Device::probe( ConfigRom& configRom ) |
---|
| 64 | { |
---|
| 65 | unsigned int vendorId = configRom.getNodeVendorId(); |
---|
| 66 | unsigned int modelId = configRom.getModelId(); |
---|
| 67 | |
---|
| 68 | GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); |
---|
| 69 | if ( vendorModel.parse() ) { |
---|
| 70 | vendorModel.printTable(); |
---|
| 71 | return vendorModel.isPresent( vendorId, modelId ); |
---|
| 72 | } |
---|
| 73 | |
---|
| 74 | return false; |
---|
| 75 | } |
---|
| 76 | |
---|
| 77 | bool |
---|
| 78 | Device::discover() |
---|
| 79 | { |
---|
| 80 | unsigned int vendorId = m_pConfigRom->getNodeVendorId(); |
---|
| 81 | unsigned int modelId = m_pConfigRom->getModelId(); |
---|
| 82 | |
---|
| 83 | GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); |
---|
| 84 | if ( vendorModel.parse() ) { |
---|
| 85 | m_model = vendorModel.find( vendorId, modelId ); |
---|
| 86 | } |
---|
| 87 | |
---|
| 88 | if (!GenericAVC::VendorModel::isValid(m_model)) { |
---|
| 89 | return false; |
---|
| 90 | } |
---|
| 91 | debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", |
---|
| 92 | m_model.vendor_name.c_str(), m_model.model_name.c_str()); |
---|
| 93 | |
---|
| 94 | // get the info from the EFC |
---|
| 95 | if ( !discoverUsingEFC() ) { |
---|
| 96 | debugError( "Could not discover using EFC\n" ); |
---|
| 97 | return false; |
---|
| 98 | } |
---|
| 99 | |
---|
| 100 | // discover AVC-wise |
---|
| 101 | if ( !GenericAVC::AvDevice::discover() ) { |
---|
| 102 | debugError( "Could not discover GenericAVC::AvDevice\n" ); |
---|
| 103 | return false; |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | return true; |
---|
| 107 | } |
---|
| 108 | |
---|
| 109 | bool |
---|
| 110 | Device::discoverUsingEFC() |
---|
| 111 | { |
---|
| 112 | m_efc_discovery_done = false; |
---|
| 113 | |
---|
| 114 | if (!doEfcOverAVC(m_HwInfo)) { |
---|
| 115 | debugError("Could not read hardware capabilities\n"); |
---|
| 116 | return false; |
---|
| 117 | } |
---|
| 118 | |
---|
| 119 | // save the EFC version, since some stuff |
---|
| 120 | // depends on this |
---|
| 121 | m_efc_version = m_HwInfo.m_header.version; |
---|
| 122 | |
---|
| 123 | if (!updatePolledValues()) { |
---|
| 124 | debugError("Could not update polled values\n"); |
---|
| 125 | return false; |
---|
| 126 | } |
---|
| 127 | |
---|
| 128 | m_efc_discovery_done = true; |
---|
| 129 | return true; |
---|
| 130 | } |
---|
| 131 | |
---|
| 132 | FFADODevice * |
---|
| 133 | Device::createDevice( Ieee1394Service& ieee1394Service, |
---|
| 134 | std::auto_ptr<ConfigRom>( configRom )) |
---|
| 135 | { |
---|
| 136 | unsigned int vendorId = configRom->getNodeVendorId(); |
---|
| 137 | unsigned int modelId = configRom->getModelId(); |
---|
| 138 | |
---|
| 139 | switch(vendorId) { |
---|
| 140 | case FW_VENDORID_ECHO: return new ECHO::AudioFire(ieee1394Service, configRom ); |
---|
| 141 | default: return new Device(ieee1394Service, configRom ); |
---|
| 142 | } |
---|
| 143 | } |
---|
| 144 | |
---|
| 145 | bool |
---|
| 146 | Device::doEfcOverAVC(EfcCmd &c) { |
---|
75 | | } |
---|
76 | | |
---|
77 | | efccmd->showEfcCmd(); |
---|
78 | | delete efccmd; |
---|
79 | | |
---|
80 | | // test the next command |
---|
81 | | cmd.setCommandType( AVC::AVCCommand::eCT_Control ); |
---|
82 | | |
---|
83 | | EfcPolledValuesCmd *efccmd2=new EfcPolledValuesCmd(); |
---|
84 | | if (!efccmd2) { |
---|
85 | | debugError("could not allocate efc cmd 2\n"); |
---|
86 | | return; |
---|
87 | | } |
---|
88 | | cmd.m_cmd = efccmd2; |
---|
89 | | |
---|
90 | | if ( !cmd.fire() ) { |
---|
91 | | debugError( "EfcOverAVCCmd command failed\n" ); |
---|
92 | | } |
---|
93 | | |
---|
94 | | efccmd2->showEfcCmd(); |
---|
95 | | delete efccmd2; |
---|
96 | | |
---|
97 | | } |
---|
98 | | |
---|
99 | | |
---|
100 | | bool |
---|
101 | | Device::probe( ConfigRom& configRom ) |
---|
102 | | { |
---|
103 | | unsigned int vendorId = configRom.getNodeVendorId(); |
---|
104 | | unsigned int modelId = configRom.getModelId(); |
---|
105 | | |
---|
106 | | GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); |
---|
107 | | if ( vendorModel.parse() ) { |
---|
108 | | vendorModel.printTable(); |
---|
109 | | return vendorModel.isPresent( vendorId, modelId ); |
---|
110 | | } |
---|
111 | | |
---|
112 | | return false; |
---|
113 | | } |
---|
114 | | |
---|
115 | | bool |
---|
116 | | Device::discover() |
---|
117 | | { |
---|
118 | | unsigned int vendorId = m_pConfigRom->getNodeVendorId(); |
---|
119 | | unsigned int modelId = m_pConfigRom->getModelId(); |
---|
120 | | |
---|
121 | | GenericAVC::VendorModel vendorModel( SHAREDIR "/ffado_driver_fireworks.txt" ); |
---|
122 | | if ( vendorModel.parse() ) { |
---|
123 | | m_model = vendorModel.find( vendorId, modelId ); |
---|
124 | | } |
---|
125 | | |
---|
126 | | if (!GenericAVC::VendorModel::isValid(m_model)) { |
---|
127 | | return false; |
---|
128 | | } |
---|
129 | | debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", |
---|
130 | | m_model.vendor_name.c_str(), m_model.model_name.c_str()); |
---|
131 | | |
---|
132 | | if ( !GenericAVC::AvDevice::discover() ) { |
---|
133 | | debugError( "Could not discover GenericAVC::AvDevice\n" ); |
---|
| 162 | c.showEfcCmd(); |
---|
| 163 | return false; |
---|
| 164 | } |
---|
| 165 | // c.showEfcCmd(); |
---|
| 166 | |
---|
| 167 | if ( c.m_header.retval != EfcCmd::eERV_Ok |
---|
| 168 | && c.m_header.retval != EfcCmd::eERV_FlashBusy) { |
---|
| 169 | debugError( "EFC command failed\n" ); |
---|
| 170 | c.showEfcCmd(); |
---|
140 | | FFADODevice * |
---|
141 | | Device::createDevice( Ieee1394Service& ieee1394Service, |
---|
142 | | std::auto_ptr<ConfigRom>( configRom )) |
---|
143 | | { |
---|
144 | | unsigned int vendorId = configRom->getNodeVendorId(); |
---|
145 | | |
---|
146 | | // return NULL; |
---|
147 | | |
---|
148 | | unsigned int modelId = configRom->getModelId(); |
---|
149 | | |
---|
150 | | switch(vendorId) { |
---|
151 | | case FW_VENDORID_ECHO: return new ECHO::AudioFire(ieee1394Service, configRom ); |
---|
152 | | default: return new Device(ieee1394Service, configRom ); |
---|
153 | | } |
---|
154 | | } |
---|
155 | | |
---|
| 177 | bool |
---|
| 178 | Device::updatePolledValues() { |
---|
| 179 | bool retval; |
---|
| 180 | |
---|
| 181 | pthread_mutex_lock( &m_polled_mutex ); |
---|
| 182 | retval = doEfcOverAVC(m_Polled); |
---|
| 183 | pthread_mutex_unlock( &m_polled_mutex ); |
---|
| 184 | |
---|
| 185 | return retval; |
---|
| 186 | } |
---|
| 187 | |
---|
| 188 | FFADODevice::ClockSourceVector |
---|
| 189 | Device::getSupportedClockSources() { |
---|
| 190 | FFADODevice::ClockSourceVector r; |
---|
| 191 | |
---|
| 192 | if (!m_efc_discovery_done) { |
---|
| 193 | debugError("EFC discovery not done yet!\n"); |
---|
| 194 | return r; |
---|
| 195 | } |
---|
| 196 | |
---|
| 197 | uint32_t active_clock=getClock(); |
---|
| 198 | |
---|
| 199 | if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_INTERNAL)) { |
---|
| 200 | debugOutput(DEBUG_LEVEL_VERBOSE, "Internal clock supported\n"); |
---|
| 201 | ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_INTERNAL); |
---|
| 202 | s.active=(active_clock == EFC_CMD_HW_CLOCK_INTERNAL); |
---|
| 203 | if (s.type != eCT_Invalid) r.push_back(s); |
---|
| 204 | } |
---|
| 205 | if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_SYTMATCH)) { |
---|
| 206 | debugOutput(DEBUG_LEVEL_VERBOSE, "Syt Match clock supported\n"); |
---|
| 207 | ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_SYTMATCH); |
---|
| 208 | s.active=(active_clock == EFC_CMD_HW_CLOCK_SYTMATCH); |
---|
| 209 | if (s.type != eCT_Invalid) r.push_back(s); |
---|
| 210 | } |
---|
| 211 | if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_WORDCLOCK)) { |
---|
| 212 | debugOutput(DEBUG_LEVEL_VERBOSE, "WordClock supported\n"); |
---|
| 213 | ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_WORDCLOCK); |
---|
| 214 | s.active=(active_clock == EFC_CMD_HW_CLOCK_WORDCLOCK); |
---|
| 215 | if (s.type != eCT_Invalid) r.push_back(s); |
---|
| 216 | } |
---|
| 217 | if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_SPDIF)) { |
---|
| 218 | debugOutput(DEBUG_LEVEL_VERBOSE, "SPDIF clock supported\n"); |
---|
| 219 | ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_SPDIF); |
---|
| 220 | s.active=(active_clock == EFC_CMD_HW_CLOCK_SPDIF); |
---|
| 221 | if (s.type != eCT_Invalid) r.push_back(s); |
---|
| 222 | } |
---|
| 223 | if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_ADAT_1)) { |
---|
| 224 | debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 1 clock supported\n"); |
---|
| 225 | ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_ADAT_1); |
---|
| 226 | s.active=(active_clock == EFC_CMD_HW_CLOCK_ADAT_1); |
---|
| 227 | if (s.type != eCT_Invalid) r.push_back(s); |
---|
| 228 | } |
---|
| 229 | if(EFC_CMD_HW_CHECK_FLAG(m_HwInfo.m_supported_clocks, EFC_CMD_HW_CLOCK_ADAT_2)) { |
---|
| 230 | debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 2 clock supported\n"); |
---|
| 231 | ClockSource s=clockIdToClockSource(EFC_CMD_HW_CLOCK_ADAT_2); |
---|
| 232 | s.active=(active_clock == EFC_CMD_HW_CLOCK_ADAT_2); |
---|
| 233 | if (s.type != eCT_Invalid) r.push_back(s); |
---|
| 234 | } |
---|
| 235 | |
---|
| 236 | return r; |
---|
| 237 | } |
---|
| 238 | |
---|
| 239 | bool |
---|
| 240 | Device::isClockValid(uint32_t id) { |
---|
| 241 | // always valid |
---|
| 242 | if (id==EFC_CMD_HW_CLOCK_INTERNAL) return true; |
---|
| 243 | |
---|
| 244 | // the polled values are used to detect |
---|
| 245 | // whether clocks are valid |
---|
| 246 | if (!updatePolledValues()) { |
---|
| 247 | debugError("Could not update polled values\n"); |
---|
| 248 | return false; |
---|
| 249 | } |
---|
| 250 | return EFC_CMD_HW_CHECK_FLAG(m_Polled.m_status,id); |
---|
| 251 | } |
---|
| 252 | |
---|
| 253 | bool |
---|
| 254 | Device::setActiveClockSource(ClockSource s) { |
---|
| 255 | bool result; |
---|
| 256 | |
---|
| 257 | debugOutput(DEBUG_LEVEL_VERBOSE, "setting clock source to id: %d\n",s.id); |
---|
| 258 | |
---|
| 259 | if(!isClockValid(s.id)) { |
---|
| 260 | debugError("Clock not valid\n"); |
---|
| 261 | return false; |
---|
| 262 | } |
---|
| 263 | |
---|
| 264 | result=setClock(s.id); |
---|
| 265 | |
---|
| 266 | // From the ECHO sources: |
---|
| 267 | // "If this is a 1200F and the sample rate is being set via EFC, then |
---|
| 268 | // send the "phy reconnect command" so the device will vanish and reappear |
---|
| 269 | // with a new descriptor." |
---|
| 270 | |
---|
| 271 | // EfcPhyReconnectCmd rccmd; |
---|
| 272 | // if(!doEfcOverAVC(rccmd)) { |
---|
| 273 | // debugError("Phy reconnect failed"); |
---|
| 274 | // } else { |
---|
| 275 | // // sleep for one second such that the phy can get reconnected |
---|
| 276 | // sleep(1); |
---|
| 277 | // } |
---|
| 278 | |
---|
| 279 | return result; |
---|
| 280 | } |
---|
| 281 | |
---|
| 282 | FFADODevice::ClockSource |
---|
| 283 | Device::getActiveClockSource() { |
---|
| 284 | ClockSource s; |
---|
| 285 | uint32_t active_clock=getClock(); |
---|
| 286 | s=clockIdToClockSource(active_clock); |
---|
| 287 | s.active=true; |
---|
| 288 | return s; |
---|
| 289 | } |
---|
| 290 | |
---|
| 291 | FFADODevice::ClockSource |
---|
| 292 | Device::clockIdToClockSource(uint32_t clockid) { |
---|
| 293 | ClockSource s; |
---|
| 294 | debugOutput(DEBUG_LEVEL_VERBOSE, "clock id: %lu\n", clockid); |
---|
| 295 | |
---|
| 296 | // the polled values are used to detect |
---|
| 297 | // whether clocks are valid |
---|
| 298 | if (!updatePolledValues()) { |
---|
| 299 | debugError("Could not update polled values\n"); |
---|
| 300 | return s; |
---|
| 301 | } |
---|
| 302 | |
---|
| 303 | switch (clockid) { |
---|
| 304 | case EFC_CMD_HW_CLOCK_INTERNAL: |
---|
| 305 | debugOutput(DEBUG_LEVEL_VERBOSE, "Internal clock\n"); |
---|
| 306 | s.type=eCT_Internal; |
---|
| 307 | s.description="Internal sync"; |
---|
| 308 | break; |
---|
| 309 | |
---|
| 310 | case EFC_CMD_HW_CLOCK_SYTMATCH: |
---|
| 311 | debugOutput(DEBUG_LEVEL_VERBOSE, "Syt Match\n"); |
---|
| 312 | s.type=eCT_SytMatch; |
---|
| 313 | s.description="SYT Match"; |
---|
| 314 | break; |
---|
| 315 | |
---|
| 316 | case EFC_CMD_HW_CLOCK_WORDCLOCK: |
---|
| 317 | debugOutput(DEBUG_LEVEL_VERBOSE, "WordClock\n"); |
---|
| 318 | s.type=eCT_WordClock; |
---|
| 319 | s.description="Word Clock"; |
---|
| 320 | break; |
---|
| 321 | |
---|
| 322 | case EFC_CMD_HW_CLOCK_SPDIF: |
---|
| 323 | debugOutput(DEBUG_LEVEL_VERBOSE, "SPDIF clock\n"); |
---|
| 324 | s.type=eCT_SPDIF; |
---|
| 325 | s.description="SPDIF"; |
---|
| 326 | break; |
---|
| 327 | |
---|
| 328 | case EFC_CMD_HW_CLOCK_ADAT_1: |
---|
| 329 | debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 1 clock\n"); |
---|
| 330 | s.type=eCT_ADAT; |
---|
| 331 | s.description="ADAT 1"; |
---|
| 332 | break; |
---|
| 333 | |
---|
| 334 | case EFC_CMD_HW_CLOCK_ADAT_2: |
---|
| 335 | debugOutput(DEBUG_LEVEL_VERBOSE, "ADAT 2 clock\n"); |
---|
| 336 | s.type=eCT_ADAT; |
---|
| 337 | s.description="ADAT 2"; |
---|
| 338 | break; |
---|
| 339 | |
---|
| 340 | default: |
---|
| 341 | debugError("Invalid clock id: %d\n",clockid); |
---|
| 342 | return s; // return an invalid ClockSource |
---|
| 343 | } |
---|
| 344 | |
---|
| 345 | s.id=clockid; |
---|
| 346 | s.valid=isClockValid(clockid); |
---|
| 347 | |
---|
| 348 | return s; |
---|
| 349 | } |
---|
| 350 | |
---|
| 351 | uint32_t |
---|
| 352 | Device::getClock() { |
---|
| 353 | EfcGetClockCmd gccmd; |
---|
| 354 | if (!doEfcOverAVC(gccmd)) { |
---|
| 355 | debugError("Could not get clock info\n"); |
---|
| 356 | return EFC_CMD_HW_CLOCK_UNSPECIFIED; |
---|
| 357 | } |
---|
| 358 | debugOutput(DEBUG_LEVEL_VERBOSE, "Active clock: 0x%08lX\n",gccmd.m_clock); |
---|
| 359 | gccmd.showEfcCmd(); |
---|
| 360 | |
---|
| 361 | return gccmd.m_clock; |
---|
| 362 | } |
---|
| 363 | |
---|
| 364 | bool |
---|
| 365 | Device::setClock(uint32_t id) { |
---|
| 366 | EfcGetClockCmd gccmd; |
---|
| 367 | if (!doEfcOverAVC(gccmd)) { |
---|
| 368 | debugError("Could not get clock info\n"); |
---|
| 369 | return false; |
---|
| 370 | } |
---|
| 371 | debugOutput(DEBUG_LEVEL_VERBOSE, "Set clock: 0x%08lX\n", id); |
---|
| 372 | |
---|
| 373 | EfcSetClockCmd sccmd; |
---|
| 374 | sccmd.m_clock=id; |
---|
| 375 | sccmd.m_samplerate=gccmd.m_samplerate; |
---|
| 376 | sccmd.m_index=0; |
---|
| 377 | if (!doEfcOverAVC(sccmd)) { |
---|
| 378 | debugError("Could not set clock info\n"); |
---|
| 379 | return false; |
---|
| 380 | } |
---|
| 381 | return true; |
---|
| 382 | } |
---|