1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  ALSA PCM device for the
4  *  ALSA interface to ivtv PCM capture streams
5  *
6  *  Copyright (C) 2009,2012  Andy Walls <awalls@md.metrocast.net>
7  *  Copyright (C) 2009  Devin Heitmueller <dheitmueller@kernellabs.com>
8  *
9  *  Portions of this work were sponsored by ONELAN Limited for the cx18 driver
10  */
11 
12 #include "ivtv-driver.h"
13 #include "ivtv-queue.h"
14 #include "ivtv-streams.h"
15 #include "ivtv-fileops.h"
16 #include "ivtv-alsa.h"
17 #include "ivtv-alsa-pcm.h"
18 
19 #include <linux/vmalloc.h>
20 
21 #include <sound/core.h>
22 #include <sound/pcm.h>
23 
24 
25 static unsigned int pcm_debug;
26 module_param(pcm_debug, int, 0644);
27 MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
28 
29 #define dprintk(fmt, arg...) \
30 	do { \
31 		if (pcm_debug) \
32 			pr_info("ivtv-alsa-pcm %s: " fmt, __func__, ##arg); \
33 	} while (0)
34 
35 static const struct snd_pcm_hardware snd_ivtv_hw_capture = {
36 	.info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
37 		SNDRV_PCM_INFO_MMAP           |
38 		SNDRV_PCM_INFO_INTERLEAVED    |
39 		SNDRV_PCM_INFO_MMAP_VALID,
40 
41 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
42 
43 	.rates = SNDRV_PCM_RATE_48000,
44 
45 	.rate_min = 48000,
46 	.rate_max = 48000,
47 	.channels_min = 2,
48 	.channels_max = 2,
49 	.buffer_bytes_max = 62720 * 8,	/* just about the value in usbaudio.c */
50 	.period_bytes_min = 64,		/* 12544/2, */
51 	.period_bytes_max = 12544,
52 	.periods_min = 2,
53 	.periods_max = 98,		/* 12544, */
54 };
55 
56 static void ivtv_alsa_announce_pcm_data(struct snd_ivtv_card *itvsc,
57 					u8 *pcm_data,
58 					size_t num_bytes)
59 {
60 	struct snd_pcm_substream *substream;
61 	struct snd_pcm_runtime *runtime;
62 	unsigned int oldptr;
63 	unsigned int stride;
64 	int period_elapsed = 0;
65 	int length;
66 
67 	dprintk("ivtv alsa announce ptr=%p data=%p num_bytes=%zu\n", itvsc,
68 		pcm_data, num_bytes);
69 
70 	substream = itvsc->capture_pcm_substream;
71 	if (substream == NULL) {
72 		dprintk("substream was NULL\n");
73 		return;
74 	}
75 
76 	runtime = substream->runtime;
77 	if (runtime == NULL) {
78 		dprintk("runtime was NULL\n");
79 		return;
80 	}
81 
82 	stride = runtime->frame_bits >> 3;
83 	if (stride == 0) {
84 		dprintk("stride is zero\n");
85 		return;
86 	}
87 
88 	length = num_bytes / stride;
89 	if (length == 0) {
90 		dprintk("%s: length was zero\n", __func__);
91 		return;
92 	}
93 
94 	if (runtime->dma_area == NULL) {
95 		dprintk("dma area was NULL - ignoring\n");
96 		return;
97 	}
98 
99 	oldptr = itvsc->hwptr_done_capture;
100 	if (oldptr + length >= runtime->buffer_size) {
101 		unsigned int cnt =
102 			runtime->buffer_size - oldptr;
103 		memcpy(runtime->dma_area + oldptr * stride, pcm_data,
104 		       cnt * stride);
105 		memcpy(runtime->dma_area, pcm_data + cnt * stride,
106 		       length * stride - cnt * stride);
107 	} else {
108 		memcpy(runtime->dma_area + oldptr * stride, pcm_data,
109 		       length * stride);
110 	}
111 	snd_pcm_stream_lock(substream);
112 
113 	itvsc->hwptr_done_capture += length;
114 	if (itvsc->hwptr_done_capture >=
115 	    runtime->buffer_size)
116 		itvsc->hwptr_done_capture -=
117 			runtime->buffer_size;
118 
119 	itvsc->capture_transfer_done += length;
120 	if (itvsc->capture_transfer_done >=
121 	    runtime->period_size) {
122 		itvsc->capture_transfer_done -=
123 			runtime->period_size;
124 		period_elapsed = 1;
125 	}
126 
127 	snd_pcm_stream_unlock(substream);
128 
129 	if (period_elapsed)
130 		snd_pcm_period_elapsed(substream);
131 }
132 
133 static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream)
134 {
135 	struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
136 	struct snd_pcm_runtime *runtime = substream->runtime;
137 	struct v4l2_device *v4l2_dev = itvsc->v4l2_dev;
138 	struct ivtv *itv = to_ivtv(v4l2_dev);
139 	struct ivtv_stream *s;
140 	struct ivtv_open_id item;
141 	int ret;
142 
143 	/* Instruct the CX2341[56] to start sending packets */
144 	snd_ivtv_lock(itvsc);
145 
146 	if (ivtv_init_on_first_open(itv)) {
147 		snd_ivtv_unlock(itvsc);
148 		return -ENXIO;
149 	}
150 
151 	s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
152 
153 	v4l2_fh_init(&item.fh, &s->vdev);
154 	item.itv = itv;
155 	item.type = s->type;
156 
157 	/* See if the stream is available */
158 	if (ivtv_claim_stream(&item, item.type)) {
159 		/* No, it's already in use */
160 		v4l2_fh_exit(&item.fh);
161 		snd_ivtv_unlock(itvsc);
162 		return -EBUSY;
163 	}
164 
165 	if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) ||
166 	    test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
167 		/* We're already streaming.  No additional action required */
168 		snd_ivtv_unlock(itvsc);
169 		return 0;
170 	}
171 
172 
173 	runtime->hw = snd_ivtv_hw_capture;
174 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
175 	itvsc->capture_pcm_substream = substream;
176 	runtime->private_data = itv;
177 
178 	itv->pcm_announce_callback = ivtv_alsa_announce_pcm_data;
179 
180 	/* Not currently streaming, so start it up */
181 	set_bit(IVTV_F_S_STREAMING, &s->s_flags);
182 	ret = ivtv_start_v4l2_encode_stream(s);
183 	snd_ivtv_unlock(itvsc);
184 
185 	return ret;
186 }
187 
188 static int snd_ivtv_pcm_capture_close(struct snd_pcm_substream *substream)
189 {
190 	struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
191 	struct v4l2_device *v4l2_dev = itvsc->v4l2_dev;
192 	struct ivtv *itv = to_ivtv(v4l2_dev);
193 	struct ivtv_stream *s;
194 
195 	/* Instruct the ivtv to stop sending packets */
196 	snd_ivtv_lock(itvsc);
197 	s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
198 	ivtv_stop_v4l2_encode_stream(s, 0);
199 	clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
200 
201 	ivtv_release_stream(s);
202 
203 	itv->pcm_announce_callback = NULL;
204 	snd_ivtv_unlock(itvsc);
205 
206 	return 0;
207 }
208 
209 static int snd_ivtv_pcm_ioctl(struct snd_pcm_substream *substream,
210 		     unsigned int cmd, void *arg)
211 {
212 	struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
213 	int ret;
214 
215 	snd_ivtv_lock(itvsc);
216 	ret = snd_pcm_lib_ioctl(substream, cmd, arg);
217 	snd_ivtv_unlock(itvsc);
218 	return ret;
219 }
220 
221 
222 static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
223 					size_t size)
224 {
225 	struct snd_pcm_runtime *runtime = subs->runtime;
226 
227 	dprintk("Allocating vbuffer\n");
228 	if (runtime->dma_area) {
229 		if (runtime->dma_bytes > size)
230 			return 0;
231 
232 		vfree(runtime->dma_area);
233 	}
234 	runtime->dma_area = vmalloc(size);
235 	if (!runtime->dma_area)
236 		return -ENOMEM;
237 
238 	runtime->dma_bytes = size;
239 
240 	return 0;
241 }
242 
243 static int snd_ivtv_pcm_hw_params(struct snd_pcm_substream *substream,
244 			 struct snd_pcm_hw_params *params)
245 {
246 	dprintk("%s called\n", __func__);
247 
248 	return snd_pcm_alloc_vmalloc_buffer(substream,
249 					   params_buffer_bytes(params));
250 }
251 
252 static int snd_ivtv_pcm_hw_free(struct snd_pcm_substream *substream)
253 {
254 	struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
255 	unsigned long flags;
256 	unsigned char *dma_area = NULL;
257 
258 	spin_lock_irqsave(&itvsc->slock, flags);
259 	if (substream->runtime->dma_area) {
260 		dprintk("freeing pcm capture region\n");
261 		dma_area = substream->runtime->dma_area;
262 		substream->runtime->dma_area = NULL;
263 	}
264 	spin_unlock_irqrestore(&itvsc->slock, flags);
265 	vfree(dma_area);
266 
267 	return 0;
268 }
269 
270 static int snd_ivtv_pcm_prepare(struct snd_pcm_substream *substream)
271 {
272 	struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
273 
274 	itvsc->hwptr_done_capture = 0;
275 	itvsc->capture_transfer_done = 0;
276 
277 	return 0;
278 }
279 
280 static int snd_ivtv_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
281 {
282 	return 0;
283 }
284 
285 static
286 snd_pcm_uframes_t snd_ivtv_pcm_pointer(struct snd_pcm_substream *substream)
287 {
288 	unsigned long flags;
289 	snd_pcm_uframes_t hwptr_done;
290 	struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
291 
292 	spin_lock_irqsave(&itvsc->slock, flags);
293 	hwptr_done = itvsc->hwptr_done_capture;
294 	spin_unlock_irqrestore(&itvsc->slock, flags);
295 
296 	return hwptr_done;
297 }
298 
299 static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
300 					     unsigned long offset)
301 {
302 	void *pageptr = subs->runtime->dma_area + offset;
303 
304 	return vmalloc_to_page(pageptr);
305 }
306 
307 static const struct snd_pcm_ops snd_ivtv_pcm_capture_ops = {
308 	.open		= snd_ivtv_pcm_capture_open,
309 	.close		= snd_ivtv_pcm_capture_close,
310 	.ioctl		= snd_ivtv_pcm_ioctl,
311 	.hw_params	= snd_ivtv_pcm_hw_params,
312 	.hw_free	= snd_ivtv_pcm_hw_free,
313 	.prepare	= snd_ivtv_pcm_prepare,
314 	.trigger	= snd_ivtv_pcm_trigger,
315 	.pointer	= snd_ivtv_pcm_pointer,
316 	.page		= snd_pcm_get_vmalloc_page,
317 };
318 
319 int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc)
320 {
321 	struct snd_pcm *sp;
322 	struct snd_card *sc = itvsc->sc;
323 	struct v4l2_device *v4l2_dev = itvsc->v4l2_dev;
324 	struct ivtv *itv = to_ivtv(v4l2_dev);
325 	int ret;
326 
327 	ret = snd_pcm_new(sc, "CX2341[56] PCM",
328 			  0, /* PCM device 0, the only one for this card */
329 			  0, /* 0 playback substreams */
330 			  1, /* 1 capture substream */
331 			  &sp);
332 	if (ret) {
333 		IVTV_ALSA_ERR("%s: snd_ivtv_pcm_create() failed with err %d\n",
334 			      __func__, ret);
335 		goto err_exit;
336 	}
337 
338 	spin_lock_init(&itvsc->slock);
339 
340 	snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
341 			&snd_ivtv_pcm_capture_ops);
342 	sp->info_flags = 0;
343 	sp->private_data = itvsc;
344 	strscpy(sp->name, itv->card_name, sizeof(sp->name));
345 
346 	return 0;
347 
348 err_exit:
349 	return ret;
350 }
351