Changeset fb6c98f in mainline for uspace/drv/audio/sb16/dsp.c
- Timestamp:
- 2012-08-20T14:03:19Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6f57933
- Parents:
- 018ab50
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/audio/sb16/dsp.c
r018ab50 rfb6c98f 62 62 #define AUTO_DMA_MODE 63 63 64 static inline const char * dsp_state_to_str(dsp_state_t state) 65 { 66 static const char* state_names[] = { 67 [DSP_PLAYBACK_ACTIVE_EVENTS] = "PLAYBACK w/ EVENTS", 68 [DSP_CAPTURE_ACTIVE_EVENTS] = "CAPTURE w/o ACTIVE", 69 [DSP_PLAYBACK_NOEVENTS] = "PLAYBACK w/. EVENTS", 70 [DSP_CAPTURE_NOEVENTS] = "CAPTURE w/o EVENTS", 71 [DSP_STOPPED] = "STOPPED", 72 [DSP_READY] = "READY", 73 [DSP_NO_BUFFER] = "NO BUFFER", 74 }; 75 if (state < (sizeof(state_names) / sizeof(state_names[0]))) 76 return state_names[state]; 77 return "UNKNOWN"; 78 } 79 80 81 static inline void sb_dsp_change_state(sb_dsp_t *dsp, dsp_state_t state) 82 { 83 assert(dsp); 84 ddf_log_verbose("Changing state from %s to %s", 85 dsp_state_to_str(dsp->state), dsp_state_to_str(state)); 86 dsp->state = state; 87 } 88 64 89 static inline int sb_dsp_read(sb_dsp_t *dsp, uint8_t *data) 65 90 { … … 162 187 } 163 188 164 static inline void sb_clear_buffer(sb_dsp_t *dsp)165 {166 assert(dsp);167 dmamem_unmap_anonymous(dsp->buffer.data);168 dsp->buffer.data = NULL;169 dsp->buffer.size = 0;170 }171 172 189 static inline size_t sample_count(pcm_sample_format_t format, size_t byte_count) 173 190 { … … 185 202 dsp->event_exchange = NULL; 186 203 dsp->sb_dev = dev; 187 dsp->status = DSP_STOPPED; 188 dsp->ignore_interrupts = false; 204 dsp->state = DSP_NO_BUFFER; 189 205 sb_dsp_reset(dsp); 190 206 /* "DSP takes about 100 microseconds to initialize itself" */ … … 213 229 assert(dsp); 214 230 215 #ifndef AUTO_DMA_MODE216 if (dsp->status == DSP_PLAYBACK) {217 sb_dsp_start_active(dsp, SINGLE_DMA_16B_DA);218 }219 220 if (dsp->status == DSP_CAPTURE) {221 sb_dsp_start_active(dsp, SINGLE_DMA_16B_AD);222 }223 #endif224 225 if (dsp->ignore_interrupts)226 return;227 228 231 dsp->active.frame_count += 229 232 dsp->active.samples / ((dsp->active.mode & DSP_MODE_STEREO) ? 2 : 1); 230 233 231 if (dsp->event_exchange) { 232 switch (dsp->status) { 233 case DSP_PLAYBACK: 234 async_msg_1(dsp->event_exchange, 235 PCM_EVENT_FRAMES_PLAYED, dsp->active.frame_count); 236 break; 237 case DSP_CAPTURE: 238 async_msg_1(dsp->event_exchange, 239 PCM_EVENT_FRAMES_CAPTURED, dsp->active.frame_count); 240 break; 241 default: 242 case DSP_STOPPED: 243 ddf_log_warning("Interrupt while DSP stopped and " 244 "event exchange present. Terminating exchange"); 245 async_exchange_end(dsp->event_exchange); 246 dsp->event_exchange = NULL; 247 } 248 } else { 249 ddf_log_warning("Interrupt with no event consumer."); 234 switch (dsp->state) 235 { 236 case DSP_PLAYBACK_ACTIVE_EVENTS: 237 async_msg_1(dsp->event_exchange, 238 PCM_EVENT_FRAMES_PLAYED, dsp->active.frame_count); 239 case DSP_PLAYBACK_NOEVENTS: 240 #ifndef AUTO_DMA_MODE 241 sb_dsp_start_active(dsp, SINGLE_DMA_16B_DA); 242 #endif 243 break; 244 case DSP_CAPTURE_ACTIVE_EVENTS: 245 async_msg_1(dsp->event_exchange, 246 PCM_EVENT_FRAMES_CAPTURED, dsp->active.frame_count); 247 case DSP_CAPTURE_NOEVENTS: 248 #ifndef AUTO_DMA_MODE 249 sb_dsp_start_active(dsp, SINGLE_DMA_16B_DA); 250 #endif 251 break; 252 default: 253 ddf_log_warning("Interrupt while DSP not active"); 250 254 } 251 255 } … … 273 277 int sb_dsp_get_buffer_position(sb_dsp_t *dsp, size_t *pos) 274 278 { 275 if ( !dsp->buffer.data)279 if (dsp->state == DSP_NO_BUFFER) 276 280 return ENOENT; 277 281 282 assert(dsp->buffer.data); 278 283 async_sess_t *sess = devman_parent_device_connect(EXCHANGE_ATOMIC, 279 284 dsp->sb_dev->handle, IPC_FLAG_BLOCKING); … … 314 319 } 315 320 321 int sb_dsp_set_event_session(sb_dsp_t *dsp, async_sess_t *session) 322 { 323 assert(dsp); 324 if (dsp->event_session) 325 return EBUSY; 326 dsp->event_session = session; 327 ddf_log_debug("Set event session to %p.", session); 328 return EOK; 329 } 330 331 async_sess_t * sb_dsp_get_event_session(sb_dsp_t *dsp) 332 { 333 assert(dsp); 334 ddf_log_debug("Get event session: %p.", dsp->event_session); 335 return dsp->event_session; 336 } 337 316 338 int sb_dsp_get_buffer(sb_dsp_t *dsp, void **buffer, size_t *size) 317 339 { … … 321 343 /* buffer is already setup by for someone, refuse to work until 322 344 * it's released */ 323 if (dsp-> buffer.data)345 if (dsp->state != DSP_NO_BUFFER) 324 346 return EBUSY; 347 assert(dsp->buffer.data == NULL); 325 348 326 349 const int ret = sb_setup_buffer(dsp, *size); … … 333 356 if (size) 334 357 *size = dsp->buffer.size; 358 sb_dsp_change_state(dsp, DSP_READY); 335 359 } 336 360 return ret; 337 361 } 338 362 339 int sb_dsp_set_event_session(sb_dsp_t *dsp, async_sess_t *session)340 {341 assert(dsp);342 if (dsp->event_session)343 return EBUSY;344 dsp->event_session = session;345 ddf_log_debug("Set event session to %p.", session);346 return EOK;347 }348 349 async_sess_t * sb_dsp_get_event_session(sb_dsp_t *dsp)350 {351 assert(dsp);352 ddf_log_debug("Get event session: %p.", dsp->event_session);353 return dsp->event_session;354 }355 356 363 int sb_dsp_release_buffer(sb_dsp_t *dsp) 357 364 { 358 365 assert(dsp); 359 sb_clear_buffer(dsp);360 async_exchange_end(dsp->event_exchange);361 dsp->event_exchange = NULL;362 if (dsp->event_session)363 async_hangup(dsp->event_session);364 dsp-> event_session = NULL;366 if (dsp->state != DSP_READY && dsp->state != DSP_STOPPED) 367 return EINVAL; 368 assert(dsp->buffer.data); 369 dmamem_unmap_anonymous(dsp->buffer.data); 370 dsp->buffer.data = NULL; 371 dsp->buffer.size = 0; 365 372 ddf_log_debug("DSP buffer released."); 373 sb_dsp_change_state(dsp, DSP_NO_BUFFER); 366 374 return EOK; 367 375 } … … 388 396 if (!dsp->event_exchange) 389 397 return ENOMEM; 390 dsp->ignore_interrupts = false;391 398 } 392 399 … … 409 416 sampling_rate / (dsp->active.samples * channels)); 410 417 411 dsp->status = DSP_PLAYBACK; 418 sb_dsp_change_state(dsp, 419 frames ? DSP_PLAYBACK_ACTIVE_EVENTS : DSP_PLAYBACK_NOEVENTS); 412 420 413 421 return EOK; … … 422 430 async_exchange_end(dsp->event_exchange); 423 431 dsp->event_exchange = NULL; 432 sb_dsp_change_state(dsp, DSP_STOPPED); 424 433 return EOK; 425 434 } … … 445 454 if (!dsp->event_exchange) 446 455 return ENOMEM; 447 dsp->ignore_interrupts = false;448 456 } 449 457 … … 465 473 "(~1/%u sec)", dsp->active.samples, 466 474 sampling_rate / (dsp->active.samples * channels)); 467 dsp->status = DSP_CAPTURE;468 475 sb_dsp_change_state(dsp, 476 frames ? DSP_CAPTURE_ACTIVE_EVENTS : DSP_CAPTURE_NOEVENTS); 469 477 return EOK; 470 478 } … … 478 486 async_exchange_end(dsp->event_exchange); 479 487 dsp->event_exchange = NULL; 488 sb_dsp_change_state(dsp, DSP_STOPPED); 480 489 return EOK; 481 490 }
Note:
See TracChangeset
for help on using the changeset viewer.