1 /* 2 * Driver for Digigram miXart soundcards 3 * 4 * main file with alsa callbacks 5 * 6 * Copyright (c) 2003 by Digigram <alsa@digigram.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23 24 #include <sound/driver.h> 25 #include <linux/init.h> 26 #include <linux/interrupt.h> 27 #include <linux/pci.h> 28 #include <linux/dma-mapping.h> 29 #include <linux/moduleparam.h> 30 #include <linux/mutex.h> 31 #include <linux/dma-mapping.h> 32 33 #include <sound/core.h> 34 #include <sound/initval.h> 35 #include <sound/info.h> 36 #include <sound/control.h> 37 #include <sound/pcm.h> 38 #include <sound/pcm_params.h> 39 #include "mixart.h" 40 #include "mixart_hwdep.h" 41 #include "mixart_core.h" 42 #include "mixart_mixer.h" 43 44 #define CARD_NAME "miXart" 45 46 MODULE_AUTHOR("Digigram <alsa@digigram.com>"); 47 MODULE_DESCRIPTION("Digigram " CARD_NAME); 48 MODULE_LICENSE("GPL"); 49 MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}"); 50 51 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 52 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 53 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 54 55 module_param_array(index, int, NULL, 0444); 56 MODULE_PARM_DESC(index, "Index value for Digigram " CARD_NAME " soundcard."); 57 module_param_array(id, charp, NULL, 0444); 58 MODULE_PARM_DESC(id, "ID string for Digigram " CARD_NAME " soundcard."); 59 module_param_array(enable, bool, NULL, 0444); 60 MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard."); 61 62 /* 63 */ 64 65 static struct pci_device_id snd_mixart_ids[] = { 66 { 0x1057, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* MC8240 */ 67 { 0, } 68 }; 69 70 MODULE_DEVICE_TABLE(pci, snd_mixart_ids); 71 72 73 static int mixart_set_pipe_state(struct mixart_mgr *mgr, 74 struct mixart_pipe *pipe, int start) 75 { 76 struct mixart_group_state_req group_state; 77 struct mixart_group_state_resp group_state_resp; 78 struct mixart_msg request; 79 int err; 80 u32 system_msg_uid; 81 82 switch(pipe->status) { 83 case PIPE_RUNNING: 84 case PIPE_CLOCK_SET: 85 if(start) return 0; /* already started */ 86 break; 87 case PIPE_STOPPED: 88 if(!start) return 0; /* already stopped */ 89 break; 90 default: 91 snd_printk(KERN_ERR "error mixart_set_pipe_state called with wrong pipe->status!\n"); 92 return -EINVAL; /* function called with wrong pipe status */ 93 } 94 95 system_msg_uid = 0x12345678; /* the event ! (take care: the MSB and two LSB's have to be 0) */ 96 97 /* wait on the last MSG_SYSTEM_SEND_SYNCHRO_CMD command to be really finished */ 98 99 request.message_id = MSG_SYSTEM_WAIT_SYNCHRO_CMD; 100 request.uid = (struct mixart_uid){0,0}; 101 request.data = &system_msg_uid; 102 request.size = sizeof(system_msg_uid); 103 104 err = snd_mixart_send_msg_wait_notif(mgr, &request, system_msg_uid); 105 if(err) { 106 snd_printk(KERN_ERR "error : MSG_SYSTEM_WAIT_SYNCHRO_CMD was not notified !\n"); 107 return err; 108 } 109 110 /* start or stop the pipe (1 pipe) */ 111 112 memset(&group_state, 0, sizeof(group_state)); 113 group_state.pipe_count = 1; 114 group_state.pipe_uid[0] = pipe->group_uid; 115 116 if(start) 117 request.message_id = MSG_STREAM_START_STREAM_GRP_PACKET; 118 else 119 request.message_id = MSG_STREAM_STOP_STREAM_GRP_PACKET; 120 121 request.uid = pipe->group_uid; /*(struct mixart_uid){0,0};*/ 122 request.data = &group_state; 123 request.size = sizeof(group_state); 124 125 err = snd_mixart_send_msg(mgr, &request, sizeof(group_state_resp), &group_state_resp); 126 if (err < 0 || group_state_resp.txx_status != 0) { 127 snd_printk(KERN_ERR "error MSG_STREAM_ST***_STREAM_GRP_PACKET err=%x stat=%x !\n", err, group_state_resp.txx_status); 128 return -EINVAL; 129 } 130 131 if(start) { 132 u32 stat; 133 134 group_state.pipe_count = 0; /* in case of start same command once again with pipe_count=0 */ 135 136 err = snd_mixart_send_msg(mgr, &request, sizeof(group_state_resp), &group_state_resp); 137 if (err < 0 || group_state_resp.txx_status != 0) { 138 snd_printk(KERN_ERR "error MSG_STREAM_START_STREAM_GRP_PACKET err=%x stat=%x !\n", err, group_state_resp.txx_status); 139 return -EINVAL; 140 } 141 142 /* in case of start send a synchro top */ 143 144 request.message_id = MSG_SYSTEM_SEND_SYNCHRO_CMD; 145 request.uid = (struct mixart_uid){0,0}; 146 request.data = NULL; 147 request.size = 0; 148 149 err = snd_mixart_send_msg(mgr, &request, sizeof(stat), &stat); 150 if (err < 0 || stat != 0) { 151 snd_printk(KERN_ERR "error MSG_SYSTEM_SEND_SYNCHRO_CMD err=%x stat=%x !\n", err, stat); 152 return -EINVAL; 153 } 154 155 pipe->status = PIPE_RUNNING; 156 } 157 else /* !start */ 158 pipe->status = PIPE_STOPPED; 159 160 return 0; 161 } 162 163 164 static int mixart_set_clock(struct mixart_mgr *mgr, 165 struct mixart_pipe *pipe, unsigned int rate) 166 { 167 struct mixart_msg request; 168 struct mixart_clock_properties clock_properties; 169 struct mixart_clock_properties_resp clock_prop_resp; 170 int err; 171 172 switch(pipe->status) { 173 case PIPE_CLOCK_SET: 174 break; 175 case PIPE_RUNNING: 176 if(rate != 0) 177 break; 178 default: 179 if(rate == 0) 180 return 0; /* nothing to do */ 181 else { 182 snd_printk(KERN_ERR "error mixart_set_clock(%d) called with wrong pipe->status !\n", rate); 183 return -EINVAL; 184 } 185 } 186 187 memset(&clock_properties, 0, sizeof(clock_properties)); 188 clock_properties.clock_generic_type = (rate != 0) ? CGT_INTERNAL_CLOCK : CGT_NO_CLOCK; 189 clock_properties.clock_mode = CM_STANDALONE; 190 clock_properties.frequency = rate; 191 clock_properties.nb_callers = 1; /* only one entry in uid_caller ! */ 192 clock_properties.uid_caller[0] = pipe->group_uid; 193 194 snd_printdd("mixart_set_clock to %d kHz\n", rate); 195 196 request.message_id = MSG_CLOCK_SET_PROPERTIES; 197 request.uid = mgr->uid_console_manager; 198 request.data = &clock_properties; 199 request.size = sizeof(clock_properties); 200 201 err = snd_mixart_send_msg(mgr, &request, sizeof(clock_prop_resp), &clock_prop_resp); 202 if (err < 0 || clock_prop_resp.status != 0 || clock_prop_resp.clock_mode != CM_STANDALONE) { 203 snd_printk(KERN_ERR "error MSG_CLOCK_SET_PROPERTIES err=%x stat=%x mod=%x !\n", err, clock_prop_resp.status, clock_prop_resp.clock_mode); 204 return -EINVAL; 205 } 206 207 if(rate) pipe->status = PIPE_CLOCK_SET; 208 else pipe->status = PIPE_RUNNING; 209 210 return 0; 211 } 212 213 214 /* 215 * Allocate or reference output pipe for analog IOs (pcmp0/1) 216 */ 217 struct mixart_pipe * 218 snd_mixart_add_ref_pipe(struct snd_mixart *chip, int pcm_number, int capture, 219 int monitoring) 220 { 221 int stream_count; 222 struct mixart_pipe *pipe; 223 struct mixart_msg request; 224 225 if(capture) { 226 if (pcm_number == MIXART_PCM_ANALOG) { 227 pipe = &(chip->pipe_in_ana); /* analog inputs */ 228 } else { 229 pipe = &(chip->pipe_in_dig); /* digital inputs */ 230 } 231 request.message_id = MSG_STREAM_ADD_OUTPUT_GROUP; 232 stream_count = MIXART_CAPTURE_STREAMS; 233 } else { 234 if (pcm_number == MIXART_PCM_ANALOG) { 235 pipe = &(chip->pipe_out_ana); /* analog outputs */ 236 } else { 237 pipe = &(chip->pipe_out_dig); /* digital outputs */ 238 } 239 request.message_id = MSG_STREAM_ADD_INPUT_GROUP; 240 stream_count = MIXART_PLAYBACK_STREAMS; 241 } 242 243 /* a new stream is opened and there are already all streams in use */ 244 if( (monitoring == 0) && (pipe->references >= stream_count) ) { 245 return NULL; 246 } 247 248 /* pipe is not yet defined */ 249 if( pipe->status == PIPE_UNDEFINED ) { 250 int err, i; 251 struct { 252 struct mixart_streaming_group_req sgroup_req; 253 struct mixart_streaming_group sgroup_resp; 254 } *buf; 255 256 snd_printdd("add_ref_pipe audio chip(%d) pcm(%d)\n", chip->chip_idx, pcm_number); 257 258 buf = kmalloc(sizeof(*buf), GFP_KERNEL); 259 if (!buf) 260 return NULL; 261 262 request.uid = (struct mixart_uid){0,0}; /* should be StreamManagerUID, but zero is OK if there is only one ! */ 263 request.data = &buf->sgroup_req; 264 request.size = sizeof(buf->sgroup_req); 265 266 memset(&buf->sgroup_req, 0, sizeof(buf->sgroup_req)); 267 268 buf->sgroup_req.stream_count = stream_count; 269 buf->sgroup_req.channel_count = 2; 270 buf->sgroup_req.latency = 256; 271 buf->sgroup_req.connector = pipe->uid_left_connector; /* the left connector */ 272 273 for (i=0; i<stream_count; i++) { 274 int j; 275 struct mixart_flowinfo *flowinfo; 276 struct mixart_bufferinfo *bufferinfo; 277 278 /* we don't yet know the format, so config 16 bit pcm audio for instance */ 279 buf->sgroup_req.stream_info[i].size_max_byte_frame = 1024; 280 buf->sgroup_req.stream_info[i].size_max_sample_frame = 256; 281 buf->sgroup_req.stream_info[i].nb_bytes_max_per_sample = MIXART_FLOAT_P__4_0_TO_HEX; /* is 4.0f */ 282 283 /* find the right bufferinfo_array */ 284 j = (chip->chip_idx * MIXART_MAX_STREAM_PER_CARD) + (pcm_number * (MIXART_PLAYBACK_STREAMS + MIXART_CAPTURE_STREAMS)) + i; 285 if(capture) j += MIXART_PLAYBACK_STREAMS; /* in the array capture is behind playback */ 286 287 buf->sgroup_req.flow_entry[i] = j; 288 289 flowinfo = (struct mixart_flowinfo *)chip->mgr->flowinfo.area; 290 flowinfo[j].bufferinfo_array_phy_address = (u32)chip->mgr->bufferinfo.addr + (j * sizeof(struct mixart_bufferinfo)); 291 flowinfo[j].bufferinfo_count = 1; /* 1 will set the miXart to ring-buffer mode ! */ 292 293 bufferinfo = (struct mixart_bufferinfo *)chip->mgr->bufferinfo.area; 294 bufferinfo[j].buffer_address = 0; /* buffer is not yet allocated */ 295 bufferinfo[j].available_length = 0; /* buffer is not yet allocated */ 296 297 /* construct the identifier of the stream buffer received in the interrupts ! */ 298 bufferinfo[j].buffer_id = (chip->chip_idx << MIXART_NOTIFY_CARD_OFFSET) + (pcm_number << MIXART_NOTIFY_PCM_OFFSET ) + i; 299 if(capture) { 300 bufferinfo[j].buffer_id |= MIXART_NOTIFY_CAPT_MASK; 301 } 302 } 303 304 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(buf->sgroup_resp), &buf->sgroup_resp); 305 if((err < 0) || (buf->sgroup_resp.status != 0)) { 306 snd_printk(KERN_ERR "error MSG_STREAM_ADD_**PUT_GROUP err=%x stat=%x !\n", err, buf->sgroup_resp.status); 307 kfree(buf); 308 return NULL; 309 } 310 311 pipe->group_uid = buf->sgroup_resp.group; /* id of the pipe, as returned by embedded */ 312 pipe->stream_count = buf->sgroup_resp.stream_count; 313 /* pipe->stream_uid[i] = buf->sgroup_resp.stream[i].stream_uid; */ 314 315 pipe->status = PIPE_STOPPED; 316 kfree(buf); 317 } 318 319 if(monitoring) pipe->monitoring = 1; 320 else pipe->references++; 321 322 return pipe; 323 } 324 325 326 int snd_mixart_kill_ref_pipe(struct mixart_mgr *mgr, 327 struct mixart_pipe *pipe, int monitoring) 328 { 329 int err = 0; 330 331 if(pipe->status == PIPE_UNDEFINED) 332 return 0; 333 334 if(monitoring) 335 pipe->monitoring = 0; 336 else 337 pipe->references--; 338 339 if((pipe->references <= 0) && (pipe->monitoring == 0)) { 340 341 struct mixart_msg request; 342 struct mixart_delete_group_resp delete_resp; 343 344 /* release the clock */ 345 err = mixart_set_clock( mgr, pipe, 0); 346 if( err < 0 ) { 347 snd_printk(KERN_ERR "mixart_set_clock(0) return error!\n"); 348 } 349 350 /* stop the pipe */ 351 err = mixart_set_pipe_state(mgr, pipe, 0); 352 if( err < 0 ) { 353 snd_printk(KERN_ERR "error stopping pipe!\n"); 354 } 355 356 request.message_id = MSG_STREAM_DELETE_GROUP; 357 request.uid = (struct mixart_uid){0,0}; 358 request.data = &pipe->group_uid; /* the streaming group ! */ 359 request.size = sizeof(pipe->group_uid); 360 361 /* delete the pipe */ 362 err = snd_mixart_send_msg(mgr, &request, sizeof(delete_resp), &delete_resp); 363 if ((err < 0) || (delete_resp.status != 0)) { 364 snd_printk(KERN_ERR "error MSG_STREAM_DELETE_GROUP err(%x), status(%x)\n", err, delete_resp.status); 365 } 366 367 pipe->group_uid = (struct mixart_uid){0,0}; 368 pipe->stream_count = 0; 369 pipe->status = PIPE_UNDEFINED; 370 } 371 372 return err; 373 } 374 375 static int mixart_set_stream_state(struct mixart_stream *stream, int start) 376 { 377 struct snd_mixart *chip; 378 struct mixart_stream_state_req stream_state_req; 379 struct mixart_msg request; 380 381 if(!stream->substream) 382 return -EINVAL; 383 384 memset(&stream_state_req, 0, sizeof(stream_state_req)); 385 stream_state_req.stream_count = 1; 386 stream_state_req.stream_info.stream_desc.uid_pipe = stream->pipe->group_uid; 387 stream_state_req.stream_info.stream_desc.stream_idx = stream->substream->number; 388 389 if (stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 390 request.message_id = start ? MSG_STREAM_START_INPUT_STAGE_PACKET : MSG_STREAM_STOP_INPUT_STAGE_PACKET; 391 else 392 request.message_id = start ? MSG_STREAM_START_OUTPUT_STAGE_PACKET : MSG_STREAM_STOP_OUTPUT_STAGE_PACKET; 393 394 request.uid = (struct mixart_uid){0,0}; 395 request.data = &stream_state_req; 396 request.size = sizeof(stream_state_req); 397 398 stream->abs_period_elapsed = 0; /* reset stream pos */ 399 stream->buf_periods = 0; 400 stream->buf_period_frag = 0; 401 402 chip = snd_pcm_substream_chip(stream->substream); 403 404 return snd_mixart_send_msg_nonblock(chip->mgr, &request); 405 } 406 407 /* 408 * Trigger callback 409 */ 410 411 static int snd_mixart_trigger(struct snd_pcm_substream *subs, int cmd) 412 { 413 struct mixart_stream *stream = subs->runtime->private_data; 414 415 switch (cmd) { 416 case SNDRV_PCM_TRIGGER_START: 417 418 snd_printdd("SNDRV_PCM_TRIGGER_START\n"); 419 420 /* START_STREAM */ 421 if( mixart_set_stream_state(stream, 1) ) 422 return -EINVAL; 423 424 stream->status = MIXART_STREAM_STATUS_RUNNING; 425 426 break; 427 case SNDRV_PCM_TRIGGER_STOP: 428 429 /* STOP_STREAM */ 430 if( mixart_set_stream_state(stream, 0) ) 431 return -EINVAL; 432 433 stream->status = MIXART_STREAM_STATUS_OPEN; 434 435 snd_printdd("SNDRV_PCM_TRIGGER_STOP\n"); 436 437 break; 438 439 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 440 /* TODO */ 441 stream->status = MIXART_STREAM_STATUS_PAUSE; 442 snd_printdd("SNDRV_PCM_PAUSE_PUSH\n"); 443 break; 444 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 445 /* TODO */ 446 stream->status = MIXART_STREAM_STATUS_RUNNING; 447 snd_printdd("SNDRV_PCM_PAUSE_RELEASE\n"); 448 break; 449 default: 450 return -EINVAL; 451 } 452 return 0; 453 } 454 455 static int mixart_sync_nonblock_events(struct mixart_mgr *mgr) 456 { 457 unsigned long timeout = jiffies + HZ; 458 while (atomic_read(&mgr->msg_processed) > 0) { 459 if (time_after(jiffies, timeout)) { 460 snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n"); 461 return -EBUSY; 462 } 463 schedule_timeout_uninterruptible(1); 464 } 465 return 0; 466 } 467 468 /* 469 * prepare callback for all pcms 470 */ 471 static int snd_mixart_prepare(struct snd_pcm_substream *subs) 472 { 473 struct snd_mixart *chip = snd_pcm_substream_chip(subs); 474 struct mixart_stream *stream = subs->runtime->private_data; 475 476 /* TODO de fa�on non bloquante, r�appliquer les hw_params (rate, bits, codec) */ 477 478 snd_printdd("snd_mixart_prepare\n"); 479 480 mixart_sync_nonblock_events(chip->mgr); 481 482 /* only the first stream can choose the sample rate */ 483 /* the further opened streams will be limited to its frequency (see open) */ 484 if(chip->mgr->ref_count_rate == 1) 485 chip->mgr->sample_rate = subs->runtime->rate; 486 487 /* set the clock only once (first stream) on the same pipe */ 488 if(stream->pipe->references == 1) { 489 if( mixart_set_clock(chip->mgr, stream->pipe, subs->runtime->rate) ) 490 return -EINVAL; 491 } 492 493 return 0; 494 } 495 496 497 static int mixart_set_format(struct mixart_stream *stream, snd_pcm_format_t format) 498 { 499 int err; 500 struct snd_mixart *chip; 501 struct mixart_msg request; 502 struct mixart_stream_param_desc stream_param; 503 struct mixart_return_uid resp; 504 505 chip = snd_pcm_substream_chip(stream->substream); 506 507 memset(&stream_param, 0, sizeof(stream_param)); 508 509 stream_param.coding_type = CT_LINEAR; 510 stream_param.number_of_channel = stream->channels; 511 512 stream_param.sampling_freq = chip->mgr->sample_rate; 513 if(stream_param.sampling_freq == 0) 514 stream_param.sampling_freq = 44100; /* if frequency not yet defined, use some default */ 515 516 switch(format){ 517 case SNDRV_PCM_FORMAT_U8: 518 stream_param.sample_type = ST_INTEGER_8; 519 stream_param.sample_size = 8; 520 break; 521 case SNDRV_PCM_FORMAT_S16_LE: 522 stream_param.sample_type = ST_INTEGER_16LE; 523 stream_param.sample_size = 16; 524 break; 525 case SNDRV_PCM_FORMAT_S16_BE: 526 stream_param.sample_type = ST_INTEGER_16BE; 527 stream_param.sample_size = 16; 528 break; 529 case SNDRV_PCM_FORMAT_S24_3LE: 530 stream_param.sample_type = ST_INTEGER_24LE; 531 stream_param.sample_size = 24; 532 break; 533 case SNDRV_PCM_FORMAT_S24_3BE: 534 stream_param.sample_type = ST_INTEGER_24BE; 535 stream_param.sample_size = 24; 536 break; 537 case SNDRV_PCM_FORMAT_FLOAT_LE: 538 stream_param.sample_type = ST_FLOATING_POINT_32LE; 539 stream_param.sample_size = 32; 540 break; 541 case SNDRV_PCM_FORMAT_FLOAT_BE: 542 stream_param.sample_type = ST_FLOATING_POINT_32BE; 543 stream_param.sample_size = 32; 544 break; 545 default: 546 snd_printk(KERN_ERR "error mixart_set_format() : unknown format\n"); 547 return -EINVAL; 548 } 549 550 snd_printdd("set SNDRV_PCM_FORMAT sample_type(%d) sample_size(%d) freq(%d) channels(%d)\n", 551 stream_param.sample_type, stream_param.sample_size, stream_param.sampling_freq, stream->channels); 552 553 /* TODO: what else to configure ? */ 554 /* stream_param.samples_per_frame = 2; */ 555 /* stream_param.bytes_per_frame = 4; */ 556 /* stream_param.bytes_per_sample = 2; */ 557 558 stream_param.pipe_count = 1; /* set to 1 */ 559 stream_param.stream_count = 1; /* set to 1 */ 560 stream_param.stream_desc[0].uid_pipe = stream->pipe->group_uid; 561 stream_param.stream_desc[0].stream_idx = stream->substream->number; 562 563 request.message_id = MSG_STREAM_SET_INPUT_STAGE_PARAM; 564 request.uid = (struct mixart_uid){0,0}; 565 request.data = &stream_param; 566 request.size = sizeof(stream_param); 567 568 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp); 569 if((err < 0) || resp.error_code) { 570 snd_printk(KERN_ERR "MSG_STREAM_SET_INPUT_STAGE_PARAM err=%x; resp=%x\n", err, resp.error_code); 571 return -EINVAL; 572 } 573 return 0; 574 } 575 576 577 /* 578 * HW_PARAMS callback for all pcms 579 */ 580 static int snd_mixart_hw_params(struct snd_pcm_substream *subs, 581 struct snd_pcm_hw_params *hw) 582 { 583 struct snd_mixart *chip = snd_pcm_substream_chip(subs); 584 struct mixart_mgr *mgr = chip->mgr; 585 struct mixart_stream *stream = subs->runtime->private_data; 586 snd_pcm_format_t format; 587 int err; 588 int channels; 589 590 /* set up channels */ 591 channels = params_channels(hw); 592 593 /* set up format for the stream */ 594 format = params_format(hw); 595 596 mutex_lock(&mgr->setup_mutex); 597 598 /* update the stream levels */ 599 if( stream->pcm_number <= MIXART_PCM_DIGITAL ) { 600 int is_aes = stream->pcm_number > MIXART_PCM_ANALOG; 601 if( subs->stream == SNDRV_PCM_STREAM_PLAYBACK ) 602 mixart_update_playback_stream_level(chip, is_aes, subs->number); 603 else 604 mixart_update_capture_stream_level( chip, is_aes); 605 } 606 607 stream->channels = channels; 608 609 /* set the format to the board */ 610 err = mixart_set_format(stream, format); 611 if(err < 0) { 612 return err; 613 } 614 615 /* allocate buffer */ 616 err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw)); 617 618 if (err > 0) { 619 struct mixart_bufferinfo *bufferinfo; 620 int i = (chip->chip_idx * MIXART_MAX_STREAM_PER_CARD) + (stream->pcm_number * (MIXART_PLAYBACK_STREAMS+MIXART_CAPTURE_STREAMS)) + subs->number; 621 if( subs->stream == SNDRV_PCM_STREAM_CAPTURE ) { 622 i += MIXART_PLAYBACK_STREAMS; /* in array capture is behind playback */ 623 } 624 625 bufferinfo = (struct mixart_bufferinfo *)chip->mgr->bufferinfo.area; 626 bufferinfo[i].buffer_address = subs->runtime->dma_addr; 627 bufferinfo[i].available_length = subs->runtime->dma_bytes; 628 /* bufferinfo[i].buffer_id is already defined */ 629 630 snd_printdd("snd_mixart_hw_params(pcm %d) : dma_addr(%x) dma_bytes(%x) subs-number(%d)\n", i, 631 bufferinfo[i].buffer_address, 632 bufferinfo[i].available_length, 633 subs->number); 634 } 635 mutex_unlock(&mgr->setup_mutex); 636 637 return err; 638 } 639 640 static int snd_mixart_hw_free(struct snd_pcm_substream *subs) 641 { 642 struct snd_mixart *chip = snd_pcm_substream_chip(subs); 643 snd_pcm_lib_free_pages(subs); 644 mixart_sync_nonblock_events(chip->mgr); 645 return 0; 646 } 647 648 649 650 /* 651 * TODO CONFIGURATION SPACE for all pcms, mono pcm must update channels_max 652 */ 653 static struct snd_pcm_hardware snd_mixart_analog_caps = 654 { 655 .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 656 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 657 SNDRV_PCM_INFO_PAUSE), 658 .formats = ( SNDRV_PCM_FMTBIT_U8 | 659 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | 660 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | 661 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE ), 662 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 663 .rate_min = 8000, 664 .rate_max = 48000, 665 .channels_min = 1, 666 .channels_max = 2, 667 .buffer_bytes_max = (32*1024), 668 .period_bytes_min = 256, /* 256 frames U8 mono*/ 669 .period_bytes_max = (16*1024), 670 .periods_min = 2, 671 .periods_max = (32*1024/256), 672 }; 673 674 static struct snd_pcm_hardware snd_mixart_digital_caps = 675 { 676 .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 677 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 678 SNDRV_PCM_INFO_PAUSE), 679 .formats = ( SNDRV_PCM_FMTBIT_U8 | 680 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | 681 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | 682 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE ), 683 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, 684 .rate_min = 32000, 685 .rate_max = 48000, 686 .channels_min = 1, 687 .channels_max = 2, 688 .buffer_bytes_max = (32*1024), 689 .period_bytes_min = 256, /* 256 frames U8 mono*/ 690 .period_bytes_max = (16*1024), 691 .periods_min = 2, 692 .periods_max = (32*1024/256), 693 }; 694 695 696 static int snd_mixart_playback_open(struct snd_pcm_substream *subs) 697 { 698 struct snd_mixart *chip = snd_pcm_substream_chip(subs); 699 struct mixart_mgr *mgr = chip->mgr; 700 struct snd_pcm_runtime *runtime = subs->runtime; 701 struct snd_pcm *pcm = subs->pcm; 702 struct mixart_stream *stream; 703 struct mixart_pipe *pipe; 704 int err = 0; 705 int pcm_number; 706 707 mutex_lock(&mgr->setup_mutex); 708 709 if ( pcm == chip->pcm ) { 710 pcm_number = MIXART_PCM_ANALOG; 711 runtime->hw = snd_mixart_analog_caps; 712 } else { 713 snd_assert ( pcm == chip->pcm_dig ); 714 pcm_number = MIXART_PCM_DIGITAL; 715 runtime->hw = snd_mixart_digital_caps; 716 } 717 snd_printdd("snd_mixart_playback_open C%d/P%d/Sub%d\n", chip->chip_idx, pcm_number, subs->number); 718 719 /* get stream info */ 720 stream = &(chip->playback_stream[pcm_number][subs->number]); 721 722 if (stream->status != MIXART_STREAM_STATUS_FREE){ 723 /* streams in use */ 724 snd_printk(KERN_ERR "snd_mixart_playback_open C%d/P%d/Sub%d in use\n", chip->chip_idx, pcm_number, subs->number); 725 err = -EBUSY; 726 goto _exit_open; 727 } 728 729 /* get pipe pointer (out pipe) */ 730 pipe = snd_mixart_add_ref_pipe(chip, pcm_number, 0, 0); 731 732 if (pipe == NULL) { 733 err = -EINVAL; 734 goto _exit_open; 735 } 736 737 /* start the pipe if necessary */ 738 err = mixart_set_pipe_state(chip->mgr, pipe, 1); 739 if( err < 0 ) { 740 snd_printk(KERN_ERR "error starting pipe!\n"); 741 snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0); 742 err = -EINVAL; 743 goto _exit_open; 744 } 745 746 stream->pipe = pipe; 747 stream->pcm_number = pcm_number; 748 stream->status = MIXART_STREAM_STATUS_OPEN; 749 stream->substream = subs; 750 stream->channels = 0; /* not configured yet */ 751 752 runtime->private_data = stream; 753 754 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 755 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 64); 756 757 /* if a sample rate is already used, another stream cannot change */ 758 if(mgr->ref_count_rate++) { 759 if(mgr->sample_rate) { 760 runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate; 761 } 762 } 763 764 _exit_open: 765 mutex_unlock(&mgr->setup_mutex); 766 767 return err; 768 } 769 770 771 static int snd_mixart_capture_open(struct snd_pcm_substream *subs) 772 { 773 struct snd_mixart *chip = snd_pcm_substream_chip(subs); 774 struct mixart_mgr *mgr = chip->mgr; 775 struct snd_pcm_runtime *runtime = subs->runtime; 776 struct snd_pcm *pcm = subs->pcm; 777 struct mixart_stream *stream; 778 struct mixart_pipe *pipe; 779 int err = 0; 780 int pcm_number; 781 782 mutex_lock(&mgr->setup_mutex); 783 784 if ( pcm == chip->pcm ) { 785 pcm_number = MIXART_PCM_ANALOG; 786 runtime->hw = snd_mixart_analog_caps; 787 } else { 788 snd_assert ( pcm == chip->pcm_dig ); 789 pcm_number = MIXART_PCM_DIGITAL; 790 runtime->hw = snd_mixart_digital_caps; 791 } 792 793 runtime->hw.channels_min = 2; /* for instance, no mono */ 794 795 snd_printdd("snd_mixart_capture_open C%d/P%d/Sub%d\n", chip->chip_idx, pcm_number, subs->number); 796 797 /* get stream info */ 798 stream = &(chip->capture_stream[pcm_number]); 799 800 if (stream->status != MIXART_STREAM_STATUS_FREE){ 801 /* streams in use */ 802 snd_printk(KERN_ERR "snd_mixart_capture_open C%d/P%d/Sub%d in use\n", chip->chip_idx, pcm_number, subs->number); 803 err = -EBUSY; 804 goto _exit_open; 805 } 806 807 /* get pipe pointer (in pipe) */ 808 pipe = snd_mixart_add_ref_pipe(chip, pcm_number, 1, 0); 809 810 if (pipe == NULL) { 811 err = -EINVAL; 812 goto _exit_open; 813 } 814 815 /* start the pipe if necessary */ 816 err = mixart_set_pipe_state(chip->mgr, pipe, 1); 817 if( err < 0 ) { 818 snd_printk(KERN_ERR "error starting pipe!\n"); 819 snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0); 820 err = -EINVAL; 821 goto _exit_open; 822 } 823 824 stream->pipe = pipe; 825 stream->pcm_number = pcm_number; 826 stream->status = MIXART_STREAM_STATUS_OPEN; 827 stream->substream = subs; 828 stream->channels = 0; /* not configured yet */ 829 830 runtime->private_data = stream; 831 832 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 833 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 64); 834 835 /* if a sample rate is already used, another stream cannot change */ 836 if(mgr->ref_count_rate++) { 837 if(mgr->sample_rate) { 838 runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate; 839 } 840 } 841 842 _exit_open: 843 mutex_unlock(&mgr->setup_mutex); 844 845 return err; 846 } 847 848 849 850 static int snd_mixart_close(struct snd_pcm_substream *subs) 851 { 852 struct snd_mixart *chip = snd_pcm_substream_chip(subs); 853 struct mixart_mgr *mgr = chip->mgr; 854 struct mixart_stream *stream = subs->runtime->private_data; 855 856 mutex_lock(&mgr->setup_mutex); 857 858 snd_printdd("snd_mixart_close C%d/P%d/Sub%d\n", chip->chip_idx, stream->pcm_number, subs->number); 859 860 /* sample rate released */ 861 if(--mgr->ref_count_rate == 0) { 862 mgr->sample_rate = 0; 863 } 864 865 /* delete pipe */ 866 if (snd_mixart_kill_ref_pipe(mgr, stream->pipe, 0 ) < 0) { 867 868 snd_printk(KERN_ERR "error snd_mixart_kill_ref_pipe C%dP%d\n", chip->chip_idx, stream->pcm_number); 869 } 870 871 stream->pipe = NULL; 872 stream->status = MIXART_STREAM_STATUS_FREE; 873 stream->substream = NULL; 874 875 mutex_unlock(&mgr->setup_mutex); 876 return 0; 877 } 878 879 880 static snd_pcm_uframes_t snd_mixart_stream_pointer(struct snd_pcm_substream *subs) 881 { 882 struct snd_pcm_runtime *runtime = subs->runtime; 883 struct mixart_stream *stream = runtime->private_data; 884 885 return (snd_pcm_uframes_t)((stream->buf_periods * runtime->period_size) + stream->buf_period_frag); 886 } 887 888 889 890 static struct snd_pcm_ops snd_mixart_playback_ops = { 891 .open = snd_mixart_playback_open, 892 .close = snd_mixart_close, 893 .ioctl = snd_pcm_lib_ioctl, 894 .prepare = snd_mixart_prepare, 895 .hw_params = snd_mixart_hw_params, 896 .hw_free = snd_mixart_hw_free, 897 .trigger = snd_mixart_trigger, 898 .pointer = snd_mixart_stream_pointer, 899 }; 900 901 static struct snd_pcm_ops snd_mixart_capture_ops = { 902 .open = snd_mixart_capture_open, 903 .close = snd_mixart_close, 904 .ioctl = snd_pcm_lib_ioctl, 905 .prepare = snd_mixart_prepare, 906 .hw_params = snd_mixart_hw_params, 907 .hw_free = snd_mixart_hw_free, 908 .trigger = snd_mixart_trigger, 909 .pointer = snd_mixart_stream_pointer, 910 }; 911 912 static void preallocate_buffers(struct snd_mixart *chip, struct snd_pcm *pcm) 913 { 914 #if 0 915 struct snd_pcm_substream *subs; 916 int stream; 917 918 for (stream = 0; stream < 2; stream++) { 919 int idx = 0; 920 for (subs = pcm->streams[stream].substream; subs; subs = subs->next, idx++) 921 /* set up the unique device id with the chip index */ 922 subs->dma_device.id = subs->pcm->device << 16 | 923 subs->stream << 8 | (subs->number + 1) | 924 (chip->chip_idx + 1) << 24; 925 } 926 #endif 927 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 928 snd_dma_pci_data(chip->mgr->pci), 32*1024, 32*1024); 929 } 930 931 /* 932 */ 933 static int snd_mixart_pcm_analog(struct snd_mixart *chip) 934 { 935 int err; 936 struct snd_pcm *pcm; 937 char name[32]; 938 939 sprintf(name, "miXart analog %d", chip->chip_idx); 940 if ((err = snd_pcm_new(chip->card, name, MIXART_PCM_ANALOG, 941 MIXART_PLAYBACK_STREAMS, 942 MIXART_CAPTURE_STREAMS, &pcm)) < 0) { 943 snd_printk(KERN_ERR "cannot create the analog pcm %d\n", chip->chip_idx); 944 return err; 945 } 946 947 pcm->private_data = chip; 948 949 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_mixart_playback_ops); 950 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mixart_capture_ops); 951 952 pcm->info_flags = 0; 953 strcpy(pcm->name, name); 954 955 preallocate_buffers(chip, pcm); 956 957 chip->pcm = pcm; 958 return 0; 959 } 960 961 962 /* 963 */ 964 static int snd_mixart_pcm_digital(struct snd_mixart *chip) 965 { 966 int err; 967 struct snd_pcm *pcm; 968 char name[32]; 969 970 sprintf(name, "miXart AES/EBU %d", chip->chip_idx); 971 if ((err = snd_pcm_new(chip->card, name, MIXART_PCM_DIGITAL, 972 MIXART_PLAYBACK_STREAMS, 973 MIXART_CAPTURE_STREAMS, &pcm)) < 0) { 974 snd_printk(KERN_ERR "cannot create the digital pcm %d\n", chip->chip_idx); 975 return err; 976 } 977 978 pcm->private_data = chip; 979 980 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_mixart_playback_ops); 981 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mixart_capture_ops); 982 983 pcm->info_flags = 0; 984 strcpy(pcm->name, name); 985 986 preallocate_buffers(chip, pcm); 987 988 chip->pcm_dig = pcm; 989 return 0; 990 } 991 992 static int snd_mixart_chip_free(struct snd_mixart *chip) 993 { 994 kfree(chip); 995 return 0; 996 } 997 998 static int snd_mixart_chip_dev_free(struct snd_device *device) 999 { 1000 struct snd_mixart *chip = device->device_data; 1001 return snd_mixart_chip_free(chip); 1002 } 1003 1004 1005 /* 1006 */ 1007 static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int idx) 1008 { 1009 int err; 1010 struct snd_mixart *chip; 1011 static struct snd_device_ops ops = { 1012 .dev_free = snd_mixart_chip_dev_free, 1013 }; 1014 1015 mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1016 if (! chip) { 1017 snd_printk(KERN_ERR "cannot allocate chip\n"); 1018 return -ENOMEM; 1019 } 1020 1021 chip->card = card; 1022 chip->chip_idx = idx; 1023 chip->mgr = mgr; 1024 1025 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 1026 snd_mixart_chip_free(chip); 1027 return err; 1028 } 1029 1030 snd_card_set_dev(card, &mgr->pci->dev); 1031 1032 return 0; 1033 } 1034 1035 int snd_mixart_create_pcm(struct snd_mixart* chip) 1036 { 1037 int err; 1038 1039 err = snd_mixart_pcm_analog(chip); 1040 if (err < 0) 1041 return err; 1042 1043 if(chip->mgr->board_type == MIXART_DAUGHTER_TYPE_AES) { 1044 1045 err = snd_mixart_pcm_digital(chip); 1046 if (err < 0) 1047 return err; 1048 } 1049 return err; 1050 } 1051 1052 1053 /* 1054 * release all the cards assigned to a manager instance 1055 */ 1056 static int snd_mixart_free(struct mixart_mgr *mgr) 1057 { 1058 unsigned int i; 1059 1060 for (i = 0; i < mgr->num_cards; i++) { 1061 if (mgr->chip[i]) 1062 snd_card_free(mgr->chip[i]->card); 1063 } 1064 1065 /* stop mailbox */ 1066 snd_mixart_exit_mailbox(mgr); 1067 1068 /* release irq */ 1069 if (mgr->irq >= 0) 1070 free_irq(mgr->irq, (void *)mgr); 1071 1072 /* reset board if some firmware was loaded */ 1073 if(mgr->dsp_loaded) { 1074 snd_mixart_reset_board(mgr); 1075 snd_printdd("reset miXart !\n"); 1076 } 1077 1078 /* release the i/o ports */ 1079 for (i = 0; i < 2; i++) { 1080 if (mgr->mem[i].virt) 1081 iounmap(mgr->mem[i].virt); 1082 } 1083 pci_release_regions(mgr->pci); 1084 1085 /* free flowarray */ 1086 if(mgr->flowinfo.area) { 1087 snd_dma_free_pages(&mgr->flowinfo); 1088 mgr->flowinfo.area = NULL; 1089 } 1090 /* free bufferarray */ 1091 if(mgr->bufferinfo.area) { 1092 snd_dma_free_pages(&mgr->bufferinfo); 1093 mgr->bufferinfo.area = NULL; 1094 } 1095 1096 pci_disable_device(mgr->pci); 1097 kfree(mgr); 1098 return 0; 1099 } 1100 1101 /* 1102 * proc interface 1103 */ 1104 static long long snd_mixart_BA0_llseek(struct snd_info_entry *entry, 1105 void *private_file_data, 1106 struct file *file, 1107 long long offset, 1108 int orig) 1109 { 1110 offset = offset & ~3; /* 4 bytes aligned */ 1111 1112 switch(orig) { 1113 case 0: /* SEEK_SET */ 1114 file->f_pos = offset; 1115 break; 1116 case 1: /* SEEK_CUR */ 1117 file->f_pos += offset; 1118 break; 1119 case 2: /* SEEK_END, offset is negative */ 1120 file->f_pos = MIXART_BA0_SIZE + offset; 1121 break; 1122 default: 1123 return -EINVAL; 1124 } 1125 if(file->f_pos > MIXART_BA0_SIZE) 1126 file->f_pos = MIXART_BA0_SIZE; 1127 return file->f_pos; 1128 } 1129 1130 static long long snd_mixart_BA1_llseek(struct snd_info_entry *entry, 1131 void *private_file_data, 1132 struct file *file, 1133 long long offset, 1134 int orig) 1135 { 1136 offset = offset & ~3; /* 4 bytes aligned */ 1137 1138 switch(orig) { 1139 case 0: /* SEEK_SET */ 1140 file->f_pos = offset; 1141 break; 1142 case 1: /* SEEK_CUR */ 1143 file->f_pos += offset; 1144 break; 1145 case 2: /* SEEK_END, offset is negative */ 1146 file->f_pos = MIXART_BA1_SIZE + offset; 1147 break; 1148 default: 1149 return -EINVAL; 1150 } 1151 if(file->f_pos > MIXART_BA1_SIZE) 1152 file->f_pos = MIXART_BA1_SIZE; 1153 return file->f_pos; 1154 } 1155 1156 /* 1157 mixart_BA0 proc interface for BAR 0 - read callback 1158 */ 1159 static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private_data, 1160 struct file *file, char __user *buf, 1161 unsigned long count, unsigned long pos) 1162 { 1163 struct mixart_mgr *mgr = entry->private_data; 1164 1165 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1166 if(count <= 0) 1167 return 0; 1168 if(pos + count > MIXART_BA0_SIZE) 1169 count = (long)(MIXART_BA0_SIZE - pos); 1170 if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count)) 1171 return -EFAULT; 1172 return count; 1173 } 1174 1175 /* 1176 mixart_BA1 proc interface for BAR 1 - read callback 1177 */ 1178 static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private_data, 1179 struct file *file, char __user *buf, 1180 unsigned long count, unsigned long pos) 1181 { 1182 struct mixart_mgr *mgr = entry->private_data; 1183 1184 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1185 if(count <= 0) 1186 return 0; 1187 if(pos + count > MIXART_BA1_SIZE) 1188 count = (long)(MIXART_BA1_SIZE - pos); 1189 if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count)) 1190 return -EFAULT; 1191 return count; 1192 } 1193 1194 static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = { 1195 .read = snd_mixart_BA0_read, 1196 .llseek = snd_mixart_BA0_llseek 1197 }; 1198 1199 static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = { 1200 .read = snd_mixart_BA1_read, 1201 .llseek = snd_mixart_BA1_llseek 1202 }; 1203 1204 1205 static void snd_mixart_proc_read(struct snd_info_entry *entry, 1206 struct snd_info_buffer *buffer) 1207 { 1208 struct snd_mixart *chip = entry->private_data; 1209 u32 ref; 1210 1211 snd_iprintf(buffer, "Digigram miXart (alsa card %d)\n\n", chip->chip_idx); 1212 1213 /* stats available when embedded OS is running */ 1214 if (chip->mgr->dsp_loaded & ( 1 << MIXART_MOTHERBOARD_ELF_INDEX)) { 1215 snd_iprintf(buffer, "- hardware -\n"); 1216 switch (chip->mgr->board_type ) { 1217 case MIXART_DAUGHTER_TYPE_NONE : snd_iprintf(buffer, "\tmiXart8 (no daughter board)\n\n"); break; 1218 case MIXART_DAUGHTER_TYPE_AES : snd_iprintf(buffer, "\tmiXart8 AES/EBU\n\n"); break; 1219 case MIXART_DAUGHTER_TYPE_COBRANET : snd_iprintf(buffer, "\tmiXart8 Cobranet\n\n"); break; 1220 default: snd_iprintf(buffer, "\tUNKNOWN!\n\n"); break; 1221 } 1222 1223 snd_iprintf(buffer, "- system load -\n"); 1224 1225 /* get perf reference */ 1226 1227 ref = readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_SYSTEM_LOAD_OFFSET)); 1228 1229 if (ref) { 1230 u32 mailbox = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_MAILBX_LOAD_OFFSET)) / ref; 1231 u32 streaming = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_STREAM_LOAD_OFFSET)) / ref; 1232 u32 interr = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_INTERR_LOAD_OFFSET)) / ref; 1233 1234 snd_iprintf(buffer, "\tstreaming : %d\n", streaming); 1235 snd_iprintf(buffer, "\tmailbox : %d\n", mailbox); 1236 snd_iprintf(buffer, "\tinterrups handling : %d\n\n", interr); 1237 } 1238 } /* endif elf loaded */ 1239 } 1240 1241 static void __devinit snd_mixart_proc_init(struct snd_mixart *chip) 1242 { 1243 struct snd_info_entry *entry; 1244 1245 /* text interface to read perf and temp meters */ 1246 if (! snd_card_proc_new(chip->card, "board_info", &entry)) { 1247 entry->private_data = chip; 1248 entry->c.text.read_size = 1024; 1249 entry->c.text.read = snd_mixart_proc_read; 1250 } 1251 1252 if (! snd_card_proc_new(chip->card, "mixart_BA0", &entry)) { 1253 entry->content = SNDRV_INFO_CONTENT_DATA; 1254 entry->private_data = chip->mgr; 1255 entry->c.ops = &snd_mixart_proc_ops_BA0; 1256 entry->size = MIXART_BA0_SIZE; 1257 } 1258 if (! snd_card_proc_new(chip->card, "mixart_BA1", &entry)) { 1259 entry->content = SNDRV_INFO_CONTENT_DATA; 1260 entry->private_data = chip->mgr; 1261 entry->c.ops = &snd_mixart_proc_ops_BA1; 1262 entry->size = MIXART_BA1_SIZE; 1263 } 1264 } 1265 /* end of proc interface */ 1266 1267 1268 /* 1269 * probe function - creates the card manager 1270 */ 1271 static int __devinit snd_mixart_probe(struct pci_dev *pci, 1272 const struct pci_device_id *pci_id) 1273 { 1274 static int dev; 1275 struct mixart_mgr *mgr; 1276 unsigned int i; 1277 int err; 1278 size_t size; 1279 1280 /* 1281 */ 1282 if (dev >= SNDRV_CARDS) 1283 return -ENODEV; 1284 if (! enable[dev]) { 1285 dev++; 1286 return -ENOENT; 1287 } 1288 1289 /* enable PCI device */ 1290 if ((err = pci_enable_device(pci)) < 0) 1291 return err; 1292 pci_set_master(pci); 1293 1294 /* check if we can restrict PCI DMA transfers to 32 bits */ 1295 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { 1296 snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); 1297 pci_disable_device(pci); 1298 return -ENXIO; 1299 } 1300 1301 /* 1302 */ 1303 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); 1304 if (! mgr) { 1305 pci_disable_device(pci); 1306 return -ENOMEM; 1307 } 1308 1309 mgr->pci = pci; 1310 mgr->irq = -1; 1311 1312 /* resource assignment */ 1313 if ((err = pci_request_regions(pci, CARD_NAME)) < 0) { 1314 kfree(mgr); 1315 pci_disable_device(pci); 1316 return err; 1317 } 1318 for (i = 0; i < 2; i++) { 1319 mgr->mem[i].phys = pci_resource_start(pci, i); 1320 mgr->mem[i].virt = ioremap_nocache(mgr->mem[i].phys, 1321 pci_resource_len(pci, i)); 1322 } 1323 1324 if (request_irq(pci->irq, snd_mixart_interrupt, SA_INTERRUPT|SA_SHIRQ, CARD_NAME, (void *)mgr)) { 1325 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); 1326 snd_mixart_free(mgr); 1327 return -EBUSY; 1328 } 1329 mgr->irq = pci->irq; 1330 1331 sprintf(mgr->shortname, "Digigram miXart"); 1332 sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, irq %i", mgr->shortname, mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq); 1333 1334 /* ISR spinlock */ 1335 spin_lock_init(&mgr->lock); 1336 1337 /* init mailbox */ 1338 mgr->msg_fifo_readptr = 0; 1339 mgr->msg_fifo_writeptr = 0; 1340 1341 spin_lock_init(&mgr->msg_lock); 1342 mutex_init(&mgr->msg_mutex); 1343 init_waitqueue_head(&mgr->msg_sleep); 1344 atomic_set(&mgr->msg_processed, 0); 1345 1346 /* init setup mutex*/ 1347 mutex_init(&mgr->setup_mutex); 1348 1349 /* init message taslket */ 1350 tasklet_init(&mgr->msg_taskq, snd_mixart_msg_tasklet, (unsigned long) mgr); 1351 1352 /* card assignment */ 1353 mgr->num_cards = MIXART_MAX_CARDS; /* 4 FIXME: configurable? */ 1354 for (i = 0; i < mgr->num_cards; i++) { 1355 struct snd_card *card; 1356 char tmpid[16]; 1357 int idx; 1358 1359 if (index[dev] < 0) 1360 idx = index[dev]; 1361 else 1362 idx = index[dev] + i; 1363 snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : "MIXART", i); 1364 card = snd_card_new(idx, tmpid, THIS_MODULE, 0); 1365 1366 if (! card) { 1367 snd_printk(KERN_ERR "cannot allocate the card %d\n", i); 1368 snd_mixart_free(mgr); 1369 return -ENOMEM; 1370 } 1371 1372 strcpy(card->driver, CARD_NAME); 1373 sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i); 1374 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); 1375 1376 if ((err = snd_mixart_create(mgr, card, i)) < 0) { 1377 snd_mixart_free(mgr); 1378 return err; 1379 } 1380 1381 if(i==0) { 1382 /* init proc interface only for chip0 */ 1383 snd_mixart_proc_init(mgr->chip[i]); 1384 } 1385 1386 if ((err = snd_card_register(card)) < 0) { 1387 snd_mixart_free(mgr); 1388 return err; 1389 } 1390 } 1391 1392 /* init firmware status (mgr->dsp_loaded reset in hwdep_new) */ 1393 mgr->board_type = MIXART_DAUGHTER_TYPE_NONE; 1394 1395 /* create array of streaminfo */ 1396 size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS * 1397 sizeof(struct mixart_flowinfo)) ); 1398 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1399 size, &mgr->flowinfo) < 0) { 1400 snd_mixart_free(mgr); 1401 return -ENOMEM; 1402 } 1403 /* init streaminfo_array */ 1404 memset(mgr->flowinfo.area, 0, size); 1405 1406 /* create array of bufferinfo */ 1407 size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS * 1408 sizeof(struct mixart_bufferinfo)) ); 1409 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1410 size, &mgr->bufferinfo) < 0) { 1411 snd_mixart_free(mgr); 1412 return -ENOMEM; 1413 } 1414 /* init bufferinfo_array */ 1415 memset(mgr->bufferinfo.area, 0, size); 1416 1417 /* set up firmware */ 1418 err = snd_mixart_setup_firmware(mgr); 1419 if (err < 0) { 1420 snd_mixart_free(mgr); 1421 return err; 1422 } 1423 1424 pci_set_drvdata(pci, mgr); 1425 dev++; 1426 return 0; 1427 } 1428 1429 static void __devexit snd_mixart_remove(struct pci_dev *pci) 1430 { 1431 snd_mixart_free(pci_get_drvdata(pci)); 1432 pci_set_drvdata(pci, NULL); 1433 } 1434 1435 static struct pci_driver driver = { 1436 .name = "Digigram miXart", 1437 .id_table = snd_mixart_ids, 1438 .probe = snd_mixart_probe, 1439 .remove = __devexit_p(snd_mixart_remove), 1440 }; 1441 1442 static int __init alsa_card_mixart_init(void) 1443 { 1444 return pci_register_driver(&driver); 1445 } 1446 1447 static void __exit alsa_card_mixart_exit(void) 1448 { 1449 pci_unregister_driver(&driver); 1450 } 1451 1452 module_init(alsa_card_mixart_init) 1453 module_exit(alsa_card_mixart_exit) 1454