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