1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Driver for Digigram miXart soundcards
5 * main file with alsa callbacks
7 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
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>
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>
26 #include "mixart_hwdep.h"
27 #include "mixart_core.h"
28 #include "mixart_mixer.h"
30 #define CARD_NAME "miXart"
32 MODULE_AUTHOR("Digigram <alsa@digigram.com>");
33 MODULE_DESCRIPTION("Digigram " CARD_NAME
);
34 MODULE_LICENSE("GPL");
36 static int index
[SNDRV_CARDS
] = SNDRV_DEFAULT_IDX
; /* Index 0-MAX */
37 static char *id
[SNDRV_CARDS
] = SNDRV_DEFAULT_STR
; /* ID for this card */
38 static bool enable
[SNDRV_CARDS
] = SNDRV_DEFAULT_ENABLE_PNP
; /* Enable this card */
40 module_param_array(index
, int, NULL
, 0444);
41 MODULE_PARM_DESC(index
, "Index value for Digigram " CARD_NAME
" soundcard.");
42 module_param_array(id
, charp
, NULL
, 0444);
43 MODULE_PARM_DESC(id
, "ID string for Digigram " CARD_NAME
" soundcard.");
44 module_param_array(enable
, bool, NULL
, 0444);
45 MODULE_PARM_DESC(enable
, "Enable Digigram " CARD_NAME
" soundcard.");
50 static const struct pci_device_id snd_mixart_ids
[] = {
51 { PCI_VDEVICE(MOTOROLA
, 0x0003), 0, }, /* MC8240 */
55 MODULE_DEVICE_TABLE(pci
, snd_mixart_ids
);
58 static int mixart_set_pipe_state(struct mixart_mgr
*mgr
,
59 struct mixart_pipe
*pipe
, int start
)
61 struct mixart_group_state_req group_state
;
62 struct mixart_group_state_resp group_state_resp
;
63 struct mixart_msg request
;
67 switch(pipe
->status
) {
70 if(start
) return 0; /* already started */
73 if(!start
) return 0; /* already stopped */
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 */
81 system_msg_uid
= 0x12345678; /* the event ! (take care: the MSB and two LSB's have to be 0) */
83 /* wait on the last MSG_SYSTEM_SEND_SYNCHRO_CMD command to be really finished */
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
);
90 err
= snd_mixart_send_msg_wait_notif(mgr
, &request
, system_msg_uid
);
92 dev_err(&mgr
->pci
->dev
,
93 "error : MSG_SYSTEM_WAIT_SYNCHRO_CMD was not notified !\n");
97 /* start or stop the pipe (1 pipe) */
99 memset(&group_state
, 0, sizeof(group_state
));
100 group_state
.pipe_count
= 1;
101 group_state
.pipe_uid
= pipe
->group_uid
;
104 request
.message_id
= MSG_STREAM_START_STREAM_GRP_PACKET
;
106 request
.message_id
= MSG_STREAM_STOP_STREAM_GRP_PACKET
;
108 request
.uid
= pipe
->group_uid
; /*(struct mixart_uid){0,0};*/
109 request
.data
= &group_state
;
110 request
.size
= sizeof(group_state
);
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
);
123 group_state
.pipe_count
= 0; /* in case of start same command once again with pipe_count=0 */
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
);
133 /* in case of start send a synchro top */
135 request
.message_id
= MSG_SYSTEM_SEND_SYNCHRO_CMD
;
136 request
.uid
= (struct mixart_uid
){0,0};
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",
148 pipe
->status
= PIPE_RUNNING
;
151 pipe
->status
= PIPE_STOPPED
;
157 static int mixart_set_clock(struct mixart_mgr
*mgr
,
158 struct mixart_pipe
*pipe
, unsigned int rate
)
160 struct mixart_msg request
;
161 struct mixart_clock_properties clock_properties
;
162 struct mixart_clock_properties_resp clock_prop_resp
;
165 switch(pipe
->status
) {
174 return 0; /* nothing to do */
176 dev_err(&mgr
->pci
->dev
,
177 "error mixart_set_clock(%d) called with wrong pipe->status !\n",
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
= pipe
->group_uid
;
190 dev_dbg(&mgr
->pci
->dev
, "mixart_set_clock to %d kHz\n", rate
);
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
);
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
);
205 if(rate
) pipe
->status
= PIPE_CLOCK_SET
;
206 else pipe
->status
= PIPE_RUNNING
;
213 * Allocate or reference output pipe for analog IOs (pcmp0/1)
216 snd_mixart_add_ref_pipe(struct snd_mixart
*chip
, int pcm_number
, int capture
,
220 struct mixart_pipe
*pipe
;
221 struct mixart_msg request
;
224 if (pcm_number
== MIXART_PCM_ANALOG
) {
225 pipe
= &(chip
->pipe_in_ana
); /* analog inputs */
227 pipe
= &(chip
->pipe_in_dig
); /* digital inputs */
229 request
.message_id
= MSG_STREAM_ADD_OUTPUT_GROUP
;
230 stream_count
= MIXART_CAPTURE_STREAMS
;
232 if (pcm_number
== MIXART_PCM_ANALOG
) {
233 pipe
= &(chip
->pipe_out_ana
); /* analog outputs */
235 pipe
= &(chip
->pipe_out_dig
); /* digital outputs */
237 request
.message_id
= MSG_STREAM_ADD_INPUT_GROUP
;
238 stream_count
= MIXART_PLAYBACK_STREAMS
;
241 /* a new stream is opened and there are already all streams in use */
242 if( (monitoring
== 0) && (pipe
->references
>= stream_count
) ) {
246 /* pipe is not yet defined */
247 if( pipe
->status
== PIPE_UNDEFINED
) {
250 struct mixart_streaming_group_req sgroup_req
;
251 struct mixart_streaming_group sgroup_resp
;
254 dev_dbg(chip
->card
->dev
,
255 "add_ref_pipe audio chip(%d) pcm(%d)\n",
256 chip
->chip_idx
, pcm_number
);
258 buf
= kmalloc(sizeof(*buf
), GFP_KERNEL
);
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
);
266 memset(&buf
->sgroup_req
, 0, sizeof(buf
->sgroup_req
));
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 */
273 for (i
=0; i
<stream_count
; i
++) {
275 struct mixart_flowinfo
*flowinfo
;
276 struct mixart_bufferinfo
*bufferinfo
;
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 */
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 */
287 buf
->sgroup_req
.flow_entry
[i
] = j
;
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 ! */
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 */
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
;
300 bufferinfo
[j
].buffer_id
|= MIXART_NOTIFY_CAPT_MASK
;
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
);
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; */
317 pipe
->status
= PIPE_STOPPED
;
321 if(monitoring
) pipe
->monitoring
= 1;
322 else pipe
->references
++;
328 int snd_mixart_kill_ref_pipe(struct mixart_mgr
*mgr
,
329 struct mixart_pipe
*pipe
, int monitoring
)
333 if(pipe
->status
== PIPE_UNDEFINED
)
337 pipe
->monitoring
= 0;
341 if((pipe
->references
<= 0) && (pipe
->monitoring
== 0)) {
343 struct mixart_msg request
;
344 struct mixart_delete_group_resp delete_resp
;
346 /* release the clock */
347 err
= mixart_set_clock( mgr
, pipe
, 0);
349 dev_err(&mgr
->pci
->dev
,
350 "mixart_set_clock(0) return error!\n");
354 err
= mixart_set_pipe_state(mgr
, pipe
, 0);
356 dev_err(&mgr
->pci
->dev
, "error stopping pipe!\n");
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
);
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
);
372 pipe
->group_uid
= (struct mixart_uid
){0,0};
373 pipe
->stream_count
= 0;
374 pipe
->status
= PIPE_UNDEFINED
;
380 static int mixart_set_stream_state(struct mixart_stream
*stream
, int start
)
382 struct snd_mixart
*chip
;
383 struct mixart_stream_state_req stream_state_req
;
384 struct mixart_msg request
;
386 if(!stream
->substream
)
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
;
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
;
397 request
.message_id
= start
? MSG_STREAM_START_OUTPUT_STAGE_PACKET
: MSG_STREAM_STOP_OUTPUT_STAGE_PACKET
;
399 request
.uid
= (struct mixart_uid
){0,0};
400 request
.data
= &stream_state_req
;
401 request
.size
= sizeof(stream_state_req
);
403 stream
->abs_period_elapsed
= 0; /* reset stream pos */
404 stream
->buf_periods
= 0;
405 stream
->buf_period_frag
= 0;
407 chip
= snd_pcm_substream_chip(stream
->substream
);
409 return snd_mixart_send_msg_nonblock(chip
->mgr
, &request
);
416 static int snd_mixart_trigger(struct snd_pcm_substream
*subs
, int cmd
)
418 struct mixart_stream
*stream
= subs
->runtime
->private_data
;
421 case SNDRV_PCM_TRIGGER_START
:
423 dev_dbg(subs
->pcm
->card
->dev
, "SNDRV_PCM_TRIGGER_START\n");
426 if( mixart_set_stream_state(stream
, 1) )
429 stream
->status
= MIXART_STREAM_STATUS_RUNNING
;
432 case SNDRV_PCM_TRIGGER_STOP
:
435 if( mixart_set_stream_state(stream
, 0) )
438 stream
->status
= MIXART_STREAM_STATUS_OPEN
;
440 dev_dbg(subs
->pcm
->card
->dev
, "SNDRV_PCM_TRIGGER_STOP\n");
444 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
446 stream
->status
= MIXART_STREAM_STATUS_PAUSE
;
447 dev_dbg(subs
->pcm
->card
->dev
, "SNDRV_PCM_PAUSE_PUSH\n");
449 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
451 stream
->status
= MIXART_STREAM_STATUS_RUNNING
;
452 dev_dbg(subs
->pcm
->card
->dev
, "SNDRV_PCM_PAUSE_RELEASE\n");
460 static int mixart_sync_nonblock_events(struct mixart_mgr
*mgr
)
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");
469 schedule_timeout_uninterruptible(1);
475 * prepare callback for all pcms
477 static int snd_mixart_prepare(struct snd_pcm_substream
*subs
)
479 struct snd_mixart
*chip
= snd_pcm_substream_chip(subs
);
480 struct mixart_stream
*stream
= subs
->runtime
->private_data
;
482 /* TODO de façon non bloquante, réappliquer les hw_params (rate, bits, codec) */
484 dev_dbg(chip
->card
->dev
, "snd_mixart_prepare\n");
486 mixart_sync_nonblock_events(chip
->mgr
);
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
;
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
) )
503 static int mixart_set_format(struct mixart_stream
*stream
, snd_pcm_format_t format
)
506 struct snd_mixart
*chip
;
507 struct mixart_msg request
;
508 struct mixart_stream_param_desc stream_param
;
509 struct mixart_return_uid resp
;
511 chip
= snd_pcm_substream_chip(stream
->substream
);
513 memset(&stream_param
, 0, sizeof(stream_param
));
515 stream_param
.coding_type
= CT_LINEAR
;
516 stream_param
.number_of_channel
= stream
->channels
;
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 */
523 case SNDRV_PCM_FORMAT_U8
:
524 stream_param
.sample_type
= ST_INTEGER_8
;
525 stream_param
.sample_size
= 8;
527 case SNDRV_PCM_FORMAT_S16_LE
:
528 stream_param
.sample_type
= ST_INTEGER_16LE
;
529 stream_param
.sample_size
= 16;
531 case SNDRV_PCM_FORMAT_S16_BE
:
532 stream_param
.sample_type
= ST_INTEGER_16BE
;
533 stream_param
.sample_size
= 16;
535 case SNDRV_PCM_FORMAT_S24_3LE
:
536 stream_param
.sample_type
= ST_INTEGER_24LE
;
537 stream_param
.sample_size
= 24;
539 case SNDRV_PCM_FORMAT_S24_3BE
:
540 stream_param
.sample_type
= ST_INTEGER_24BE
;
541 stream_param
.sample_size
= 24;
543 case SNDRV_PCM_FORMAT_FLOAT_LE
:
544 stream_param
.sample_type
= ST_FLOATING_POINT_32LE
;
545 stream_param
.sample_size
= 32;
547 case SNDRV_PCM_FORMAT_FLOAT_BE
:
548 stream_param
.sample_type
= ST_FLOATING_POINT_32BE
;
549 stream_param
.sample_size
= 32;
552 dev_err(chip
->card
->dev
,
553 "error mixart_set_format() : unknown format\n");
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
);
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; */
566 stream_param
.pipe_count
= 1; /* set to 1 */
567 stream_param
.stream_count
= 1; /* set to 1 */
568 stream_param
.stream_desc
.uid_pipe
= stream
->pipe
->group_uid
;
569 stream_param
.stream_desc
.stream_idx
= stream
->substream
->number
;
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
);
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
);
588 * HW_PARAMS callback for all pcms
590 static int snd_mixart_hw_params(struct snd_pcm_substream
*subs
,
591 struct snd_pcm_hw_params
*hw
)
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
;
600 /* set up channels */
601 channels
= params_channels(hw
);
603 /* set up format for the stream */
604 format
= params_format(hw
);
606 mutex_lock(&mgr
->setup_mutex
);
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
);
614 mixart_update_capture_stream_level( chip
, is_aes
);
617 stream
->channels
= channels
;
619 /* set the format to the board */
620 err
= mixart_set_format(stream
, format
);
622 mutex_unlock(&mgr
->setup_mutex
);
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 */
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 */
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
,
644 mutex_unlock(&mgr
->setup_mutex
);
649 static int snd_mixart_hw_free(struct snd_pcm_substream
*subs
)
651 struct snd_mixart
*chip
= snd_pcm_substream_chip(subs
);
652 mixart_sync_nonblock_events(chip
->mgr
);
659 * TODO CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
661 static const struct snd_pcm_hardware snd_mixart_analog_caps
=
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
,
675 .buffer_bytes_max
= (32*1024),
676 .period_bytes_min
= 256, /* 256 frames U8 mono*/
677 .period_bytes_max
= (16*1024),
679 .periods_max
= (32*1024/256),
682 static const struct snd_pcm_hardware snd_mixart_digital_caps
=
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
,
696 .buffer_bytes_max
= (32*1024),
697 .period_bytes_min
= 256, /* 256 frames U8 mono*/
698 .period_bytes_max
= (16*1024),
700 .periods_max
= (32*1024/256),
704 static int snd_mixart_playback_open(struct snd_pcm_substream
*subs
)
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
;
715 mutex_lock(&mgr
->setup_mutex
);
717 if ( pcm
== chip
->pcm
) {
718 pcm_number
= MIXART_PCM_ANALOG
;
719 runtime
->hw
= snd_mixart_analog_caps
;
721 snd_BUG_ON(pcm
!= chip
->pcm_dig
);
722 pcm_number
= MIXART_PCM_DIGITAL
;
723 runtime
->hw
= snd_mixart_digital_caps
;
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
);
729 /* get stream info */
730 stream
= &(chip
->playback_stream
[pcm_number
][subs
->number
]);
732 if (stream
->status
!= MIXART_STREAM_STATUS_FREE
){
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
);
741 /* get pipe pointer (out pipe) */
742 pipe
= snd_mixart_add_ref_pipe(chip
, pcm_number
, 0, 0);
749 /* start the pipe if necessary */
750 err
= mixart_set_pipe_state(chip
->mgr
, pipe
, 1);
752 dev_err(chip
->card
->dev
, "error starting pipe!\n");
753 snd_mixart_kill_ref_pipe(chip
->mgr
, pipe
, 0);
759 stream
->pcm_number
= pcm_number
;
760 stream
->status
= MIXART_STREAM_STATUS_OPEN
;
761 stream
->substream
= subs
;
762 stream
->channels
= 0; /* not configured yet */
764 runtime
->private_data
= stream
;
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);
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
;
777 mutex_unlock(&mgr
->setup_mutex
);
783 static int snd_mixart_capture_open(struct snd_pcm_substream
*subs
)
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
;
794 mutex_lock(&mgr
->setup_mutex
);
796 if ( pcm
== chip
->pcm
) {
797 pcm_number
= MIXART_PCM_ANALOG
;
798 runtime
->hw
= snd_mixart_analog_caps
;
800 snd_BUG_ON(pcm
!= chip
->pcm_dig
);
801 pcm_number
= MIXART_PCM_DIGITAL
;
802 runtime
->hw
= snd_mixart_digital_caps
;
805 runtime
->hw
.channels_min
= 2; /* for instance, no mono */
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
);
810 /* get stream info */
811 stream
= &(chip
->capture_stream
[pcm_number
]);
813 if (stream
->status
!= MIXART_STREAM_STATUS_FREE
){
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
);
822 /* get pipe pointer (in pipe) */
823 pipe
= snd_mixart_add_ref_pipe(chip
, pcm_number
, 1, 0);
830 /* start the pipe if necessary */
831 err
= mixart_set_pipe_state(chip
->mgr
, pipe
, 1);
833 dev_err(chip
->card
->dev
, "error starting pipe!\n");
834 snd_mixart_kill_ref_pipe(chip
->mgr
, pipe
, 0);
840 stream
->pcm_number
= pcm_number
;
841 stream
->status
= MIXART_STREAM_STATUS_OPEN
;
842 stream
->substream
= subs
;
843 stream
->channels
= 0; /* not configured yet */
845 runtime
->private_data
= stream
;
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);
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
;
858 mutex_unlock(&mgr
->setup_mutex
);
865 static int snd_mixart_close(struct snd_pcm_substream
*subs
)
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
;
871 mutex_lock(&mgr
->setup_mutex
);
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
);
876 /* sample rate released */
877 if(--mgr
->ref_count_rate
== 0) {
878 mgr
->sample_rate
= 0;
882 if (snd_mixart_kill_ref_pipe(mgr
, stream
->pipe
, 0 ) < 0) {
884 dev_err(chip
->card
->dev
,
885 "error snd_mixart_kill_ref_pipe C%dP%d\n",
886 chip
->chip_idx
, stream
->pcm_number
);
890 stream
->status
= MIXART_STREAM_STATUS_FREE
;
891 stream
->substream
= NULL
;
893 mutex_unlock(&mgr
->setup_mutex
);
898 static snd_pcm_uframes_t
snd_mixart_stream_pointer(struct snd_pcm_substream
*subs
)
900 struct snd_pcm_runtime
*runtime
= subs
->runtime
;
901 struct mixart_stream
*stream
= runtime
->private_data
;
903 return (snd_pcm_uframes_t
)((stream
->buf_periods
* runtime
->period_size
) + stream
->buf_period_frag
);
908 static 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
,
918 static 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
,
928 static void preallocate_buffers(struct snd_mixart
*chip
, struct snd_pcm
*pcm
)
931 struct snd_pcm_substream
*subs
;
934 for (stream
= 0; stream
< 2; stream
++) {
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;
943 snd_pcm_set_managed_buffer_all(pcm
, SNDRV_DMA_TYPE_DEV
,
944 &chip
->mgr
->pci
->dev
,
950 static int snd_mixart_pcm_analog(struct snd_mixart
*chip
)
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
);
961 dev_err(chip
->card
->dev
,
962 "cannot create the analog pcm %d\n", chip
->chip_idx
);
966 pcm
->private_data
= chip
;
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
);
972 pcm
->nonatomic
= true;
973 strcpy(pcm
->name
, name
);
975 preallocate_buffers(chip
, pcm
);
984 static int snd_mixart_pcm_digital(struct snd_mixart
*chip
)
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
);
995 dev_err(chip
->card
->dev
,
996 "cannot create the digital pcm %d\n", chip
->chip_idx
);
1000 pcm
->private_data
= chip
;
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
);
1005 pcm
->info_flags
= 0;
1006 pcm
->nonatomic
= true;
1007 strcpy(pcm
->name
, name
);
1009 preallocate_buffers(chip
, pcm
);
1011 chip
->pcm_dig
= pcm
;
1015 static int snd_mixart_chip_free(struct snd_mixart
*chip
)
1021 static int snd_mixart_chip_dev_free(struct snd_device
*device
)
1023 struct snd_mixart
*chip
= device
->device_data
;
1024 return snd_mixart_chip_free(chip
);
1030 static int snd_mixart_create(struct mixart_mgr
*mgr
, struct snd_card
*card
, int idx
)
1033 struct snd_mixart
*chip
;
1034 static const struct snd_device_ops ops
= {
1035 .dev_free
= snd_mixart_chip_dev_free
,
1038 chip
= kzalloc(sizeof(*chip
), GFP_KERNEL
);
1043 chip
->chip_idx
= idx
;
1045 card
->sync_irq
= mgr
->irq
;
1047 err
= snd_device_new(card
, SNDRV_DEV_LOWLEVEL
, chip
, &ops
);
1049 snd_mixart_chip_free(chip
);
1053 mgr
->chip
[idx
] = chip
;
1057 int snd_mixart_create_pcm(struct snd_mixart
* chip
)
1061 err
= snd_mixart_pcm_analog(chip
);
1065 if(chip
->mgr
->board_type
== MIXART_DAUGHTER_TYPE_AES
) {
1067 err
= snd_mixart_pcm_digital(chip
);
1076 * release all the cards assigned to a manager instance
1078 static int snd_mixart_free(struct mixart_mgr
*mgr
)
1082 for (i
= 0; i
< mgr
->num_cards
; i
++) {
1084 snd_card_free(mgr
->chip
[i
]->card
);
1088 snd_mixart_exit_mailbox(mgr
);
1092 free_irq(mgr
->irq
, mgr
);
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");
1100 /* release the i/o ports */
1101 for (i
= 0; i
< 2; ++i
)
1102 iounmap(mgr
->mem
[i
].virt
);
1104 pci_release_regions(mgr
->pci
);
1106 /* free flowarray */
1107 if(mgr
->flowinfo
.area
) {
1108 snd_dma_free_pages(&mgr
->flowinfo
);
1109 mgr
->flowinfo
.area
= NULL
;
1111 /* free bufferarray */
1112 if(mgr
->bufferinfo
.area
) {
1113 snd_dma_free_pages(&mgr
->bufferinfo
);
1114 mgr
->bufferinfo
.area
= NULL
;
1117 pci_disable_device(mgr
->pci
);
1127 mixart_BA0 proc interface for BAR 0 - read callback
1129 static 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
)
1134 struct mixart_mgr
*mgr
= entry
->private_data
;
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
))
1143 mixart_BA1 proc interface for BAR 1 - read callback
1145 static 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
)
1150 struct mixart_mgr
*mgr
= entry
->private_data
;
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
))
1158 static const struct snd_info_entry_ops snd_mixart_proc_ops_BA0
= {
1159 .read
= snd_mixart_BA0_read
,
1162 static const struct snd_info_entry_ops snd_mixart_proc_ops_BA1
= {
1163 .read
= snd_mixart_BA1_read
,
1167 static void snd_mixart_proc_read(struct snd_info_entry
*entry
,
1168 struct snd_info_buffer
*buffer
)
1170 struct snd_mixart
*chip
= entry
->private_data
;
1173 snd_iprintf(buffer
, "Digigram miXart (alsa card %d)\n\n", chip
->chip_idx
);
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;
1185 snd_iprintf(buffer
, "- system load -\n");
1187 /* get perf reference */
1189 ref
= readl_be( MIXART_MEM( chip
->mgr
, MIXART_PSEUDOREG_PERF_SYSTEM_LOAD_OFFSET
));
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
;
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
);
1200 } /* endif elf loaded */
1203 static void snd_mixart_proc_init(struct snd_mixart
*chip
)
1205 struct snd_info_entry
*entry
;
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
);
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
;
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
;
1224 /* end of proc interface */
1228 * probe function - creates the card manager
1230 static int snd_mixart_probe(struct pci_dev
*pci
,
1231 const struct pci_device_id
*pci_id
)
1234 struct mixart_mgr
*mgr
;
1241 if (dev
>= SNDRV_CARDS
)
1243 if (! enable
[dev
]) {
1248 /* enable PCI device */
1249 err
= pci_enable_device(pci
);
1252 pci_set_master(pci
);
1254 /* check if we can restrict PCI DMA transfers to 32 bits */
1255 if (dma_set_mask(&pci
->dev
, DMA_BIT_MASK(32)) < 0) {
1257 "architecture does not support 32bit PCI busmaster DMA\n");
1258 pci_disable_device(pci
);
1264 mgr
= kzalloc(sizeof(*mgr
), GFP_KERNEL
);
1266 pci_disable_device(pci
);
1273 /* resource assignment */
1274 err
= pci_request_regions(pci
, CARD_NAME
);
1277 pci_disable_device(pci
);
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",
1286 snd_mixart_free(mgr
);
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
);
1298 mgr
->irq
= pci
->irq
;
1301 mgr
->msg_fifo_readptr
= 0;
1302 mgr
->msg_fifo_writeptr
= 0;
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);
1309 /* init setup mutex*/
1310 mutex_init(&mgr
->setup_mutex
);
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
;
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
,
1328 dev_err(&pci
->dev
, "cannot allocate the card %d\n", i
);
1329 snd_mixart_free(mgr
);
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
);
1340 err
= snd_mixart_create(mgr
, card
, i
);
1342 snd_card_free(card
);
1343 snd_mixart_free(mgr
);
1348 /* init proc interface only for chip0 */
1349 snd_mixart_proc_init(mgr
->chip
[i
]);
1352 err
= snd_card_register(card
);
1354 snd_mixart_free(mgr
);
1359 /* init firmware status (mgr->dsp_loaded reset in hwdep_new) */
1360 mgr
->board_type
= MIXART_DAUGHTER_TYPE_NONE
;
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
);
1370 /* init streaminfo_array */
1371 memset(mgr
->flowinfo
.area
, 0, size
);
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
);
1381 /* init bufferinfo_array */
1382 memset(mgr
->bufferinfo
.area
, 0, size
);
1384 /* set up firmware */
1385 err
= snd_mixart_setup_firmware(mgr
);
1387 snd_mixart_free(mgr
);
1391 pci_set_drvdata(pci
, mgr
);
1396 static void snd_mixart_remove(struct pci_dev
*pci
)
1398 snd_mixart_free(pci_get_drvdata(pci
));
1401 static 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
,
1408 module_pci_driver(mixart_driver
);