Lines Matching +full:audio +full:- +full:core
1 // SPDX-License-Identifier: GPL-2.0
2 // Support for audio capture for tm5600/6000/6010
3 // Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org>
5 // Based on cx88-alsa.c
15 #include <sound/core.h>
23 #include "tm6000-regs.h"
29 printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg); \
36 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
64 * BOARD Specific: Sets audio DMA
69 struct tm6000_core *core = chip->core; in _tm6000_start_audio_dma() local
71 dprintk(1, "Starting audio DMA\n"); in _tm6000_start_audio_dma()
73 /* Enables audio */ in _tm6000_start_audio_dma()
74 tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_IF, 0x40, 0x40); in _tm6000_start_audio_dma()
76 tm6000_set_audio_bitrate(core, 48000); in _tm6000_start_audio_dma()
82 * BOARD Specific: Resets audio DMA
86 struct tm6000_core *core = chip->core; in _tm6000_stop_audio_dma() local
88 dprintk(1, "Stopping audio DMA\n"); in _tm6000_stop_audio_dma()
90 /* Disables audio */ in _tm6000_stop_audio_dma()
91 tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_IF, 0x00, 0x40); in _tm6000_stop_audio_dma()
126 * audio pcm capture open callback
131 struct snd_pcm_runtime *runtime = substream->runtime; in snd_tm6000_pcm_open()
139 chip->substream = substream; in snd_tm6000_pcm_open()
141 runtime->hw = snd_tm6000_digital_hw; in snd_tm6000_pcm_open()
151 * audio close callback
156 struct tm6000_core *core = chip->core; in snd_tm6000_close() local
158 if (atomic_read(&core->stream_started) > 0) { in snd_tm6000_close()
159 atomic_set(&core->stream_started, 0); in snd_tm6000_close()
160 schedule_work(&core->wq_trigger); in snd_tm6000_close()
166 static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size) in tm6000_fillbuf() argument
168 struct snd_tm6000_card *chip = core->adev; in tm6000_fillbuf()
169 struct snd_pcm_substream *substream = chip->substream; in tm6000_fillbuf()
175 if (atomic_read(&core->stream_started) == 0) in tm6000_fillbuf()
180 return -EINVAL; in tm6000_fillbuf()
183 runtime = substream->runtime; in tm6000_fillbuf()
184 if (!runtime || !runtime->dma_area) { in tm6000_fillbuf()
186 return -EINVAL; in tm6000_fillbuf()
189 buf_pos = chip->buf_pos; in tm6000_fillbuf()
190 stride = runtime->frame_bits >> 3; in tm6000_fillbuf()
194 return -EINVAL; in tm6000_fillbuf()
200 return -EINVAL; in tm6000_fillbuf()
203 dprintk(1, "Copying %d bytes at %p[%d] - buf size=%d x %d\n", size, in tm6000_fillbuf()
204 runtime->dma_area, buf_pos, in tm6000_fillbuf()
205 (unsigned int)runtime->buffer_size, stride); in tm6000_fillbuf()
207 if (buf_pos + length >= runtime->buffer_size) { in tm6000_fillbuf()
208 unsigned int cnt = runtime->buffer_size - buf_pos; in tm6000_fillbuf()
209 memcpy(runtime->dma_area + buf_pos * stride, buf, cnt * stride); in tm6000_fillbuf()
210 memcpy(runtime->dma_area, buf + cnt * stride, in tm6000_fillbuf()
211 length * stride - cnt * stride); in tm6000_fillbuf()
213 memcpy(runtime->dma_area + buf_pos * stride, buf, in tm6000_fillbuf()
218 chip->buf_pos += length; in tm6000_fillbuf()
219 if (chip->buf_pos >= runtime->buffer_size) in tm6000_fillbuf()
220 chip->buf_pos -= runtime->buffer_size; in tm6000_fillbuf()
222 chip->period_pos += length; in tm6000_fillbuf()
223 if (chip->period_pos >= runtime->period_size) { in tm6000_fillbuf()
224 chip->period_pos -= runtime->period_size; in tm6000_fillbuf()
243 chip->buf_pos = 0; in snd_tm6000_prepare()
244 chip->period_pos = 0; in snd_tm6000_prepare()
255 struct tm6000_core *core = container_of(work, struct tm6000_core, in audio_trigger() local
257 struct snd_tm6000_card *chip = core->adev; in audio_trigger()
259 if (atomic_read(&core->stream_started)) { in audio_trigger()
271 struct tm6000_core *core = chip->core; in snd_tm6000_card_trigger() local
278 atomic_set(&core->stream_started, 1); in snd_tm6000_card_trigger()
283 atomic_set(&core->stream_started, 0); in snd_tm6000_card_trigger()
286 err = -EINVAL; in snd_tm6000_card_trigger()
289 schedule_work(&core->wq_trigger); in snd_tm6000_card_trigger()
300 return chip->buf_pos; in snd_tm6000_pointer()
318 /* FIXME: Control interface - How to control volume/mute? */
325 * Alsa Constructor - Component probe
340 return -ENODEV; in tm6000_audio_init()
343 return -ENOENT; in tm6000_audio_init()
345 rc = snd_card_new(&dev->udev->dev, index[devnr], "tm6000", in tm6000_audio_init()
351 strscpy(card->driver, "tm6000-alsa", sizeof(card->driver)); in tm6000_audio_init()
352 strscpy(card->shortname, "TM5600/60x0", sizeof(card->shortname)); in tm6000_audio_init()
353 sprintf(card->longname, "TM5600/60x0 Audio at bus %d device %d", in tm6000_audio_init()
354 dev->udev->bus->busnum, dev->udev->devnum); in tm6000_audio_init()
357 le16_to_cpu(dev->udev->descriptor.idVendor), in tm6000_audio_init()
358 le16_to_cpu(dev->udev->descriptor.idProduct)); in tm6000_audio_init()
363 rc = -ENOMEM; in tm6000_audio_init()
367 chip->core = dev; in tm6000_audio_init()
368 chip->card = card; in tm6000_audio_init()
369 dev->adev = chip; in tm6000_audio_init()
370 spin_lock_init(&chip->reg_lock); in tm6000_audio_init()
372 rc = snd_pcm_new(card, "TM6000 Audio", 0, 0, 1, &pcm); in tm6000_audio_init()
376 pcm->info_flags = 0; in tm6000_audio_init()
377 pcm->private_data = chip; in tm6000_audio_init()
378 strscpy(pcm->name, "Trident TM5600/60x0", sizeof(pcm->name)); in tm6000_audio_init()
383 INIT_WORK(&dev->wq_trigger, audio_trigger); in tm6000_audio_init()
388 dprintk(1, "Registered audio driver for %s\n", card->longname); in tm6000_audio_init()
394 dev->adev = NULL; in tm6000_audio_init()
406 chip = dev->adev; in tm6000_audio_fini()
411 if (!chip->card) in tm6000_audio_fini()
414 snd_card_free(chip->card); in tm6000_audio_fini()
415 chip->card = NULL; in tm6000_audio_fini()
417 dev->adev = NULL; in tm6000_audio_fini()
424 .name = "TM6000 Audio Extension",