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