Lines Matching +full:pcm +full:- +full:interface +full:- +full:rate
1 // SPDX-License-Identifier: GPL-2.0-or-later
14 #include <linux/dma-mapping.h>
23 #include <sound/pcm.h>
36 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
67 switch(pipe->status) {
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 */
92 dev_err(&mgr->pci->dev,
101 group_state.pipe_uid = pipe->group_uid;
108 request.uid = pipe->group_uid; /*(struct mixart_uid){0,0};*/
114 dev_err(&mgr->pci->dev,
117 return -EINVAL;
127 dev_err(&mgr->pci->dev,
130 return -EINVAL;
142 dev_err(&mgr->pci->dev,
145 return -EINVAL;
148 pipe->status = PIPE_RUNNING;
151 pipe->status = PIPE_STOPPED;
158 struct mixart_pipe *pipe, unsigned int rate)
165 switch(pipe->status) {
169 if(rate != 0)
173 if(rate == 0)
176 dev_err(&mgr->pci->dev,
177 "error mixart_set_clock(%d) called with wrong pipe->status !\n",
178 rate);
179 return -EINVAL;
184 clock_properties.clock_generic_type = (rate != 0) ? CGT_INTERNAL_CLOCK : CGT_NO_CLOCK;
186 clock_properties.frequency = rate;
188 clock_properties.uid_caller = pipe->group_uid;
190 dev_dbg(&mgr->pci->dev, "mixart_set_clock to %d kHz\n", rate);
193 request.uid = mgr->uid_console_manager;
199 dev_err(&mgr->pci->dev,
202 return -EINVAL;
205 if(rate) pipe->status = PIPE_CLOCK_SET;
206 else pipe->status = PIPE_RUNNING;
225 pipe = &(chip->pipe_in_ana); /* analog inputs */
227 pipe = &(chip->pipe_in_dig); /* digital inputs */
233 pipe = &(chip->pipe_out_ana); /* analog outputs */
235 pipe = &(chip->pipe_out_dig); /* digital outputs */
242 if( (monitoring == 0) && (pipe->references >= stream_count) ) {
247 if( pipe->status == PIPE_UNDEFINED ) {
254 dev_dbg(chip->card->dev,
255 "add_ref_pipe audio chip(%d) pcm(%d)\n",
256 chip->chip_idx, pcm_number);
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 */
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 */
284 j = (chip->chip_idx * MIXART_MAX_STREAM_PER_CARD) + (pcm_number * (MIXART_PLAYBACK_STREAMS + MIXART_CAPTURE_STREAMS)) + i;
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;
298 bufferinfo[j].buffer_id = (chip->chip_idx << MIXART_NOTIFY_CARD_OFFSET) + (pcm_number << MIXART_NOTIFY_PCM_OFFSET ) + i;
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,
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++;
333 if(pipe->status == PIPE_UNDEFINED)
337 pipe->monitoring = 0;
339 pipe->references--;
341 if((pipe->references <= 0) && (pipe->monitoring == 0)) {
349 dev_err(&mgr->pci->dev,
356 dev_err(&mgr->pci->dev, "error stopping pipe!\n");
361 request.data = &pipe->group_uid; /* the streaming group ! */
362 request.size = sizeof(pipe->group_uid);
367 dev_err(&mgr->pci->dev,
372 pipe->group_uid = (struct mixart_uid){0,0};
373 pipe->stream_count = 0;
374 pipe->status = PIPE_UNDEFINED;
386 if(!stream->substream)
387 return -EINVAL;
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)
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);
418 struct mixart_stream *stream = subs->runtime->private_data;
423 dev_dbg(subs->pcm->card->dev, "SNDRV_PCM_TRIGGER_START\n");
427 return -EINVAL;
429 stream->status = MIXART_STREAM_STATUS_RUNNING;
436 return -EINVAL;
438 stream->status = MIXART_STREAM_STATUS_OPEN;
440 dev_dbg(subs->pcm->card->dev, "SNDRV_PCM_TRIGGER_STOP\n");
446 stream->status = MIXART_STREAM_STATUS_PAUSE;
447 dev_dbg(subs->pcm->card->dev, "SNDRV_PCM_PAUSE_PUSH\n");
451 stream->status = MIXART_STREAM_STATUS_RUNNING;
452 dev_dbg(subs->pcm->card->dev, "SNDRV_PCM_PAUSE_RELEASE\n");
455 return -EINVAL;
463 while (atomic_read(&mgr->msg_processed) > 0) {
465 dev_err(&mgr->pci->dev,
467 return -EBUSY;
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 */
490 if(chip->mgr->ref_count_rate == 1)
491 chip->mgr->sample_rate = subs->runtime->rate;
494 if(stream->pipe->references == 1) {
495 if( mixart_set_clock(chip->mgr, stream->pipe, subs->runtime->rate) )
496 return -EINVAL;
511 chip = snd_pcm_substream_chip(stream->substream);
516 stream_param.number_of_channel = stream->channels;
518 stream_param.sampling_freq = chip->mgr->sample_rate;
552 dev_err(chip->card->dev,
554 return -EINVAL;
557 dev_dbg(chip->card->dev,
559 stream_param.sample_type, stream_param.sample_size, stream_param.sampling_freq, stream->channels);
568 stream_param.stream_desc.uid_pipe = stream->pipe->group_uid;
569 stream_param.stream_desc.stream_idx = stream->substream->number;
576 err = snd_mixart_send_msg(chip->mgr, &request, sizeof(resp), &resp);
578 dev_err(chip->card->dev,
581 return -EINVAL;
594 struct mixart_mgr *mgr = chip->mgr;
595 struct mixart_stream *stream = subs->runtime->private_data;
606 guard(mutex)(&mgr->setup_mutex);
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);
617 stream->channels = channels;
624 if (subs->runtime->buffer_changed) {
626 int i = (chip->chip_idx * MIXART_MAX_STREAM_PER_CARD) + (stream->pcm_number * (MIXART_PLAYBACK_STREAMS+MIXART_CAPTURE_STREAMS)) + subs->number;
627 if( subs->stream == SNDRV_PCM_STREAM_CAPTURE ) {
631 bufferinfo = (struct mixart_bufferinfo *)chip->mgr->bufferinfo.area;
632 bufferinfo[i].buffer_address = subs->runtime->dma_addr;
633 bufferinfo[i].available_length = subs->runtime->dma_bytes;
636 dev_dbg(chip->card->dev,
637 "snd_mixart_hw_params(pcm %d) : dma_addr(%x) dma_bytes(%x) subs-number(%d)\n",
640 subs->number);
649 mixart_sync_nonblock_events(chip->mgr);
656 * TODO CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
704 struct mixart_mgr *mgr = chip->mgr;
705 struct snd_pcm_runtime *runtime = subs->runtime;
706 struct snd_pcm *pcm = subs->pcm;
712 guard(mutex)(&mgr->setup_mutex);
714 if ( pcm == chip->pcm ) {
716 runtime->hw = snd_mixart_analog_caps;
718 snd_BUG_ON(pcm != chip->pcm_dig);
720 runtime->hw = snd_mixart_digital_caps;
722 dev_dbg(chip->card->dev,
724 chip->chip_idx, pcm_number, subs->number);
727 stream = &(chip->playback_stream[pcm_number][subs->number]);
729 if (stream->status != MIXART_STREAM_STATUS_FREE){
731 dev_err(chip->card->dev,
733 chip->chip_idx, pcm_number, subs->number);
734 return -EBUSY;
741 return -EINVAL;
744 err = mixart_set_pipe_state(chip->mgr, pipe, 1);
746 dev_err(chip->card->dev, "error starting pipe!\n");
747 snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0);
748 return -EINVAL;
751 stream->pipe = pipe;
752 stream->pcm_number = pcm_number;
753 stream->status = MIXART_STREAM_STATUS_OPEN;
754 stream->substream = subs;
755 stream->channels = 0; /* not configured yet */
757 runtime->private_data = stream;
762 /* if a sample rate is already used, another stream cannot change */
763 if(mgr->ref_count_rate++) {
764 if(mgr->sample_rate) {
765 runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;
776 struct mixart_mgr *mgr = chip->mgr;
777 struct snd_pcm_runtime *runtime = subs->runtime;
778 struct snd_pcm *pcm = subs->pcm;
784 guard(mutex)(&mgr->setup_mutex);
786 if ( pcm == chip->pcm ) {
788 runtime->hw = snd_mixart_analog_caps;
790 snd_BUG_ON(pcm != chip->pcm_dig);
792 runtime->hw = snd_mixart_digital_caps;
795 runtime->hw.channels_min = 2; /* for instance, no mono */
797 dev_dbg(chip->card->dev, "snd_mixart_capture_open C%d/P%d/Sub%d\n",
798 chip->chip_idx, pcm_number, subs->number);
801 stream = &(chip->capture_stream[pcm_number]);
803 if (stream->status != MIXART_STREAM_STATUS_FREE){
805 dev_err(chip->card->dev,
807 chip->chip_idx, pcm_number, subs->number);
808 return -EBUSY;
815 return -EINVAL;
818 err = mixart_set_pipe_state(chip->mgr, pipe, 1);
820 dev_err(chip->card->dev, "error starting pipe!\n");
821 snd_mixart_kill_ref_pipe(chip->mgr, pipe, 0);
822 return -EINVAL;
825 stream->pipe = pipe;
826 stream->pcm_number = pcm_number;
827 stream->status = MIXART_STREAM_STATUS_OPEN;
828 stream->substream = subs;
829 stream->channels = 0; /* not configured yet */
831 runtime->private_data = stream;
836 /* if a sample rate is already used, another stream cannot change */
837 if(mgr->ref_count_rate++) {
838 if(mgr->sample_rate) {
839 runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;
851 struct mixart_mgr *mgr = chip->mgr;
852 struct mixart_stream *stream = subs->runtime->private_data;
854 guard(mutex)(&mgr->setup_mutex);
856 dev_dbg(chip->card->dev, "snd_mixart_close C%d/P%d/Sub%d\n",
857 chip->chip_idx, stream->pcm_number, subs->number);
859 /* sample rate released */
860 if(--mgr->ref_count_rate == 0) {
861 mgr->sample_rate = 0;
865 if (snd_mixart_kill_ref_pipe(mgr, stream->pipe, 0 ) < 0) {
867 dev_err(chip->card->dev,
869 chip->chip_idx, stream->pcm_number);
872 stream->pipe = NULL;
873 stream->status = MIXART_STREAM_STATUS_FREE;
874 stream->substream = NULL;
882 struct snd_pcm_runtime *runtime = subs->runtime;
883 struct mixart_stream *stream = runtime->private_data;
885 return (snd_pcm_uframes_t)((stream->buf_periods * runtime->period_size) + stream->buf_period_frag);
910 static void preallocate_buffers(struct snd_mixart *chip, struct snd_pcm *pcm)
918 for (subs = pcm->streams[stream].substream; subs; subs = subs->next, idx++)
920 subs->dma_device.id = subs->pcm->device << 16 |
921 subs->stream << 8 | (subs->number + 1) |
922 (chip->chip_idx + 1) << 24;
925 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
926 &chip->mgr->pci->dev,
935 struct snd_pcm *pcm;
938 sprintf(name, "miXart analog %d", chip->chip_idx);
939 err = snd_pcm_new(chip->card, name, MIXART_PCM_ANALOG,
941 MIXART_CAPTURE_STREAMS, &pcm);
943 dev_err(chip->card->dev,
944 "cannot create the analog pcm %d\n", chip->chip_idx);
948 pcm->private_data = chip;
950 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_mixart_playback_ops);
951 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mixart_capture_ops);
953 pcm->info_flags = 0;
954 pcm->nonatomic = true;
955 strscpy(pcm->name, name);
957 preallocate_buffers(chip, pcm);
959 chip->pcm = pcm;
969 struct snd_pcm *pcm;
972 sprintf(name, "miXart AES/EBU %d", chip->chip_idx);
973 err = snd_pcm_new(chip->card, name, MIXART_PCM_DIGITAL,
975 MIXART_CAPTURE_STREAMS, &pcm);
977 dev_err(chip->card->dev,
978 "cannot create the digital pcm %d\n", chip->chip_idx);
982 pcm->private_data = chip;
984 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_mixart_playback_ops);
985 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mixart_capture_ops);
987 pcm->info_flags = 0;
988 pcm->nonatomic = true;
989 strscpy(pcm->name, name);
991 preallocate_buffers(chip, pcm);
993 chip->pcm_dig = pcm;
1005 struct snd_mixart *chip = device->device_data;
1022 return -ENOMEM;
1024 chip->card = card;
1025 chip->chip_idx = idx;
1026 chip->mgr = mgr;
1027 card->sync_irq = mgr->irq;
1035 mgr->chip[idx] = chip;
1047 if(chip->mgr->board_type == MIXART_DAUGHTER_TYPE_AES) {
1064 for (i = 0; i < mgr->num_cards; i++) {
1065 if (mgr->chip[i])
1066 snd_card_free(mgr->chip[i]->card);
1073 if (mgr->irq >= 0)
1074 free_irq(mgr->irq, mgr);
1077 if(mgr->dsp_loaded) {
1079 dev_dbg(&mgr->pci->dev, "reset miXart !\n");
1084 iounmap(mgr->mem[i].virt);
1086 pci_release_regions(mgr->pci);
1089 if(mgr->flowinfo.area) {
1090 snd_dma_free_pages(&mgr->flowinfo);
1091 mgr->flowinfo.area = NULL;
1094 if(mgr->bufferinfo.area) {
1095 snd_dma_free_pages(&mgr->bufferinfo);
1096 mgr->bufferinfo.area = NULL;
1099 pci_disable_device(mgr->pci);
1105 * proc interface
1109 mixart_BA0 proc interface for BAR 0 - read callback
1116 struct mixart_mgr *mgr = entry->private_data;
1120 return -EFAULT;
1125 mixart_BA1 proc interface for BAR 1 - read callback
1132 struct mixart_mgr *mgr = entry->private_data;
1136 return -EFAULT;
1152 struct snd_mixart *chip = entry->private_data;
1155 snd_iprintf(buffer, "Digigram miXart (alsa card %d)\n\n", chip->chip_idx);
1158 if (chip->mgr->dsp_loaded & ( 1 << MIXART_MOTHERBOARD_ELF_INDEX)) {
1159 snd_iprintf(buffer, "- hardware -\n");
1160 switch (chip->mgr->board_type ) {
1167 snd_iprintf(buffer, "- system load -\n");
1171 ref = readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_SYSTEM_LOAD_OFFSET));
1174 u32 mailbox = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_MAILBX_LOAD_OFFSET)) / ref;
1175 u32 streaming = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_STREAM_LOAD_OFFSET)) / ref;
1176 u32 interr = 100 * readl_be( MIXART_MEM( chip->mgr, MIXART_PSEUDOREG_PERF_INTERR_LOAD_OFFSET)) / ref;
1189 /* text interface to read perf and temp meters */
1190 snd_card_ro_proc_new(chip->card, "board_info", chip,
1193 if (! snd_card_proc_new(chip->card, "mixart_BA0", &entry)) {
1194 entry->content = SNDRV_INFO_CONTENT_DATA;
1195 entry->private_data = chip->mgr;
1196 entry->c.ops = &snd_mixart_proc_ops_BA0;
1197 entry->size = MIXART_BA0_SIZE;
1199 if (! snd_card_proc_new(chip->card, "mixart_BA1", &entry)) {
1200 entry->content = SNDRV_INFO_CONTENT_DATA;
1201 entry->private_data = chip->mgr;
1202 entry->c.ops = &snd_mixart_proc_ops_BA1;
1203 entry->size = MIXART_BA1_SIZE;
1206 /* end of proc interface */
1210 * probe function - creates the card manager
1224 return -ENODEV;
1227 return -ENOENT;
1237 if (dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) {
1238 dev_err(&pci->dev,
1241 return -ENXIO;
1249 return -ENOMEM;
1252 mgr->pci = pci;
1253 mgr->irq = -1;
1263 mgr->mem[i].phys = pci_resource_start(pci, i);
1264 mgr->mem[i].virt = pci_ioremap_bar(pci, i);
1265 if (!mgr->mem[i].virt) {
1266 dev_err(&pci->dev, "unable to remap resource 0x%lx\n",
1267 mgr->mem[i].phys);
1269 return -EBUSY;
1273 if (request_threaded_irq(pci->irq, snd_mixart_interrupt,
1276 dev_err(&pci->dev, "unable to grab IRQ %d\n", pci->irq);
1278 return -EBUSY;
1280 mgr->irq = pci->irq;
1283 mgr->msg_fifo_readptr = 0;
1284 mgr->msg_fifo_writeptr = 0;
1286 mutex_init(&mgr->lock);
1287 mutex_init(&mgr->msg_lock);
1288 init_waitqueue_head(&mgr->msg_sleep);
1289 atomic_set(&mgr->msg_processed, 0);
1292 mutex_init(&mgr->setup_mutex);
1295 mgr->num_cards = MIXART_MAX_CARDS; /* 4 FIXME: configurable? */
1296 for (i = 0; i < mgr->num_cards; i++) {
1305 snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : "MIXART", i);
1306 err = snd_card_new(&pci->dev, idx, tmpid, THIS_MODULE,
1310 dev_err(&pci->dev, "cannot allocate the card %d\n", i);
1315 strscpy(card->driver, CARD_NAME);
1316 snprintf(card->shortname, sizeof(card->shortname),
1317 "Digigram miXart [PCM #%d]", i);
1318 snprintf(card->longname, sizeof(card->longname),
1319 "Digigram miXart at 0x%lx & 0x%lx, irq %i [PCM #%d]",
1320 mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq, i);
1330 /* init proc interface only for chip0 */
1331 snd_mixart_proc_init(mgr->chip[i]);
1341 /* init firmware status (mgr->dsp_loaded reset in hwdep_new) */
1342 mgr->board_type = MIXART_DAUGHTER_TYPE_NONE;
1347 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
1348 size, &mgr->flowinfo) < 0) {
1350 return -ENOMEM;
1353 memset(mgr->flowinfo.area, 0, size);
1358 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
1359 size, &mgr->bufferinfo) < 0) {
1361 return -ENOMEM;
1364 memset(mgr->bufferinfo.area, 0, size);