aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/oss/pcm_oss.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-06 13:56:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-06 13:56:51 -0400
commit920f2ecdf6c3b3526f60fbd38c68597953cad3ee (patch)
tree18188922ba38a5c53ee8d17032eb5c46dffc7fa2 /sound/core/oss/pcm_oss.c
parent9ced560b82606b35adb33a27012a148d418a4c1f (diff)
parentfc18282cdcba984ab89c74d7e844c10114ae0795 (diff)
Merge tag 'sound-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This development cycle resulted in a fair amount of changes in both core and driver sides. The most significant change in ALSA core is about PCM. Also the support of of-graph card and the new DAPM widget for DSP are noteworthy changes in ASoC core. And there're lots of small changes splat over the tree, as you can see in diffstat. Below are a few highlights: ALSA core: - Removal of set_fs() hackery from PCM core stuff, and the code reorganization / optimization thereafter - Improved support of PCM ack ops, and a new ABI for improved control/status mmap handling - Lots of constifications in various codes ASoC core: - The support of of-graph card, which may work as a better generic device for a replacement of simple-card - New widget types intended mainly for use with DSPs ASoC drivers: - New drivers for Allwinner V3s SoCs - Ensonic ES8316 codec support - More Intel SKL and KBL works - More device support for Intel SST Atom (mostly for cheap tablets and 2-in-1 devices) - Support for Rockchip PDM controllers - Support for STM32 I2S and S/PDIF controllers - Support for ZTE AUD96P22 codecs HD-audio: - Support of new Realtek codecs (ALC215/ALC285/ALC289), more quirks for HP and Dell machines - A few more fixes for i915 component binding" * tag 'sound-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (418 commits) ALSA: hda - Fix unbalance of i915 module refcount ASoC: Intel: Skylake: Remove driver debugfs exit ASoC: Intel: Skylake: explicitly add the headers sst-dsp.h ALSA: hda/realtek - Remove GPIO_MASK ALSA: hda/realtek - Fix typo of pincfg for Dell quirk ALSA: pcm: add a documentation for tracepoints ALSA: atmel: ac97c: fix error return code in atmel_ac97c_probe() ALSA: x86: fix error return code in hdmi_lpe_audio_probe() ASoC: Intel: Skylake: Add support to read firmware registers ASoC: Intel: Skylake: Add sram address to sst_addr structure ASoC: Intel: Skylake: Debugfs facility to dump module config ASoC: Intel: Skylake: Add debugfs support ASoC: fix semicolon.cocci warnings ASoC: rt5645: Add quirk override by module option ASoC: rsnd: make arrays path and cmd_case static const ASoC: audio-graph-card: add widgets and routing for external amplifier support ASoC: audio-graph-card: update bindings for amplifier support ASoC: rt5665: calibration should be done before jack detection ASoC: rsnd: constify dev_pm_ops structures. ASoC: nau8825: change crosstalk-bypass property to bool type ...
Diffstat (limited to 'sound/core/oss/pcm_oss.c')
-rw-r--r--sound/core/oss/pcm_oss.c101
1 files changed, 24 insertions, 77 deletions
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index cd8b7bef8d06..e49f448ee04f 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -67,18 +67,6 @@ static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file);
67static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file); 67static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file);
68static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file); 68static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file);
69 69
70static inline mm_segment_t snd_enter_user(void)
71{
72 mm_segment_t fs = get_fs();
73 set_fs(get_ds());
74 return fs;
75}
76
77static inline void snd_leave_user(mm_segment_t fs)
78{
79 set_fs(fs);
80}
81
82/* 70/*
83 * helper functions to process hw_params 71 * helper functions to process hw_params
84 */ 72 */
@@ -799,7 +787,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
799static int choose_rate(struct snd_pcm_substream *substream, 787static int choose_rate(struct snd_pcm_substream *substream,
800 struct snd_pcm_hw_params *params, unsigned int best_rate) 788 struct snd_pcm_hw_params *params, unsigned int best_rate)
801{ 789{
802 struct snd_interval *it; 790 const struct snd_interval *it;
803 struct snd_pcm_hw_params *save; 791 struct snd_pcm_hw_params *save;
804 unsigned int rate, prev; 792 unsigned int rate, prev;
805 793
@@ -807,7 +795,7 @@ static int choose_rate(struct snd_pcm_substream *substream,
807 if (save == NULL) 795 if (save == NULL)
808 return -ENOMEM; 796 return -ENOMEM;
809 *save = *params; 797 *save = *params;
810 it = hw_param_interval(save, SNDRV_PCM_HW_PARAM_RATE); 798 it = hw_param_interval_c(save, SNDRV_PCM_HW_PARAM_RATE);
811 799
812 /* try multiples of the best rate */ 800 /* try multiples of the best rate */
813 rate = best_rate; 801 rate = best_rate;
@@ -848,7 +836,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
848 int direct; 836 int direct;
849 snd_pcm_format_t format, sformat; 837 snd_pcm_format_t format, sformat;
850 int n; 838 int n;
851 struct snd_mask sformat_mask; 839 const struct snd_mask *sformat_mask;
852 struct snd_mask mask; 840 struct snd_mask mask;
853 841
854 if (trylock) { 842 if (trylock) {
@@ -891,18 +879,18 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
891 879
892 format = snd_pcm_oss_format_from(runtime->oss.format); 880 format = snd_pcm_oss_format_from(runtime->oss.format);
893 881
894 sformat_mask = *hw_param_mask(sparams, SNDRV_PCM_HW_PARAM_FORMAT); 882 sformat_mask = hw_param_mask_c(sparams, SNDRV_PCM_HW_PARAM_FORMAT);
895 if (direct) 883 if (direct)
896 sformat = format; 884 sformat = format;
897 else 885 else
898 sformat = snd_pcm_plug_slave_format(format, &sformat_mask); 886 sformat = snd_pcm_plug_slave_format(format, sformat_mask);
899 887
900 if ((__force int)sformat < 0 || 888 if ((__force int)sformat < 0 ||
901 !snd_mask_test(&sformat_mask, (__force int)sformat)) { 889 !snd_mask_test(sformat_mask, (__force int)sformat)) {
902 for (sformat = (__force snd_pcm_format_t)0; 890 for (sformat = (__force snd_pcm_format_t)0;
903 (__force int)sformat <= (__force int)SNDRV_PCM_FORMAT_LAST; 891 (__force int)sformat <= (__force int)SNDRV_PCM_FORMAT_LAST;
904 sformat = (__force snd_pcm_format_t)((__force int)sformat + 1)) { 892 sformat = (__force snd_pcm_format_t)((__force int)sformat + 1)) {
905 if (snd_mask_test(&sformat_mask, (__force int)sformat) && 893 if (snd_mask_test(sformat_mask, (__force int)sformat) &&
906 snd_pcm_oss_format_to(sformat) >= 0) 894 snd_pcm_oss_format_to(sformat) >= 0)
907 break; 895 break;
908 } 896 }
@@ -1191,14 +1179,8 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const
1191 if (ret < 0) 1179 if (ret < 0)
1192 break; 1180 break;
1193 } 1181 }
1194 if (in_kernel) { 1182 ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true,
1195 mm_segment_t fs; 1183 frames, in_kernel);
1196 fs = snd_enter_user();
1197 ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames);
1198 snd_leave_user(fs);
1199 } else {
1200 ret = snd_pcm_lib_write(substream, (void __force __user *)ptr, frames);
1201 }
1202 if (ret != -EPIPE && ret != -ESTRPIPE) 1184 if (ret != -EPIPE && ret != -ESTRPIPE)
1203 break; 1185 break;
1204 /* test, if we can't store new data, because the stream */ 1186 /* test, if we can't store new data, because the stream */
@@ -1234,14 +1216,8 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
1234 ret = snd_pcm_oss_capture_position_fixup(substream, &delay); 1216 ret = snd_pcm_oss_capture_position_fixup(substream, &delay);
1235 if (ret < 0) 1217 if (ret < 0)
1236 break; 1218 break;
1237 if (in_kernel) { 1219 ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true,
1238 mm_segment_t fs; 1220 frames, in_kernel);
1239 fs = snd_enter_user();
1240 ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames);
1241 snd_leave_user(fs);
1242 } else {
1243 ret = snd_pcm_lib_read(substream, (void __force __user *)ptr, frames);
1244 }
1245 if (ret == -EPIPE) { 1221 if (ret == -EPIPE) {
1246 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { 1222 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
1247 ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); 1223 ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
@@ -1256,7 +1232,8 @@ snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *p
1256 return ret; 1232 return ret;
1257} 1233}
1258 1234
1259snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel) 1235#ifdef CONFIG_SND_PCM_OSS_PLUGINS
1236snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames)
1260{ 1237{
1261 struct snd_pcm_runtime *runtime = substream->runtime; 1238 struct snd_pcm_runtime *runtime = substream->runtime;
1262 int ret; 1239 int ret;
@@ -1273,14 +1250,7 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void
1273 if (ret < 0) 1250 if (ret < 0)
1274 break; 1251 break;
1275 } 1252 }
1276 if (in_kernel) { 1253 ret = snd_pcm_kernel_writev(substream, bufs, frames);
1277 mm_segment_t fs;
1278 fs = snd_enter_user();
1279 ret = snd_pcm_lib_writev(substream, (void __user **)bufs, frames);
1280 snd_leave_user(fs);
1281 } else {
1282 ret = snd_pcm_lib_writev(substream, (void __user **)bufs, frames);
1283 }
1284 if (ret != -EPIPE && ret != -ESTRPIPE) 1254 if (ret != -EPIPE && ret != -ESTRPIPE)
1285 break; 1255 break;
1286 1256
@@ -1292,7 +1262,7 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void
1292 return ret; 1262 return ret;
1293} 1263}
1294 1264
1295snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel) 1265snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames)
1296{ 1266{
1297 struct snd_pcm_runtime *runtime = substream->runtime; 1267 struct snd_pcm_runtime *runtime = substream->runtime;
1298 int ret; 1268 int ret;
@@ -1313,19 +1283,13 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void *
1313 if (ret < 0) 1283 if (ret < 0)
1314 break; 1284 break;
1315 } 1285 }
1316 if (in_kernel) { 1286 ret = snd_pcm_kernel_readv(substream, bufs, frames);
1317 mm_segment_t fs;
1318 fs = snd_enter_user();
1319 ret = snd_pcm_lib_readv(substream, (void __user **)bufs, frames);
1320 snd_leave_user(fs);
1321 } else {
1322 ret = snd_pcm_lib_readv(substream, (void __user **)bufs, frames);
1323 }
1324 if (ret != -EPIPE && ret != -ESTRPIPE) 1287 if (ret != -EPIPE && ret != -ESTRPIPE)
1325 break; 1288 break;
1326 } 1289 }
1327 return ret; 1290 return ret;
1328} 1291}
1292#endif /* CONFIG_SND_PCM_OSS_PLUGINS */
1329 1293
1330static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel) 1294static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel)
1331{ 1295{
@@ -1650,27 +1614,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1650 size = runtime->control->appl_ptr % runtime->period_size; 1614 size = runtime->control->appl_ptr % runtime->period_size;
1651 if (size > 0) { 1615 if (size > 0) {
1652 size = runtime->period_size - size; 1616 size = runtime->period_size - size;
1653 if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) { 1617 if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED)
1654 size = (runtime->frame_bits * size) / 8; 1618 snd_pcm_lib_write(substream, NULL, size);
1655 while (size > 0) { 1619 else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
1656 mm_segment_t fs; 1620 snd_pcm_lib_writev(substream, NULL, size);
1657 size_t size1 = size < runtime->oss.period_bytes ? size : runtime->oss.period_bytes;
1658 size -= size1;
1659 size1 *= 8;
1660 size1 /= runtime->sample_bits;
1661 snd_pcm_format_set_silence(runtime->format,
1662 runtime->oss.buffer,
1663 size1);
1664 size1 /= runtime->channels; /* frames */
1665 fs = snd_enter_user();
1666 snd_pcm_lib_write(substream, (void __force __user *)runtime->oss.buffer, size1);
1667 snd_leave_user(fs);
1668 }
1669 } else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
1670 void __user *buffers[runtime->channels];
1671 memset(buffers, 0, runtime->channels * sizeof(void *));
1672 snd_pcm_lib_writev(substream, buffers, size);
1673 }
1674 } 1621 }
1675 mutex_unlock(&runtime->oss.params_lock); 1622 mutex_unlock(&runtime->oss.params_lock);
1676 /* 1623 /*
@@ -1780,7 +1727,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1780 int direct; 1727 int direct;
1781 struct snd_pcm_hw_params *params; 1728 struct snd_pcm_hw_params *params;
1782 unsigned int formats = 0; 1729 unsigned int formats = 0;
1783 struct snd_mask format_mask; 1730 const struct snd_mask *format_mask;
1784 int fmt; 1731 int fmt;
1785 1732
1786 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) 1733 if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
@@ -1802,12 +1749,12 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1802 return -ENOMEM; 1749 return -ENOMEM;
1803 _snd_pcm_hw_params_any(params); 1750 _snd_pcm_hw_params_any(params);
1804 err = snd_pcm_hw_refine(substream, params); 1751 err = snd_pcm_hw_refine(substream, params);
1805 format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 1752 format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
1806 kfree(params); 1753 kfree(params);
1807 if (err < 0) 1754 if (err < 0)
1808 return err; 1755 return err;
1809 for (fmt = 0; fmt < 32; ++fmt) { 1756 for (fmt = 0; fmt < 32; ++fmt) {
1810 if (snd_mask_test(&format_mask, fmt)) { 1757 if (snd_mask_test(format_mask, fmt)) {
1811 int f = snd_pcm_oss_format_to(fmt); 1758 int f = snd_pcm_oss_format_to(fmt);
1812 if (f >= 0) 1759 if (f >= 0)
1813 formats |= f; 1760 formats |= f;