hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/core/pcm_lib.c
....@@ -1,23 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Digital Audio (PCM) abstract layer
34 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
45 * Abramo Bagnara <abramo@alsa-project.org>
5
- *
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
- *
216 */
227
238 #include <linux/slab.h>
....@@ -45,9 +30,6 @@
4530 #define trace_applptr(substream, prev, curr)
4631 #define trace_applptr_start(substream, frame)
4732 #endif
48
-
49
-#define STRING_LENGTH_OF_INT 12
50
-#define MAX_USR_CTRL_CNT 128
5133
5234 static int fill_silence_frames(struct snd_pcm_substream *substream,
5335 snd_pcm_uframes_t off, snd_pcm_uframes_t frames);
....@@ -163,8 +145,13 @@
163145 struct snd_pcm_runtime *runtime = substream->runtime;
164146
165147 trace_xrun(substream);
166
- if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
167
- snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
148
+ if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
149
+ struct timespec64 tstamp;
150
+
151
+ snd_pcm_gettime(runtime, &tstamp);
152
+ runtime->status->tstamp.tv_sec = tstamp.tv_sec;
153
+ runtime->status->tstamp.tv_nsec = tstamp.tv_nsec;
154
+ }
168155 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
169156 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {
170157 char name[16];
....@@ -219,12 +206,12 @@
219206 }
220207
221208 static void update_audio_tstamp(struct snd_pcm_substream *substream,
222
- struct timespec *curr_tstamp,
223
- struct timespec *audio_tstamp)
209
+ struct timespec64 *curr_tstamp,
210
+ struct timespec64 *audio_tstamp)
224211 {
225212 struct snd_pcm_runtime *runtime = substream->runtime;
226213 u64 audio_frames, audio_nsecs;
227
- struct timespec driver_tstamp;
214
+ struct timespec64 driver_tstamp;
228215
229216 if (runtime->tstamp_mode != SNDRV_PCM_TSTAMP_ENABLE)
230217 return;
....@@ -248,18 +235,23 @@
248235 }
249236 audio_nsecs = div_u64(audio_frames * 1000000000LL,
250237 runtime->rate);
251
- *audio_tstamp = ns_to_timespec(audio_nsecs);
238
+ *audio_tstamp = ns_to_timespec64(audio_nsecs);
252239 }
253
- if (!timespec_equal(&runtime->status->audio_tstamp, audio_tstamp)) {
254
- runtime->status->audio_tstamp = *audio_tstamp;
255
- runtime->status->tstamp = *curr_tstamp;
240
+
241
+ if (runtime->status->audio_tstamp.tv_sec != audio_tstamp->tv_sec ||
242
+ runtime->status->audio_tstamp.tv_nsec != audio_tstamp->tv_nsec) {
243
+ runtime->status->audio_tstamp.tv_sec = audio_tstamp->tv_sec;
244
+ runtime->status->audio_tstamp.tv_nsec = audio_tstamp->tv_nsec;
245
+ runtime->status->tstamp.tv_sec = curr_tstamp->tv_sec;
246
+ runtime->status->tstamp.tv_nsec = curr_tstamp->tv_nsec;
256247 }
248
+
257249
258250 /*
259251 * re-take a driver timestamp to let apps detect if the reference tstamp
260252 * read by low-level hardware was provided with a delay
261253 */
262
- snd_pcm_gettime(substream->runtime, (struct timespec *)&driver_tstamp);
254
+ snd_pcm_gettime(substream->runtime, &driver_tstamp);
263255 runtime->driver_tstamp = driver_tstamp;
264256 }
265257
....@@ -272,8 +264,8 @@
272264 snd_pcm_sframes_t hdelta, delta;
273265 unsigned long jdelta;
274266 unsigned long curr_jiffies;
275
- struct timespec curr_tstamp;
276
- struct timespec audio_tstamp;
267
+ struct timespec64 curr_tstamp;
268
+ struct timespec64 audio_tstamp;
277269 int crossed_boundary = 0;
278270
279271 old_hw_ptr = runtime->status->hw_ptr;
....@@ -296,9 +288,9 @@
296288
297289 /* re-test in case tstamp type is not supported in hardware and was demoted to DEFAULT */
298290 if (runtime->audio_tstamp_report.actual_type == SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT)
299
- snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp);
291
+ snd_pcm_gettime(runtime, &curr_tstamp);
300292 } else
301
- snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp);
293
+ snd_pcm_gettime(runtime, &curr_tstamp);
302294 }
303295
304296 if (pos == SNDRV_PCM_POS_XRUN) {
....@@ -499,7 +491,7 @@
499491 EXPORT_SYMBOL(snd_pcm_set_ops);
500492
501493 /**
502
- * snd_pcm_sync - set the PCM sync id
494
+ * snd_pcm_set_sync - set the PCM sync id
503495 * @substream: the pcm substream
504496 *
505497 * Sets the PCM sync identifier for the card.
....@@ -1462,7 +1454,7 @@
14621454
14631455 static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
14641456 {
1465
- static unsigned int pow2_sizes[] = {
1457
+ static const unsigned int pow2_sizes[] = {
14661458 1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7,
14671459 1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15,
14681460 1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23,
....@@ -2183,6 +2175,14 @@
21832175 if (err < 0)
21842176 goto _end_unlock;
21852177
2178
+ runtime->twake = runtime->control->avail_min ? : 1;
2179
+ if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
2180
+ snd_pcm_update_hw_ptr(substream);
2181
+
2182
+ /*
2183
+ * If size < start_threshold, wait indefinitely. Another
2184
+ * thread may start capture
2185
+ */
21862186 if (!is_playback &&
21872187 runtime->status->state == SNDRV_PCM_STATE_PREPARED &&
21882188 size >= runtime->start_threshold) {
....@@ -2191,10 +2191,8 @@
21912191 goto _end_unlock;
21922192 }
21932193
2194
- runtime->twake = runtime->control->avail_min ? : 1;
2195
- if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
2196
- snd_pcm_update_hw_ptr(substream);
21972194 avail = snd_pcm_avail(substream);
2195
+
21982196 while (size > 0) {
21992197 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
22002198 snd_pcm_uframes_t cont;
....@@ -2223,14 +2221,18 @@
22232221 if (frames > cont)
22242222 frames = cont;
22252223 if (snd_BUG_ON(!frames)) {
2226
- runtime->twake = 0;
2227
- snd_pcm_stream_unlock_irq(substream);
2228
- return -EINVAL;
2224
+ err = -EINVAL;
2225
+ goto _end_unlock;
2226
+ }
2227
+ if (!atomic_inc_unless_negative(&runtime->buffer_accessing)) {
2228
+ err = -EBUSY;
2229
+ goto _end_unlock;
22292230 }
22302231 snd_pcm_stream_unlock_irq(substream);
22312232 err = writer(substream, appl_ofs, data, offset, frames,
22322233 transfer);
22332234 snd_pcm_stream_lock_irq(substream);
2235
+ atomic_dec(&runtime->buffer_accessing);
22342236 if (err < 0)
22352237 goto _end_unlock;
22362238 err = pcm_accessible_state(runtime);
....@@ -2325,7 +2327,6 @@
23252327 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
23262328
23272329 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2328
- uinfo->count = 0;
23292330 uinfo->count = info->max_channels;
23302331 uinfo->value.integer.min = 0;
23312332 uinfo->value.integer.max = SNDRV_CHMAP_LAST;
....@@ -2349,7 +2350,7 @@
23492350 if (!substream)
23502351 return -ENODEV;
23512352 memset(ucontrol->value.integer.value, 0,
2352
- sizeof(ucontrol->value.integer.value));
2353
+ sizeof(long) * info->max_channels);
23532354 if (!substream->runtime)
23542355 return 0; /* no channels set */
23552356 for (map = info->chmap; map->channels; map++) {
....@@ -2417,24 +2418,6 @@
24172418 kfree(info);
24182419 }
24192420
2420
-static int pcm_volume_ctl_info(struct snd_kcontrol *kcontrol,
2421
- struct snd_ctl_elem_info *uinfo)
2422
-{
2423
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2424
- uinfo->count = 1;
2425
- uinfo->value.integer.min = 0;
2426
- uinfo->value.integer.max = 0x2000;
2427
- return 0;
2428
-}
2429
-
2430
-static void pcm_volume_ctl_private_free(struct snd_kcontrol *kcontrol)
2431
-{
2432
- struct snd_pcm_volume *info = snd_kcontrol_chip(kcontrol);
2433
-
2434
- info->pcm->streams[info->stream].vol_kctl = NULL;
2435
- kfree(info);
2436
-}
2437
-
24382421 /**
24392422 * snd_pcm_add_chmap_ctls - create channel-mapping control elements
24402423 * @pcm: the assigned PCM instance
....@@ -2496,166 +2479,3 @@
24962479 return 0;
24972480 }
24982481 EXPORT_SYMBOL_GPL(snd_pcm_add_chmap_ctls);
2499
-
2500
-/**
2501
- * snd_pcm_add_volume_ctls - create volume control elements
2502
- * @pcm: the assigned PCM instance
2503
- * @stream: stream direction
2504
- * @max_length: the max length of the volume parameter of stream
2505
- * @private_value: the value passed to each kcontrol's private_value field
2506
- * @info_ret: store struct snd_pcm_volume instance if non-NULL
2507
- *
2508
- * Create volume control elements assigned to the given PCM stream(s).
2509
- * Returns zero if succeed, or a negative error value.
2510
- */
2511
-int snd_pcm_add_volume_ctls(struct snd_pcm *pcm, int stream,
2512
- const struct snd_pcm_volume_elem *volume,
2513
- int max_length,
2514
- unsigned long private_value,
2515
- struct snd_pcm_volume **info_ret)
2516
-{
2517
- struct snd_pcm_volume *info;
2518
- struct snd_kcontrol_new knew = {
2519
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2520
- .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2521
- SNDRV_CTL_ELEM_ACCESS_READWRITE,
2522
- .info = pcm_volume_ctl_info,
2523
- };
2524
- int err;
2525
- int size;
2526
-
2527
- info = kzalloc(sizeof(*info), GFP_KERNEL);
2528
- if (!info)
2529
- return -ENOMEM;
2530
- info->pcm = pcm;
2531
- info->stream = stream;
2532
- info->volume = volume;
2533
- info->max_length = max_length;
2534
- size = sizeof("Playback ") + sizeof(" Volume") +
2535
- STRING_LENGTH_OF_INT*sizeof(char) + 1;
2536
- knew.name = kzalloc(size, GFP_KERNEL);
2537
- if (!knew.name) {
2538
- kfree(info);
2539
- return -ENOMEM;
2540
- }
2541
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
2542
- snprintf((char *)knew.name, size, "%s %d %s",
2543
- "Playback", pcm->device, "Volume");
2544
- else
2545
- snprintf((char *)knew.name, size, "%s %d %s",
2546
- "Capture", pcm->device, "Volume");
2547
- knew.device = pcm->device;
2548
- knew.count = pcm->streams[stream].substream_count;
2549
- knew.private_value = private_value;
2550
- info->kctl = snd_ctl_new1(&knew, info);
2551
- if (!info->kctl) {
2552
- kfree(info);
2553
- kfree(knew.name);
2554
- return -ENOMEM;
2555
- }
2556
- info->kctl->private_free = pcm_volume_ctl_private_free;
2557
- err = snd_ctl_add(pcm->card, info->kctl);
2558
- if (err < 0) {
2559
- kfree(info);
2560
- kfree(knew.name);
2561
- return -ENOMEM;
2562
- }
2563
- pcm->streams[stream].vol_kctl = info->kctl;
2564
- if (info_ret)
2565
- *info_ret = info;
2566
- kfree(knew.name);
2567
- return 0;
2568
-}
2569
-EXPORT_SYMBOL(snd_pcm_add_volume_ctls);
2570
-
2571
-static int pcm_usr_ctl_info(struct snd_kcontrol *kcontrol,
2572
- struct snd_ctl_elem_info *uinfo)
2573
-{
2574
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2575
- uinfo->count = MAX_USR_CTRL_CNT;
2576
- uinfo->value.integer.min = 0;
2577
- uinfo->value.integer.max = INT_MAX;
2578
- return 0;
2579
-}
2580
-
2581
-static void pcm_usr_ctl_private_free(struct snd_kcontrol *kcontrol)
2582
-{
2583
- struct snd_pcm_usr *info = snd_kcontrol_chip(kcontrol);
2584
-
2585
- info->pcm->streams[info->stream].usr_kctl = NULL;
2586
- kfree(info);
2587
-}
2588
-
2589
-/**
2590
- * snd_pcm_add_usr_ctls - create user control elements
2591
- * @pcm: the assigned PCM instance
2592
- * @stream: stream direction
2593
- * @max_length: the max length of the user parameter of stream
2594
- * @private_value: the value passed to each kcontrol's private_value field
2595
- * @info_ret: store struct snd_pcm_usr instance if non-NULL
2596
- *
2597
- * Create usr control elements assigned to the given PCM stream(s).
2598
- * Returns zero if succeed, or a negative error value.
2599
- */
2600
-int snd_pcm_add_usr_ctls(struct snd_pcm *pcm, int stream,
2601
- const struct snd_pcm_usr_elem *usr,
2602
- int max_length, int max_kctrl_str_len,
2603
- unsigned long private_value,
2604
- struct snd_pcm_usr **info_ret)
2605
-{
2606
- struct snd_pcm_usr *info;
2607
- struct snd_kcontrol_new knew = {
2608
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2609
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
2610
- .info = pcm_usr_ctl_info,
2611
- };
2612
- int err;
2613
- char *buf;
2614
-
2615
- info = kzalloc(sizeof(*info), GFP_KERNEL);
2616
- if (!info)
2617
- return -ENOMEM;
2618
-
2619
- info->pcm = pcm;
2620
- info->stream = stream;
2621
- info->usr = usr;
2622
- info->max_length = max_length;
2623
- buf = kzalloc(max_kctrl_str_len, GFP_KERNEL);
2624
- if (!buf) {
2625
- pr_err("%s: buffer allocation failed\n", __func__);
2626
- kfree(info);
2627
- return -ENOMEM;
2628
- }
2629
- knew.name = buf;
2630
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
2631
- snprintf(buf, max_kctrl_str_len, "%s %d %s",
2632
- "Playback", pcm->device, "User kcontrol");
2633
- else
2634
- snprintf(buf, max_kctrl_str_len, "%s %d %s",
2635
- "Capture", pcm->device, "User kcontrol");
2636
- knew.device = pcm->device;
2637
- knew.count = pcm->streams[stream].substream_count;
2638
- knew.private_value = private_value;
2639
- info->kctl = snd_ctl_new1(&knew, info);
2640
- if (!info->kctl) {
2641
- kfree(info);
2642
- kfree(knew.name);
2643
- pr_err("%s: snd_ctl_new failed\n", __func__);
2644
- return -ENOMEM;
2645
- }
2646
- info->kctl->private_free = pcm_usr_ctl_private_free;
2647
- err = snd_ctl_add(pcm->card, info->kctl);
2648
- if (err < 0) {
2649
- kfree(info);
2650
- kfree(knew.name);
2651
- pr_err("%s: snd_ctl_add failed:%d\n", __func__,
2652
- err);
2653
- return -ENOMEM;
2654
- }
2655
- pcm->streams[stream].usr_kctl = info->kctl;
2656
- if (info_ret)
2657
- *info_ret = info;
2658
- kfree(knew.name);
2659
- return 0;
2660
-}
2661
-EXPORT_SYMBOL(snd_pcm_add_usr_ctls);