aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/asound.h1
-rw-r--r--include/sound/pcm.h1
-rw-r--r--sound/core/pcm_lib.c19
-rw-r--r--sound/core/pcm_native.c15
4 files changed, 33 insertions, 3 deletions
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 6add80fc2512..82aed3f47534 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -255,6 +255,7 @@ typedef int __bitwise snd_pcm_subformat_t;
255#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */ 255#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */
256#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */ 256#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */
257#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */ 257#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */
258#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */
258 259
259typedef int __bitwise snd_pcm_state_t; 260typedef int __bitwise snd_pcm_state_t;
260#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0) /* stream is open */ 261#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0) /* stream is open */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 267effddb070..8a69b5c1e1c4 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -98,6 +98,7 @@ struct snd_pcm_ops {
98#define SNDRV_PCM_IOCTL1_INFO 1 98#define SNDRV_PCM_IOCTL1_INFO 1
99#define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2 99#define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2
100#define SNDRV_PCM_IOCTL1_GSTATE 3 100#define SNDRV_PCM_IOCTL1_GSTATE 3
101#define SNDRV_PCM_IOCTL1_FIFO_SIZE 4
101 102
102#define SNDRV_PCM_TRIGGER_STOP 0 103#define SNDRV_PCM_TRIGGER_STOP 0
103#define SNDRV_PCM_TRIGGER_START 1 104#define SNDRV_PCM_TRIGGER_START 1
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index d659995ac3ac..adc2b0bd1132 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1524,6 +1524,23 @@ static int snd_pcm_lib_ioctl_channel_info(struct snd_pcm_substream *substream,
1524 return 0; 1524 return 0;
1525} 1525}
1526 1526
1527static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
1528 void *arg)
1529{
1530 struct snd_pcm_hw_params *params = arg;
1531 snd_pcm_format_t format;
1532 int channels, width;
1533
1534 params->fifo_size = substream->runtime->hw.fifo_size;
1535 if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_FIFO_IN_FRAMES)) {
1536 format = params_format(params);
1537 channels = params_channels(params);
1538 width = snd_pcm_format_physical_width(format);
1539 params->fifo_size /= width * channels;
1540 }
1541 return 0;
1542}
1543
1527/** 1544/**
1528 * snd_pcm_lib_ioctl - a generic PCM ioctl callback 1545 * snd_pcm_lib_ioctl - a generic PCM ioctl callback
1529 * @substream: the pcm substream instance 1546 * @substream: the pcm substream instance
@@ -1545,6 +1562,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
1545 return snd_pcm_lib_ioctl_reset(substream, arg); 1562 return snd_pcm_lib_ioctl_reset(substream, arg);
1546 case SNDRV_PCM_IOCTL1_CHANNEL_INFO: 1563 case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
1547 return snd_pcm_lib_ioctl_channel_info(substream, arg); 1564 return snd_pcm_lib_ioctl_channel_info(substream, arg);
1565 case SNDRV_PCM_IOCTL1_FIFO_SIZE:
1566 return snd_pcm_lib_ioctl_fifo_size(substream, arg);
1548 } 1567 }
1549 return -ENXIO; 1568 return -ENXIO;
1550} 1569}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 45dc53fcfa2f..84da3ba17c86 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -312,9 +312,18 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
312 312
313 hw = &substream->runtime->hw; 313 hw = &substream->runtime->hw;
314 if (!params->info) 314 if (!params->info)
315 params->info = hw->info; 315 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
316 if (!params->fifo_size) 316 if (!params->fifo_size) {
317 params->fifo_size = hw->fifo_size; 317 if (snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) ==
318 snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT]) &&
319 snd_mask_min(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS]) ==
320 snd_mask_max(&params->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) {
321 changed = substream->ops->ioctl(substream,
322 SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
323 if (params < 0)
324 return changed;
325 }
326 }
318 params->rmask = 0; 327 params->rmask = 0;
319 return 0; 328 return 0;
320} 329}