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