diff options
186 files changed, 3016 insertions, 4288 deletions
diff --git a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst index 95c5443eff38..58ffa3f5bda7 100644 --- a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst +++ b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst | |||
@@ -2080,8 +2080,8 @@ sleeping poll threads, etc. | |||
2080 | 2080 | ||
2081 | This callback is also atomic as default. | 2081 | This callback is also atomic as default. |
2082 | 2082 | ||
2083 | copy and silence callbacks | 2083 | copy_user, copy_kernel and fill_silence ops |
2084 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | 2084 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2085 | 2085 | ||
2086 | These callbacks are not mandatory, and can be omitted in most cases. | 2086 | These callbacks are not mandatory, and can be omitted in most cases. |
2087 | These callbacks are used when the hardware buffer cannot be in the | 2087 | These callbacks are used when the hardware buffer cannot be in the |
@@ -3532,8 +3532,9 @@ external hardware buffer in interrupts (or in tasklets, preferably). | |||
3532 | 3532 | ||
3533 | The first case works fine if the external hardware buffer is large | 3533 | The first case works fine if the external hardware buffer is large |
3534 | enough. This method doesn't need any extra buffers and thus is more | 3534 | enough. This method doesn't need any extra buffers and thus is more |
3535 | effective. You need to define the ``copy`` and ``silence`` callbacks | 3535 | effective. You need to define the ``copy_user`` and ``copy_kernel`` |
3536 | for the data transfer. However, there is a drawback: it cannot be | 3536 | callbacks for the data transfer, in addition to ``fill_silence`` |
3537 | callback for playback. However, there is a drawback: it cannot be | ||
3537 | mmapped. The examples are GUS's GF1 PCM or emu8000's wavetable PCM. | 3538 | mmapped. The examples are GUS's GF1 PCM or emu8000's wavetable PCM. |
3538 | 3539 | ||
3539 | The second case allows for mmap on the buffer, although you have to | 3540 | The second case allows for mmap on the buffer, although you have to |
@@ -3545,30 +3546,34 @@ Another case is when the chip uses a PCI memory-map region for the | |||
3545 | buffer instead of the host memory. In this case, mmap is available only | 3546 | buffer instead of the host memory. In this case, mmap is available only |
3546 | on certain architectures like the Intel one. In non-mmap mode, the data | 3547 | on certain architectures like the Intel one. In non-mmap mode, the data |
3547 | cannot be transferred as in the normal way. Thus you need to define the | 3548 | cannot be transferred as in the normal way. Thus you need to define the |
3548 | ``copy`` and ``silence`` callbacks as well, as in the cases above. The | 3549 | ``copy_user``, ``copy_kernel`` and ``fill_silence`` callbacks as well, |
3549 | examples are found in ``rme32.c`` and ``rme96.c``. | 3550 | as in the cases above. The examples are found in ``rme32.c`` and |
3551 | ``rme96.c``. | ||
3550 | 3552 | ||
3551 | The implementation of the ``copy`` and ``silence`` callbacks depends | 3553 | The implementation of the ``copy_user``, ``copy_kernel`` and |
3552 | upon whether the hardware supports interleaved or non-interleaved | 3554 | ``silence`` callbacks depends upon whether the hardware supports |
3553 | samples. The ``copy`` callback is defined like below, a bit | 3555 | interleaved or non-interleaved samples. The ``copy_user`` callback is |
3554 | differently depending whether the direction is playback or capture: | 3556 | defined like below, a bit differently depending whether the direction |
3557 | is playback or capture: | ||
3555 | 3558 | ||
3556 | :: | 3559 | :: |
3557 | 3560 | ||
3558 | static int playback_copy(struct snd_pcm_substream *substream, int channel, | 3561 | static int playback_copy_user(struct snd_pcm_substream *substream, |
3559 | snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count); | 3562 | int channel, unsigned long pos, |
3560 | static int capture_copy(struct snd_pcm_substream *substream, int channel, | 3563 | void __user *src, unsigned long count); |
3561 | snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count); | 3564 | static int capture_copy_user(struct snd_pcm_substream *substream, |
3565 | int channel, unsigned long pos, | ||
3566 | void __user *dst, unsigned long count); | ||
3562 | 3567 | ||
3563 | In the case of interleaved samples, the second argument (``channel``) is | 3568 | In the case of interleaved samples, the second argument (``channel``) is |
3564 | not used. The third argument (``pos``) points the current position | 3569 | not used. The third argument (``pos``) points the current position |
3565 | offset in frames. | 3570 | offset in bytes. |
3566 | 3571 | ||
3567 | The meaning of the fourth argument is different between playback and | 3572 | The meaning of the fourth argument is different between playback and |
3568 | capture. For playback, it holds the source data pointer, and for | 3573 | capture. For playback, it holds the source data pointer, and for |
3569 | capture, it's the destination data pointer. | 3574 | capture, it's the destination data pointer. |
3570 | 3575 | ||
3571 | The last argument is the number of frames to be copied. | 3576 | The last argument is the number of bytes to be copied. |
3572 | 3577 | ||
3573 | What you have to do in this callback is again different between playback | 3578 | What you have to do in this callback is again different between playback |
3574 | and capture directions. In the playback case, you copy the given amount | 3579 | and capture directions. In the playback case, you copy the given amount |
@@ -3578,8 +3583,7 @@ way, the copy would be like: | |||
3578 | 3583 | ||
3579 | :: | 3584 | :: |
3580 | 3585 | ||
3581 | my_memcpy(my_buffer + frames_to_bytes(runtime, pos), src, | 3586 | my_memcpy_from_user(my_buffer + pos, src, count); |
3582 | frames_to_bytes(runtime, count)); | ||
3583 | 3587 | ||
3584 | For the capture direction, you copy the given amount of data (``count``) | 3588 | For the capture direction, you copy the given amount of data (``count``) |
3585 | at the specified offset (``pos``) on the hardware buffer to the | 3589 | at the specified offset (``pos``) on the hardware buffer to the |
@@ -3587,31 +3591,68 @@ specified pointer (``dst``). | |||
3587 | 3591 | ||
3588 | :: | 3592 | :: |
3589 | 3593 | ||
3590 | my_memcpy(dst, my_buffer + frames_to_bytes(runtime, pos), | 3594 | my_memcpy_to_user(dst, my_buffer + pos, count); |
3591 | frames_to_bytes(runtime, count)); | 3595 | |
3596 | Here the functions are named as ``from_user`` and ``to_user`` because | ||
3597 | it's the user-space buffer that is passed to these callbacks. That | ||
3598 | is, the callback is supposed to copy from/to the user-space data | ||
3599 | directly to/from the hardware buffer. | ||
3592 | 3600 | ||
3593 | Note that both the position and the amount of data are given in frames. | 3601 | Careful readers might notice that these callbacks receive the |
3602 | arguments in bytes, not in frames like other callbacks. It's because | ||
3603 | it would make coding easier like the examples above, and also it makes | ||
3604 | easier to unify both the interleaved and non-interleaved cases, as | ||
3605 | explained in the following. | ||
3594 | 3606 | ||
3595 | In the case of non-interleaved samples, the implementation will be a bit | 3607 | In the case of non-interleaved samples, the implementation will be a bit |
3596 | more complicated. | 3608 | more complicated. The callback is called for each channel, passed by |
3609 | the second argument, so totally it's called for N-channels times per | ||
3610 | transfer. | ||
3611 | |||
3612 | The meaning of other arguments are almost same as the interleaved | ||
3613 | case. The callback is supposed to copy the data from/to the given | ||
3614 | user-space buffer, but only for the given channel. For the detailed | ||
3615 | implementations, please check ``isa/gus/gus_pcm.c`` or | ||
3616 | "pci/rme9652/rme9652.c" as examples. | ||
3617 | |||
3618 | The above callbacks are the copy from/to the user-space buffer. There | ||
3619 | are some cases where we want copy from/to the kernel-space buffer | ||
3620 | instead. In such a case, ``copy_kernel`` callback is called. It'd | ||
3621 | look like: | ||
3622 | |||
3623 | :: | ||
3624 | |||
3625 | static int playback_copy_kernel(struct snd_pcm_substream *substream, | ||
3626 | int channel, unsigned long pos, | ||
3627 | void *src, unsigned long count); | ||
3628 | static int capture_copy_kernel(struct snd_pcm_substream *substream, | ||
3629 | int channel, unsigned long pos, | ||
3630 | void *dst, unsigned long count); | ||
3631 | |||
3632 | As found easily, the only difference is that the buffer pointer is | ||
3633 | without ``__user`` prefix; that is, a kernel-buffer pointer is passed | ||
3634 | in the fourth argument. Correspondingly, the implementation would be | ||
3635 | a version without the user-copy, such as: | ||
3597 | 3636 | ||
3598 | You need to check the channel argument, and if it's -1, copy the whole | 3637 | :: |
3599 | channels. Otherwise, you have to copy only the specified channel. Please | 3638 | |
3600 | check ``isa/gus/gus_pcm.c`` as an example. | 3639 | my_memcpy(my_buffer + pos, src, count); |
3601 | 3640 | ||
3602 | The ``silence`` callback is also implemented in a similar way | 3641 | Usually for the playback, another callback ``fill_silence`` is |
3642 | defined. It's implemented in a similar way as the copy callbacks | ||
3643 | above: | ||
3603 | 3644 | ||
3604 | :: | 3645 | :: |
3605 | 3646 | ||
3606 | static int silence(struct snd_pcm_substream *substream, int channel, | 3647 | static int silence(struct snd_pcm_substream *substream, int channel, |
3607 | snd_pcm_uframes_t pos, snd_pcm_uframes_t count); | 3648 | unsigned long pos, unsigned long count); |
3608 | 3649 | ||
3609 | The meanings of arguments are the same as in the ``copy`` callback, | 3650 | The meanings of arguments are the same as in the ``copy_user`` and |
3610 | although there is no ``src/dst`` argument. In the case of interleaved | 3651 | ``copy_kernel`` callbacks, although there is no buffer pointer |
3611 | samples, the channel argument has no meaning, as well as on ``copy`` | 3652 | argument. In the case of interleaved samples, the channel argument has |
3612 | callback. | 3653 | no meaning, as well as on ``copy_*`` callbacks. |
3613 | 3654 | ||
3614 | The role of ``silence`` callback is to set the given amount | 3655 | The role of ``fill_silence`` callback is to set the given amount |
3615 | (``count``) of silence data at the specified offset (``pos``) on the | 3656 | (``count``) of silence data at the specified offset (``pos``) on the |
3616 | hardware buffer. Suppose that the data format is signed (that is, the | 3657 | hardware buffer. Suppose that the data format is signed (that is, the |
3617 | silent-data is 0), and the implementation using a memset-like function | 3658 | silent-data is 0), and the implementation using a memset-like function |
@@ -3619,11 +3660,11 @@ would be like: | |||
3619 | 3660 | ||
3620 | :: | 3661 | :: |
3621 | 3662 | ||
3622 | my_memcpy(my_buffer + frames_to_bytes(runtime, pos), 0, | 3663 | my_memset(my_buffer + pos, 0, count); |
3623 | frames_to_bytes(runtime, count)); | ||
3624 | 3664 | ||
3625 | In the case of non-interleaved samples, again, the implementation | 3665 | In the case of non-interleaved samples, again, the implementation |
3626 | becomes a bit more complicated. See, for example, ``isa/gus/gus_pcm.c``. | 3666 | becomes a bit more complicated, as it's called N-times per transfer |
3667 | for each channel. See, for example, ``isa/gus/gus_pcm.c``. | ||
3627 | 3668 | ||
3628 | Non-Contiguous Buffers | 3669 | Non-Contiguous Buffers |
3629 | ---------------------- | 3670 | ---------------------- |
diff --git a/drivers/dma/dw/Kconfig b/drivers/dma/dw/Kconfig index 5a37b9fcf40d..04b9728c1d26 100644 --- a/drivers/dma/dw/Kconfig +++ b/drivers/dma/dw/Kconfig | |||
@@ -6,17 +6,12 @@ config DW_DMAC_CORE | |||
6 | tristate | 6 | tristate |
7 | select DMA_ENGINE | 7 | select DMA_ENGINE |
8 | 8 | ||
9 | config DW_DMAC_BIG_ENDIAN_IO | ||
10 | bool | ||
11 | |||
12 | config DW_DMAC | 9 | config DW_DMAC |
13 | tristate "Synopsys DesignWare AHB DMA platform driver" | 10 | tristate "Synopsys DesignWare AHB DMA platform driver" |
14 | select DW_DMAC_CORE | 11 | select DW_DMAC_CORE |
15 | select DW_DMAC_BIG_ENDIAN_IO if AVR32 | ||
16 | default y if CPU_AT32AP7000 | ||
17 | help | 12 | help |
18 | Support the Synopsys DesignWare AHB DMA controller. This | 13 | Support the Synopsys DesignWare AHB DMA controller. This |
19 | can be integrated in chips such as the Atmel AT32ap7000. | 14 | can be integrated in chips such as the Intel Cherrytrail. |
20 | 15 | ||
21 | config DW_DMAC_PCI | 16 | config DW_DMAC_PCI |
22 | tristate "Synopsys DesignWare AHB DMA PCI driver" | 17 | tristate "Synopsys DesignWare AHB DMA PCI driver" |
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index e500950dad82..f43e6dafe446 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c | |||
@@ -561,92 +561,14 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
561 | dwc_descriptor_complete(dwc, bad_desc, true); | 561 | dwc_descriptor_complete(dwc, bad_desc, true); |
562 | } | 562 | } |
563 | 563 | ||
564 | /* --------------------- Cyclic DMA API extensions -------------------- */ | ||
565 | |||
566 | dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan) | ||
567 | { | ||
568 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | ||
569 | return channel_readl(dwc, SAR); | ||
570 | } | ||
571 | EXPORT_SYMBOL(dw_dma_get_src_addr); | ||
572 | |||
573 | dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan) | ||
574 | { | ||
575 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | ||
576 | return channel_readl(dwc, DAR); | ||
577 | } | ||
578 | EXPORT_SYMBOL(dw_dma_get_dst_addr); | ||
579 | |||
580 | /* Called with dwc->lock held and all DMAC interrupts disabled */ | ||
581 | static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | ||
582 | u32 status_block, u32 status_err, u32 status_xfer) | ||
583 | { | ||
584 | unsigned long flags; | ||
585 | |||
586 | if (status_block & dwc->mask) { | ||
587 | void (*callback)(void *param); | ||
588 | void *callback_param; | ||
589 | |||
590 | dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n", | ||
591 | channel_readl(dwc, LLP)); | ||
592 | dma_writel(dw, CLEAR.BLOCK, dwc->mask); | ||
593 | |||
594 | callback = dwc->cdesc->period_callback; | ||
595 | callback_param = dwc->cdesc->period_callback_param; | ||
596 | |||
597 | if (callback) | ||
598 | callback(callback_param); | ||
599 | } | ||
600 | |||
601 | /* | ||
602 | * Error and transfer complete are highly unlikely, and will most | ||
603 | * likely be due to a configuration error by the user. | ||
604 | */ | ||
605 | if (unlikely(status_err & dwc->mask) || | ||
606 | unlikely(status_xfer & dwc->mask)) { | ||
607 | unsigned int i; | ||
608 | |||
609 | dev_err(chan2dev(&dwc->chan), | ||
610 | "cyclic DMA unexpected %s interrupt, stopping DMA transfer\n", | ||
611 | status_xfer ? "xfer" : "error"); | ||
612 | |||
613 | spin_lock_irqsave(&dwc->lock, flags); | ||
614 | |||
615 | dwc_dump_chan_regs(dwc); | ||
616 | |||
617 | dwc_chan_disable(dw, dwc); | ||
618 | |||
619 | /* Make sure DMA does not restart by loading a new list */ | ||
620 | channel_writel(dwc, LLP, 0); | ||
621 | channel_writel(dwc, CTL_LO, 0); | ||
622 | channel_writel(dwc, CTL_HI, 0); | ||
623 | |||
624 | dma_writel(dw, CLEAR.BLOCK, dwc->mask); | ||
625 | dma_writel(dw, CLEAR.ERROR, dwc->mask); | ||
626 | dma_writel(dw, CLEAR.XFER, dwc->mask); | ||
627 | |||
628 | for (i = 0; i < dwc->cdesc->periods; i++) | ||
629 | dwc_dump_lli(dwc, dwc->cdesc->desc[i]); | ||
630 | |||
631 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
632 | } | ||
633 | |||
634 | /* Re-enable interrupts */ | ||
635 | channel_set_bit(dw, MASK.BLOCK, dwc->mask); | ||
636 | } | ||
637 | |||
638 | /* ------------------------------------------------------------------------- */ | ||
639 | |||
640 | static void dw_dma_tasklet(unsigned long data) | 564 | static void dw_dma_tasklet(unsigned long data) |
641 | { | 565 | { |
642 | struct dw_dma *dw = (struct dw_dma *)data; | 566 | struct dw_dma *dw = (struct dw_dma *)data; |
643 | struct dw_dma_chan *dwc; | 567 | struct dw_dma_chan *dwc; |
644 | u32 status_block; | ||
645 | u32 status_xfer; | 568 | u32 status_xfer; |
646 | u32 status_err; | 569 | u32 status_err; |
647 | unsigned int i; | 570 | unsigned int i; |
648 | 571 | ||
649 | status_block = dma_readl(dw, RAW.BLOCK); | ||
650 | status_xfer = dma_readl(dw, RAW.XFER); | 572 | status_xfer = dma_readl(dw, RAW.XFER); |
651 | status_err = dma_readl(dw, RAW.ERROR); | 573 | status_err = dma_readl(dw, RAW.ERROR); |
652 | 574 | ||
@@ -655,8 +577,7 @@ static void dw_dma_tasklet(unsigned long data) | |||
655 | for (i = 0; i < dw->dma.chancnt; i++) { | 577 | for (i = 0; i < dw->dma.chancnt; i++) { |
656 | dwc = &dw->chan[i]; | 578 | dwc = &dw->chan[i]; |
657 | if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) | 579 | if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) |
658 | dwc_handle_cyclic(dw, dwc, status_block, status_err, | 580 | dev_vdbg(dw->dma.dev, "Cyclic xfer is not implemented\n"); |
659 | status_xfer); | ||
660 | else if (status_err & (1 << i)) | 581 | else if (status_err & (1 << i)) |
661 | dwc_handle_error(dw, dwc); | 582 | dwc_handle_error(dw, dwc); |
662 | else if (status_xfer & (1 << i)) | 583 | else if (status_xfer & (1 << i)) |
@@ -1264,255 +1185,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
1264 | dev_vdbg(chan2dev(chan), "%s: done\n", __func__); | 1185 | dev_vdbg(chan2dev(chan), "%s: done\n", __func__); |
1265 | } | 1186 | } |
1266 | 1187 | ||
1267 | /* --------------------- Cyclic DMA API extensions -------------------- */ | ||
1268 | |||
1269 | /** | ||
1270 | * dw_dma_cyclic_start - start the cyclic DMA transfer | ||
1271 | * @chan: the DMA channel to start | ||
1272 | * | ||
1273 | * Must be called with soft interrupts disabled. Returns zero on success or | ||
1274 | * -errno on failure. | ||
1275 | */ | ||
1276 | int dw_dma_cyclic_start(struct dma_chan *chan) | ||
1277 | { | ||
1278 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | ||
1279 | struct dw_dma *dw = to_dw_dma(chan->device); | ||
1280 | unsigned long flags; | ||
1281 | |||
1282 | if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { | ||
1283 | dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n"); | ||
1284 | return -ENODEV; | ||
1285 | } | ||
1286 | |||
1287 | spin_lock_irqsave(&dwc->lock, flags); | ||
1288 | |||
1289 | /* Enable interrupts to perform cyclic transfer */ | ||
1290 | channel_set_bit(dw, MASK.BLOCK, dwc->mask); | ||
1291 | |||
1292 | dwc_dostart(dwc, dwc->cdesc->desc[0]); | ||
1293 | |||
1294 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
1295 | |||
1296 | return 0; | ||
1297 | } | ||
1298 | EXPORT_SYMBOL(dw_dma_cyclic_start); | ||
1299 | |||
1300 | /** | ||
1301 | * dw_dma_cyclic_stop - stop the cyclic DMA transfer | ||
1302 | * @chan: the DMA channel to stop | ||
1303 | * | ||
1304 | * Must be called with soft interrupts disabled. | ||
1305 | */ | ||
1306 | void dw_dma_cyclic_stop(struct dma_chan *chan) | ||
1307 | { | ||
1308 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | ||
1309 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | ||
1310 | unsigned long flags; | ||
1311 | |||
1312 | spin_lock_irqsave(&dwc->lock, flags); | ||
1313 | |||
1314 | dwc_chan_disable(dw, dwc); | ||
1315 | |||
1316 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
1317 | } | ||
1318 | EXPORT_SYMBOL(dw_dma_cyclic_stop); | ||
1319 | |||
1320 | /** | ||
1321 | * dw_dma_cyclic_prep - prepare the cyclic DMA transfer | ||
1322 | * @chan: the DMA channel to prepare | ||
1323 | * @buf_addr: physical DMA address where the buffer starts | ||
1324 | * @buf_len: total number of bytes for the entire buffer | ||
1325 | * @period_len: number of bytes for each period | ||
1326 | * @direction: transfer direction, to or from device | ||
1327 | * | ||
1328 | * Must be called before trying to start the transfer. Returns a valid struct | ||
1329 | * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful. | ||
1330 | */ | ||
1331 | struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, | ||
1332 | dma_addr_t buf_addr, size_t buf_len, size_t period_len, | ||
1333 | enum dma_transfer_direction direction) | ||
1334 | { | ||
1335 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | ||
1336 | struct dma_slave_config *sconfig = &dwc->dma_sconfig; | ||
1337 | struct dw_cyclic_desc *cdesc; | ||
1338 | struct dw_cyclic_desc *retval = NULL; | ||
1339 | struct dw_desc *desc; | ||
1340 | struct dw_desc *last = NULL; | ||
1341 | u8 lms = DWC_LLP_LMS(dwc->dws.m_master); | ||
1342 | unsigned long was_cyclic; | ||
1343 | unsigned int reg_width; | ||
1344 | unsigned int periods; | ||
1345 | unsigned int i; | ||
1346 | unsigned long flags; | ||
1347 | |||
1348 | spin_lock_irqsave(&dwc->lock, flags); | ||
1349 | if (dwc->nollp) { | ||
1350 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
1351 | dev_dbg(chan2dev(&dwc->chan), | ||
1352 | "channel doesn't support LLP transfers\n"); | ||
1353 | return ERR_PTR(-EINVAL); | ||
1354 | } | ||
1355 | |||
1356 | if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) { | ||
1357 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
1358 | dev_dbg(chan2dev(&dwc->chan), | ||
1359 | "queue and/or active list are not empty\n"); | ||
1360 | return ERR_PTR(-EBUSY); | ||
1361 | } | ||
1362 | |||
1363 | was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags); | ||
1364 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
1365 | if (was_cyclic) { | ||
1366 | dev_dbg(chan2dev(&dwc->chan), | ||
1367 | "channel already prepared for cyclic DMA\n"); | ||
1368 | return ERR_PTR(-EBUSY); | ||
1369 | } | ||
1370 | |||
1371 | retval = ERR_PTR(-EINVAL); | ||
1372 | |||
1373 | if (unlikely(!is_slave_direction(direction))) | ||
1374 | goto out_err; | ||
1375 | |||
1376 | dwc->direction = direction; | ||
1377 | |||
1378 | if (direction == DMA_MEM_TO_DEV) | ||
1379 | reg_width = __ffs(sconfig->dst_addr_width); | ||
1380 | else | ||
1381 | reg_width = __ffs(sconfig->src_addr_width); | ||
1382 | |||
1383 | periods = buf_len / period_len; | ||
1384 | |||
1385 | /* Check for too big/unaligned periods and unaligned DMA buffer. */ | ||
1386 | if (period_len > (dwc->block_size << reg_width)) | ||
1387 | goto out_err; | ||
1388 | if (unlikely(period_len & ((1 << reg_width) - 1))) | ||
1389 | goto out_err; | ||
1390 | if (unlikely(buf_addr & ((1 << reg_width) - 1))) | ||
1391 | goto out_err; | ||
1392 | |||
1393 | retval = ERR_PTR(-ENOMEM); | ||
1394 | |||
1395 | cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL); | ||
1396 | if (!cdesc) | ||
1397 | goto out_err; | ||
1398 | |||
1399 | cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL); | ||
1400 | if (!cdesc->desc) | ||
1401 | goto out_err_alloc; | ||
1402 | |||
1403 | for (i = 0; i < periods; i++) { | ||
1404 | desc = dwc_desc_get(dwc); | ||
1405 | if (!desc) | ||
1406 | goto out_err_desc_get; | ||
1407 | |||
1408 | switch (direction) { | ||
1409 | case DMA_MEM_TO_DEV: | ||
1410 | lli_write(desc, dar, sconfig->dst_addr); | ||
1411 | lli_write(desc, sar, buf_addr + period_len * i); | ||
1412 | lli_write(desc, ctllo, (DWC_DEFAULT_CTLLO(chan) | ||
1413 | | DWC_CTLL_DST_WIDTH(reg_width) | ||
1414 | | DWC_CTLL_SRC_WIDTH(reg_width) | ||
1415 | | DWC_CTLL_DST_FIX | ||
1416 | | DWC_CTLL_SRC_INC | ||
1417 | | DWC_CTLL_INT_EN)); | ||
1418 | |||
1419 | lli_set(desc, ctllo, sconfig->device_fc ? | ||
1420 | DWC_CTLL_FC(DW_DMA_FC_P_M2P) : | ||
1421 | DWC_CTLL_FC(DW_DMA_FC_D_M2P)); | ||
1422 | |||
1423 | break; | ||
1424 | case DMA_DEV_TO_MEM: | ||
1425 | lli_write(desc, dar, buf_addr + period_len * i); | ||
1426 | lli_write(desc, sar, sconfig->src_addr); | ||
1427 | lli_write(desc, ctllo, (DWC_DEFAULT_CTLLO(chan) | ||
1428 | | DWC_CTLL_SRC_WIDTH(reg_width) | ||
1429 | | DWC_CTLL_DST_WIDTH(reg_width) | ||
1430 | | DWC_CTLL_DST_INC | ||
1431 | | DWC_CTLL_SRC_FIX | ||
1432 | | DWC_CTLL_INT_EN)); | ||
1433 | |||
1434 | lli_set(desc, ctllo, sconfig->device_fc ? | ||
1435 | DWC_CTLL_FC(DW_DMA_FC_P_P2M) : | ||
1436 | DWC_CTLL_FC(DW_DMA_FC_D_P2M)); | ||
1437 | |||
1438 | break; | ||
1439 | default: | ||
1440 | break; | ||
1441 | } | ||
1442 | |||
1443 | lli_write(desc, ctlhi, period_len >> reg_width); | ||
1444 | cdesc->desc[i] = desc; | ||
1445 | |||
1446 | if (last) | ||
1447 | lli_write(last, llp, desc->txd.phys | lms); | ||
1448 | |||
1449 | last = desc; | ||
1450 | } | ||
1451 | |||
1452 | /* Let's make a cyclic list */ | ||
1453 | lli_write(last, llp, cdesc->desc[0]->txd.phys | lms); | ||
1454 | |||
1455 | dev_dbg(chan2dev(&dwc->chan), | ||
1456 | "cyclic prepared buf %pad len %zu period %zu periods %d\n", | ||
1457 | &buf_addr, buf_len, period_len, periods); | ||
1458 | |||
1459 | cdesc->periods = periods; | ||
1460 | dwc->cdesc = cdesc; | ||
1461 | |||
1462 | return cdesc; | ||
1463 | |||
1464 | out_err_desc_get: | ||
1465 | while (i--) | ||
1466 | dwc_desc_put(dwc, cdesc->desc[i]); | ||
1467 | out_err_alloc: | ||
1468 | kfree(cdesc); | ||
1469 | out_err: | ||
1470 | clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags); | ||
1471 | return (struct dw_cyclic_desc *)retval; | ||
1472 | } | ||
1473 | EXPORT_SYMBOL(dw_dma_cyclic_prep); | ||
1474 | |||
1475 | /** | ||
1476 | * dw_dma_cyclic_free - free a prepared cyclic DMA transfer | ||
1477 | * @chan: the DMA channel to free | ||
1478 | */ | ||
1479 | void dw_dma_cyclic_free(struct dma_chan *chan) | ||
1480 | { | ||
1481 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | ||
1482 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | ||
1483 | struct dw_cyclic_desc *cdesc = dwc->cdesc; | ||
1484 | unsigned int i; | ||
1485 | unsigned long flags; | ||
1486 | |||
1487 | dev_dbg(chan2dev(&dwc->chan), "%s\n", __func__); | ||
1488 | |||
1489 | if (!cdesc) | ||
1490 | return; | ||
1491 | |||
1492 | spin_lock_irqsave(&dwc->lock, flags); | ||
1493 | |||
1494 | dwc_chan_disable(dw, dwc); | ||
1495 | |||
1496 | dma_writel(dw, CLEAR.BLOCK, dwc->mask); | ||
1497 | dma_writel(dw, CLEAR.ERROR, dwc->mask); | ||
1498 | dma_writel(dw, CLEAR.XFER, dwc->mask); | ||
1499 | |||
1500 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
1501 | |||
1502 | for (i = 0; i < cdesc->periods; i++) | ||
1503 | dwc_desc_put(dwc, cdesc->desc[i]); | ||
1504 | |||
1505 | kfree(cdesc->desc); | ||
1506 | kfree(cdesc); | ||
1507 | |||
1508 | dwc->cdesc = NULL; | ||
1509 | |||
1510 | clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags); | ||
1511 | } | ||
1512 | EXPORT_SYMBOL(dw_dma_cyclic_free); | ||
1513 | |||
1514 | /*----------------------------------------------------------------------*/ | ||
1515 | |||
1516 | int dw_dma_probe(struct dw_dma_chip *chip) | 1188 | int dw_dma_probe(struct dw_dma_chip *chip) |
1517 | { | 1189 | { |
1518 | struct dw_dma_platform_data *pdata; | 1190 | struct dw_dma_platform_data *pdata; |
@@ -1642,7 +1314,7 @@ int dw_dma_probe(struct dw_dma_chip *chip) | |||
1642 | if (autocfg) { | 1314 | if (autocfg) { |
1643 | unsigned int r = DW_DMA_MAX_NR_CHANNELS - i - 1; | 1315 | unsigned int r = DW_DMA_MAX_NR_CHANNELS - i - 1; |
1644 | void __iomem *addr = &__dw_regs(dw)->DWC_PARAMS[r]; | 1316 | void __iomem *addr = &__dw_regs(dw)->DWC_PARAMS[r]; |
1645 | unsigned int dwc_params = dma_readl_native(addr); | 1317 | unsigned int dwc_params = readl(addr); |
1646 | 1318 | ||
1647 | dev_dbg(chip->dev, "DWC_PARAMS[%d]: 0x%08x\n", i, | 1319 | dev_dbg(chip->dev, "DWC_PARAMS[%d]: 0x%08x\n", i, |
1648 | dwc_params); | 1320 | dwc_params); |
diff --git a/drivers/dma/dw/regs.h b/drivers/dma/dw/regs.h index 32a328721c88..09e7dfdbb790 100644 --- a/drivers/dma/dw/regs.h +++ b/drivers/dma/dw/regs.h | |||
@@ -116,20 +116,6 @@ struct dw_dma_regs { | |||
116 | DW_REG(GLOBAL_CFG); | 116 | DW_REG(GLOBAL_CFG); |
117 | }; | 117 | }; |
118 | 118 | ||
119 | /* | ||
120 | * Big endian I/O access when reading and writing to the DMA controller | ||
121 | * registers. This is needed on some platforms, like the Atmel AVR32 | ||
122 | * architecture. | ||
123 | */ | ||
124 | |||
125 | #ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO | ||
126 | #define dma_readl_native ioread32be | ||
127 | #define dma_writel_native iowrite32be | ||
128 | #else | ||
129 | #define dma_readl_native readl | ||
130 | #define dma_writel_native writel | ||
131 | #endif | ||
132 | |||
133 | /* Bitfields in DW_PARAMS */ | 119 | /* Bitfields in DW_PARAMS */ |
134 | #define DW_PARAMS_NR_CHAN 8 /* number of channels */ | 120 | #define DW_PARAMS_NR_CHAN 8 /* number of channels */ |
135 | #define DW_PARAMS_NR_MASTER 11 /* number of AHB masters */ | 121 | #define DW_PARAMS_NR_MASTER 11 /* number of AHB masters */ |
@@ -280,7 +266,6 @@ struct dw_dma_chan { | |||
280 | unsigned long flags; | 266 | unsigned long flags; |
281 | struct list_head active_list; | 267 | struct list_head active_list; |
282 | struct list_head queue; | 268 | struct list_head queue; |
283 | struct dw_cyclic_desc *cdesc; | ||
284 | 269 | ||
285 | unsigned int descs_allocated; | 270 | unsigned int descs_allocated; |
286 | 271 | ||
@@ -302,9 +287,9 @@ __dwc_regs(struct dw_dma_chan *dwc) | |||
302 | } | 287 | } |
303 | 288 | ||
304 | #define channel_readl(dwc, name) \ | 289 | #define channel_readl(dwc, name) \ |
305 | dma_readl_native(&(__dwc_regs(dwc)->name)) | 290 | readl(&(__dwc_regs(dwc)->name)) |
306 | #define channel_writel(dwc, name, val) \ | 291 | #define channel_writel(dwc, name, val) \ |
307 | dma_writel_native((val), &(__dwc_regs(dwc)->name)) | 292 | writel((val), &(__dwc_regs(dwc)->name)) |
308 | 293 | ||
309 | static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan) | 294 | static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan) |
310 | { | 295 | { |
@@ -333,9 +318,9 @@ static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw) | |||
333 | } | 318 | } |
334 | 319 | ||
335 | #define dma_readl(dw, name) \ | 320 | #define dma_readl(dw, name) \ |
336 | dma_readl_native(&(__dw_regs(dw)->name)) | 321 | readl(&(__dw_regs(dw)->name)) |
337 | #define dma_writel(dw, name, val) \ | 322 | #define dma_writel(dw, name, val) \ |
338 | dma_writel_native((val), &(__dw_regs(dw)->name)) | 323 | writel((val), &(__dw_regs(dw)->name)) |
339 | 324 | ||
340 | #define idma32_readq(dw, name) \ | 325 | #define idma32_readq(dw, name) \ |
341 | hi_lo_readq(&(__dw_regs(dw)->name)) | 326 | hi_lo_readq(&(__dw_regs(dw)->name)) |
@@ -352,43 +337,30 @@ static inline struct dw_dma *to_dw_dma(struct dma_device *ddev) | |||
352 | return container_of(ddev, struct dw_dma, dma); | 337 | return container_of(ddev, struct dw_dma, dma); |
353 | } | 338 | } |
354 | 339 | ||
355 | #ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO | ||
356 | typedef __be32 __dw32; | ||
357 | #else | ||
358 | typedef __le32 __dw32; | ||
359 | #endif | ||
360 | |||
361 | /* LLI == Linked List Item; a.k.a. DMA block descriptor */ | 340 | /* LLI == Linked List Item; a.k.a. DMA block descriptor */ |
362 | struct dw_lli { | 341 | struct dw_lli { |
363 | /* values that are not changed by hardware */ | 342 | /* values that are not changed by hardware */ |
364 | __dw32 sar; | 343 | __le32 sar; |
365 | __dw32 dar; | 344 | __le32 dar; |
366 | __dw32 llp; /* chain to next lli */ | 345 | __le32 llp; /* chain to next lli */ |
367 | __dw32 ctllo; | 346 | __le32 ctllo; |
368 | /* values that may get written back: */ | 347 | /* values that may get written back: */ |
369 | __dw32 ctlhi; | 348 | __le32 ctlhi; |
370 | /* sstat and dstat can snapshot peripheral register state. | 349 | /* sstat and dstat can snapshot peripheral register state. |
371 | * silicon config may discard either or both... | 350 | * silicon config may discard either or both... |
372 | */ | 351 | */ |
373 | __dw32 sstat; | 352 | __le32 sstat; |
374 | __dw32 dstat; | 353 | __le32 dstat; |
375 | }; | 354 | }; |
376 | 355 | ||
377 | struct dw_desc { | 356 | struct dw_desc { |
378 | /* FIRST values the hardware uses */ | 357 | /* FIRST values the hardware uses */ |
379 | struct dw_lli lli; | 358 | struct dw_lli lli; |
380 | 359 | ||
381 | #ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO | ||
382 | #define lli_set(d, reg, v) ((d)->lli.reg |= cpu_to_be32(v)) | ||
383 | #define lli_clear(d, reg, v) ((d)->lli.reg &= ~cpu_to_be32(v)) | ||
384 | #define lli_read(d, reg) be32_to_cpu((d)->lli.reg) | ||
385 | #define lli_write(d, reg, v) ((d)->lli.reg = cpu_to_be32(v)) | ||
386 | #else | ||
387 | #define lli_set(d, reg, v) ((d)->lli.reg |= cpu_to_le32(v)) | 360 | #define lli_set(d, reg, v) ((d)->lli.reg |= cpu_to_le32(v)) |
388 | #define lli_clear(d, reg, v) ((d)->lli.reg &= ~cpu_to_le32(v)) | 361 | #define lli_clear(d, reg, v) ((d)->lli.reg &= ~cpu_to_le32(v)) |
389 | #define lli_read(d, reg) le32_to_cpu((d)->lli.reg) | 362 | #define lli_read(d, reg) le32_to_cpu((d)->lli.reg) |
390 | #define lli_write(d, reg, v) ((d)->lli.reg = cpu_to_le32(v)) | 363 | #define lli_write(d, reg, v) ((d)->lli.reg = cpu_to_le32(v)) |
391 | #endif | ||
392 | 364 | ||
393 | /* THEN values for driver housekeeping */ | 365 | /* THEN values for driver housekeeping */ |
394 | struct list_head desc_node; | 366 | struct list_head desc_node; |
diff --git a/drivers/media/pci/solo6x10/solo6x10-g723.c b/drivers/media/pci/solo6x10/solo6x10-g723.c index 36e93540bb49..3ca947092775 100644 --- a/drivers/media/pci/solo6x10/solo6x10-g723.c +++ b/drivers/media/pci/solo6x10/solo6x10-g723.c | |||
@@ -223,9 +223,9 @@ static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss) | |||
223 | return idx * G723_FRAMES_PER_PAGE; | 223 | return idx * G723_FRAMES_PER_PAGE; |
224 | } | 224 | } |
225 | 225 | ||
226 | static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel, | 226 | static int __snd_solo_pcm_copy(struct snd_pcm_substream *ss, |
227 | snd_pcm_uframes_t pos, void __user *dst, | 227 | unsigned long pos, void *dst, |
228 | snd_pcm_uframes_t count) | 228 | unsigned long count, bool in_kernel) |
229 | { | 229 | { |
230 | struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); | 230 | struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); |
231 | struct solo_dev *solo_dev = solo_pcm->solo_dev; | 231 | struct solo_dev *solo_dev = solo_pcm->solo_dev; |
@@ -242,16 +242,31 @@ static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel, | |||
242 | if (err) | 242 | if (err) |
243 | return err; | 243 | return err; |
244 | 244 | ||
245 | err = copy_to_user(dst + (i * G723_PERIOD_BYTES), | 245 | if (in_kernel) |
246 | solo_pcm->g723_buf, G723_PERIOD_BYTES); | 246 | memcpy(dst, solo_pcm->g723_buf, G723_PERIOD_BYTES); |
247 | 247 | else if (copy_to_user((void __user *)dst, | |
248 | if (err) | 248 | solo_pcm->g723_buf, G723_PERIOD_BYTES)) |
249 | return -EFAULT; | 249 | return -EFAULT; |
250 | dst += G723_PERIOD_BYTES; | ||
250 | } | 251 | } |
251 | 252 | ||
252 | return 0; | 253 | return 0; |
253 | } | 254 | } |
254 | 255 | ||
256 | static int snd_solo_pcm_copy_user(struct snd_pcm_substream *ss, int channel, | ||
257 | unsigned long pos, void __user *dst, | ||
258 | unsigned long count) | ||
259 | { | ||
260 | return __snd_solo_pcm_copy(ss, pos, (void *)dst, count, false); | ||
261 | } | ||
262 | |||
263 | static int snd_solo_pcm_copy_kernel(struct snd_pcm_substream *ss, int channel, | ||
264 | unsigned long pos, void *dst, | ||
265 | unsigned long count) | ||
266 | { | ||
267 | return __snd_solo_pcm_copy(ss, pos, dst, count, true); | ||
268 | } | ||
269 | |||
255 | static const struct snd_pcm_ops snd_solo_pcm_ops = { | 270 | static const struct snd_pcm_ops snd_solo_pcm_ops = { |
256 | .open = snd_solo_pcm_open, | 271 | .open = snd_solo_pcm_open, |
257 | .close = snd_solo_pcm_close, | 272 | .close = snd_solo_pcm_close, |
@@ -261,7 +276,8 @@ static const struct snd_pcm_ops snd_solo_pcm_ops = { | |||
261 | .prepare = snd_solo_pcm_prepare, | 276 | .prepare = snd_solo_pcm_prepare, |
262 | .trigger = snd_solo_pcm_trigger, | 277 | .trigger = snd_solo_pcm_trigger, |
263 | .pointer = snd_solo_pcm_pointer, | 278 | .pointer = snd_solo_pcm_pointer, |
264 | .copy = snd_solo_pcm_copy, | 279 | .copy_user = snd_solo_pcm_copy_user, |
280 | .copy_kernel = snd_solo_pcm_copy_kernel, | ||
265 | }; | 281 | }; |
266 | 282 | ||
267 | static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol, | 283 | static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol, |
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c index e8cf0b97bf02..3637ddf909a4 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | |||
@@ -353,9 +353,8 @@ static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream) | |||
353 | struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect; | 353 | struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect; |
354 | 354 | ||
355 | pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max; | 355 | pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max; |
356 | snd_pcm_indirect_playback_transfer(substream, pcm_indirect, | 356 | return snd_pcm_indirect_playback_transfer(substream, pcm_indirect, |
357 | snd_bcm2835_pcm_transfer); | 357 | snd_bcm2835_pcm_transfer); |
358 | return 0; | ||
359 | } | 358 | } |
360 | 359 | ||
361 | /* trigger callback */ | 360 | /* trigger callback */ |
diff --git a/drivers/usb/gadget/function/u_uac1.c b/drivers/usb/gadget/function/u_uac1.c index c78c84138a28..ca88e4c0fd1e 100644 --- a/drivers/usb/gadget/function/u_uac1.c +++ b/drivers/usb/gadget/function/u_uac1.c | |||
@@ -157,7 +157,6 @@ size_t u_audio_playback(struct gaudio *card, void *buf, size_t count) | |||
157 | struct gaudio_snd_dev *snd = &card->playback; | 157 | struct gaudio_snd_dev *snd = &card->playback; |
158 | struct snd_pcm_substream *substream = snd->substream; | 158 | struct snd_pcm_substream *substream = snd->substream; |
159 | struct snd_pcm_runtime *runtime = substream->runtime; | 159 | struct snd_pcm_runtime *runtime = substream->runtime; |
160 | mm_segment_t old_fs; | ||
161 | ssize_t result; | 160 | ssize_t result; |
162 | snd_pcm_sframes_t frames; | 161 | snd_pcm_sframes_t frames; |
163 | 162 | ||
@@ -174,15 +173,11 @@ try_again: | |||
174 | } | 173 | } |
175 | 174 | ||
176 | frames = bytes_to_frames(runtime, count); | 175 | frames = bytes_to_frames(runtime, count); |
177 | old_fs = get_fs(); | 176 | result = snd_pcm_kernel_write(snd->substream, buf, frames); |
178 | set_fs(KERNEL_DS); | ||
179 | result = snd_pcm_lib_write(snd->substream, (void __user *)buf, frames); | ||
180 | if (result != frames) { | 177 | if (result != frames) { |
181 | ERROR(card, "Playback error: %d\n", (int)result); | 178 | ERROR(card, "Playback error: %d\n", (int)result); |
182 | set_fs(old_fs); | ||
183 | goto try_again; | 179 | goto try_again; |
184 | } | 180 | } |
185 | set_fs(old_fs); | ||
186 | 181 | ||
187 | return 0; | 182 | return 0; |
188 | } | 183 | } |
diff --git a/include/linux/dma/dw.h b/include/linux/dma/dw.h index b63b25814d77..e166cac8e870 100644 --- a/include/linux/dma/dw.h +++ b/include/linux/dma/dw.h | |||
@@ -50,25 +50,4 @@ static inline int dw_dma_probe(struct dw_dma_chip *chip) { return -ENODEV; } | |||
50 | static inline int dw_dma_remove(struct dw_dma_chip *chip) { return 0; } | 50 | static inline int dw_dma_remove(struct dw_dma_chip *chip) { return 0; } |
51 | #endif /* CONFIG_DW_DMAC_CORE */ | 51 | #endif /* CONFIG_DW_DMAC_CORE */ |
52 | 52 | ||
53 | /* DMA API extensions */ | ||
54 | struct dw_desc; | ||
55 | |||
56 | struct dw_cyclic_desc { | ||
57 | struct dw_desc **desc; | ||
58 | unsigned long periods; | ||
59 | void (*period_callback)(void *param); | ||
60 | void *period_callback_param; | ||
61 | }; | ||
62 | |||
63 | struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, | ||
64 | dma_addr_t buf_addr, size_t buf_len, size_t period_len, | ||
65 | enum dma_transfer_direction direction); | ||
66 | void dw_dma_cyclic_free(struct dma_chan *chan); | ||
67 | int dw_dma_cyclic_start(struct dma_chan *chan); | ||
68 | void dw_dma_cyclic_stop(struct dma_chan *chan); | ||
69 | |||
70 | dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan); | ||
71 | |||
72 | dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan); | ||
73 | |||
74 | #endif /* _DMA_DW_H */ | 53 | #endif /* _DMA_DW_H */ |
diff --git a/include/sound/ak4113.h b/include/sound/ak4113.h index 58c145620c3c..b2d09fd09559 100644 --- a/include/sound/ak4113.h +++ b/include/sound/ak4113.h | |||
@@ -281,6 +281,14 @@ typedef void (ak4113_write_t)(void *private_data, unsigned char addr, | |||
281 | unsigned char data); | 281 | unsigned char data); |
282 | typedef unsigned char (ak4113_read_t)(void *private_data, unsigned char addr); | 282 | typedef unsigned char (ak4113_read_t)(void *private_data, unsigned char addr); |
283 | 283 | ||
284 | enum { | ||
285 | AK4113_PARITY_ERRORS, | ||
286 | AK4113_V_BIT_ERRORS, | ||
287 | AK4113_QCRC_ERRORS, | ||
288 | AK4113_CCRC_ERRORS, | ||
289 | AK4113_NUM_ERRORS | ||
290 | }; | ||
291 | |||
284 | struct ak4113 { | 292 | struct ak4113 { |
285 | struct snd_card *card; | 293 | struct snd_card *card; |
286 | ak4113_write_t *write; | 294 | ak4113_write_t *write; |
@@ -292,10 +300,7 @@ struct ak4113 { | |||
292 | unsigned char regmap[AK4113_WRITABLE_REGS]; | 300 | unsigned char regmap[AK4113_WRITABLE_REGS]; |
293 | struct snd_kcontrol *kctls[AK4113_CONTROLS]; | 301 | struct snd_kcontrol *kctls[AK4113_CONTROLS]; |
294 | struct snd_pcm_substream *substream; | 302 | struct snd_pcm_substream *substream; |
295 | unsigned long parity_errors; | 303 | unsigned long errors[AK4113_NUM_ERRORS]; |
296 | unsigned long v_bit_errors; | ||
297 | unsigned long qcrc_errors; | ||
298 | unsigned long ccrc_errors; | ||
299 | unsigned char rcs0; | 304 | unsigned char rcs0; |
300 | unsigned char rcs1; | 305 | unsigned char rcs1; |
301 | unsigned char rcs2; | 306 | unsigned char rcs2; |
diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h index b6feb7e225f2..39df064c82fc 100644 --- a/include/sound/ak4114.h +++ b/include/sound/ak4114.h | |||
@@ -163,6 +163,14 @@ | |||
163 | typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data); | 163 | typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data); |
164 | typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr); | 164 | typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr); |
165 | 165 | ||
166 | enum { | ||
167 | AK4114_PARITY_ERRORS, | ||
168 | AK4114_V_BIT_ERRORS, | ||
169 | AK4114_QCRC_ERRORS, | ||
170 | AK4114_CCRC_ERRORS, | ||
171 | AK4114_NUM_ERRORS | ||
172 | }; | ||
173 | |||
166 | struct ak4114 { | 174 | struct ak4114 { |
167 | struct snd_card *card; | 175 | struct snd_card *card; |
168 | ak4114_write_t * write; | 176 | ak4114_write_t * write; |
@@ -176,10 +184,7 @@ struct ak4114 { | |||
176 | struct snd_kcontrol *kctls[AK4114_CONTROLS]; | 184 | struct snd_kcontrol *kctls[AK4114_CONTROLS]; |
177 | struct snd_pcm_substream *playback_substream; | 185 | struct snd_pcm_substream *playback_substream; |
178 | struct snd_pcm_substream *capture_substream; | 186 | struct snd_pcm_substream *capture_substream; |
179 | unsigned long parity_errors; | 187 | unsigned long errors[AK4114_NUM_ERRORS]; |
180 | unsigned long v_bit_errors; | ||
181 | unsigned long qcrc_errors; | ||
182 | unsigned long ccrc_errors; | ||
183 | unsigned char rcs0; | 188 | unsigned char rcs0; |
184 | unsigned char rcs1; | 189 | unsigned char rcs1; |
185 | struct delayed_work work; | 190 | struct delayed_work work; |
diff --git a/include/sound/ak4117.h b/include/sound/ak4117.h index 1e8178171baf..5fab517cfe46 100644 --- a/include/sound/ak4117.h +++ b/include/sound/ak4117.h | |||
@@ -155,6 +155,14 @@ | |||
155 | typedef void (ak4117_write_t)(void *private_data, unsigned char addr, unsigned char data); | 155 | typedef void (ak4117_write_t)(void *private_data, unsigned char addr, unsigned char data); |
156 | typedef unsigned char (ak4117_read_t)(void *private_data, unsigned char addr); | 156 | typedef unsigned char (ak4117_read_t)(void *private_data, unsigned char addr); |
157 | 157 | ||
158 | enum { | ||
159 | AK4117_PARITY_ERRORS, | ||
160 | AK4117_V_BIT_ERRORS, | ||
161 | AK4117_QCRC_ERRORS, | ||
162 | AK4117_CCRC_ERRORS, | ||
163 | AK4117_NUM_ERRORS | ||
164 | }; | ||
165 | |||
158 | struct ak4117 { | 166 | struct ak4117 { |
159 | struct snd_card *card; | 167 | struct snd_card *card; |
160 | ak4117_write_t * write; | 168 | ak4117_write_t * write; |
@@ -165,10 +173,7 @@ struct ak4117 { | |||
165 | unsigned char regmap[5]; | 173 | unsigned char regmap[5]; |
166 | struct snd_kcontrol *kctls[AK4117_CONTROLS]; | 174 | struct snd_kcontrol *kctls[AK4117_CONTROLS]; |
167 | struct snd_pcm_substream *substream; | 175 | struct snd_pcm_substream *substream; |
168 | unsigned long parity_errors; | 176 | unsigned long errors[AK4117_NUM_ERRORS]; |
169 | unsigned long v_bit_errors; | ||
170 | unsigned long qcrc_errors; | ||
171 | unsigned long ccrc_errors; | ||
172 | unsigned char rcs0; | 177 | unsigned char rcs0; |
173 | unsigned char rcs1; | 178 | unsigned char rcs1; |
174 | unsigned char rcs2; | 179 | unsigned char rcs2; |
diff --git a/include/sound/core.h b/include/sound/core.h index f7d8c10c4c45..55385588eefa 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
@@ -142,7 +142,7 @@ struct snd_card { | |||
142 | wait_queue_head_t power_sleep; | 142 | wait_queue_head_t power_sleep; |
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) | 145 | #if IS_ENABLED(CONFIG_SND_MIXER_OSS) |
146 | struct snd_mixer_oss *mixer_oss; | 146 | struct snd_mixer_oss *mixer_oss; |
147 | int mixer_oss_change_count; | 147 | int mixer_oss_change_count; |
148 | #endif | 148 | #endif |
@@ -243,7 +243,7 @@ int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size | |||
243 | 243 | ||
244 | extern struct snd_card *snd_cards[SNDRV_CARDS]; | 244 | extern struct snd_card *snd_cards[SNDRV_CARDS]; |
245 | int snd_card_locked(int card); | 245 | int snd_card_locked(int card); |
246 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) | 246 | #if IS_ENABLED(CONFIG_SND_MIXER_OSS) |
247 | #define SND_MIXER_OSS_NOTIFY_REGISTER 0 | 247 | #define SND_MIXER_OSS_NOTIFY_REGISTER 0 |
248 | #define SND_MIXER_OSS_NOTIFY_DISCONNECT 1 | 248 | #define SND_MIXER_OSS_NOTIFY_DISCONNECT 1 |
249 | #define SND_MIXER_OSS_NOTIFY_FREE 2 | 249 | #define SND_MIXER_OSS_NOTIFY_FREE 2 |
@@ -394,7 +394,7 @@ static inline void snd_printdd(const char *format, ...) {} | |||
394 | #define SNDRV_OSS_VERSION ((3<<16)|(8<<8)|(1<<4)|(0)) /* 3.8.1a */ | 394 | #define SNDRV_OSS_VERSION ((3<<16)|(8<<8)|(1<<4)|(0)) /* 3.8.1a */ |
395 | 395 | ||
396 | /* for easier backward-porting */ | 396 | /* for easier backward-porting */ |
397 | #if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) | 397 | #if IS_ENABLED(CONFIG_GAMEPORT) |
398 | #define gameport_set_dev_parent(gp,xdev) ((gp)->dev.parent = (xdev)) | 398 | #define gameport_set_dev_parent(gp,xdev) ((gp)->dev.parent = (xdev)) |
399 | #define gameport_set_port_data(gp,r) ((gp)->port_data = (r)) | 399 | #define gameport_set_port_data(gp,r) ((gp)->port_data = (r)) |
400 | #define gameport_get_port_data(gp) (gp)->port_data | 400 | #define gameport_get_port_data(gp) (gp)->port_data |
diff --git a/include/sound/emux_synth.h b/include/sound/emux_synth.h index a0a40b74bf13..19a0cb561ffc 100644 --- a/include/sound/emux_synth.h +++ b/include/sound/emux_synth.h | |||
@@ -25,9 +25,7 @@ | |||
25 | #include <sound/seq_device.h> | 25 | #include <sound/seq_device.h> |
26 | #include <sound/soundfont.h> | 26 | #include <sound/soundfont.h> |
27 | #include <sound/seq_midi_emul.h> | 27 | #include <sound/seq_midi_emul.h> |
28 | #ifdef CONFIG_SND_SEQUENCER_OSS | ||
29 | #include <sound/seq_oss.h> | 28 | #include <sound/seq_oss.h> |
30 | #endif | ||
31 | #include <sound/emux_legacy.h> | 29 | #include <sound/emux_legacy.h> |
32 | #include <sound/seq_virmidi.h> | 30 | #include <sound/seq_virmidi.h> |
33 | 31 | ||
@@ -66,7 +64,7 @@ struct snd_emux_operators { | |||
66 | const void __user *data, long count); | 64 | const void __user *data, long count); |
67 | void (*sysex)(struct snd_emux *emu, char *buf, int len, int parsed, | 65 | void (*sysex)(struct snd_emux *emu, char *buf, int len, int parsed, |
68 | struct snd_midi_channel_set *chset); | 66 | struct snd_midi_channel_set *chset); |
69 | #ifdef CONFIG_SND_SEQUENCER_OSS | 67 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
70 | int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2); | 68 | int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2); |
71 | #endif | 69 | #endif |
72 | }; | 70 | }; |
@@ -129,7 +127,7 @@ struct snd_emux { | |||
129 | struct snd_info_entry *proc; | 127 | struct snd_info_entry *proc; |
130 | #endif | 128 | #endif |
131 | 129 | ||
132 | #ifdef CONFIG_SND_SEQUENCER_OSS | 130 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
133 | struct snd_seq_device *oss_synth; | 131 | struct snd_seq_device *oss_synth; |
134 | #endif | 132 | #endif |
135 | }; | 133 | }; |
@@ -150,7 +148,7 @@ struct snd_emux_port { | |||
150 | #ifdef SNDRV_EMUX_USE_RAW_EFFECT | 148 | #ifdef SNDRV_EMUX_USE_RAW_EFFECT |
151 | struct snd_emux_effect_table *effect; | 149 | struct snd_emux_effect_table *effect; |
152 | #endif | 150 | #endif |
153 | #ifdef CONFIG_SND_SEQUENCER_OSS | 151 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
154 | struct snd_seq_oss_arg *oss_arg; | 152 | struct snd_seq_oss_arg *oss_arg; |
155 | #endif | 153 | #endif |
156 | }; | 154 | }; |
diff --git a/include/sound/mixer_oss.h b/include/sound/mixer_oss.h index 13cb0b430a1b..930da10fb65b 100644 --- a/include/sound/mixer_oss.h +++ b/include/sound/mixer_oss.h | |||
@@ -22,7 +22,7 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) | 25 | #if IS_ENABLED(CONFIG_SND_MIXER_OSS) |
26 | 26 | ||
27 | #define SNDRV_OSS_MAX_MIXERS 32 | 27 | #define SNDRV_OSS_MAX_MIXERS 32 |
28 | 28 | ||
diff --git a/include/sound/opl3.h b/include/sound/opl3.h index 6ba670707831..a4a593590cff 100644 --- a/include/sound/opl3.h +++ b/include/sound/opl3.h | |||
@@ -55,10 +55,8 @@ | |||
55 | #include <sound/hwdep.h> | 55 | #include <sound/hwdep.h> |
56 | #include <sound/timer.h> | 56 | #include <sound/timer.h> |
57 | #include <sound/seq_midi_emul.h> | 57 | #include <sound/seq_midi_emul.h> |
58 | #ifdef CONFIG_SND_SEQUENCER_OSS | ||
59 | #include <sound/seq_oss.h> | 58 | #include <sound/seq_oss.h> |
60 | #include <sound/seq_oss_legacy.h> | 59 | #include <sound/seq_oss_legacy.h> |
61 | #endif | ||
62 | #include <sound/seq_device.h> | 60 | #include <sound/seq_device.h> |
63 | #include <sound/asound_fm.h> | 61 | #include <sound/asound_fm.h> |
64 | 62 | ||
@@ -321,7 +319,7 @@ struct snd_opl3 { | |||
321 | unsigned char fm_mode; /* OPL mode, see SNDRV_DM_FM_MODE_XXX */ | 319 | unsigned char fm_mode; /* OPL mode, see SNDRV_DM_FM_MODE_XXX */ |
322 | unsigned char rhythm; /* percussion mode flag */ | 320 | unsigned char rhythm; /* percussion mode flag */ |
323 | unsigned char max_voices; /* max number of voices */ | 321 | unsigned char max_voices; /* max number of voices */ |
324 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) | 322 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
325 | #define SNDRV_OPL3_MODE_SYNTH 0 /* OSS - voices allocated by application */ | 323 | #define SNDRV_OPL3_MODE_SYNTH 0 /* OSS - voices allocated by application */ |
326 | #define SNDRV_OPL3_MODE_SEQ 1 /* ALSA - driver handles voice allocation */ | 324 | #define SNDRV_OPL3_MODE_SEQ 1 /* ALSA - driver handles voice allocation */ |
327 | int synth_mode; /* synth mode */ | 325 | int synth_mode; /* synth mode */ |
@@ -330,7 +328,7 @@ struct snd_opl3 { | |||
330 | struct snd_seq_device *seq_dev; /* sequencer device */ | 328 | struct snd_seq_device *seq_dev; /* sequencer device */ |
331 | struct snd_midi_channel_set * chset; | 329 | struct snd_midi_channel_set * chset; |
332 | 330 | ||
333 | #ifdef CONFIG_SND_SEQUENCER_OSS | 331 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
334 | struct snd_seq_device *oss_seq_dev; /* OSS sequencer device */ | 332 | struct snd_seq_device *oss_seq_dev; /* OSS sequencer device */ |
335 | struct snd_midi_channel_set * oss_chset; | 333 | struct snd_midi_channel_set * oss_chset; |
336 | #endif | 334 | #endif |
@@ -374,7 +372,7 @@ int snd_opl3_release(struct snd_hwdep * hw, struct file *file); | |||
374 | 372 | ||
375 | void snd_opl3_reset(struct snd_opl3 * opl3); | 373 | void snd_opl3_reset(struct snd_opl3 * opl3); |
376 | 374 | ||
377 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) | 375 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
378 | long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count, | 376 | long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count, |
379 | loff_t *offset); | 377 | loff_t *offset); |
380 | int snd_opl3_load_patch(struct snd_opl3 *opl3, | 378 | int snd_opl3_load_patch(struct snd_opl3 *opl3, |
diff --git a/include/sound/pcm-indirect.h b/include/sound/pcm-indirect.h index 1df7acaaa535..7ade285328cf 100644 --- a/include/sound/pcm-indirect.h +++ b/include/sound/pcm-indirect.h | |||
@@ -43,7 +43,7 @@ typedef void (*snd_pcm_indirect_copy_t)(struct snd_pcm_substream *substream, | |||
43 | /* | 43 | /* |
44 | * helper function for playback ack callback | 44 | * helper function for playback ack callback |
45 | */ | 45 | */ |
46 | static inline void | 46 | static inline int |
47 | snd_pcm_indirect_playback_transfer(struct snd_pcm_substream *substream, | 47 | snd_pcm_indirect_playback_transfer(struct snd_pcm_substream *substream, |
48 | struct snd_pcm_indirect *rec, | 48 | struct snd_pcm_indirect *rec, |
49 | snd_pcm_indirect_copy_t copy) | 49 | snd_pcm_indirect_copy_t copy) |
@@ -56,6 +56,8 @@ snd_pcm_indirect_playback_transfer(struct snd_pcm_substream *substream, | |||
56 | if (diff) { | 56 | if (diff) { |
57 | if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) | 57 | if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) |
58 | diff += runtime->boundary; | 58 | diff += runtime->boundary; |
59 | if (diff < 0) | ||
60 | return -EINVAL; | ||
59 | rec->sw_ready += (int)frames_to_bytes(runtime, diff); | 61 | rec->sw_ready += (int)frames_to_bytes(runtime, diff); |
60 | rec->appl_ptr = appl_ptr; | 62 | rec->appl_ptr = appl_ptr; |
61 | } | 63 | } |
@@ -82,6 +84,7 @@ snd_pcm_indirect_playback_transfer(struct snd_pcm_substream *substream, | |||
82 | rec->hw_ready += bytes; | 84 | rec->hw_ready += bytes; |
83 | rec->sw_ready -= bytes; | 85 | rec->sw_ready -= bytes; |
84 | } | 86 | } |
87 | return 0; | ||
85 | } | 88 | } |
86 | 89 | ||
87 | /* | 90 | /* |
@@ -109,7 +112,7 @@ snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream, | |||
109 | /* | 112 | /* |
110 | * helper function for capture ack callback | 113 | * helper function for capture ack callback |
111 | */ | 114 | */ |
112 | static inline void | 115 | static inline int |
113 | snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream, | 116 | snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream, |
114 | struct snd_pcm_indirect *rec, | 117 | struct snd_pcm_indirect *rec, |
115 | snd_pcm_indirect_copy_t copy) | 118 | snd_pcm_indirect_copy_t copy) |
@@ -121,6 +124,8 @@ snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream, | |||
121 | if (diff) { | 124 | if (diff) { |
122 | if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) | 125 | if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) |
123 | diff += runtime->boundary; | 126 | diff += runtime->boundary; |
127 | if (diff < 0) | ||
128 | return -EINVAL; | ||
124 | rec->sw_ready -= frames_to_bytes(runtime, diff); | 129 | rec->sw_ready -= frames_to_bytes(runtime, diff); |
125 | rec->appl_ptr = appl_ptr; | 130 | rec->appl_ptr = appl_ptr; |
126 | } | 131 | } |
@@ -147,6 +152,7 @@ snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream, | |||
147 | rec->hw_ready -= bytes; | 152 | rec->hw_ready -= bytes; |
148 | rec->sw_ready += bytes; | 153 | rec->sw_ready += bytes; |
149 | } | 154 | } |
155 | return 0; | ||
150 | } | 156 | } |
151 | 157 | ||
152 | /* | 158 | /* |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 361749e60799..5a22075c5fcf 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #define snd_pcm_substream_chip(substream) ((substream)->private_data) | 34 | #define snd_pcm_substream_chip(substream) ((substream)->private_data) |
35 | #define snd_pcm_chip(pcm) ((pcm)->private_data) | 35 | #define snd_pcm_chip(pcm) ((pcm)->private_data) |
36 | 36 | ||
37 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 37 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) |
38 | #include <sound/pcm_oss.h> | 38 | #include <sound/pcm_oss.h> |
39 | #endif | 39 | #endif |
40 | 40 | ||
@@ -78,11 +78,13 @@ struct snd_pcm_ops { | |||
78 | struct timespec *system_ts, struct timespec *audio_ts, | 78 | struct timespec *system_ts, struct timespec *audio_ts, |
79 | struct snd_pcm_audio_tstamp_config *audio_tstamp_config, | 79 | struct snd_pcm_audio_tstamp_config *audio_tstamp_config, |
80 | struct snd_pcm_audio_tstamp_report *audio_tstamp_report); | 80 | struct snd_pcm_audio_tstamp_report *audio_tstamp_report); |
81 | int (*copy)(struct snd_pcm_substream *substream, int channel, | 81 | int (*fill_silence)(struct snd_pcm_substream *substream, int channel, |
82 | snd_pcm_uframes_t pos, | 82 | unsigned long pos, unsigned long bytes); |
83 | void __user *buf, snd_pcm_uframes_t count); | 83 | int (*copy_user)(struct snd_pcm_substream *substream, int channel, |
84 | int (*silence)(struct snd_pcm_substream *substream, int channel, | 84 | unsigned long pos, void __user *buf, |
85 | snd_pcm_uframes_t pos, snd_pcm_uframes_t count); | 85 | unsigned long bytes); |
86 | int (*copy_kernel)(struct snd_pcm_substream *substream, int channel, | ||
87 | unsigned long pos, void *buf, unsigned long bytes); | ||
86 | struct page *(*page)(struct snd_pcm_substream *substream, | 88 | struct page *(*page)(struct snd_pcm_substream *substream, |
87 | unsigned long offset); | 89 | unsigned long offset); |
88 | int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma); | 90 | int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma); |
@@ -100,9 +102,9 @@ struct snd_pcm_ops { | |||
100 | #endif | 102 | #endif |
101 | 103 | ||
102 | #define SNDRV_PCM_IOCTL1_RESET 0 | 104 | #define SNDRV_PCM_IOCTL1_RESET 0 |
103 | #define SNDRV_PCM_IOCTL1_INFO 1 | 105 | /* 1 is absent slot. */ |
104 | #define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2 | 106 | #define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2 |
105 | #define SNDRV_PCM_IOCTL1_GSTATE 3 | 107 | /* 3 is absent slot. */ |
106 | #define SNDRV_PCM_IOCTL1_FIFO_SIZE 4 | 108 | #define SNDRV_PCM_IOCTL1_FIFO_SIZE 4 |
107 | 109 | ||
108 | #define SNDRV_PCM_TRIGGER_STOP 0 | 110 | #define SNDRV_PCM_TRIGGER_STOP 0 |
@@ -418,7 +420,7 @@ struct snd_pcm_runtime { | |||
418 | struct snd_pcm_audio_tstamp_report audio_tstamp_report; | 420 | struct snd_pcm_audio_tstamp_report audio_tstamp_report; |
419 | struct timespec driver_tstamp; | 421 | struct timespec driver_tstamp; |
420 | 422 | ||
421 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 423 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) |
422 | /* -- OSS things -- */ | 424 | /* -- OSS things -- */ |
423 | struct snd_pcm_oss_runtime oss; | 425 | struct snd_pcm_oss_runtime oss; |
424 | #endif | 426 | #endif |
@@ -464,7 +466,7 @@ struct snd_pcm_substream { | |||
464 | unsigned int f_flags; | 466 | unsigned int f_flags; |
465 | void (*pcm_release)(struct snd_pcm_substream *); | 467 | void (*pcm_release)(struct snd_pcm_substream *); |
466 | struct pid *pid; | 468 | struct pid *pid; |
467 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 469 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) |
468 | /* -- OSS things -- */ | 470 | /* -- OSS things -- */ |
469 | struct snd_pcm_oss_substream oss; | 471 | struct snd_pcm_oss_substream oss; |
470 | #endif | 472 | #endif |
@@ -494,7 +496,7 @@ struct snd_pcm_str { | |||
494 | unsigned int substream_count; | 496 | unsigned int substream_count; |
495 | unsigned int substream_opened; | 497 | unsigned int substream_opened; |
496 | struct snd_pcm_substream *substream; | 498 | struct snd_pcm_substream *substream; |
497 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 499 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) |
498 | /* -- OSS things -- */ | 500 | /* -- OSS things -- */ |
499 | struct snd_pcm_oss_stream oss; | 501 | struct snd_pcm_oss_stream oss; |
500 | #endif | 502 | #endif |
@@ -526,18 +528,11 @@ struct snd_pcm { | |||
526 | void (*private_free) (struct snd_pcm *pcm); | 528 | void (*private_free) (struct snd_pcm *pcm); |
527 | bool internal; /* pcm is for internal use only */ | 529 | bool internal; /* pcm is for internal use only */ |
528 | bool nonatomic; /* whole PCM operations are in non-atomic context */ | 530 | bool nonatomic; /* whole PCM operations are in non-atomic context */ |
529 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 531 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) |
530 | struct snd_pcm_oss oss; | 532 | struct snd_pcm_oss oss; |
531 | #endif | 533 | #endif |
532 | }; | 534 | }; |
533 | 535 | ||
534 | struct snd_pcm_notify { | ||
535 | int (*n_register) (struct snd_pcm * pcm); | ||
536 | int (*n_disconnect) (struct snd_pcm * pcm); | ||
537 | int (*n_unregister) (struct snd_pcm * pcm); | ||
538 | struct list_head list; | ||
539 | }; | ||
540 | |||
541 | /* | 536 | /* |
542 | * Registering | 537 | * Registering |
543 | */ | 538 | */ |
@@ -552,7 +547,15 @@ int snd_pcm_new_internal(struct snd_card *card, const char *id, int device, | |||
552 | struct snd_pcm **rpcm); | 547 | struct snd_pcm **rpcm); |
553 | int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count); | 548 | int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count); |
554 | 549 | ||
550 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) | ||
551 | struct snd_pcm_notify { | ||
552 | int (*n_register) (struct snd_pcm * pcm); | ||
553 | int (*n_disconnect) (struct snd_pcm * pcm); | ||
554 | int (*n_unregister) (struct snd_pcm * pcm); | ||
555 | struct list_head list; | ||
556 | }; | ||
555 | int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree); | 557 | int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree); |
558 | #endif | ||
556 | 559 | ||
557 | /* | 560 | /* |
558 | * Native I/O | 561 | * Native I/O |
@@ -968,12 +971,6 @@ static inline unsigned int params_buffer_bytes(const struct snd_pcm_hw_params *p | |||
968 | } | 971 | } |
969 | 972 | ||
970 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v); | 973 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v); |
971 | void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c); | ||
972 | void snd_interval_div(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c); | ||
973 | void snd_interval_muldivk(const struct snd_interval *a, const struct snd_interval *b, | ||
974 | unsigned int k, struct snd_interval *c); | ||
975 | void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k, | ||
976 | const struct snd_interval *b, struct snd_interval *c); | ||
977 | int snd_interval_list(struct snd_interval *i, unsigned int count, | 974 | int snd_interval_list(struct snd_interval *i, unsigned int count, |
978 | const unsigned int *list, unsigned int mask); | 975 | const unsigned int *list, unsigned int mask); |
979 | int snd_interval_ranges(struct snd_interval *i, unsigned int count, | 976 | int snd_interval_ranges(struct snd_interval *i, unsigned int count, |
@@ -984,15 +981,9 @@ int snd_interval_ratnum(struct snd_interval *i, | |||
984 | 981 | ||
985 | void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params); | 982 | void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params); |
986 | void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var); | 983 | void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var); |
987 | int snd_pcm_hw_params_choose(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); | ||
988 | 984 | ||
989 | int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); | 985 | int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); |
990 | 986 | ||
991 | int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream); | ||
992 | int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream); | ||
993 | |||
994 | int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, | ||
995 | u_int32_t mask); | ||
996 | int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, | 987 | int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, |
997 | u_int64_t mask); | 988 | u_int64_t mask); |
998 | int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, | 989 | int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, |
@@ -1054,7 +1045,7 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format); | |||
1054 | int snd_pcm_format_linear(snd_pcm_format_t format); | 1045 | int snd_pcm_format_linear(snd_pcm_format_t format); |
1055 | int snd_pcm_format_little_endian(snd_pcm_format_t format); | 1046 | int snd_pcm_format_little_endian(snd_pcm_format_t format); |
1056 | int snd_pcm_format_big_endian(snd_pcm_format_t format); | 1047 | int snd_pcm_format_big_endian(snd_pcm_format_t format); |
1057 | #if 0 /* just for DocBook */ | 1048 | #if 0 /* just for kernel-doc */ |
1058 | /** | 1049 | /** |
1059 | * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian | 1050 | * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian |
1060 | * @format: the format to check | 1051 | * @format: the format to check |
@@ -1080,22 +1071,66 @@ void snd_pcm_set_ops(struct snd_pcm * pcm, int direction, | |||
1080 | void snd_pcm_set_sync(struct snd_pcm_substream *substream); | 1071 | void snd_pcm_set_sync(struct snd_pcm_substream *substream); |
1081 | int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, | 1072 | int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, |
1082 | unsigned int cmd, void *arg); | 1073 | unsigned int cmd, void *arg); |
1083 | int snd_pcm_update_state(struct snd_pcm_substream *substream, | ||
1084 | struct snd_pcm_runtime *runtime); | ||
1085 | int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream); | ||
1086 | void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr); | ||
1087 | void snd_pcm_period_elapsed(struct snd_pcm_substream *substream); | 1074 | void snd_pcm_period_elapsed(struct snd_pcm_substream *substream); |
1088 | snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, | 1075 | snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, |
1089 | const void __user *buf, | 1076 | void *buf, bool interleaved, |
1090 | snd_pcm_uframes_t frames); | 1077 | snd_pcm_uframes_t frames, bool in_kernel); |
1091 | snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, | 1078 | |
1092 | void __user *buf, snd_pcm_uframes_t frames); | 1079 | static inline snd_pcm_sframes_t |
1093 | snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, | 1080 | snd_pcm_lib_write(struct snd_pcm_substream *substream, |
1094 | void __user **bufs, snd_pcm_uframes_t frames); | 1081 | const void __user *buf, snd_pcm_uframes_t frames) |
1095 | snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream, | 1082 | { |
1096 | void __user **bufs, snd_pcm_uframes_t frames); | 1083 | return __snd_pcm_lib_xfer(substream, (void *)buf, true, frames, false); |
1097 | 1084 | } | |
1098 | extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates; | 1085 | |
1086 | static inline snd_pcm_sframes_t | ||
1087 | snd_pcm_lib_read(struct snd_pcm_substream *substream, | ||
1088 | void __user *buf, snd_pcm_uframes_t frames) | ||
1089 | { | ||
1090 | return __snd_pcm_lib_xfer(substream, (void *)buf, true, frames, false); | ||
1091 | } | ||
1092 | |||
1093 | static inline snd_pcm_sframes_t | ||
1094 | snd_pcm_lib_writev(struct snd_pcm_substream *substream, | ||
1095 | void __user **bufs, snd_pcm_uframes_t frames) | ||
1096 | { | ||
1097 | return __snd_pcm_lib_xfer(substream, (void *)bufs, false, frames, false); | ||
1098 | } | ||
1099 | |||
1100 | static inline snd_pcm_sframes_t | ||
1101 | snd_pcm_lib_readv(struct snd_pcm_substream *substream, | ||
1102 | void __user **bufs, snd_pcm_uframes_t frames) | ||
1103 | { | ||
1104 | return __snd_pcm_lib_xfer(substream, (void *)bufs, false, frames, false); | ||
1105 | } | ||
1106 | |||
1107 | static inline snd_pcm_sframes_t | ||
1108 | snd_pcm_kernel_write(struct snd_pcm_substream *substream, | ||
1109 | const void *buf, snd_pcm_uframes_t frames) | ||
1110 | { | ||
1111 | return __snd_pcm_lib_xfer(substream, (void *)buf, true, frames, true); | ||
1112 | } | ||
1113 | |||
1114 | static inline snd_pcm_sframes_t | ||
1115 | snd_pcm_kernel_read(struct snd_pcm_substream *substream, | ||
1116 | void *buf, snd_pcm_uframes_t frames) | ||
1117 | { | ||
1118 | return __snd_pcm_lib_xfer(substream, buf, true, frames, true); | ||
1119 | } | ||
1120 | |||
1121 | static inline snd_pcm_sframes_t | ||
1122 | snd_pcm_kernel_writev(struct snd_pcm_substream *substream, | ||
1123 | void **bufs, snd_pcm_uframes_t frames) | ||
1124 | { | ||
1125 | return __snd_pcm_lib_xfer(substream, bufs, false, frames, true); | ||
1126 | } | ||
1127 | |||
1128 | static inline snd_pcm_sframes_t | ||
1129 | snd_pcm_kernel_readv(struct snd_pcm_substream *substream, | ||
1130 | void **bufs, snd_pcm_uframes_t frames) | ||
1131 | { | ||
1132 | return __snd_pcm_lib_xfer(substream, bufs, false, frames, true); | ||
1133 | } | ||
1099 | 1134 | ||
1100 | int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime); | 1135 | int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime); |
1101 | unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate); | 1136 | unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate); |
@@ -1130,20 +1165,6 @@ static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substrea | |||
1130 | } | 1165 | } |
1131 | } | 1166 | } |
1132 | 1167 | ||
1133 | /* | ||
1134 | * Timer interface | ||
1135 | */ | ||
1136 | |||
1137 | #ifdef CONFIG_SND_PCM_TIMER | ||
1138 | void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream); | ||
1139 | void snd_pcm_timer_init(struct snd_pcm_substream *substream); | ||
1140 | void snd_pcm_timer_done(struct snd_pcm_substream *substream); | ||
1141 | #else | ||
1142 | static inline void | ||
1143 | snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) {} | ||
1144 | static inline void snd_pcm_timer_init(struct snd_pcm_substream *substream) {} | ||
1145 | static inline void snd_pcm_timer_done(struct snd_pcm_substream *substream) {} | ||
1146 | #endif | ||
1147 | /** | 1168 | /** |
1148 | * snd_pcm_gettime - Fill the timespec depending on the timestamp mode | 1169 | * snd_pcm_gettime - Fill the timespec depending on the timestamp mode |
1149 | * @runtime: PCM runtime instance | 1170 | * @runtime: PCM runtime instance |
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index 492a3ca7f17b..6665cb29e1a2 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | #include <linux/device.h> | 31 | #include <linux/device.h> |
32 | 32 | ||
33 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) | 33 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
34 | #include <sound/seq_device.h> | 34 | #include <sound/seq_device.h> |
35 | #endif | 35 | #endif |
36 | 36 | ||
@@ -144,7 +144,7 @@ struct snd_rawmidi { | |||
144 | 144 | ||
145 | struct snd_info_entry *proc_entry; | 145 | struct snd_info_entry *proc_entry; |
146 | 146 | ||
147 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) | 147 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
148 | struct snd_seq_device *seq_dev; | 148 | struct snd_seq_device *seq_dev; |
149 | #endif | 149 | #endif |
150 | }; | 150 | }; |
diff --git a/sound/Kconfig b/sound/Kconfig index 6a215a8c0490..d7d2aac9542e 100644 --- a/sound/Kconfig +++ b/sound/Kconfig | |||
@@ -56,7 +56,7 @@ config SOUND_OSS_CORE_PRECLAIM | |||
56 | 56 | ||
57 | source "sound/oss/dmasound/Kconfig" | 57 | source "sound/oss/dmasound/Kconfig" |
58 | 58 | ||
59 | if !M68K && !UML | 59 | if !UML |
60 | 60 | ||
61 | menuconfig SND | 61 | menuconfig SND |
62 | tristate "Advanced Linux Sound Architecture" | 62 | tristate "Advanced Linux Sound Architecture" |
@@ -110,6 +110,8 @@ source "sound/soc/Kconfig" | |||
110 | 110 | ||
111 | source "sound/x86/Kconfig" | 111 | source "sound/x86/Kconfig" |
112 | 112 | ||
113 | source "sound/synth/Kconfig" | ||
114 | |||
113 | endif # SND | 115 | endif # SND |
114 | 116 | ||
115 | menuconfig SOUND_PRIME | 117 | menuconfig SOUND_PRIME |
@@ -125,7 +127,7 @@ source "sound/oss/Kconfig" | |||
125 | 127 | ||
126 | endif # SOUND_PRIME | 128 | endif # SOUND_PRIME |
127 | 129 | ||
128 | endif # !M68K | 130 | endif # !UML |
129 | 131 | ||
130 | endif # SOUND | 132 | endif # SOUND |
131 | 133 | ||
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index 78ed1ffbf786..733b6365dad6 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c | |||
@@ -271,7 +271,7 @@ static int tas_snd_vol_put(struct snd_kcontrol *kcontrol, | |||
271 | return 1; | 271 | return 1; |
272 | } | 272 | } |
273 | 273 | ||
274 | static struct snd_kcontrol_new volume_control = { | 274 | static const struct snd_kcontrol_new volume_control = { |
275 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 275 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
276 | .name = "Master Playback Volume", | 276 | .name = "Master Playback Volume", |
277 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 277 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -314,7 +314,7 @@ static int tas_snd_mute_put(struct snd_kcontrol *kcontrol, | |||
314 | return 1; | 314 | return 1; |
315 | } | 315 | } |
316 | 316 | ||
317 | static struct snd_kcontrol_new mute_control = { | 317 | static const struct snd_kcontrol_new mute_control = { |
318 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 318 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
319 | .name = "Master Playback Switch", | 319 | .name = "Master Playback Switch", |
320 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 320 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -426,7 +426,7 @@ static int tas_snd_drc_range_put(struct snd_kcontrol *kcontrol, | |||
426 | return 1; | 426 | return 1; |
427 | } | 427 | } |
428 | 428 | ||
429 | static struct snd_kcontrol_new drc_range_control = { | 429 | static const struct snd_kcontrol_new drc_range_control = { |
430 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 430 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
431 | .name = "DRC Range", | 431 | .name = "DRC Range", |
432 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 432 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -466,7 +466,7 @@ static int tas_snd_drc_switch_put(struct snd_kcontrol *kcontrol, | |||
466 | return 1; | 466 | return 1; |
467 | } | 467 | } |
468 | 468 | ||
469 | static struct snd_kcontrol_new drc_switch_control = { | 469 | static const struct snd_kcontrol_new drc_switch_control = { |
470 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 470 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
471 | .name = "DRC Range Switch", | 471 | .name = "DRC Range Switch", |
472 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 472 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -524,7 +524,7 @@ static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol, | |||
524 | return 1; | 524 | return 1; |
525 | } | 525 | } |
526 | 526 | ||
527 | static struct snd_kcontrol_new capture_source_control = { | 527 | static const struct snd_kcontrol_new capture_source_control = { |
528 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 528 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
529 | /* If we name this 'Input Source', it properly shows up in | 529 | /* If we name this 'Input Source', it properly shows up in |
530 | * alsamixer as a selection, * but it's shown under the | 530 | * alsamixer as a selection, * but it's shown under the |
@@ -586,7 +586,7 @@ static int tas_snd_treble_put(struct snd_kcontrol *kcontrol, | |||
586 | return 1; | 586 | return 1; |
587 | } | 587 | } |
588 | 588 | ||
589 | static struct snd_kcontrol_new treble_control = { | 589 | static const struct snd_kcontrol_new treble_control = { |
590 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 590 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
591 | .name = "Treble", | 591 | .name = "Treble", |
592 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 592 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -637,7 +637,7 @@ static int tas_snd_bass_put(struct snd_kcontrol *kcontrol, | |||
637 | return 1; | 637 | return 1; |
638 | } | 638 | } |
639 | 639 | ||
640 | static struct snd_kcontrol_new bass_control = { | 640 | static const struct snd_kcontrol_new bass_control = { |
641 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 641 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
642 | .name = "Bass", | 642 | .name = "Bass", |
643 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 643 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c index a0c4a5de809c..1eddf8fa188f 100644 --- a/sound/aoa/fabrics/layout.c +++ b/sound/aoa/fabrics/layout.c | |||
@@ -707,7 +707,7 @@ static int detect_choice_put(struct snd_kcontrol *kcontrol, | |||
707 | return 1; | 707 | return 1; |
708 | } | 708 | } |
709 | 709 | ||
710 | static struct snd_kcontrol_new headphone_detect_choice = { | 710 | static const struct snd_kcontrol_new headphone_detect_choice = { |
711 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 711 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
712 | .name = "Headphone Detect Autoswitch", | 712 | .name = "Headphone Detect Autoswitch", |
713 | .info = control_info, | 713 | .info = control_info, |
@@ -717,7 +717,7 @@ static struct snd_kcontrol_new headphone_detect_choice = { | |||
717 | .private_value = 0, | 717 | .private_value = 0, |
718 | }; | 718 | }; |
719 | 719 | ||
720 | static struct snd_kcontrol_new lineout_detect_choice = { | 720 | static const struct snd_kcontrol_new lineout_detect_choice = { |
721 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 721 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
722 | .name = "Line-Out Detect Autoswitch", | 722 | .name = "Line-Out Detect Autoswitch", |
723 | .info = control_info, | 723 | .info = control_info, |
@@ -749,7 +749,7 @@ static int detected_get(struct snd_kcontrol *kcontrol, | |||
749 | return 0; | 749 | return 0; |
750 | } | 750 | } |
751 | 751 | ||
752 | static struct snd_kcontrol_new headphone_detected = { | 752 | static const struct snd_kcontrol_new headphone_detected = { |
753 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 753 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
754 | .name = "Headphone Detected", | 754 | .name = "Headphone Detected", |
755 | .info = control_info, | 755 | .info = control_info, |
@@ -758,7 +758,7 @@ static struct snd_kcontrol_new headphone_detected = { | |||
758 | .private_value = 0, | 758 | .private_value = 0, |
759 | }; | 759 | }; |
760 | 760 | ||
761 | static struct snd_kcontrol_new lineout_detected = { | 761 | static const struct snd_kcontrol_new lineout_detected = { |
762 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 762 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
763 | .name = "Line-Out Detected", | 763 | .name = "Line-Out Detected", |
764 | .info = control_info, | 764 | .info = control_info, |
diff --git a/sound/atmel/Kconfig b/sound/atmel/Kconfig index 94de43a096f1..d789cbcb9106 100644 --- a/sound/atmel/Kconfig +++ b/sound/atmel/Kconfig | |||
@@ -1,18 +1,11 @@ | |||
1 | menu "Atmel devices (AVR32 and AT91)" | 1 | menu "Atmel devices (AT91)" |
2 | depends on AVR32 || ARCH_AT91 | 2 | depends on ARCH_AT91 |
3 | |||
4 | config SND_ATMEL_ABDAC | ||
5 | tristate "Atmel Audio Bitstream DAC (ABDAC) driver" | ||
6 | select SND_PCM | ||
7 | depends on DW_DMAC && AVR32 | ||
8 | help | ||
9 | ALSA sound driver for the Atmel Audio Bitstream DAC (ABDAC). | ||
10 | 3 | ||
11 | config SND_ATMEL_AC97C | 4 | config SND_ATMEL_AC97C |
12 | tristate "Atmel AC97 Controller (AC97C) driver" | 5 | tristate "Atmel AC97 Controller (AC97C) driver" |
13 | select SND_PCM | 6 | select SND_PCM |
14 | select SND_AC97_CODEC | 7 | select SND_AC97_CODEC |
15 | depends on (DW_DMAC && AVR32) || ARCH_AT91 | 8 | depends on ARCH_AT91 |
16 | help | 9 | help |
17 | ALSA sound driver for the Atmel AC97 controller. | 10 | ALSA sound driver for the Atmel AC97 controller. |
18 | 11 | ||
diff --git a/sound/atmel/Makefile b/sound/atmel/Makefile index 219dcfac6086..d4009d1430ed 100644 --- a/sound/atmel/Makefile +++ b/sound/atmel/Makefile | |||
@@ -1,5 +1,3 @@ | |||
1 | snd-atmel-abdac-objs := abdac.o | ||
2 | snd-atmel-ac97c-objs := ac97c.o | 1 | snd-atmel-ac97c-objs := ac97c.o |
3 | 2 | ||
4 | obj-$(CONFIG_SND_ATMEL_ABDAC) += snd-atmel-abdac.o | ||
5 | obj-$(CONFIG_SND_ATMEL_AC97C) += snd-atmel-ac97c.o | 3 | obj-$(CONFIG_SND_ATMEL_AC97C) += snd-atmel-ac97c.o |
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c deleted file mode 100644 index 558618802000..000000000000 --- a/sound/atmel/abdac.c +++ /dev/null | |||
@@ -1,610 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the Atmel on-chip Audio Bitstream DAC (ABDAC) | ||
3 | * | ||
4 | * Copyright (C) 2006-2009 Atmel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/clk.h> | ||
11 | #include <linux/bitmap.h> | ||
12 | #include <linux/dmaengine.h> | ||
13 | #include <linux/dma-mapping.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/io.h> | ||
20 | |||
21 | #include <sound/core.h> | ||
22 | #include <sound/initval.h> | ||
23 | #include <sound/pcm.h> | ||
24 | #include <sound/pcm_params.h> | ||
25 | #include <sound/atmel-abdac.h> | ||
26 | |||
27 | #include <linux/platform_data/dma-dw.h> | ||
28 | #include <linux/dma/dw.h> | ||
29 | |||
30 | /* DAC register offsets */ | ||
31 | #define DAC_DATA 0x0000 | ||
32 | #define DAC_CTRL 0x0008 | ||
33 | #define DAC_INT_MASK 0x000c | ||
34 | #define DAC_INT_EN 0x0010 | ||
35 | #define DAC_INT_DIS 0x0014 | ||
36 | #define DAC_INT_CLR 0x0018 | ||
37 | #define DAC_INT_STATUS 0x001c | ||
38 | |||
39 | /* Bitfields in CTRL */ | ||
40 | #define DAC_SWAP_OFFSET 30 | ||
41 | #define DAC_SWAP_SIZE 1 | ||
42 | #define DAC_EN_OFFSET 31 | ||
43 | #define DAC_EN_SIZE 1 | ||
44 | |||
45 | /* Bitfields in INT_MASK/INT_EN/INT_DIS/INT_STATUS/INT_CLR */ | ||
46 | #define DAC_UNDERRUN_OFFSET 28 | ||
47 | #define DAC_UNDERRUN_SIZE 1 | ||
48 | #define DAC_TX_READY_OFFSET 29 | ||
49 | #define DAC_TX_READY_SIZE 1 | ||
50 | |||
51 | /* Bit manipulation macros */ | ||
52 | #define DAC_BIT(name) \ | ||
53 | (1 << DAC_##name##_OFFSET) | ||
54 | #define DAC_BF(name, value) \ | ||
55 | (((value) & ((1 << DAC_##name##_SIZE) - 1)) \ | ||
56 | << DAC_##name##_OFFSET) | ||
57 | #define DAC_BFEXT(name, value) \ | ||
58 | (((value) >> DAC_##name##_OFFSET) \ | ||
59 | & ((1 << DAC_##name##_SIZE) - 1)) | ||
60 | #define DAC_BFINS(name, value, old) \ | ||
61 | (((old) & ~(((1 << DAC_##name##_SIZE) - 1) \ | ||
62 | << DAC_##name##_OFFSET)) \ | ||
63 | | DAC_BF(name, value)) | ||
64 | |||
65 | /* Register access macros */ | ||
66 | #define dac_readl(port, reg) \ | ||
67 | __raw_readl((port)->regs + DAC_##reg) | ||
68 | #define dac_writel(port, reg, value) \ | ||
69 | __raw_writel((value), (port)->regs + DAC_##reg) | ||
70 | |||
71 | /* | ||
72 | * ABDAC supports a maximum of 6 different rates from a generic clock. The | ||
73 | * generic clock has a power of two divider, which gives 6 steps from 192 kHz | ||
74 | * to 5112 Hz. | ||
75 | */ | ||
76 | #define MAX_NUM_RATES 6 | ||
77 | /* ALSA seems to use rates between 192000 Hz and 5112 Hz. */ | ||
78 | #define RATE_MAX 192000 | ||
79 | #define RATE_MIN 5112 | ||
80 | |||
81 | enum { | ||
82 | DMA_READY = 0, | ||
83 | }; | ||
84 | |||
85 | struct atmel_abdac_dma { | ||
86 | struct dma_chan *chan; | ||
87 | struct dw_cyclic_desc *cdesc; | ||
88 | }; | ||
89 | |||
90 | struct atmel_abdac { | ||
91 | struct clk *pclk; | ||
92 | struct clk *sample_clk; | ||
93 | struct platform_device *pdev; | ||
94 | struct atmel_abdac_dma dma; | ||
95 | |||
96 | struct snd_pcm_hw_constraint_list constraints_rates; | ||
97 | struct snd_pcm_substream *substream; | ||
98 | struct snd_card *card; | ||
99 | struct snd_pcm *pcm; | ||
100 | |||
101 | void __iomem *regs; | ||
102 | unsigned long flags; | ||
103 | unsigned int rates[MAX_NUM_RATES]; | ||
104 | unsigned int rates_num; | ||
105 | int irq; | ||
106 | }; | ||
107 | |||
108 | #define get_dac(card) ((struct atmel_abdac *)(card)->private_data) | ||
109 | |||
110 | /* This function is called by the DMA driver. */ | ||
111 | static void atmel_abdac_dma_period_done(void *arg) | ||
112 | { | ||
113 | struct atmel_abdac *dac = arg; | ||
114 | snd_pcm_period_elapsed(dac->substream); | ||
115 | } | ||
116 | |||
117 | static int atmel_abdac_prepare_dma(struct atmel_abdac *dac, | ||
118 | struct snd_pcm_substream *substream, | ||
119 | enum dma_data_direction direction) | ||
120 | { | ||
121 | struct dma_chan *chan = dac->dma.chan; | ||
122 | struct dw_cyclic_desc *cdesc; | ||
123 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
124 | unsigned long buffer_len, period_len; | ||
125 | |||
126 | /* | ||
127 | * We don't do DMA on "complex" transfers, i.e. with | ||
128 | * non-halfword-aligned buffers or lengths. | ||
129 | */ | ||
130 | if (runtime->dma_addr & 1 || runtime->buffer_size & 1) { | ||
131 | dev_dbg(&dac->pdev->dev, "too complex transfer\n"); | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | |||
135 | buffer_len = frames_to_bytes(runtime, runtime->buffer_size); | ||
136 | period_len = frames_to_bytes(runtime, runtime->period_size); | ||
137 | |||
138 | cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len, | ||
139 | period_len, DMA_MEM_TO_DEV); | ||
140 | if (IS_ERR(cdesc)) { | ||
141 | dev_dbg(&dac->pdev->dev, "could not prepare cyclic DMA\n"); | ||
142 | return PTR_ERR(cdesc); | ||
143 | } | ||
144 | |||
145 | cdesc->period_callback = atmel_abdac_dma_period_done; | ||
146 | cdesc->period_callback_param = dac; | ||
147 | |||
148 | dac->dma.cdesc = cdesc; | ||
149 | |||
150 | set_bit(DMA_READY, &dac->flags); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static struct snd_pcm_hardware atmel_abdac_hw = { | ||
156 | .info = (SNDRV_PCM_INFO_MMAP | ||
157 | | SNDRV_PCM_INFO_MMAP_VALID | ||
158 | | SNDRV_PCM_INFO_INTERLEAVED | ||
159 | | SNDRV_PCM_INFO_BLOCK_TRANSFER | ||
160 | | SNDRV_PCM_INFO_RESUME | ||
161 | | SNDRV_PCM_INFO_PAUSE), | ||
162 | .formats = (SNDRV_PCM_FMTBIT_S16_BE), | ||
163 | .rates = (SNDRV_PCM_RATE_KNOT), | ||
164 | .rate_min = RATE_MIN, | ||
165 | .rate_max = RATE_MAX, | ||
166 | .channels_min = 2, | ||
167 | .channels_max = 2, | ||
168 | .buffer_bytes_max = 64 * 4096, | ||
169 | .period_bytes_min = 4096, | ||
170 | .period_bytes_max = 4096, | ||
171 | .periods_min = 6, | ||
172 | .periods_max = 64, | ||
173 | }; | ||
174 | |||
175 | static int atmel_abdac_open(struct snd_pcm_substream *substream) | ||
176 | { | ||
177 | struct atmel_abdac *dac = snd_pcm_substream_chip(substream); | ||
178 | |||
179 | dac->substream = substream; | ||
180 | atmel_abdac_hw.rate_max = dac->rates[dac->rates_num - 1]; | ||
181 | atmel_abdac_hw.rate_min = dac->rates[0]; | ||
182 | substream->runtime->hw = atmel_abdac_hw; | ||
183 | |||
184 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
185 | SNDRV_PCM_HW_PARAM_RATE, &dac->constraints_rates); | ||
186 | } | ||
187 | |||
188 | static int atmel_abdac_close(struct snd_pcm_substream *substream) | ||
189 | { | ||
190 | struct atmel_abdac *dac = snd_pcm_substream_chip(substream); | ||
191 | dac->substream = NULL; | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int atmel_abdac_hw_params(struct snd_pcm_substream *substream, | ||
196 | struct snd_pcm_hw_params *hw_params) | ||
197 | { | ||
198 | struct atmel_abdac *dac = snd_pcm_substream_chip(substream); | ||
199 | int retval; | ||
200 | |||
201 | retval = snd_pcm_lib_malloc_pages(substream, | ||
202 | params_buffer_bytes(hw_params)); | ||
203 | if (retval < 0) | ||
204 | return retval; | ||
205 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | ||
206 | if (retval == 1) | ||
207 | if (test_and_clear_bit(DMA_READY, &dac->flags)) | ||
208 | dw_dma_cyclic_free(dac->dma.chan); | ||
209 | |||
210 | return retval; | ||
211 | } | ||
212 | |||
213 | static int atmel_abdac_hw_free(struct snd_pcm_substream *substream) | ||
214 | { | ||
215 | struct atmel_abdac *dac = snd_pcm_substream_chip(substream); | ||
216 | if (test_and_clear_bit(DMA_READY, &dac->flags)) | ||
217 | dw_dma_cyclic_free(dac->dma.chan); | ||
218 | return snd_pcm_lib_free_pages(substream); | ||
219 | } | ||
220 | |||
221 | static int atmel_abdac_prepare(struct snd_pcm_substream *substream) | ||
222 | { | ||
223 | struct atmel_abdac *dac = snd_pcm_substream_chip(substream); | ||
224 | int retval; | ||
225 | |||
226 | retval = clk_set_rate(dac->sample_clk, 256 * substream->runtime->rate); | ||
227 | if (retval) | ||
228 | return retval; | ||
229 | |||
230 | if (!test_bit(DMA_READY, &dac->flags)) | ||
231 | retval = atmel_abdac_prepare_dma(dac, substream, DMA_TO_DEVICE); | ||
232 | |||
233 | return retval; | ||
234 | } | ||
235 | |||
236 | static int atmel_abdac_trigger(struct snd_pcm_substream *substream, int cmd) | ||
237 | { | ||
238 | struct atmel_abdac *dac = snd_pcm_substream_chip(substream); | ||
239 | int retval = 0; | ||
240 | |||
241 | switch (cmd) { | ||
242 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | ||
243 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | ||
244 | case SNDRV_PCM_TRIGGER_START: | ||
245 | clk_prepare_enable(dac->sample_clk); | ||
246 | retval = dw_dma_cyclic_start(dac->dma.chan); | ||
247 | if (retval) | ||
248 | goto out; | ||
249 | dac_writel(dac, CTRL, DAC_BIT(EN)); | ||
250 | break; | ||
251 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ | ||
252 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ | ||
253 | case SNDRV_PCM_TRIGGER_STOP: | ||
254 | dw_dma_cyclic_stop(dac->dma.chan); | ||
255 | dac_writel(dac, DATA, 0); | ||
256 | dac_writel(dac, CTRL, 0); | ||
257 | clk_disable_unprepare(dac->sample_clk); | ||
258 | break; | ||
259 | default: | ||
260 | retval = -EINVAL; | ||
261 | break; | ||
262 | } | ||
263 | out: | ||
264 | return retval; | ||
265 | } | ||
266 | |||
267 | static snd_pcm_uframes_t | ||
268 | atmel_abdac_pointer(struct snd_pcm_substream *substream) | ||
269 | { | ||
270 | struct atmel_abdac *dac = snd_pcm_substream_chip(substream); | ||
271 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
272 | snd_pcm_uframes_t frames; | ||
273 | unsigned long bytes; | ||
274 | |||
275 | bytes = dw_dma_get_src_addr(dac->dma.chan); | ||
276 | bytes -= runtime->dma_addr; | ||
277 | |||
278 | frames = bytes_to_frames(runtime, bytes); | ||
279 | if (frames >= runtime->buffer_size) | ||
280 | frames -= runtime->buffer_size; | ||
281 | |||
282 | return frames; | ||
283 | } | ||
284 | |||
285 | static irqreturn_t abdac_interrupt(int irq, void *dev_id) | ||
286 | { | ||
287 | struct atmel_abdac *dac = dev_id; | ||
288 | u32 status; | ||
289 | |||
290 | status = dac_readl(dac, INT_STATUS); | ||
291 | if (status & DAC_BIT(UNDERRUN)) { | ||
292 | dev_err(&dac->pdev->dev, "underrun detected\n"); | ||
293 | dac_writel(dac, INT_CLR, DAC_BIT(UNDERRUN)); | ||
294 | } else { | ||
295 | dev_err(&dac->pdev->dev, "spurious interrupt (status=0x%x)\n", | ||
296 | status); | ||
297 | dac_writel(dac, INT_CLR, status); | ||
298 | } | ||
299 | |||
300 | return IRQ_HANDLED; | ||
301 | } | ||
302 | |||
303 | static struct snd_pcm_ops atmel_abdac_ops = { | ||
304 | .open = atmel_abdac_open, | ||
305 | .close = atmel_abdac_close, | ||
306 | .ioctl = snd_pcm_lib_ioctl, | ||
307 | .hw_params = atmel_abdac_hw_params, | ||
308 | .hw_free = atmel_abdac_hw_free, | ||
309 | .prepare = atmel_abdac_prepare, | ||
310 | .trigger = atmel_abdac_trigger, | ||
311 | .pointer = atmel_abdac_pointer, | ||
312 | }; | ||
313 | |||
314 | static int atmel_abdac_pcm_new(struct atmel_abdac *dac) | ||
315 | { | ||
316 | struct snd_pcm_hardware hw = atmel_abdac_hw; | ||
317 | struct snd_pcm *pcm; | ||
318 | int retval; | ||
319 | |||
320 | retval = snd_pcm_new(dac->card, dac->card->shortname, | ||
321 | dac->pdev->id, 1, 0, &pcm); | ||
322 | if (retval) | ||
323 | return retval; | ||
324 | |||
325 | strcpy(pcm->name, dac->card->shortname); | ||
326 | pcm->private_data = dac; | ||
327 | pcm->info_flags = 0; | ||
328 | dac->pcm = pcm; | ||
329 | |||
330 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &atmel_abdac_ops); | ||
331 | |||
332 | retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
333 | &dac->pdev->dev, hw.periods_min * hw.period_bytes_min, | ||
334 | hw.buffer_bytes_max); | ||
335 | |||
336 | return retval; | ||
337 | } | ||
338 | |||
339 | static bool filter(struct dma_chan *chan, void *slave) | ||
340 | { | ||
341 | struct dw_dma_slave *dws = slave; | ||
342 | |||
343 | if (dws->dma_dev == chan->device->dev) { | ||
344 | chan->private = dws; | ||
345 | return true; | ||
346 | } else | ||
347 | return false; | ||
348 | } | ||
349 | |||
350 | static int set_sample_rates(struct atmel_abdac *dac) | ||
351 | { | ||
352 | long new_rate = RATE_MAX; | ||
353 | int retval = -EINVAL; | ||
354 | int index = 0; | ||
355 | |||
356 | /* we start at 192 kHz and work our way down to 5112 Hz */ | ||
357 | while (new_rate >= RATE_MIN && index < (MAX_NUM_RATES + 1)) { | ||
358 | new_rate = clk_round_rate(dac->sample_clk, 256 * new_rate); | ||
359 | if (new_rate <= 0) | ||
360 | break; | ||
361 | /* make sure we are below the ABDAC clock */ | ||
362 | if (index < MAX_NUM_RATES && | ||
363 | new_rate <= clk_get_rate(dac->pclk)) { | ||
364 | dac->rates[index] = new_rate / 256; | ||
365 | index++; | ||
366 | } | ||
367 | /* divide by 256 and then by two to get next rate */ | ||
368 | new_rate /= 256 * 2; | ||
369 | } | ||
370 | |||
371 | if (index) { | ||
372 | int i; | ||
373 | |||
374 | /* reverse array, smallest go first */ | ||
375 | for (i = 0; i < (index / 2); i++) { | ||
376 | unsigned int tmp = dac->rates[index - 1 - i]; | ||
377 | dac->rates[index - 1 - i] = dac->rates[i]; | ||
378 | dac->rates[i] = tmp; | ||
379 | } | ||
380 | |||
381 | dac->constraints_rates.count = index; | ||
382 | dac->constraints_rates.list = dac->rates; | ||
383 | dac->constraints_rates.mask = 0; | ||
384 | dac->rates_num = index; | ||
385 | |||
386 | retval = 0; | ||
387 | } | ||
388 | |||
389 | return retval; | ||
390 | } | ||
391 | |||
392 | static int atmel_abdac_probe(struct platform_device *pdev) | ||
393 | { | ||
394 | struct snd_card *card; | ||
395 | struct atmel_abdac *dac; | ||
396 | struct resource *regs; | ||
397 | struct atmel_abdac_pdata *pdata; | ||
398 | struct clk *pclk; | ||
399 | struct clk *sample_clk; | ||
400 | int retval; | ||
401 | int irq; | ||
402 | |||
403 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
404 | if (!regs) { | ||
405 | dev_dbg(&pdev->dev, "no memory resource\n"); | ||
406 | return -ENXIO; | ||
407 | } | ||
408 | |||
409 | irq = platform_get_irq(pdev, 0); | ||
410 | if (irq < 0) { | ||
411 | dev_dbg(&pdev->dev, "could not get IRQ number\n"); | ||
412 | return irq; | ||
413 | } | ||
414 | |||
415 | pdata = pdev->dev.platform_data; | ||
416 | if (!pdata) { | ||
417 | dev_dbg(&pdev->dev, "no platform data\n"); | ||
418 | return -ENXIO; | ||
419 | } | ||
420 | |||
421 | pclk = clk_get(&pdev->dev, "pclk"); | ||
422 | if (IS_ERR(pclk)) { | ||
423 | dev_dbg(&pdev->dev, "no peripheral clock\n"); | ||
424 | return PTR_ERR(pclk); | ||
425 | } | ||
426 | sample_clk = clk_get(&pdev->dev, "sample_clk"); | ||
427 | if (IS_ERR(sample_clk)) { | ||
428 | dev_dbg(&pdev->dev, "no sample clock\n"); | ||
429 | retval = PTR_ERR(sample_clk); | ||
430 | goto out_put_pclk; | ||
431 | } | ||
432 | clk_prepare_enable(pclk); | ||
433 | |||
434 | retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, | ||
435 | SNDRV_DEFAULT_STR1, THIS_MODULE, | ||
436 | sizeof(struct atmel_abdac), &card); | ||
437 | if (retval) { | ||
438 | dev_dbg(&pdev->dev, "could not create sound card device\n"); | ||
439 | goto out_put_sample_clk; | ||
440 | } | ||
441 | |||
442 | dac = get_dac(card); | ||
443 | |||
444 | dac->irq = irq; | ||
445 | dac->card = card; | ||
446 | dac->pclk = pclk; | ||
447 | dac->sample_clk = sample_clk; | ||
448 | dac->pdev = pdev; | ||
449 | |||
450 | retval = set_sample_rates(dac); | ||
451 | if (retval < 0) { | ||
452 | dev_dbg(&pdev->dev, "could not set supported rates\n"); | ||
453 | goto out_free_card; | ||
454 | } | ||
455 | |||
456 | dac->regs = ioremap(regs->start, resource_size(regs)); | ||
457 | if (!dac->regs) { | ||
458 | dev_dbg(&pdev->dev, "could not remap register memory\n"); | ||
459 | retval = -ENOMEM; | ||
460 | goto out_free_card; | ||
461 | } | ||
462 | |||
463 | /* make sure the DAC is silent and disabled */ | ||
464 | dac_writel(dac, DATA, 0); | ||
465 | dac_writel(dac, CTRL, 0); | ||
466 | |||
467 | retval = request_irq(irq, abdac_interrupt, 0, "abdac", dac); | ||
468 | if (retval) { | ||
469 | dev_dbg(&pdev->dev, "could not request irq\n"); | ||
470 | goto out_unmap_regs; | ||
471 | } | ||
472 | |||
473 | if (pdata->dws.dma_dev) { | ||
474 | dma_cap_mask_t mask; | ||
475 | |||
476 | dma_cap_zero(mask); | ||
477 | dma_cap_set(DMA_SLAVE, mask); | ||
478 | |||
479 | dac->dma.chan = dma_request_channel(mask, filter, &pdata->dws); | ||
480 | if (dac->dma.chan) { | ||
481 | struct dma_slave_config dma_conf = { | ||
482 | .dst_addr = regs->start + DAC_DATA, | ||
483 | .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, | ||
484 | .src_maxburst = 1, | ||
485 | .dst_maxburst = 1, | ||
486 | .direction = DMA_MEM_TO_DEV, | ||
487 | .device_fc = false, | ||
488 | }; | ||
489 | |||
490 | dmaengine_slave_config(dac->dma.chan, &dma_conf); | ||
491 | } | ||
492 | } | ||
493 | if (!pdata->dws.dma_dev || !dac->dma.chan) { | ||
494 | dev_dbg(&pdev->dev, "DMA not available\n"); | ||
495 | retval = -ENODEV; | ||
496 | goto out_unmap_regs; | ||
497 | } | ||
498 | |||
499 | strcpy(card->driver, "Atmel ABDAC"); | ||
500 | strcpy(card->shortname, "Atmel ABDAC"); | ||
501 | sprintf(card->longname, "Atmel Audio Bitstream DAC"); | ||
502 | |||
503 | retval = atmel_abdac_pcm_new(dac); | ||
504 | if (retval) { | ||
505 | dev_dbg(&pdev->dev, "could not register ABDAC pcm device\n"); | ||
506 | goto out_release_dma; | ||
507 | } | ||
508 | |||
509 | retval = snd_card_register(card); | ||
510 | if (retval) { | ||
511 | dev_dbg(&pdev->dev, "could not register sound card\n"); | ||
512 | goto out_release_dma; | ||
513 | } | ||
514 | |||
515 | platform_set_drvdata(pdev, card); | ||
516 | |||
517 | dev_info(&pdev->dev, "Atmel ABDAC at 0x%p using %s\n", | ||
518 | dac->regs, dev_name(&dac->dma.chan->dev->device)); | ||
519 | |||
520 | return retval; | ||
521 | |||
522 | out_release_dma: | ||
523 | dma_release_channel(dac->dma.chan); | ||
524 | dac->dma.chan = NULL; | ||
525 | out_unmap_regs: | ||
526 | iounmap(dac->regs); | ||
527 | out_free_card: | ||
528 | snd_card_free(card); | ||
529 | out_put_sample_clk: | ||
530 | clk_put(sample_clk); | ||
531 | clk_disable_unprepare(pclk); | ||
532 | out_put_pclk: | ||
533 | clk_put(pclk); | ||
534 | return retval; | ||
535 | } | ||
536 | |||
537 | #ifdef CONFIG_PM_SLEEP | ||
538 | static int atmel_abdac_suspend(struct device *pdev) | ||
539 | { | ||
540 | struct snd_card *card = dev_get_drvdata(pdev); | ||
541 | struct atmel_abdac *dac = card->private_data; | ||
542 | |||
543 | dw_dma_cyclic_stop(dac->dma.chan); | ||
544 | clk_disable_unprepare(dac->sample_clk); | ||
545 | clk_disable_unprepare(dac->pclk); | ||
546 | |||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | static int atmel_abdac_resume(struct device *pdev) | ||
551 | { | ||
552 | struct snd_card *card = dev_get_drvdata(pdev); | ||
553 | struct atmel_abdac *dac = card->private_data; | ||
554 | |||
555 | clk_prepare_enable(dac->pclk); | ||
556 | clk_prepare_enable(dac->sample_clk); | ||
557 | if (test_bit(DMA_READY, &dac->flags)) | ||
558 | dw_dma_cyclic_start(dac->dma.chan); | ||
559 | |||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static SIMPLE_DEV_PM_OPS(atmel_abdac_pm, atmel_abdac_suspend, atmel_abdac_resume); | ||
564 | #define ATMEL_ABDAC_PM_OPS &atmel_abdac_pm | ||
565 | #else | ||
566 | #define ATMEL_ABDAC_PM_OPS NULL | ||
567 | #endif | ||
568 | |||
569 | static int atmel_abdac_remove(struct platform_device *pdev) | ||
570 | { | ||
571 | struct snd_card *card = platform_get_drvdata(pdev); | ||
572 | struct atmel_abdac *dac = get_dac(card); | ||
573 | |||
574 | clk_put(dac->sample_clk); | ||
575 | clk_disable_unprepare(dac->pclk); | ||
576 | clk_put(dac->pclk); | ||
577 | |||
578 | dma_release_channel(dac->dma.chan); | ||
579 | dac->dma.chan = NULL; | ||
580 | iounmap(dac->regs); | ||
581 | free_irq(dac->irq, dac); | ||
582 | snd_card_free(card); | ||
583 | |||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | static struct platform_driver atmel_abdac_driver = { | ||
588 | .remove = atmel_abdac_remove, | ||
589 | .driver = { | ||
590 | .name = "atmel_abdac", | ||
591 | .pm = ATMEL_ABDAC_PM_OPS, | ||
592 | }, | ||
593 | }; | ||
594 | |||
595 | static int __init atmel_abdac_init(void) | ||
596 | { | ||
597 | return platform_driver_probe(&atmel_abdac_driver, | ||
598 | atmel_abdac_probe); | ||
599 | } | ||
600 | module_init(atmel_abdac_init); | ||
601 | |||
602 | static void __exit atmel_abdac_exit(void) | ||
603 | { | ||
604 | platform_driver_unregister(&atmel_abdac_driver); | ||
605 | } | ||
606 | module_exit(atmel_abdac_exit); | ||
607 | |||
608 | MODULE_LICENSE("GPL"); | ||
609 | MODULE_DESCRIPTION("Driver for Atmel Audio Bitstream DAC (ABDAC)"); | ||
610 | MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); | ||
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 6dad042630d8..65e6948e3995 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c | |||
@@ -11,8 +11,6 @@ | |||
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/bitmap.h> | 12 | #include <linux/bitmap.h> |
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/dmaengine.h> | ||
15 | #include <linux/dma-mapping.h> | ||
16 | #include <linux/atmel_pdc.h> | 14 | #include <linux/atmel_pdc.h> |
17 | #include <linux/init.h> | 15 | #include <linux/init.h> |
18 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
@@ -34,36 +32,14 @@ | |||
34 | #include <sound/atmel-ac97c.h> | 32 | #include <sound/atmel-ac97c.h> |
35 | #include <sound/memalloc.h> | 33 | #include <sound/memalloc.h> |
36 | 34 | ||
37 | #include <linux/platform_data/dma-dw.h> | ||
38 | #include <linux/dma/dw.h> | ||
39 | |||
40 | #ifdef CONFIG_AVR32 | ||
41 | #include <mach/cpu.h> | ||
42 | #else | ||
43 | #define cpu_is_at32ap7000() 0 | ||
44 | #endif | ||
45 | |||
46 | #include "ac97c.h" | 35 | #include "ac97c.h" |
47 | 36 | ||
48 | enum { | ||
49 | DMA_TX_READY = 0, | ||
50 | DMA_RX_READY, | ||
51 | DMA_TX_CHAN_PRESENT, | ||
52 | DMA_RX_CHAN_PRESENT, | ||
53 | }; | ||
54 | |||
55 | /* Serialize access to opened variable */ | 37 | /* Serialize access to opened variable */ |
56 | static DEFINE_MUTEX(opened_mutex); | 38 | static DEFINE_MUTEX(opened_mutex); |
57 | 39 | ||
58 | struct atmel_ac97c_dma { | ||
59 | struct dma_chan *rx_chan; | ||
60 | struct dma_chan *tx_chan; | ||
61 | }; | ||
62 | |||
63 | struct atmel_ac97c { | 40 | struct atmel_ac97c { |
64 | struct clk *pclk; | 41 | struct clk *pclk; |
65 | struct platform_device *pdev; | 42 | struct platform_device *pdev; |
66 | struct atmel_ac97c_dma dma; | ||
67 | 43 | ||
68 | struct snd_pcm_substream *playback_substream; | 44 | struct snd_pcm_substream *playback_substream; |
69 | struct snd_pcm_substream *capture_substream; | 45 | struct snd_pcm_substream *capture_substream; |
@@ -74,7 +50,6 @@ struct atmel_ac97c { | |||
74 | 50 | ||
75 | u64 cur_format; | 51 | u64 cur_format; |
76 | unsigned int cur_rate; | 52 | unsigned int cur_rate; |
77 | unsigned long flags; | ||
78 | int playback_period, capture_period; | 53 | int playback_period, capture_period; |
79 | /* Serialize access to opened variable */ | 54 | /* Serialize access to opened variable */ |
80 | spinlock_t lock; | 55 | spinlock_t lock; |
@@ -91,65 +66,6 @@ struct atmel_ac97c { | |||
91 | #define ac97c_readl(chip, reg) \ | 66 | #define ac97c_readl(chip, reg) \ |
92 | __raw_readl((chip)->regs + AC97C_##reg) | 67 | __raw_readl((chip)->regs + AC97C_##reg) |
93 | 68 | ||
94 | /* This function is called by the DMA driver. */ | ||
95 | static void atmel_ac97c_dma_playback_period_done(void *arg) | ||
96 | { | ||
97 | struct atmel_ac97c *chip = arg; | ||
98 | snd_pcm_period_elapsed(chip->playback_substream); | ||
99 | } | ||
100 | |||
101 | static void atmel_ac97c_dma_capture_period_done(void *arg) | ||
102 | { | ||
103 | struct atmel_ac97c *chip = arg; | ||
104 | snd_pcm_period_elapsed(chip->capture_substream); | ||
105 | } | ||
106 | |||
107 | static int atmel_ac97c_prepare_dma(struct atmel_ac97c *chip, | ||
108 | struct snd_pcm_substream *substream, | ||
109 | enum dma_transfer_direction direction) | ||
110 | { | ||
111 | struct dma_chan *chan; | ||
112 | struct dw_cyclic_desc *cdesc; | ||
113 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
114 | unsigned long buffer_len, period_len; | ||
115 | |||
116 | /* | ||
117 | * We don't do DMA on "complex" transfers, i.e. with | ||
118 | * non-halfword-aligned buffers or lengths. | ||
119 | */ | ||
120 | if (runtime->dma_addr & 1 || runtime->buffer_size & 1) { | ||
121 | dev_dbg(&chip->pdev->dev, "too complex transfer\n"); | ||
122 | return -EINVAL; | ||
123 | } | ||
124 | |||
125 | if (direction == DMA_MEM_TO_DEV) | ||
126 | chan = chip->dma.tx_chan; | ||
127 | else | ||
128 | chan = chip->dma.rx_chan; | ||
129 | |||
130 | buffer_len = frames_to_bytes(runtime, runtime->buffer_size); | ||
131 | period_len = frames_to_bytes(runtime, runtime->period_size); | ||
132 | |||
133 | cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len, | ||
134 | period_len, direction); | ||
135 | if (IS_ERR(cdesc)) { | ||
136 | dev_dbg(&chip->pdev->dev, "could not prepare cyclic DMA\n"); | ||
137 | return PTR_ERR(cdesc); | ||
138 | } | ||
139 | |||
140 | if (direction == DMA_MEM_TO_DEV) { | ||
141 | cdesc->period_callback = atmel_ac97c_dma_playback_period_done; | ||
142 | set_bit(DMA_TX_READY, &chip->flags); | ||
143 | } else { | ||
144 | cdesc->period_callback = atmel_ac97c_dma_capture_period_done; | ||
145 | set_bit(DMA_RX_READY, &chip->flags); | ||
146 | } | ||
147 | |||
148 | cdesc->period_callback_param = chip; | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static struct snd_pcm_hardware atmel_ac97c_hw = { | 69 | static struct snd_pcm_hardware atmel_ac97c_hw = { |
154 | .info = (SNDRV_PCM_INFO_MMAP | 70 | .info = (SNDRV_PCM_INFO_MMAP |
155 | | SNDRV_PCM_INFO_MMAP_VALID | 71 | | SNDRV_PCM_INFO_MMAP_VALID |
@@ -254,13 +170,7 @@ static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream, | |||
254 | params_buffer_bytes(hw_params)); | 170 | params_buffer_bytes(hw_params)); |
255 | if (retval < 0) | 171 | if (retval < 0) |
256 | return retval; | 172 | return retval; |
257 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | 173 | |
258 | if (cpu_is_at32ap7000()) { | ||
259 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | ||
260 | if (retval == 1) | ||
261 | if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) | ||
262 | dw_dma_cyclic_free(chip->dma.tx_chan); | ||
263 | } | ||
264 | /* Set restrictions to params. */ | 174 | /* Set restrictions to params. */ |
265 | mutex_lock(&opened_mutex); | 175 | mutex_lock(&opened_mutex); |
266 | chip->cur_rate = params_rate(hw_params); | 176 | chip->cur_rate = params_rate(hw_params); |
@@ -280,10 +190,6 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream, | |||
280 | params_buffer_bytes(hw_params)); | 190 | params_buffer_bytes(hw_params)); |
281 | if (retval < 0) | 191 | if (retval < 0) |
282 | return retval; | 192 | return retval; |
283 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | ||
284 | if (cpu_is_at32ap7000() && retval == 1) | ||
285 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) | ||
286 | dw_dma_cyclic_free(chip->dma.rx_chan); | ||
287 | 193 | ||
288 | /* Set restrictions to params. */ | 194 | /* Set restrictions to params. */ |
289 | mutex_lock(&opened_mutex); | 195 | mutex_lock(&opened_mutex); |
@@ -294,26 +200,6 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream, | |||
294 | return retval; | 200 | return retval; |
295 | } | 201 | } |
296 | 202 | ||
297 | static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream) | ||
298 | { | ||
299 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | ||
300 | if (cpu_is_at32ap7000()) { | ||
301 | if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) | ||
302 | dw_dma_cyclic_free(chip->dma.tx_chan); | ||
303 | } | ||
304 | return snd_pcm_lib_free_pages(substream); | ||
305 | } | ||
306 | |||
307 | static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream) | ||
308 | { | ||
309 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | ||
310 | if (cpu_is_at32ap7000()) { | ||
311 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) | ||
312 | dw_dma_cyclic_free(chip->dma.rx_chan); | ||
313 | } | ||
314 | return snd_pcm_lib_free_pages(substream); | ||
315 | } | ||
316 | |||
317 | static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) | 203 | static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) |
318 | { | 204 | { |
319 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | 205 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); |
@@ -349,8 +235,6 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) | |||
349 | 235 | ||
350 | switch (runtime->format) { | 236 | switch (runtime->format) { |
351 | case SNDRV_PCM_FORMAT_S16_LE: | 237 | case SNDRV_PCM_FORMAT_S16_LE: |
352 | if (cpu_is_at32ap7000()) | ||
353 | word |= AC97C_CMR_CEM_LITTLE; | ||
354 | break; | 238 | break; |
355 | case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ | 239 | case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ |
356 | word &= ~(AC97C_CMR_CEM_LITTLE); | 240 | word &= ~(AC97C_CMR_CEM_LITTLE); |
@@ -389,18 +273,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) | |||
389 | dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", | 273 | dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", |
390 | runtime->rate); | 274 | runtime->rate); |
391 | 275 | ||
392 | if (cpu_is_at32ap7000()) { | 276 | /* Initialize and start the PDC */ |
393 | if (!test_bit(DMA_TX_READY, &chip->flags)) | 277 | writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR); |
394 | retval = atmel_ac97c_prepare_dma(chip, substream, | 278 | writel(block_size / 2, chip->regs + ATMEL_PDC_TCR); |
395 | DMA_MEM_TO_DEV); | 279 | writel(runtime->dma_addr + block_size, chip->regs + ATMEL_PDC_TNPR); |
396 | } else { | 280 | writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR); |
397 | /* Initialize and start the PDC */ | ||
398 | writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR); | ||
399 | writel(block_size / 2, chip->regs + ATMEL_PDC_TCR); | ||
400 | writel(runtime->dma_addr + block_size, | ||
401 | chip->regs + ATMEL_PDC_TNPR); | ||
402 | writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR); | ||
403 | } | ||
404 | 281 | ||
405 | return retval; | 282 | return retval; |
406 | } | 283 | } |
@@ -440,8 +317,6 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) | |||
440 | 317 | ||
441 | switch (runtime->format) { | 318 | switch (runtime->format) { |
442 | case SNDRV_PCM_FORMAT_S16_LE: | 319 | case SNDRV_PCM_FORMAT_S16_LE: |
443 | if (cpu_is_at32ap7000()) | ||
444 | word |= AC97C_CMR_CEM_LITTLE; | ||
445 | break; | 320 | break; |
446 | case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ | 321 | case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ |
447 | word &= ~(AC97C_CMR_CEM_LITTLE); | 322 | word &= ~(AC97C_CMR_CEM_LITTLE); |
@@ -480,18 +355,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) | |||
480 | dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", | 355 | dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", |
481 | runtime->rate); | 356 | runtime->rate); |
482 | 357 | ||
483 | if (cpu_is_at32ap7000()) { | 358 | /* Initialize and start the PDC */ |
484 | if (!test_bit(DMA_RX_READY, &chip->flags)) | 359 | writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR); |
485 | retval = atmel_ac97c_prepare_dma(chip, substream, | 360 | writel(block_size / 2, chip->regs + ATMEL_PDC_RCR); |
486 | DMA_DEV_TO_MEM); | 361 | writel(runtime->dma_addr + block_size, chip->regs + ATMEL_PDC_RNPR); |
487 | } else { | 362 | writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR); |
488 | /* Initialize and start the PDC */ | ||
489 | writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR); | ||
490 | writel(block_size / 2, chip->regs + ATMEL_PDC_RCR); | ||
491 | writel(runtime->dma_addr + block_size, | ||
492 | chip->regs + ATMEL_PDC_RNPR); | ||
493 | writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR); | ||
494 | } | ||
495 | 363 | ||
496 | return retval; | 364 | return retval; |
497 | } | 365 | } |
@@ -501,7 +369,6 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) | |||
501 | { | 369 | { |
502 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | 370 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); |
503 | unsigned long camr, ptcr = 0; | 371 | unsigned long camr, ptcr = 0; |
504 | int retval = 0; | ||
505 | 372 | ||
506 | camr = ac97c_readl(chip, CAMR); | 373 | camr = ac97c_readl(chip, CAMR); |
507 | 374 | ||
@@ -509,35 +376,23 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) | |||
509 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | 376 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ |
510 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | 377 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ |
511 | case SNDRV_PCM_TRIGGER_START: | 378 | case SNDRV_PCM_TRIGGER_START: |
512 | if (cpu_is_at32ap7000()) { | 379 | ptcr = ATMEL_PDC_TXTEN; |
513 | retval = dw_dma_cyclic_start(chip->dma.tx_chan); | ||
514 | if (retval) | ||
515 | goto out; | ||
516 | } else { | ||
517 | ptcr = ATMEL_PDC_TXTEN; | ||
518 | } | ||
519 | camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX; | 380 | camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX; |
520 | break; | 381 | break; |
521 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ | 382 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ |
522 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ | 383 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ |
523 | case SNDRV_PCM_TRIGGER_STOP: | 384 | case SNDRV_PCM_TRIGGER_STOP: |
524 | if (cpu_is_at32ap7000()) | 385 | ptcr |= ATMEL_PDC_TXTDIS; |
525 | dw_dma_cyclic_stop(chip->dma.tx_chan); | ||
526 | else | ||
527 | ptcr |= ATMEL_PDC_TXTDIS; | ||
528 | if (chip->opened <= 1) | 386 | if (chip->opened <= 1) |
529 | camr &= ~AC97C_CMR_CENA; | 387 | camr &= ~AC97C_CMR_CENA; |
530 | break; | 388 | break; |
531 | default: | 389 | default: |
532 | retval = -EINVAL; | 390 | return -EINVAL; |
533 | goto out; | ||
534 | } | 391 | } |
535 | 392 | ||
536 | ac97c_writel(chip, CAMR, camr); | 393 | ac97c_writel(chip, CAMR, camr); |
537 | if (!cpu_is_at32ap7000()) | 394 | writel(ptcr, chip->regs + ATMEL_PDC_PTCR); |
538 | writel(ptcr, chip->regs + ATMEL_PDC_PTCR); | 395 | return 0; |
539 | out: | ||
540 | return retval; | ||
541 | } | 396 | } |
542 | 397 | ||
543 | static int | 398 | static int |
@@ -545,7 +400,6 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) | |||
545 | { | 400 | { |
546 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); | 401 | struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); |
547 | unsigned long camr, ptcr = 0; | 402 | unsigned long camr, ptcr = 0; |
548 | int retval = 0; | ||
549 | 403 | ||
550 | camr = ac97c_readl(chip, CAMR); | 404 | camr = ac97c_readl(chip, CAMR); |
551 | ptcr = readl(chip->regs + ATMEL_PDC_PTSR); | 405 | ptcr = readl(chip->regs + ATMEL_PDC_PTSR); |
@@ -554,35 +408,23 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) | |||
554 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | 408 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ |
555 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | 409 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ |
556 | case SNDRV_PCM_TRIGGER_START: | 410 | case SNDRV_PCM_TRIGGER_START: |
557 | if (cpu_is_at32ap7000()) { | 411 | ptcr = ATMEL_PDC_RXTEN; |
558 | retval = dw_dma_cyclic_start(chip->dma.rx_chan); | ||
559 | if (retval) | ||
560 | goto out; | ||
561 | } else { | ||
562 | ptcr = ATMEL_PDC_RXTEN; | ||
563 | } | ||
564 | camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX; | 412 | camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX; |
565 | break; | 413 | break; |
566 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ | 414 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ |
567 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ | 415 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ |
568 | case SNDRV_PCM_TRIGGER_STOP: | 416 | case SNDRV_PCM_TRIGGER_STOP: |
569 | if (cpu_is_at32ap7000()) | 417 | ptcr |= ATMEL_PDC_RXTDIS; |
570 | dw_dma_cyclic_stop(chip->dma.rx_chan); | ||
571 | else | ||
572 | ptcr |= (ATMEL_PDC_RXTDIS); | ||
573 | if (chip->opened <= 1) | 418 | if (chip->opened <= 1) |
574 | camr &= ~AC97C_CMR_CENA; | 419 | camr &= ~AC97C_CMR_CENA; |
575 | break; | 420 | break; |
576 | default: | 421 | default: |
577 | retval = -EINVAL; | 422 | return -EINVAL; |
578 | break; | ||
579 | } | 423 | } |
580 | 424 | ||
581 | ac97c_writel(chip, CAMR, camr); | 425 | ac97c_writel(chip, CAMR, camr); |
582 | if (!cpu_is_at32ap7000()) | 426 | writel(ptcr, chip->regs + ATMEL_PDC_PTCR); |
583 | writel(ptcr, chip->regs + ATMEL_PDC_PTCR); | 427 | return 0; |
584 | out: | ||
585 | return retval; | ||
586 | } | 428 | } |
587 | 429 | ||
588 | static snd_pcm_uframes_t | 430 | static snd_pcm_uframes_t |
@@ -593,10 +435,7 @@ atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream) | |||
593 | snd_pcm_uframes_t frames; | 435 | snd_pcm_uframes_t frames; |
594 | unsigned long bytes; | 436 | unsigned long bytes; |
595 | 437 | ||
596 | if (cpu_is_at32ap7000()) | 438 | bytes = readl(chip->regs + ATMEL_PDC_TPR); |
597 | bytes = dw_dma_get_src_addr(chip->dma.tx_chan); | ||
598 | else | ||
599 | bytes = readl(chip->regs + ATMEL_PDC_TPR); | ||
600 | bytes -= runtime->dma_addr; | 439 | bytes -= runtime->dma_addr; |
601 | 440 | ||
602 | frames = bytes_to_frames(runtime, bytes); | 441 | frames = bytes_to_frames(runtime, bytes); |
@@ -613,10 +452,7 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream) | |||
613 | snd_pcm_uframes_t frames; | 452 | snd_pcm_uframes_t frames; |
614 | unsigned long bytes; | 453 | unsigned long bytes; |
615 | 454 | ||
616 | if (cpu_is_at32ap7000()) | 455 | bytes = readl(chip->regs + ATMEL_PDC_RPR); |
617 | bytes = dw_dma_get_dst_addr(chip->dma.rx_chan); | ||
618 | else | ||
619 | bytes = readl(chip->regs + ATMEL_PDC_RPR); | ||
620 | bytes -= runtime->dma_addr; | 456 | bytes -= runtime->dma_addr; |
621 | 457 | ||
622 | frames = bytes_to_frames(runtime, bytes); | 458 | frames = bytes_to_frames(runtime, bytes); |
@@ -630,7 +466,7 @@ static struct snd_pcm_ops atmel_ac97_playback_ops = { | |||
630 | .close = atmel_ac97c_playback_close, | 466 | .close = atmel_ac97c_playback_close, |
631 | .ioctl = snd_pcm_lib_ioctl, | 467 | .ioctl = snd_pcm_lib_ioctl, |
632 | .hw_params = atmel_ac97c_playback_hw_params, | 468 | .hw_params = atmel_ac97c_playback_hw_params, |
633 | .hw_free = atmel_ac97c_playback_hw_free, | 469 | .hw_free = snd_pcm_lib_free_pages, |
634 | .prepare = atmel_ac97c_playback_prepare, | 470 | .prepare = atmel_ac97c_playback_prepare, |
635 | .trigger = atmel_ac97c_playback_trigger, | 471 | .trigger = atmel_ac97c_playback_trigger, |
636 | .pointer = atmel_ac97c_playback_pointer, | 472 | .pointer = atmel_ac97c_playback_pointer, |
@@ -641,7 +477,7 @@ static struct snd_pcm_ops atmel_ac97_capture_ops = { | |||
641 | .close = atmel_ac97c_capture_close, | 477 | .close = atmel_ac97c_capture_close, |
642 | .ioctl = snd_pcm_lib_ioctl, | 478 | .ioctl = snd_pcm_lib_ioctl, |
643 | .hw_params = atmel_ac97c_capture_hw_params, | 479 | .hw_params = atmel_ac97c_capture_hw_params, |
644 | .hw_free = atmel_ac97c_capture_hw_free, | 480 | .hw_free = snd_pcm_lib_free_pages, |
645 | .prepare = atmel_ac97c_capture_prepare, | 481 | .prepare = atmel_ac97c_capture_prepare, |
646 | .trigger = atmel_ac97c_capture_trigger, | 482 | .trigger = atmel_ac97c_capture_trigger, |
647 | .pointer = atmel_ac97c_capture_pointer, | 483 | .pointer = atmel_ac97c_capture_pointer, |
@@ -666,49 +502,40 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) | |||
666 | casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", | 502 | casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", |
667 | casr & AC97C_CSR_TXRDY ? " TXRDY" : "", | 503 | casr & AC97C_CSR_TXRDY ? " TXRDY" : "", |
668 | !casr ? " NONE" : ""); | 504 | !casr ? " NONE" : ""); |
669 | if (!cpu_is_at32ap7000()) { | 505 | if ((casr & camr) & AC97C_CSR_ENDTX) { |
670 | if ((casr & camr) & AC97C_CSR_ENDTX) { | 506 | runtime = chip->playback_substream->runtime; |
671 | runtime = chip->playback_substream->runtime; | 507 | block_size = frames_to_bytes(runtime, runtime->period_size); |
672 | block_size = frames_to_bytes(runtime, | 508 | chip->playback_period++; |
673 | runtime->period_size); | 509 | |
674 | chip->playback_period++; | 510 | if (chip->playback_period == runtime->periods) |
675 | 511 | chip->playback_period = 0; | |
676 | if (chip->playback_period == runtime->periods) | 512 | next_period = chip->playback_period + 1; |
677 | chip->playback_period = 0; | 513 | if (next_period == runtime->periods) |
678 | next_period = chip->playback_period + 1; | 514 | next_period = 0; |
679 | if (next_period == runtime->periods) | 515 | |
680 | next_period = 0; | 516 | offset = block_size * next_period; |
681 | 517 | ||
682 | offset = block_size * next_period; | 518 | writel(runtime->dma_addr + offset, chip->regs + ATMEL_PDC_TNPR); |
683 | 519 | writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR); | |
684 | writel(runtime->dma_addr + offset, | 520 | |
685 | chip->regs + ATMEL_PDC_TNPR); | 521 | snd_pcm_period_elapsed(chip->playback_substream); |
686 | writel(block_size / 2, | 522 | } |
687 | chip->regs + ATMEL_PDC_TNCR); | 523 | if ((casr & camr) & AC97C_CSR_ENDRX) { |
688 | 524 | runtime = chip->capture_substream->runtime; | |
689 | snd_pcm_period_elapsed( | 525 | block_size = frames_to_bytes(runtime, runtime->period_size); |
690 | chip->playback_substream); | 526 | chip->capture_period++; |
691 | } | 527 | |
692 | if ((casr & camr) & AC97C_CSR_ENDRX) { | 528 | if (chip->capture_period == runtime->periods) |
693 | runtime = chip->capture_substream->runtime; | 529 | chip->capture_period = 0; |
694 | block_size = frames_to_bytes(runtime, | 530 | next_period = chip->capture_period + 1; |
695 | runtime->period_size); | 531 | if (next_period == runtime->periods) |
696 | chip->capture_period++; | 532 | next_period = 0; |
697 | 533 | ||
698 | if (chip->capture_period == runtime->periods) | 534 | offset = block_size * next_period; |
699 | chip->capture_period = 0; | 535 | |
700 | next_period = chip->capture_period + 1; | 536 | writel(runtime->dma_addr + offset, chip->regs + ATMEL_PDC_RNPR); |
701 | if (next_period == runtime->periods) | 537 | writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR); |
702 | next_period = 0; | 538 | snd_pcm_period_elapsed(chip->capture_substream); |
703 | |||
704 | offset = block_size * next_period; | ||
705 | |||
706 | writel(runtime->dma_addr + offset, | ||
707 | chip->regs + ATMEL_PDC_RNPR); | ||
708 | writel(block_size / 2, | ||
709 | chip->regs + ATMEL_PDC_RNCR); | ||
710 | snd_pcm_period_elapsed(chip->capture_substream); | ||
711 | } | ||
712 | } | 539 | } |
713 | retval = IRQ_HANDLED; | 540 | retval = IRQ_HANDLED; |
714 | } | 541 | } |
@@ -763,29 +590,20 @@ static int atmel_ac97c_pcm_new(struct atmel_ac97c *chip) | |||
763 | { | 590 | { |
764 | struct snd_pcm *pcm; | 591 | struct snd_pcm *pcm; |
765 | struct snd_pcm_hardware hw = atmel_ac97c_hw; | 592 | struct snd_pcm_hardware hw = atmel_ac97c_hw; |
766 | int capture, playback, retval, err; | 593 | int retval; |
767 | 594 | ||
768 | capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | 595 | retval = snd_ac97_pcm_assign(chip->ac97_bus, |
769 | playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | 596 | ARRAY_SIZE(at91_ac97_pcm_defs), |
597 | at91_ac97_pcm_defs); | ||
598 | if (retval) | ||
599 | return retval; | ||
770 | 600 | ||
771 | if (!cpu_is_at32ap7000()) { | 601 | retval = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm); |
772 | err = snd_ac97_pcm_assign(chip->ac97_bus, | ||
773 | ARRAY_SIZE(at91_ac97_pcm_defs), | ||
774 | at91_ac97_pcm_defs); | ||
775 | if (err) | ||
776 | return err; | ||
777 | } | ||
778 | retval = snd_pcm_new(chip->card, chip->card->shortname, | ||
779 | 0, playback, capture, &pcm); | ||
780 | if (retval) | 602 | if (retval) |
781 | return retval; | 603 | return retval; |
782 | 604 | ||
783 | if (capture) | 605 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &atmel_ac97_capture_ops); |
784 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | 606 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &atmel_ac97_playback_ops); |
785 | &atmel_ac97_capture_ops); | ||
786 | if (playback) | ||
787 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, | ||
788 | &atmel_ac97_playback_ops); | ||
789 | 607 | ||
790 | retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 608 | retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
791 | &chip->pdev->dev, hw.periods_min * hw.period_bytes_min, | 609 | &chip->pdev->dev, hw.periods_min * hw.period_bytes_min, |
@@ -875,17 +693,6 @@ timed_out: | |||
875 | return 0xffff; | 693 | return 0xffff; |
876 | } | 694 | } |
877 | 695 | ||
878 | static bool filter(struct dma_chan *chan, void *slave) | ||
879 | { | ||
880 | struct dw_dma_slave *dws = slave; | ||
881 | |||
882 | if (dws->dma_dev == chan->device->dev) { | ||
883 | chan->private = dws; | ||
884 | return true; | ||
885 | } else | ||
886 | return false; | ||
887 | } | ||
888 | |||
889 | static void atmel_ac97c_reset(struct atmel_ac97c *chip) | 696 | static void atmel_ac97c_reset(struct atmel_ac97c *chip) |
890 | { | 697 | { |
891 | ac97c_writel(chip, MR, 0); | 698 | ac97c_writel(chip, MR, 0); |
@@ -971,12 +778,7 @@ static int atmel_ac97c_probe(struct platform_device *pdev) | |||
971 | return -ENXIO; | 778 | return -ENXIO; |
972 | } | 779 | } |
973 | 780 | ||
974 | if (cpu_is_at32ap7000()) { | 781 | pclk = clk_get(&pdev->dev, "ac97_clk"); |
975 | pclk = clk_get(&pdev->dev, "pclk"); | ||
976 | } else { | ||
977 | pclk = clk_get(&pdev->dev, "ac97_clk"); | ||
978 | } | ||
979 | |||
980 | if (IS_ERR(pclk)) { | 782 | if (IS_ERR(pclk)) { |
981 | dev_dbg(&pdev->dev, "no peripheral clock\n"); | 783 | dev_dbg(&pdev->dev, "no peripheral clock\n"); |
982 | return PTR_ERR(pclk); | 784 | return PTR_ERR(pclk); |
@@ -1047,88 +849,16 @@ static int atmel_ac97c_probe(struct platform_device *pdev) | |||
1047 | goto err_ac97_bus; | 849 | goto err_ac97_bus; |
1048 | } | 850 | } |
1049 | 851 | ||
1050 | if (cpu_is_at32ap7000()) { | ||
1051 | if (pdata->rx_dws.dma_dev) { | ||
1052 | dma_cap_mask_t mask; | ||
1053 | |||
1054 | dma_cap_zero(mask); | ||
1055 | dma_cap_set(DMA_SLAVE, mask); | ||
1056 | |||
1057 | chip->dma.rx_chan = dma_request_channel(mask, filter, | ||
1058 | &pdata->rx_dws); | ||
1059 | if (chip->dma.rx_chan) { | ||
1060 | struct dma_slave_config dma_conf = { | ||
1061 | .src_addr = regs->start + AC97C_CARHR + | ||
1062 | 2, | ||
1063 | .src_addr_width = | ||
1064 | DMA_SLAVE_BUSWIDTH_2_BYTES, | ||
1065 | .src_maxburst = 1, | ||
1066 | .dst_maxburst = 1, | ||
1067 | .direction = DMA_DEV_TO_MEM, | ||
1068 | .device_fc = false, | ||
1069 | }; | ||
1070 | |||
1071 | dmaengine_slave_config(chip->dma.rx_chan, | ||
1072 | &dma_conf); | ||
1073 | } | ||
1074 | |||
1075 | dev_info(&chip->pdev->dev, "using %s for DMA RX\n", | ||
1076 | dev_name(&chip->dma.rx_chan->dev->device)); | ||
1077 | set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | ||
1078 | } | ||
1079 | |||
1080 | if (pdata->tx_dws.dma_dev) { | ||
1081 | dma_cap_mask_t mask; | ||
1082 | |||
1083 | dma_cap_zero(mask); | ||
1084 | dma_cap_set(DMA_SLAVE, mask); | ||
1085 | |||
1086 | chip->dma.tx_chan = dma_request_channel(mask, filter, | ||
1087 | &pdata->tx_dws); | ||
1088 | if (chip->dma.tx_chan) { | ||
1089 | struct dma_slave_config dma_conf = { | ||
1090 | .dst_addr = regs->start + AC97C_CATHR + | ||
1091 | 2, | ||
1092 | .dst_addr_width = | ||
1093 | DMA_SLAVE_BUSWIDTH_2_BYTES, | ||
1094 | .src_maxburst = 1, | ||
1095 | .dst_maxburst = 1, | ||
1096 | .direction = DMA_MEM_TO_DEV, | ||
1097 | .device_fc = false, | ||
1098 | }; | ||
1099 | |||
1100 | dmaengine_slave_config(chip->dma.tx_chan, | ||
1101 | &dma_conf); | ||
1102 | } | ||
1103 | |||
1104 | dev_info(&chip->pdev->dev, "using %s for DMA TX\n", | ||
1105 | dev_name(&chip->dma.tx_chan->dev->device)); | ||
1106 | set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | ||
1107 | } | ||
1108 | |||
1109 | if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) && | ||
1110 | !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) { | ||
1111 | dev_dbg(&pdev->dev, "DMA not available\n"); | ||
1112 | retval = -ENODEV; | ||
1113 | goto err_dma; | ||
1114 | } | ||
1115 | } else { | ||
1116 | /* Just pretend that we have DMA channel(for at91 i is actually | ||
1117 | * the PDC) */ | ||
1118 | set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | ||
1119 | set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | ||
1120 | } | ||
1121 | |||
1122 | retval = atmel_ac97c_pcm_new(chip); | 852 | retval = atmel_ac97c_pcm_new(chip); |
1123 | if (retval) { | 853 | if (retval) { |
1124 | dev_dbg(&pdev->dev, "could not register ac97 pcm device\n"); | 854 | dev_dbg(&pdev->dev, "could not register ac97 pcm device\n"); |
1125 | goto err_dma; | 855 | goto err_ac97_bus; |
1126 | } | 856 | } |
1127 | 857 | ||
1128 | retval = snd_card_register(card); | 858 | retval = snd_card_register(card); |
1129 | if (retval) { | 859 | if (retval) { |
1130 | dev_dbg(&pdev->dev, "could not register sound card\n"); | 860 | dev_dbg(&pdev->dev, "could not register sound card\n"); |
1131 | goto err_dma; | 861 | goto err_ac97_bus; |
1132 | } | 862 | } |
1133 | 863 | ||
1134 | platform_set_drvdata(pdev, card); | 864 | platform_set_drvdata(pdev, card); |
@@ -1138,17 +868,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev) | |||
1138 | 868 | ||
1139 | return 0; | 869 | return 0; |
1140 | 870 | ||
1141 | err_dma: | ||
1142 | if (cpu_is_at32ap7000()) { | ||
1143 | if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) | ||
1144 | dma_release_channel(chip->dma.rx_chan); | ||
1145 | if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) | ||
1146 | dma_release_channel(chip->dma.tx_chan); | ||
1147 | clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | ||
1148 | clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | ||
1149 | chip->dma.rx_chan = NULL; | ||
1150 | chip->dma.tx_chan = NULL; | ||
1151 | } | ||
1152 | err_ac97_bus: | 871 | err_ac97_bus: |
1153 | if (gpio_is_valid(chip->reset_pin)) | 872 | if (gpio_is_valid(chip->reset_pin)) |
1154 | gpio_free(chip->reset_pin); | 873 | gpio_free(chip->reset_pin); |
@@ -1170,14 +889,7 @@ static int atmel_ac97c_suspend(struct device *pdev) | |||
1170 | struct snd_card *card = dev_get_drvdata(pdev); | 889 | struct snd_card *card = dev_get_drvdata(pdev); |
1171 | struct atmel_ac97c *chip = card->private_data; | 890 | struct atmel_ac97c *chip = card->private_data; |
1172 | 891 | ||
1173 | if (cpu_is_at32ap7000()) { | ||
1174 | if (test_bit(DMA_RX_READY, &chip->flags)) | ||
1175 | dw_dma_cyclic_stop(chip->dma.rx_chan); | ||
1176 | if (test_bit(DMA_TX_READY, &chip->flags)) | ||
1177 | dw_dma_cyclic_stop(chip->dma.tx_chan); | ||
1178 | } | ||
1179 | clk_disable_unprepare(chip->pclk); | 892 | clk_disable_unprepare(chip->pclk); |
1180 | |||
1181 | return 0; | 893 | return 0; |
1182 | } | 894 | } |
1183 | 895 | ||
@@ -1187,12 +899,6 @@ static int atmel_ac97c_resume(struct device *pdev) | |||
1187 | struct atmel_ac97c *chip = card->private_data; | 899 | struct atmel_ac97c *chip = card->private_data; |
1188 | 900 | ||
1189 | clk_prepare_enable(chip->pclk); | 901 | clk_prepare_enable(chip->pclk); |
1190 | if (cpu_is_at32ap7000()) { | ||
1191 | if (test_bit(DMA_RX_READY, &chip->flags)) | ||
1192 | dw_dma_cyclic_start(chip->dma.rx_chan); | ||
1193 | if (test_bit(DMA_TX_READY, &chip->flags)) | ||
1194 | dw_dma_cyclic_start(chip->dma.tx_chan); | ||
1195 | } | ||
1196 | return 0; | 902 | return 0; |
1197 | } | 903 | } |
1198 | 904 | ||
@@ -1219,17 +925,6 @@ static int atmel_ac97c_remove(struct platform_device *pdev) | |||
1219 | iounmap(chip->regs); | 925 | iounmap(chip->regs); |
1220 | free_irq(chip->irq, chip); | 926 | free_irq(chip->irq, chip); |
1221 | 927 | ||
1222 | if (cpu_is_at32ap7000()) { | ||
1223 | if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) | ||
1224 | dma_release_channel(chip->dma.rx_chan); | ||
1225 | if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) | ||
1226 | dma_release_channel(chip->dma.tx_chan); | ||
1227 | clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); | ||
1228 | clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); | ||
1229 | chip->dma.rx_chan = NULL; | ||
1230 | chip->dma.tx_chan = NULL; | ||
1231 | } | ||
1232 | |||
1233 | snd_card_free(card); | 928 | snd_card_free(card); |
1234 | 929 | ||
1235 | return 0; | 930 | return 0; |
diff --git a/sound/core/Kconfig b/sound/core/Kconfig index 9749f9e8b45c..6e937a8146a1 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig | |||
@@ -18,8 +18,12 @@ config SND_DMAENGINE_PCM | |||
18 | config SND_HWDEP | 18 | config SND_HWDEP |
19 | tristate | 19 | tristate |
20 | 20 | ||
21 | config SND_SEQ_DEVICE | ||
22 | tristate | ||
23 | |||
21 | config SND_RAWMIDI | 24 | config SND_RAWMIDI |
22 | tristate | 25 | tristate |
26 | select SND_SEQ_DEVICE if SND_SEQUENCER != n | ||
23 | 27 | ||
24 | config SND_COMPRESS_OFFLOAD | 28 | config SND_COMPRESS_OFFLOAD |
25 | tristate | 29 | tristate |
@@ -33,38 +37,15 @@ config SND_JACK_INPUT_DEV | |||
33 | depends on SND_JACK | 37 | depends on SND_JACK |
34 | default y if INPUT=y || INPUT=SND | 38 | default y if INPUT=y || INPUT=SND |
35 | 39 | ||
36 | config SND_SEQUENCER | ||
37 | tristate "Sequencer support" | ||
38 | select SND_TIMER | ||
39 | help | ||
40 | Say Y or M to enable MIDI sequencer and router support. This | ||
41 | feature allows routing and enqueueing of MIDI events. Events | ||
42 | can be processed at a given time. | ||
43 | |||
44 | Many programs require this feature, so you should enable it | ||
45 | unless you know what you're doing. | ||
46 | |||
47 | config SND_SEQ_DUMMY | ||
48 | tristate "Sequencer dummy client" | ||
49 | depends on SND_SEQUENCER | ||
50 | help | ||
51 | Say Y here to enable the dummy sequencer client. This client | ||
52 | is a simple MIDI-through client: all normal input events are | ||
53 | redirected to the output port immediately. | ||
54 | |||
55 | You don't need this unless you want to connect many MIDI | ||
56 | devices or applications together. | ||
57 | |||
58 | To compile this driver as a module, choose M here: the module | ||
59 | will be called snd-seq-dummy. | ||
60 | |||
61 | config SND_OSSEMUL | 40 | config SND_OSSEMUL |
41 | bool "Enable OSS Emulation" | ||
62 | select SOUND_OSS_CORE | 42 | select SOUND_OSS_CORE |
63 | bool | 43 | help |
44 | This option enables the build of OSS emulation layer. | ||
64 | 45 | ||
65 | config SND_MIXER_OSS | 46 | config SND_MIXER_OSS |
66 | tristate "OSS Mixer API" | 47 | tristate "OSS Mixer API" |
67 | select SND_OSSEMUL | 48 | depends on SND_OSSEMUL |
68 | help | 49 | help |
69 | To enable OSS mixer API emulation (/dev/mixer*), say Y here | 50 | To enable OSS mixer API emulation (/dev/mixer*), say Y here |
70 | and read <file:Documentation/sound/alsa/OSS-Emulation.txt>. | 51 | and read <file:Documentation/sound/alsa/OSS-Emulation.txt>. |
@@ -76,7 +57,7 @@ config SND_MIXER_OSS | |||
76 | 57 | ||
77 | config SND_PCM_OSS | 58 | config SND_PCM_OSS |
78 | tristate "OSS PCM (digital audio) API" | 59 | tristate "OSS PCM (digital audio) API" |
79 | select SND_OSSEMUL | 60 | depends on SND_OSSEMUL |
80 | select SND_PCM | 61 | select SND_PCM |
81 | help | 62 | help |
82 | To enable OSS digital audio (PCM) emulation (/dev/dsp*), say Y | 63 | To enable OSS digital audio (PCM) emulation (/dev/dsp*), say Y |
@@ -107,20 +88,6 @@ config SND_PCM_TIMER | |||
107 | For some embedded devices, we may disable it to reduce memory | 88 | For some embedded devices, we may disable it to reduce memory |
108 | footprint, about 20KB on x86_64 platform. | 89 | footprint, about 20KB on x86_64 platform. |
109 | 90 | ||
110 | config SND_SEQUENCER_OSS | ||
111 | bool "OSS Sequencer API" | ||
112 | depends on SND_SEQUENCER | ||
113 | select SND_OSSEMUL | ||
114 | help | ||
115 | Say Y here to enable OSS sequencer emulation (both | ||
116 | /dev/sequencer and /dev/music interfaces). | ||
117 | |||
118 | Many programs still use the OSS API, so say Y. | ||
119 | |||
120 | If you choose M in "Sequencer support" (SND_SEQUENCER), | ||
121 | this will be compiled as a module. The module will be called | ||
122 | snd-seq-oss. | ||
123 | |||
124 | config SND_HRTIMER | 91 | config SND_HRTIMER |
125 | tristate "HR-timer backend support" | 92 | tristate "HR-timer backend support" |
126 | depends on HIGH_RES_TIMERS | 93 | depends on HIGH_RES_TIMERS |
@@ -133,14 +100,6 @@ config SND_HRTIMER | |||
133 | To compile this driver as a module, choose M here: the module | 100 | To compile this driver as a module, choose M here: the module |
134 | will be called snd-hrtimer. | 101 | will be called snd-hrtimer. |
135 | 102 | ||
136 | config SND_SEQ_HRTIMER_DEFAULT | ||
137 | bool "Use HR-timer as default sequencer timer" | ||
138 | depends on SND_HRTIMER && SND_SEQUENCER | ||
139 | default y | ||
140 | help | ||
141 | Say Y here to use the HR-timer backend as the default sequencer | ||
142 | timer. | ||
143 | |||
144 | config SND_DYNAMIC_MINORS | 103 | config SND_DYNAMIC_MINORS |
145 | bool "Dynamic device file minor numbers" | 104 | bool "Dynamic device file minor numbers" |
146 | help | 105 | help |
diff --git a/sound/core/Makefile b/sound/core/Makefile index e85d9dd12c2d..e2066e2ef9f8 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile | |||
@@ -22,6 +22,7 @@ snd-pcm-$(CONFIG_SND_PCM_IEC958) += pcm_iec958.o | |||
22 | 22 | ||
23 | # for trace-points | 23 | # for trace-points |
24 | CFLAGS_pcm_lib.o := -I$(src) | 24 | CFLAGS_pcm_lib.o := -I$(src) |
25 | CFLAGS_pcm_native.o := -I$(src) | ||
25 | 26 | ||
26 | snd-pcm-dmaengine-objs := pcm_dmaengine.o | 27 | snd-pcm-dmaengine-objs := pcm_dmaengine.o |
27 | 28 | ||
@@ -30,6 +31,7 @@ snd-timer-objs := timer.o | |||
30 | snd-hrtimer-objs := hrtimer.o | 31 | snd-hrtimer-objs := hrtimer.o |
31 | snd-rtctimer-objs := rtctimer.o | 32 | snd-rtctimer-objs := rtctimer.o |
32 | snd-hwdep-objs := hwdep.o | 33 | snd-hwdep-objs := hwdep.o |
34 | snd-seq-device-objs := seq_device.o | ||
33 | 35 | ||
34 | snd-compress-objs := compress_offload.o | 36 | snd-compress-objs := compress_offload.o |
35 | 37 | ||
@@ -39,6 +41,7 @@ obj-$(CONFIG_SND_TIMER) += snd-timer.o | |||
39 | obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o | 41 | obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o |
40 | obj-$(CONFIG_SND_PCM) += snd-pcm.o | 42 | obj-$(CONFIG_SND_PCM) += snd-pcm.o |
41 | obj-$(CONFIG_SND_DMAENGINE_PCM) += snd-pcm-dmaengine.o | 43 | obj-$(CONFIG_SND_DMAENGINE_PCM) += snd-pcm-dmaengine.o |
44 | obj-$(CONFIG_SND_SEQ_DEVICE) += snd-seq-device.o | ||
42 | obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o | 45 | obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o |
43 | 46 | ||
44 | obj-$(CONFIG_SND_OSSEMUL) += oss/ | 47 | obj-$(CONFIG_SND_OSSEMUL) += oss/ |
diff --git a/sound/core/control.c b/sound/core/control.c index c109b82eef4b..ecd358213b83 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -747,65 +747,45 @@ static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, | |||
747 | static int snd_ctl_elem_list(struct snd_card *card, | 747 | static int snd_ctl_elem_list(struct snd_card *card, |
748 | struct snd_ctl_elem_list __user *_list) | 748 | struct snd_ctl_elem_list __user *_list) |
749 | { | 749 | { |
750 | struct list_head *plist; | ||
751 | struct snd_ctl_elem_list list; | 750 | struct snd_ctl_elem_list list; |
752 | struct snd_kcontrol *kctl; | 751 | struct snd_kcontrol *kctl; |
753 | struct snd_ctl_elem_id *dst, *id; | 752 | struct snd_ctl_elem_id id; |
754 | unsigned int offset, space, jidx; | 753 | unsigned int offset, space, jidx; |
754 | int err = 0; | ||
755 | 755 | ||
756 | if (copy_from_user(&list, _list, sizeof(list))) | 756 | if (copy_from_user(&list, _list, sizeof(list))) |
757 | return -EFAULT; | 757 | return -EFAULT; |
758 | offset = list.offset; | 758 | offset = list.offset; |
759 | space = list.space; | 759 | space = list.space; |
760 | /* try limit maximum space */ | 760 | |
761 | if (space > 16384) | 761 | down_read(&card->controls_rwsem); |
762 | return -ENOMEM; | 762 | list.count = card->controls_count; |
763 | list.used = 0; | ||
763 | if (space > 0) { | 764 | if (space > 0) { |
764 | /* allocate temporary buffer for atomic operation */ | 765 | list_for_each_entry(kctl, &card->controls, list) { |
765 | dst = vmalloc(space * sizeof(struct snd_ctl_elem_id)); | 766 | if (offset >= kctl->count) { |
766 | if (dst == NULL) | 767 | offset -= kctl->count; |
767 | return -ENOMEM; | 768 | continue; |
768 | down_read(&card->controls_rwsem); | 769 | } |
769 | list.count = card->controls_count; | 770 | for (jidx = offset; jidx < kctl->count; jidx++) { |
770 | plist = card->controls.next; | 771 | snd_ctl_build_ioff(&id, kctl, jidx); |
771 | while (plist != &card->controls) { | 772 | if (copy_to_user(list.pids + list.used, &id, |
772 | if (offset == 0) | 773 | sizeof(id))) { |
773 | break; | 774 | err = -EFAULT; |
774 | kctl = snd_kcontrol(plist); | 775 | goto out; |
775 | if (offset < kctl->count) | 776 | } |
776 | break; | ||
777 | offset -= kctl->count; | ||
778 | plist = plist->next; | ||
779 | } | ||
780 | list.used = 0; | ||
781 | id = dst; | ||
782 | while (space > 0 && plist != &card->controls) { | ||
783 | kctl = snd_kcontrol(plist); | ||
784 | for (jidx = offset; space > 0 && jidx < kctl->count; jidx++) { | ||
785 | snd_ctl_build_ioff(id, kctl, jidx); | ||
786 | id++; | ||
787 | space--; | ||
788 | list.used++; | 777 | list.used++; |
778 | if (!--space) | ||
779 | goto out; | ||
789 | } | 780 | } |
790 | plist = plist->next; | ||
791 | offset = 0; | 781 | offset = 0; |
792 | } | 782 | } |
793 | up_read(&card->controls_rwsem); | ||
794 | if (list.used > 0 && | ||
795 | copy_to_user(list.pids, dst, | ||
796 | list.used * sizeof(struct snd_ctl_elem_id))) { | ||
797 | vfree(dst); | ||
798 | return -EFAULT; | ||
799 | } | ||
800 | vfree(dst); | ||
801 | } else { | ||
802 | down_read(&card->controls_rwsem); | ||
803 | list.count = card->controls_count; | ||
804 | up_read(&card->controls_rwsem); | ||
805 | } | 783 | } |
806 | if (copy_to_user(_list, &list, sizeof(list))) | 784 | out: |
807 | return -EFAULT; | 785 | up_read(&card->controls_rwsem); |
808 | return 0; | 786 | if (!err && copy_to_user(_list, &list, sizeof(list))) |
787 | err = -EFAULT; | ||
788 | return err; | ||
809 | } | 789 | } |
810 | 790 | ||
811 | static bool validate_element_member_dimension(struct snd_ctl_elem_info *info) | 791 | static bool validate_element_member_dimension(struct snd_ctl_elem_info *info) |
diff --git a/sound/core/ctljack.c b/sound/core/ctljack.c index 84a3cd683068..0249d5e6ac23 100644 --- a/sound/core/ctljack.c +++ b/sound/core/ctljack.c | |||
@@ -23,7 +23,7 @@ static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol, | |||
23 | return 0; | 23 | return 0; |
24 | } | 24 | } |
25 | 25 | ||
26 | static struct snd_kcontrol_new jack_detect_kctl = { | 26 | static const struct snd_kcontrol_new jack_detect_kctl = { |
27 | /* name is filled later */ | 27 | /* name is filled later */ |
28 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | 28 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, |
29 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 29 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
diff --git a/sound/core/info.c b/sound/core/info.c index 8ab72e0f5932..bcf6a48cc70d 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -344,12 +344,12 @@ static ssize_t snd_info_text_entry_write(struct file *file, | |||
344 | } | 344 | } |
345 | } | 345 | } |
346 | if (next > buf->len) { | 346 | if (next > buf->len) { |
347 | char *nbuf = krealloc(buf->buffer, PAGE_ALIGN(next), | 347 | char *nbuf = kvzalloc(PAGE_ALIGN(next), GFP_KERNEL); |
348 | GFP_KERNEL | __GFP_ZERO); | ||
349 | if (!nbuf) { | 348 | if (!nbuf) { |
350 | err = -ENOMEM; | 349 | err = -ENOMEM; |
351 | goto error; | 350 | goto error; |
352 | } | 351 | } |
352 | kvfree(buf->buffer); | ||
353 | buf->buffer = nbuf; | 353 | buf->buffer = nbuf; |
354 | buf->len = PAGE_ALIGN(next); | 354 | buf->len = PAGE_ALIGN(next); |
355 | } | 355 | } |
@@ -427,7 +427,7 @@ static int snd_info_text_entry_release(struct inode *inode, struct file *file) | |||
427 | single_release(inode, file); | 427 | single_release(inode, file); |
428 | kfree(data->rbuffer); | 428 | kfree(data->rbuffer); |
429 | if (data->wbuffer) { | 429 | if (data->wbuffer) { |
430 | kfree(data->wbuffer->buffer); | 430 | kvfree(data->wbuffer->buffer); |
431 | kfree(data->wbuffer); | 431 | kfree(data->wbuffer); |
432 | } | 432 | } |
433 | 433 | ||
@@ -652,7 +652,6 @@ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) | |||
652 | *line = '\0'; | 652 | *line = '\0'; |
653 | return 0; | 653 | return 0; |
654 | } | 654 | } |
655 | |||
656 | EXPORT_SYMBOL(snd_info_get_line); | 655 | EXPORT_SYMBOL(snd_info_get_line); |
657 | 656 | ||
658 | /** | 657 | /** |
@@ -690,7 +689,6 @@ const char *snd_info_get_str(char *dest, const char *src, int len) | |||
690 | src++; | 689 | src++; |
691 | return src; | 690 | return src; |
692 | } | 691 | } |
693 | |||
694 | EXPORT_SYMBOL(snd_info_get_str); | 692 | EXPORT_SYMBOL(snd_info_get_str); |
695 | 693 | ||
696 | /* | 694 | /* |
@@ -748,7 +746,6 @@ struct snd_info_entry *snd_info_create_module_entry(struct module * module, | |||
748 | entry->module = module; | 746 | entry->module = module; |
749 | return entry; | 747 | return entry; |
750 | } | 748 | } |
751 | |||
752 | EXPORT_SYMBOL(snd_info_create_module_entry); | 749 | EXPORT_SYMBOL(snd_info_create_module_entry); |
753 | 750 | ||
754 | /** | 751 | /** |
@@ -772,7 +769,6 @@ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, | |||
772 | } | 769 | } |
773 | return entry; | 770 | return entry; |
774 | } | 771 | } |
775 | |||
776 | EXPORT_SYMBOL(snd_info_create_card_entry); | 772 | EXPORT_SYMBOL(snd_info_create_card_entry); |
777 | 773 | ||
778 | static void snd_info_disconnect(struct snd_info_entry *entry) | 774 | static void snd_info_disconnect(struct snd_info_entry *entry) |
@@ -815,7 +811,6 @@ void snd_info_free_entry(struct snd_info_entry * entry) | |||
815 | entry->private_free(entry); | 811 | entry->private_free(entry); |
816 | kfree(entry); | 812 | kfree(entry); |
817 | } | 813 | } |
818 | |||
819 | EXPORT_SYMBOL(snd_info_free_entry); | 814 | EXPORT_SYMBOL(snd_info_free_entry); |
820 | 815 | ||
821 | /** | 816 | /** |
@@ -858,7 +853,6 @@ int snd_info_register(struct snd_info_entry * entry) | |||
858 | mutex_unlock(&info_mutex); | 853 | mutex_unlock(&info_mutex); |
859 | return 0; | 854 | return 0; |
860 | } | 855 | } |
861 | |||
862 | EXPORT_SYMBOL(snd_info_register); | 856 | EXPORT_SYMBOL(snd_info_register); |
863 | 857 | ||
864 | /* | 858 | /* |
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c index 1478c8dfd473..f479374b6bd8 100644 --- a/sound/core/info_oss.c +++ b/sound/core/info_oss.c | |||
@@ -61,7 +61,6 @@ int snd_oss_info_register(int dev, int num, char *string) | |||
61 | mutex_unlock(&strings); | 61 | mutex_unlock(&strings); |
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
64 | |||
65 | EXPORT_SYMBOL(snd_oss_info_register); | 64 | EXPORT_SYMBOL(snd_oss_info_register); |
66 | 65 | ||
67 | static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) | 66 | static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev) |
diff --git a/sound/core/init.c b/sound/core/init.c index 6bda8436d765..00f2cbb76e69 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -452,7 +452,6 @@ int snd_card_disconnect(struct snd_card *card) | |||
452 | #endif | 452 | #endif |
453 | return 0; | 453 | return 0; |
454 | } | 454 | } |
455 | |||
456 | EXPORT_SYMBOL(snd_card_disconnect); | 455 | EXPORT_SYMBOL(snd_card_disconnect); |
457 | 456 | ||
458 | static int snd_card_do_free(struct snd_card *card) | 457 | static int snd_card_do_free(struct snd_card *card) |
@@ -718,7 +717,7 @@ int snd_card_add_dev_attr(struct snd_card *card, | |||
718 | 717 | ||
719 | dev_err(card->dev, "Too many groups assigned\n"); | 718 | dev_err(card->dev, "Too many groups assigned\n"); |
720 | return -ENOSPC; | 719 | return -ENOSPC; |
721 | }; | 720 | } |
722 | EXPORT_SYMBOL_GPL(snd_card_add_dev_attr); | 721 | EXPORT_SYMBOL_GPL(snd_card_add_dev_attr); |
723 | 722 | ||
724 | /** | 723 | /** |
@@ -775,7 +774,6 @@ int snd_card_register(struct snd_card *card) | |||
775 | #endif | 774 | #endif |
776 | return 0; | 775 | return 0; |
777 | } | 776 | } |
778 | |||
779 | EXPORT_SYMBOL(snd_card_register); | 777 | EXPORT_SYMBOL(snd_card_register); |
780 | 778 | ||
781 | #ifdef CONFIG_SND_PROC_FS | 779 | #ifdef CONFIG_SND_PROC_FS |
@@ -895,7 +893,6 @@ int snd_component_add(struct snd_card *card, const char *component) | |||
895 | strcat(card->components, component); | 893 | strcat(card->components, component); |
896 | return 0; | 894 | return 0; |
897 | } | 895 | } |
898 | |||
899 | EXPORT_SYMBOL(snd_component_add); | 896 | EXPORT_SYMBOL(snd_component_add); |
900 | 897 | ||
901 | /** | 898 | /** |
@@ -930,7 +927,6 @@ int snd_card_file_add(struct snd_card *card, struct file *file) | |||
930 | spin_unlock(&card->files_lock); | 927 | spin_unlock(&card->files_lock); |
931 | return 0; | 928 | return 0; |
932 | } | 929 | } |
933 | |||
934 | EXPORT_SYMBOL(snd_card_file_add); | 930 | EXPORT_SYMBOL(snd_card_file_add); |
935 | 931 | ||
936 | /** | 932 | /** |
@@ -972,7 +968,6 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) | |||
972 | put_device(&card->card_dev); | 968 | put_device(&card->card_dev); |
973 | return 0; | 969 | return 0; |
974 | } | 970 | } |
975 | |||
976 | EXPORT_SYMBOL(snd_card_file_remove); | 971 | EXPORT_SYMBOL(snd_card_file_remove); |
977 | 972 | ||
978 | #ifdef CONFIG_PM | 973 | #ifdef CONFIG_PM |
@@ -1012,6 +1007,5 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state) | |||
1012 | remove_wait_queue(&card->power_sleep, &wait); | 1007 | remove_wait_queue(&card->power_sleep, &wait); |
1013 | return result; | 1008 | return result; |
1014 | } | 1009 | } |
1015 | |||
1016 | EXPORT_SYMBOL(snd_power_wait); | 1010 | EXPORT_SYMBOL(snd_power_wait); |
1017 | #endif /* CONFIG_PM */ | 1011 | #endif /* CONFIG_PM */ |
diff --git a/sound/core/isadma.c b/sound/core/isadma.c index 31e8544d7f2d..7a8515abb5f9 100644 --- a/sound/core/isadma.c +++ b/sound/core/isadma.c | |||
@@ -55,7 +55,6 @@ void snd_dma_program(unsigned long dma, | |||
55 | enable_dma(dma); | 55 | enable_dma(dma); |
56 | release_dma_lock(flags); | 56 | release_dma_lock(flags); |
57 | } | 57 | } |
58 | |||
59 | EXPORT_SYMBOL(snd_dma_program); | 58 | EXPORT_SYMBOL(snd_dma_program); |
60 | 59 | ||
61 | /** | 60 | /** |
@@ -73,7 +72,6 @@ void snd_dma_disable(unsigned long dma) | |||
73 | disable_dma(dma); | 72 | disable_dma(dma); |
74 | release_dma_lock(flags); | 73 | release_dma_lock(flags); |
75 | } | 74 | } |
76 | |||
77 | EXPORT_SYMBOL(snd_dma_disable); | 75 | EXPORT_SYMBOL(snd_dma_disable); |
78 | 76 | ||
79 | /** | 77 | /** |
@@ -113,5 +111,4 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) | |||
113 | else | 111 | else |
114 | return size - result; | 112 | return size - result; |
115 | } | 113 | } |
116 | |||
117 | EXPORT_SYMBOL(snd_dma_pointer); | 114 | EXPORT_SYMBOL(snd_dma_pointer); |
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index f05cb6a8cbe0..7f89d3c79a4b 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c | |||
@@ -54,6 +54,7 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags) | |||
54 | pg = get_order(size); | 54 | pg = get_order(size); |
55 | return (void *) __get_free_pages(gfp_flags, pg); | 55 | return (void *) __get_free_pages(gfp_flags, pg); |
56 | } | 56 | } |
57 | EXPORT_SYMBOL(snd_malloc_pages); | ||
57 | 58 | ||
58 | /** | 59 | /** |
59 | * snd_free_pages - release the pages | 60 | * snd_free_pages - release the pages |
@@ -71,6 +72,7 @@ void snd_free_pages(void *ptr, size_t size) | |||
71 | pg = get_order(size); | 72 | pg = get_order(size); |
72 | free_pages((unsigned long) ptr, pg); | 73 | free_pages((unsigned long) ptr, pg); |
73 | } | 74 | } |
75 | EXPORT_SYMBOL(snd_free_pages); | ||
74 | 76 | ||
75 | /* | 77 | /* |
76 | * | 78 | * |
@@ -217,6 +219,7 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size, | |||
217 | dmab->bytes = size; | 219 | dmab->bytes = size; |
218 | return 0; | 220 | return 0; |
219 | } | 221 | } |
222 | EXPORT_SYMBOL(snd_dma_alloc_pages); | ||
220 | 223 | ||
221 | /** | 224 | /** |
222 | * snd_dma_alloc_pages_fallback - allocate the buffer area according to the given type with fallback | 225 | * snd_dma_alloc_pages_fallback - allocate the buffer area according to the given type with fallback |
@@ -254,6 +257,7 @@ int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size, | |||
254 | return -ENOMEM; | 257 | return -ENOMEM; |
255 | return 0; | 258 | return 0; |
256 | } | 259 | } |
260 | EXPORT_SYMBOL(snd_dma_alloc_pages_fallback); | ||
257 | 261 | ||
258 | 262 | ||
259 | /** | 263 | /** |
@@ -287,13 +291,4 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab) | |||
287 | pr_err("snd-malloc: invalid device type %d\n", dmab->dev.type); | 291 | pr_err("snd-malloc: invalid device type %d\n", dmab->dev.type); |
288 | } | 292 | } |
289 | } | 293 | } |
290 | |||
291 | /* | ||
292 | * exports | ||
293 | */ | ||
294 | EXPORT_SYMBOL(snd_dma_alloc_pages); | ||
295 | EXPORT_SYMBOL(snd_dma_alloc_pages_fallback); | ||
296 | EXPORT_SYMBOL(snd_dma_free_pages); | 294 | EXPORT_SYMBOL(snd_dma_free_pages); |
297 | |||
298 | EXPORT_SYMBOL(snd_malloc_pages); | ||
299 | EXPORT_SYMBOL(snd_free_pages); | ||
diff --git a/sound/core/memory.c b/sound/core/memory.c index 4cd664efad77..19c9ea90d9bf 100644 --- a/sound/core/memory.c +++ b/sound/core/memory.c | |||
@@ -55,7 +55,6 @@ int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size | |||
55 | return 0; | 55 | return 0; |
56 | #endif | 56 | #endif |
57 | } | 57 | } |
58 | |||
59 | EXPORT_SYMBOL(copy_to_user_fromio); | 58 | EXPORT_SYMBOL(copy_to_user_fromio); |
60 | 59 | ||
61 | /** | 60 | /** |
@@ -88,5 +87,4 @@ int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size | |||
88 | return 0; | 87 | return 0; |
89 | #endif | 88 | #endif |
90 | } | 89 | } |
91 | |||
92 | EXPORT_SYMBOL(copy_from_user_toio); | 90 | EXPORT_SYMBOL(copy_from_user_toio); |
diff --git a/sound/core/misc.c b/sound/core/misc.c index 21b228046e88..0f818d593c9e 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c | |||
@@ -48,7 +48,6 @@ void release_and_free_resource(struct resource *res) | |||
48 | kfree(res); | 48 | kfree(res); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | |||
52 | EXPORT_SYMBOL(release_and_free_resource); | 51 | EXPORT_SYMBOL(release_and_free_resource); |
53 | 52 | ||
54 | #ifdef CONFIG_SND_VERBOSE_PRINTK | 53 | #ifdef CONFIG_SND_VERBOSE_PRINTK |
diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c index 6faa1d719206..d870b2d93135 100644 --- a/sound/core/oss/io.c +++ b/sound/core/oss/io.c | |||
@@ -26,9 +26,9 @@ | |||
26 | #include "pcm_plugin.h" | 26 | #include "pcm_plugin.h" |
27 | 27 | ||
28 | #define pcm_write(plug,buf,count) snd_pcm_oss_write3(plug,buf,count,1) | 28 | #define pcm_write(plug,buf,count) snd_pcm_oss_write3(plug,buf,count,1) |
29 | #define pcm_writev(plug,vec,count) snd_pcm_oss_writev3(plug,vec,count,1) | 29 | #define pcm_writev(plug,vec,count) snd_pcm_oss_writev3(plug,vec,count) |
30 | #define pcm_read(plug,buf,count) snd_pcm_oss_read3(plug,buf,count,1) | 30 | #define pcm_read(plug,buf,count) snd_pcm_oss_read3(plug,buf,count,1) |
31 | #define pcm_readv(plug,vec,count) snd_pcm_oss_readv3(plug,vec,count,1) | 31 | #define pcm_readv(plug,vec,count) snd_pcm_oss_readv3(plug,vec,count) |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Basic io plugin | 34 | * Basic io plugin |
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 2ff9c12d664a..379bf486ccc7 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
@@ -395,6 +395,7 @@ int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned l | |||
395 | fmixer.mixer = card->mixer_oss; | 395 | fmixer.mixer = card->mixer_oss; |
396 | return snd_mixer_oss_ioctl1(&fmixer, cmd, arg); | 396 | return snd_mixer_oss_ioctl1(&fmixer, cmd, arg); |
397 | } | 397 | } |
398 | EXPORT_SYMBOL(snd_mixer_oss_ioctl_card); | ||
398 | 399 | ||
399 | #ifdef CONFIG_COMPAT | 400 | #ifdef CONFIG_COMPAT |
400 | /* all compatible */ | 401 | /* all compatible */ |
@@ -1425,5 +1426,3 @@ static void __exit alsa_mixer_oss_exit(void) | |||
1425 | 1426 | ||
1426 | module_init(alsa_mixer_oss_init) | 1427 | module_init(alsa_mixer_oss_init) |
1427 | module_exit(alsa_mixer_oss_exit) | 1428 | module_exit(alsa_mixer_oss_exit) |
1428 | |||
1429 | EXPORT_SYMBOL(snd_mixer_oss_ioctl_card); | ||
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 36baf962f9b0..5e1009d959a8 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); | |||
67 | static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file); | 67 | static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file); |
68 | static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file); | 68 | static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file); |
69 | 69 | ||
70 | static 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 | |||
77 | static 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, | |||
799 | static int choose_rate(struct snd_pcm_substream *substream, | 787 | static 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 | ||
1259 | snd_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 |
1236 | snd_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 | ||
1295 | snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel) | 1265 | snd_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 | ||
1330 | static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel) | 1294 | static 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; |
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 727ac44d39f4..cadc93792868 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c | |||
@@ -266,7 +266,8 @@ snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pc | |||
266 | return frames; | 266 | return frames; |
267 | } | 267 | } |
268 | 268 | ||
269 | static int snd_pcm_plug_formats(struct snd_mask *mask, snd_pcm_format_t format) | 269 | static int snd_pcm_plug_formats(const struct snd_mask *mask, |
270 | snd_pcm_format_t format) | ||
270 | { | 271 | { |
271 | struct snd_mask formats = *mask; | 272 | struct snd_mask formats = *mask; |
272 | u64 linfmts = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | | 273 | u64 linfmts = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 | |
@@ -309,7 +310,7 @@ static snd_pcm_format_t preferred_formats[] = { | |||
309 | }; | 310 | }; |
310 | 311 | ||
311 | snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, | 312 | snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, |
312 | struct snd_mask *format_mask) | 313 | const struct snd_mask *format_mask) |
313 | { | 314 | { |
314 | int i; | 315 | int i; |
315 | 316 | ||
diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h index a5035c2369a6..c9cd29d86efd 100644 --- a/sound/core/oss/pcm_plugin.h +++ b/sound/core/oss/pcm_plugin.h | |||
@@ -126,7 +126,7 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *substream, | |||
126 | struct snd_pcm_hw_params *slave_params); | 126 | struct snd_pcm_hw_params *slave_params); |
127 | 127 | ||
128 | snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, | 128 | snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format, |
129 | struct snd_mask *format_mask); | 129 | const struct snd_mask *format_mask); |
130 | 130 | ||
131 | int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin); | 131 | int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin); |
132 | 132 | ||
@@ -162,17 +162,15 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, | |||
162 | snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, | 162 | snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, |
163 | char *ptr, snd_pcm_uframes_t size, int in_kernel); | 163 | char *ptr, snd_pcm_uframes_t size, int in_kernel); |
164 | snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, | 164 | snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, |
165 | void **bufs, snd_pcm_uframes_t frames, | 165 | void **bufs, snd_pcm_uframes_t frames); |
166 | int in_kernel); | ||
167 | snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, | 166 | snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, |
168 | void **bufs, snd_pcm_uframes_t frames, | 167 | void **bufs, snd_pcm_uframes_t frames); |
169 | int in_kernel); | ||
170 | 168 | ||
171 | #else | 169 | #else |
172 | 170 | ||
173 | static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; } | 171 | static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; } |
174 | static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; } | 172 | static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; } |
175 | static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { return format; } | 173 | static inline int snd_pcm_plug_slave_format(int format, const struct snd_mask *format_mask) { return format; } |
176 | 174 | ||
177 | #endif | 175 | #endif |
178 | 176 | ||
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 8e980aa678d0..4b3290447398 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -31,13 +31,17 @@ | |||
31 | #include <sound/control.h> | 31 | #include <sound/control.h> |
32 | #include <sound/info.h> | 32 | #include <sound/info.h> |
33 | 33 | ||
34 | #include "pcm_local.h" | ||
35 | |||
34 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>"); | 36 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>"); |
35 | MODULE_DESCRIPTION("Midlevel PCM code for ALSA."); | 37 | MODULE_DESCRIPTION("Midlevel PCM code for ALSA."); |
36 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
37 | 39 | ||
38 | static LIST_HEAD(snd_pcm_devices); | 40 | static LIST_HEAD(snd_pcm_devices); |
39 | static LIST_HEAD(snd_pcm_notify_list); | ||
40 | static DEFINE_MUTEX(register_mutex); | 41 | static DEFINE_MUTEX(register_mutex); |
42 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) | ||
43 | static LIST_HEAD(snd_pcm_notify_list); | ||
44 | #endif | ||
41 | 45 | ||
42 | static int snd_pcm_free(struct snd_pcm *pcm); | 46 | static int snd_pcm_free(struct snd_pcm *pcm); |
43 | static int snd_pcm_dev_free(struct snd_device *device); | 47 | static int snd_pcm_dev_free(struct snd_device *device); |
@@ -884,16 +888,23 @@ static void snd_pcm_free_stream(struct snd_pcm_str * pstr) | |||
884 | put_device(&pstr->dev); | 888 | put_device(&pstr->dev); |
885 | } | 889 | } |
886 | 890 | ||
891 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) | ||
892 | #define pcm_call_notify(pcm, call) \ | ||
893 | do { \ | ||
894 | struct snd_pcm_notify *_notify; \ | ||
895 | list_for_each_entry(_notify, &snd_pcm_notify_list, list) \ | ||
896 | _notify->call(pcm); \ | ||
897 | } while (0) | ||
898 | #else | ||
899 | #define pcm_call_notify(pcm, call) do {} while (0) | ||
900 | #endif | ||
901 | |||
887 | static int snd_pcm_free(struct snd_pcm *pcm) | 902 | static int snd_pcm_free(struct snd_pcm *pcm) |
888 | { | 903 | { |
889 | struct snd_pcm_notify *notify; | ||
890 | |||
891 | if (!pcm) | 904 | if (!pcm) |
892 | return 0; | 905 | return 0; |
893 | if (!pcm->internal) { | 906 | if (!pcm->internal) |
894 | list_for_each_entry(notify, &snd_pcm_notify_list, list) | 907 | pcm_call_notify(pcm, n_unregister); |
895 | notify->n_unregister(pcm); | ||
896 | } | ||
897 | if (pcm->private_free) | 908 | if (pcm->private_free) |
898 | pcm->private_free(pcm); | 909 | pcm->private_free(pcm); |
899 | snd_pcm_lib_preallocate_free_for_all(pcm); | 910 | snd_pcm_lib_preallocate_free_for_all(pcm); |
@@ -1069,7 +1080,6 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
1069 | { | 1080 | { |
1070 | int cidx, err; | 1081 | int cidx, err; |
1071 | struct snd_pcm_substream *substream; | 1082 | struct snd_pcm_substream *substream; |
1072 | struct snd_pcm_notify *notify; | ||
1073 | struct snd_pcm *pcm; | 1083 | struct snd_pcm *pcm; |
1074 | 1084 | ||
1075 | if (snd_BUG_ON(!device || !device->device_data)) | 1085 | if (snd_BUG_ON(!device || !device->device_data)) |
@@ -1107,8 +1117,7 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
1107 | snd_pcm_timer_init(substream); | 1117 | snd_pcm_timer_init(substream); |
1108 | } | 1118 | } |
1109 | 1119 | ||
1110 | list_for_each_entry(notify, &snd_pcm_notify_list, list) | 1120 | pcm_call_notify(pcm, n_register); |
1111 | notify->n_register(pcm); | ||
1112 | 1121 | ||
1113 | unlock: | 1122 | unlock: |
1114 | mutex_unlock(®ister_mutex); | 1123 | mutex_unlock(®ister_mutex); |
@@ -1118,7 +1127,6 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
1118 | static int snd_pcm_dev_disconnect(struct snd_device *device) | 1127 | static int snd_pcm_dev_disconnect(struct snd_device *device) |
1119 | { | 1128 | { |
1120 | struct snd_pcm *pcm = device->device_data; | 1129 | struct snd_pcm *pcm = device->device_data; |
1121 | struct snd_pcm_notify *notify; | ||
1122 | struct snd_pcm_substream *substream; | 1130 | struct snd_pcm_substream *substream; |
1123 | int cidx; | 1131 | int cidx; |
1124 | 1132 | ||
@@ -1138,8 +1146,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) | |||
1138 | } | 1146 | } |
1139 | } | 1147 | } |
1140 | if (!pcm->internal) { | 1148 | if (!pcm->internal) { |
1141 | list_for_each_entry(notify, &snd_pcm_notify_list, list) | 1149 | pcm_call_notify(pcm, n_disconnect); |
1142 | notify->n_disconnect(pcm); | ||
1143 | } | 1150 | } |
1144 | for (cidx = 0; cidx < 2; cidx++) { | 1151 | for (cidx = 0; cidx < 2; cidx++) { |
1145 | if (!pcm->internal) | 1152 | if (!pcm->internal) |
@@ -1151,6 +1158,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) | |||
1151 | return 0; | 1158 | return 0; |
1152 | } | 1159 | } |
1153 | 1160 | ||
1161 | #if IS_ENABLED(CONFIG_SND_PCM_OSS) | ||
1154 | /** | 1162 | /** |
1155 | * snd_pcm_notify - Add/remove the notify list | 1163 | * snd_pcm_notify - Add/remove the notify list |
1156 | * @notify: PCM notify list | 1164 | * @notify: PCM notify list |
@@ -1183,6 +1191,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | |||
1183 | return 0; | 1191 | return 0; |
1184 | } | 1192 | } |
1185 | EXPORT_SYMBOL(snd_pcm_notify); | 1193 | EXPORT_SYMBOL(snd_pcm_notify); |
1194 | #endif /* CONFIG_SND_PCM_OSS */ | ||
1186 | 1195 | ||
1187 | #ifdef CONFIG_SND_PROC_FS | 1196 | #ifdef CONFIG_SND_PROC_FS |
1188 | /* | 1197 | /* |
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index 1f64ab0c2a95..8a0f8d51e95d 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c | |||
@@ -27,17 +27,13 @@ static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream, | |||
27 | s32 __user *src) | 27 | s32 __user *src) |
28 | { | 28 | { |
29 | snd_pcm_sframes_t delay; | 29 | snd_pcm_sframes_t delay; |
30 | mm_segment_t fs; | ||
31 | int err; | ||
32 | 30 | ||
33 | fs = snd_enter_user(); | 31 | delay = snd_pcm_delay(substream); |
34 | err = snd_pcm_delay(substream, &delay); | 32 | if (delay < 0) |
35 | snd_leave_user(fs); | 33 | return delay; |
36 | if (err < 0) | ||
37 | return err; | ||
38 | if (put_user(delay, src)) | 34 | if (put_user(delay, src)) |
39 | return -EFAULT; | 35 | return -EFAULT; |
40 | return err; | 36 | return 0; |
41 | } | 37 | } |
42 | 38 | ||
43 | static int snd_pcm_ioctl_rewind_compat(struct snd_pcm_substream *substream, | 39 | static int snd_pcm_ioctl_rewind_compat(struct snd_pcm_substream *substream, |
diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c index e70379fb63d0..9881d087756f 100644 --- a/sound/core/pcm_drm_eld.c +++ b/sound/core/pcm_drm_eld.c | |||
@@ -29,13 +29,13 @@ static int eld_limit_rates(struct snd_pcm_hw_params *params, | |||
29 | struct snd_pcm_hw_rule *rule) | 29 | struct snd_pcm_hw_rule *rule) |
30 | { | 30 | { |
31 | struct snd_interval *r = hw_param_interval(params, rule->var); | 31 | struct snd_interval *r = hw_param_interval(params, rule->var); |
32 | struct snd_interval *c; | 32 | const struct snd_interval *c; |
33 | unsigned int rate_mask = 7, i; | 33 | unsigned int rate_mask = 7, i; |
34 | const u8 *sad, *eld = rule->private; | 34 | const u8 *sad, *eld = rule->private; |
35 | 35 | ||
36 | sad = drm_eld_sad(eld); | 36 | sad = drm_eld_sad(eld); |
37 | if (sad) { | 37 | if (sad) { |
38 | c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | 38 | c = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); |
39 | 39 | ||
40 | for (i = drm_eld_sad_count(eld); i > 0; i--, sad += 3) { | 40 | for (i = drm_eld_sad_count(eld); i > 0; i--, sad += 3) { |
41 | unsigned max_channels = sad_max_channels(sad); | 41 | unsigned max_channels = sad_max_channels(sad); |
@@ -57,7 +57,7 @@ static int eld_limit_channels(struct snd_pcm_hw_params *params, | |||
57 | struct snd_pcm_hw_rule *rule) | 57 | struct snd_pcm_hw_rule *rule) |
58 | { | 58 | { |
59 | struct snd_interval *c = hw_param_interval(params, rule->var); | 59 | struct snd_interval *c = hw_param_interval(params, rule->var); |
60 | struct snd_interval *r; | 60 | const struct snd_interval *r; |
61 | struct snd_interval t = { .min = 1, .max = 2, .integer = 1, }; | 61 | struct snd_interval t = { .min = 1, .max = 2, .integer = 1, }; |
62 | unsigned int i; | 62 | unsigned int i; |
63 | const u8 *sad, *eld = rule->private; | 63 | const u8 *sad, *eld = rule->private; |
@@ -67,7 +67,7 @@ static int eld_limit_channels(struct snd_pcm_hw_params *params, | |||
67 | unsigned int rate_mask = 0; | 67 | unsigned int rate_mask = 0; |
68 | 68 | ||
69 | /* Convert the rate interval to a mask */ | 69 | /* Convert the rate interval to a mask */ |
70 | r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 70 | r = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); |
71 | for (i = 0; i < ARRAY_SIZE(eld_rates); i++) | 71 | for (i = 0; i < ARRAY_SIZE(eld_rates); i++) |
72 | if (r->min <= eld_rates[i] && r->max >= eld_rates[i]) | 72 | if (r->min <= eld_rates[i] && r->max >= eld_rates[i]) |
73 | rate_mask |= BIT(i); | 73 | rate_mask |= BIT(i); |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 009e6c98754e..e8131c060c86 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
34 | #include <sound/timer.h> | 34 | #include <sound/timer.h> |
35 | 35 | ||
36 | #include "pcm_local.h" | ||
37 | |||
36 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | 38 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG |
37 | #define CREATE_TRACE_POINTS | 39 | #define CREATE_TRACE_POINTS |
38 | #include "pcm_trace.h" | 40 | #include "pcm_trace.h" |
@@ -40,8 +42,12 @@ | |||
40 | #define trace_hwptr(substream, pos, in_interrupt) | 42 | #define trace_hwptr(substream, pos, in_interrupt) |
41 | #define trace_xrun(substream) | 43 | #define trace_xrun(substream) |
42 | #define trace_hw_ptr_error(substream, reason) | 44 | #define trace_hw_ptr_error(substream, reason) |
45 | #define trace_applptr(substream, prev, curr) | ||
43 | #endif | 46 | #endif |
44 | 47 | ||
48 | static int fill_silence_frames(struct snd_pcm_substream *substream, | ||
49 | snd_pcm_uframes_t off, snd_pcm_uframes_t frames); | ||
50 | |||
45 | /* | 51 | /* |
46 | * fill ring buffer with silence | 52 | * fill ring buffer with silence |
47 | * runtime->silence_start: starting pointer to silence area | 53 | * runtime->silence_start: starting pointer to silence area |
@@ -55,6 +61,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram | |||
55 | { | 61 | { |
56 | struct snd_pcm_runtime *runtime = substream->runtime; | 62 | struct snd_pcm_runtime *runtime = substream->runtime; |
57 | snd_pcm_uframes_t frames, ofs, transfer; | 63 | snd_pcm_uframes_t frames, ofs, transfer; |
64 | int err; | ||
58 | 65 | ||
59 | if (runtime->silence_size < runtime->boundary) { | 66 | if (runtime->silence_size < runtime->boundary) { |
60 | snd_pcm_sframes_t noise_dist, n; | 67 | snd_pcm_sframes_t noise_dist, n; |
@@ -107,33 +114,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram | |||
107 | ofs = runtime->silence_start % runtime->buffer_size; | 114 | ofs = runtime->silence_start % runtime->buffer_size; |
108 | while (frames > 0) { | 115 | while (frames > 0) { |
109 | transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames; | 116 | transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames; |
110 | if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED || | 117 | err = fill_silence_frames(substream, ofs, transfer); |
111 | runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { | 118 | snd_BUG_ON(err < 0); |
112 | if (substream->ops->silence) { | ||
113 | int err; | ||
114 | err = substream->ops->silence(substream, -1, ofs, transfer); | ||
115 | snd_BUG_ON(err < 0); | ||
116 | } else { | ||
117 | char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs); | ||
118 | snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels); | ||
119 | } | ||
120 | } else { | ||
121 | unsigned int c; | ||
122 | unsigned int channels = runtime->channels; | ||
123 | if (substream->ops->silence) { | ||
124 | for (c = 0; c < channels; ++c) { | ||
125 | int err; | ||
126 | err = substream->ops->silence(substream, c, ofs, transfer); | ||
127 | snd_BUG_ON(err < 0); | ||
128 | } | ||
129 | } else { | ||
130 | size_t dma_csize = runtime->dma_bytes / channels; | ||
131 | for (c = 0; c < channels; ++c) { | ||
132 | char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, ofs); | ||
133 | snd_pcm_format_set_silence(runtime->format, hwbuf, transfer); | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | runtime->silence_filled += transfer; | 119 | runtime->silence_filled += transfer; |
138 | frames -= transfer; | 120 | frames -= transfer; |
139 | ofs = 0; | 121 | ofs = 0; |
@@ -508,7 +490,6 @@ void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, | |||
508 | for (substream = stream->substream; substream != NULL; substream = substream->next) | 490 | for (substream = stream->substream; substream != NULL; substream = substream->next) |
509 | substream->ops = ops; | 491 | substream->ops = ops; |
510 | } | 492 | } |
511 | |||
512 | EXPORT_SYMBOL(snd_pcm_set_ops); | 493 | EXPORT_SYMBOL(snd_pcm_set_ops); |
513 | 494 | ||
514 | /** | 495 | /** |
@@ -526,7 +507,6 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream) | |||
526 | runtime->sync.id32[2] = -1; | 507 | runtime->sync.id32[2] = -1; |
527 | runtime->sync.id32[3] = -1; | 508 | runtime->sync.id32[3] = -1; |
528 | } | 509 | } |
529 | |||
530 | EXPORT_SYMBOL(snd_pcm_set_sync); | 510 | EXPORT_SYMBOL(snd_pcm_set_sync); |
531 | 511 | ||
532 | /* | 512 | /* |
@@ -643,7 +623,6 @@ int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) | |||
643 | } | 623 | } |
644 | return changed; | 624 | return changed; |
645 | } | 625 | } |
646 | |||
647 | EXPORT_SYMBOL(snd_interval_refine); | 626 | EXPORT_SYMBOL(snd_interval_refine); |
648 | 627 | ||
649 | static int snd_interval_refine_first(struct snd_interval *i) | 628 | static int snd_interval_refine_first(struct snd_interval *i) |
@@ -906,7 +885,6 @@ int snd_interval_ratnum(struct snd_interval *i, | |||
906 | } | 885 | } |
907 | return err; | 886 | return err; |
908 | } | 887 | } |
909 | |||
910 | EXPORT_SYMBOL(snd_interval_ratnum); | 888 | EXPORT_SYMBOL(snd_interval_ratnum); |
911 | 889 | ||
912 | /** | 890 | /** |
@@ -1044,7 +1022,6 @@ int snd_interval_list(struct snd_interval *i, unsigned int count, | |||
1044 | } | 1022 | } |
1045 | return snd_interval_refine(i, &list_range); | 1023 | return snd_interval_refine(i, &list_range); |
1046 | } | 1024 | } |
1047 | |||
1048 | EXPORT_SYMBOL(snd_interval_list); | 1025 | EXPORT_SYMBOL(snd_interval_list); |
1049 | 1026 | ||
1050 | /** | 1027 | /** |
@@ -1183,7 +1160,6 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, | |||
1183 | va_end(args); | 1160 | va_end(args); |
1184 | return 0; | 1161 | return 0; |
1185 | } | 1162 | } |
1186 | |||
1187 | EXPORT_SYMBOL(snd_pcm_hw_rule_add); | 1163 | EXPORT_SYMBOL(snd_pcm_hw_rule_add); |
1188 | 1164 | ||
1189 | /** | 1165 | /** |
@@ -1247,7 +1223,6 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa | |||
1247 | struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; | 1223 | struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; |
1248 | return snd_interval_setinteger(constrs_interval(constrs, var)); | 1224 | return snd_interval_setinteger(constrs_interval(constrs, var)); |
1249 | } | 1225 | } |
1250 | |||
1251 | EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); | 1226 | EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); |
1252 | 1227 | ||
1253 | /** | 1228 | /** |
@@ -1273,7 +1248,6 @@ int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_par | |||
1273 | t.integer = 0; | 1248 | t.integer = 0; |
1274 | return snd_interval_refine(constrs_interval(constrs, var), &t); | 1249 | return snd_interval_refine(constrs_interval(constrs, var), &t); |
1275 | } | 1250 | } |
1276 | |||
1277 | EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax); | 1251 | EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax); |
1278 | 1252 | ||
1279 | static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, | 1253 | static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, |
@@ -1304,7 +1278,6 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, | |||
1304 | snd_pcm_hw_rule_list, (void *)l, | 1278 | snd_pcm_hw_rule_list, (void *)l, |
1305 | var, -1); | 1279 | var, -1); |
1306 | } | 1280 | } |
1307 | |||
1308 | EXPORT_SYMBOL(snd_pcm_hw_constraint_list); | 1281 | EXPORT_SYMBOL(snd_pcm_hw_constraint_list); |
1309 | 1282 | ||
1310 | static int snd_pcm_hw_rule_ranges(struct snd_pcm_hw_params *params, | 1283 | static int snd_pcm_hw_rule_ranges(struct snd_pcm_hw_params *params, |
@@ -1371,7 +1344,6 @@ int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, | |||
1371 | snd_pcm_hw_rule_ratnums, (void *)r, | 1344 | snd_pcm_hw_rule_ratnums, (void *)r, |
1372 | var, -1); | 1345 | var, -1); |
1373 | } | 1346 | } |
1374 | |||
1375 | EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums); | 1347 | EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums); |
1376 | 1348 | ||
1377 | static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, | 1349 | static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, |
@@ -1406,7 +1378,6 @@ int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, | |||
1406 | snd_pcm_hw_rule_ratdens, (void *)r, | 1378 | snd_pcm_hw_rule_ratdens, (void *)r, |
1407 | var, -1); | 1379 | var, -1); |
1408 | } | 1380 | } |
1409 | |||
1410 | EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens); | 1381 | EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens); |
1411 | 1382 | ||
1412 | static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, | 1383 | static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, |
@@ -1415,7 +1386,8 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, | |||
1415 | unsigned int l = (unsigned long) rule->private; | 1386 | unsigned int l = (unsigned long) rule->private; |
1416 | int width = l & 0xffff; | 1387 | int width = l & 0xffff; |
1417 | unsigned int msbits = l >> 16; | 1388 | unsigned int msbits = l >> 16; |
1418 | struct snd_interval *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); | 1389 | const struct snd_interval *i = |
1390 | hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); | ||
1419 | 1391 | ||
1420 | if (!snd_interval_single(i)) | 1392 | if (!snd_interval_single(i)) |
1421 | return 0; | 1393 | return 0; |
@@ -1452,7 +1424,6 @@ int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, | |||
1452 | (void*) l, | 1424 | (void*) l, |
1453 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); | 1425 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); |
1454 | } | 1426 | } |
1455 | |||
1456 | EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits); | 1427 | EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits); |
1457 | 1428 | ||
1458 | static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, | 1429 | static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, |
@@ -1480,7 +1451,6 @@ int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime, | |||
1480 | snd_pcm_hw_rule_step, (void *) step, | 1451 | snd_pcm_hw_rule_step, (void *) step, |
1481 | var, -1); | 1452 | var, -1); |
1482 | } | 1453 | } |
1483 | |||
1484 | EXPORT_SYMBOL(snd_pcm_hw_constraint_step); | 1454 | EXPORT_SYMBOL(snd_pcm_hw_constraint_step); |
1485 | 1455 | ||
1486 | static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) | 1456 | static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) |
@@ -1511,7 +1481,6 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime, | |||
1511 | snd_pcm_hw_rule_pow2, NULL, | 1481 | snd_pcm_hw_rule_pow2, NULL, |
1512 | var, -1); | 1482 | var, -1); |
1513 | } | 1483 | } |
1514 | |||
1515 | EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); | 1484 | EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); |
1516 | 1485 | ||
1517 | static int snd_pcm_hw_rule_noresample_func(struct snd_pcm_hw_params *params, | 1486 | static int snd_pcm_hw_rule_noresample_func(struct snd_pcm_hw_params *params, |
@@ -1570,7 +1539,6 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) | |||
1570 | _snd_pcm_hw_param_any(params, k); | 1539 | _snd_pcm_hw_param_any(params, k); |
1571 | params->info = ~0U; | 1540 | params->info = ~0U; |
1572 | } | 1541 | } |
1573 | |||
1574 | EXPORT_SYMBOL(_snd_pcm_hw_params_any); | 1542 | EXPORT_SYMBOL(_snd_pcm_hw_params_any); |
1575 | 1543 | ||
1576 | /** | 1544 | /** |
@@ -1603,7 +1571,6 @@ int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, | |||
1603 | } | 1571 | } |
1604 | return -EINVAL; | 1572 | return -EINVAL; |
1605 | } | 1573 | } |
1606 | |||
1607 | EXPORT_SYMBOL(snd_pcm_hw_param_value); | 1574 | EXPORT_SYMBOL(snd_pcm_hw_param_value); |
1608 | 1575 | ||
1609 | void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, | 1576 | void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, |
@@ -1621,7 +1588,6 @@ void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, | |||
1621 | snd_BUG(); | 1588 | snd_BUG(); |
1622 | } | 1589 | } |
1623 | } | 1590 | } |
1624 | |||
1625 | EXPORT_SYMBOL(_snd_pcm_hw_param_setempty); | 1591 | EXPORT_SYMBOL(_snd_pcm_hw_param_setempty); |
1626 | 1592 | ||
1627 | static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, | 1593 | static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, |
@@ -1668,7 +1634,6 @@ int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, | |||
1668 | } | 1634 | } |
1669 | return snd_pcm_hw_param_value(params, var, dir); | 1635 | return snd_pcm_hw_param_value(params, var, dir); |
1670 | } | 1636 | } |
1671 | |||
1672 | EXPORT_SYMBOL(snd_pcm_hw_param_first); | 1637 | EXPORT_SYMBOL(snd_pcm_hw_param_first); |
1673 | 1638 | ||
1674 | static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, | 1639 | static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, |
@@ -1715,48 +1680,8 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, | |||
1715 | } | 1680 | } |
1716 | return snd_pcm_hw_param_value(params, var, dir); | 1681 | return snd_pcm_hw_param_value(params, var, dir); |
1717 | } | 1682 | } |
1718 | |||
1719 | EXPORT_SYMBOL(snd_pcm_hw_param_last); | 1683 | EXPORT_SYMBOL(snd_pcm_hw_param_last); |
1720 | 1684 | ||
1721 | /** | ||
1722 | * snd_pcm_hw_param_choose - choose a configuration defined by @params | ||
1723 | * @pcm: PCM instance | ||
1724 | * @params: the hw_params instance | ||
1725 | * | ||
1726 | * Choose one configuration from configuration space defined by @params. | ||
1727 | * The configuration chosen is that obtained fixing in this order: | ||
1728 | * first access, first format, first subformat, min channels, | ||
1729 | * min rate, min period time, max buffer size, min tick time | ||
1730 | * | ||
1731 | * Return: Zero if successful, or a negative error code on failure. | ||
1732 | */ | ||
1733 | int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, | ||
1734 | struct snd_pcm_hw_params *params) | ||
1735 | { | ||
1736 | static int vars[] = { | ||
1737 | SNDRV_PCM_HW_PARAM_ACCESS, | ||
1738 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
1739 | SNDRV_PCM_HW_PARAM_SUBFORMAT, | ||
1740 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
1741 | SNDRV_PCM_HW_PARAM_RATE, | ||
1742 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | ||
1743 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | ||
1744 | SNDRV_PCM_HW_PARAM_TICK_TIME, | ||
1745 | -1 | ||
1746 | }; | ||
1747 | int err, *v; | ||
1748 | |||
1749 | for (v = vars; *v != -1; v++) { | ||
1750 | if (*v != SNDRV_PCM_HW_PARAM_BUFFER_SIZE) | ||
1751 | err = snd_pcm_hw_param_first(pcm, params, *v, NULL); | ||
1752 | else | ||
1753 | err = snd_pcm_hw_param_last(pcm, params, *v, NULL); | ||
1754 | if (snd_BUG_ON(err < 0)) | ||
1755 | return err; | ||
1756 | } | ||
1757 | return 0; | ||
1758 | } | ||
1759 | |||
1760 | static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, | 1685 | static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, |
1761 | void *arg) | 1686 | void *arg) |
1762 | { | 1687 | { |
@@ -1843,8 +1768,6 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, | |||
1843 | unsigned int cmd, void *arg) | 1768 | unsigned int cmd, void *arg) |
1844 | { | 1769 | { |
1845 | switch (cmd) { | 1770 | switch (cmd) { |
1846 | case SNDRV_PCM_IOCTL1_INFO: | ||
1847 | return 0; | ||
1848 | case SNDRV_PCM_IOCTL1_RESET: | 1771 | case SNDRV_PCM_IOCTL1_RESET: |
1849 | return snd_pcm_lib_ioctl_reset(substream, arg); | 1772 | return snd_pcm_lib_ioctl_reset(substream, arg); |
1850 | case SNDRV_PCM_IOCTL1_CHANNEL_INFO: | 1773 | case SNDRV_PCM_IOCTL1_CHANNEL_INFO: |
@@ -1854,7 +1777,6 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, | |||
1854 | } | 1777 | } |
1855 | return -ENXIO; | 1778 | return -ENXIO; |
1856 | } | 1779 | } |
1857 | |||
1858 | EXPORT_SYMBOL(snd_pcm_lib_ioctl); | 1780 | EXPORT_SYMBOL(snd_pcm_lib_ioctl); |
1859 | 1781 | ||
1860 | /** | 1782 | /** |
@@ -1890,7 +1812,6 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) | |||
1890 | kill_fasync(&runtime->fasync, SIGIO, POLL_IN); | 1812 | kill_fasync(&runtime->fasync, SIGIO, POLL_IN); |
1891 | snd_pcm_stream_unlock_irqrestore(substream, flags); | 1813 | snd_pcm_stream_unlock_irqrestore(substream, flags); |
1892 | } | 1814 | } |
1893 | |||
1894 | EXPORT_SYMBOL(snd_pcm_period_elapsed); | 1815 | EXPORT_SYMBOL(snd_pcm_period_elapsed); |
1895 | 1816 | ||
1896 | /* | 1817 | /* |
@@ -1985,129 +1906,147 @@ static int wait_for_avail(struct snd_pcm_substream *substream, | |||
1985 | return err; | 1906 | return err; |
1986 | } | 1907 | } |
1987 | 1908 | ||
1988 | static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, | 1909 | typedef int (*pcm_transfer_f)(struct snd_pcm_substream *substream, |
1989 | unsigned int hwoff, | 1910 | int channel, unsigned long hwoff, |
1990 | unsigned long data, unsigned int off, | 1911 | void *buf, unsigned long bytes); |
1991 | snd_pcm_uframes_t frames) | 1912 | |
1913 | typedef int (*pcm_copy_f)(struct snd_pcm_substream *, snd_pcm_uframes_t, void *, | ||
1914 | snd_pcm_uframes_t, snd_pcm_uframes_t, pcm_transfer_f); | ||
1915 | |||
1916 | /* calculate the target DMA-buffer position to be written/read */ | ||
1917 | static void *get_dma_ptr(struct snd_pcm_runtime *runtime, | ||
1918 | int channel, unsigned long hwoff) | ||
1992 | { | 1919 | { |
1993 | struct snd_pcm_runtime *runtime = substream->runtime; | 1920 | return runtime->dma_area + hwoff + |
1994 | int err; | 1921 | channel * (runtime->dma_bytes / runtime->channels); |
1995 | char __user *buf = (char __user *) data + frames_to_bytes(runtime, off); | 1922 | } |
1996 | if (substream->ops->copy) { | 1923 | |
1997 | if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0) | 1924 | /* default copy_user ops for write; used for both interleaved and non- modes */ |
1998 | return err; | 1925 | static int default_write_copy(struct snd_pcm_substream *substream, |
1999 | } else { | 1926 | int channel, unsigned long hwoff, |
2000 | char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); | 1927 | void *buf, unsigned long bytes) |
2001 | if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) | 1928 | { |
2002 | return -EFAULT; | 1929 | if (copy_from_user(get_dma_ptr(substream->runtime, channel, hwoff), |
2003 | } | 1930 | (void __user *)buf, bytes)) |
1931 | return -EFAULT; | ||
2004 | return 0; | 1932 | return 0; |
2005 | } | 1933 | } |
2006 | |||
2007 | typedef int (*transfer_f)(struct snd_pcm_substream *substream, unsigned int hwoff, | ||
2008 | unsigned long data, unsigned int off, | ||
2009 | snd_pcm_uframes_t size); | ||
2010 | 1934 | ||
2011 | static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, | 1935 | /* default copy_kernel ops for write */ |
2012 | unsigned long data, | 1936 | static int default_write_copy_kernel(struct snd_pcm_substream *substream, |
2013 | snd_pcm_uframes_t size, | 1937 | int channel, unsigned long hwoff, |
2014 | int nonblock, | 1938 | void *buf, unsigned long bytes) |
2015 | transfer_f transfer) | 1939 | { |
1940 | memcpy(get_dma_ptr(substream->runtime, channel, hwoff), buf, bytes); | ||
1941 | return 0; | ||
1942 | } | ||
1943 | |||
1944 | /* fill silence instead of copy data; called as a transfer helper | ||
1945 | * from __snd_pcm_lib_write() or directly from noninterleaved_copy() when | ||
1946 | * a NULL buffer is passed | ||
1947 | */ | ||
1948 | static int fill_silence(struct snd_pcm_substream *substream, int channel, | ||
1949 | unsigned long hwoff, void *buf, unsigned long bytes) | ||
2016 | { | 1950 | { |
2017 | struct snd_pcm_runtime *runtime = substream->runtime; | 1951 | struct snd_pcm_runtime *runtime = substream->runtime; |
2018 | snd_pcm_uframes_t xfer = 0; | ||
2019 | snd_pcm_uframes_t offset = 0; | ||
2020 | snd_pcm_uframes_t avail; | ||
2021 | int err = 0; | ||
2022 | 1952 | ||
2023 | if (size == 0) | 1953 | if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) |
2024 | return 0; | 1954 | return 0; |
1955 | if (substream->ops->fill_silence) | ||
1956 | return substream->ops->fill_silence(substream, channel, | ||
1957 | hwoff, bytes); | ||
2025 | 1958 | ||
2026 | snd_pcm_stream_lock_irq(substream); | 1959 | snd_pcm_format_set_silence(runtime->format, |
2027 | switch (runtime->status->state) { | 1960 | get_dma_ptr(runtime, channel, hwoff), |
2028 | case SNDRV_PCM_STATE_PREPARED: | 1961 | bytes_to_samples(runtime, bytes)); |
2029 | case SNDRV_PCM_STATE_RUNNING: | 1962 | return 0; |
2030 | case SNDRV_PCM_STATE_PAUSED: | 1963 | } |
2031 | break; | ||
2032 | case SNDRV_PCM_STATE_XRUN: | ||
2033 | err = -EPIPE; | ||
2034 | goto _end_unlock; | ||
2035 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2036 | err = -ESTRPIPE; | ||
2037 | goto _end_unlock; | ||
2038 | default: | ||
2039 | err = -EBADFD; | ||
2040 | goto _end_unlock; | ||
2041 | } | ||
2042 | 1964 | ||
2043 | runtime->twake = runtime->control->avail_min ? : 1; | 1965 | /* default copy_user ops for read; used for both interleaved and non- modes */ |
2044 | if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) | 1966 | static int default_read_copy(struct snd_pcm_substream *substream, |
2045 | snd_pcm_update_hw_ptr(substream); | 1967 | int channel, unsigned long hwoff, |
2046 | avail = snd_pcm_playback_avail(runtime); | 1968 | void *buf, unsigned long bytes) |
2047 | while (size > 0) { | 1969 | { |
2048 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; | 1970 | if (copy_to_user((void __user *)buf, |
2049 | snd_pcm_uframes_t cont; | 1971 | get_dma_ptr(substream->runtime, channel, hwoff), |
2050 | if (!avail) { | 1972 | bytes)) |
2051 | if (nonblock) { | 1973 | return -EFAULT; |
2052 | err = -EAGAIN; | 1974 | return 0; |
2053 | goto _end_unlock; | 1975 | } |
2054 | } | ||
2055 | runtime->twake = min_t(snd_pcm_uframes_t, size, | ||
2056 | runtime->control->avail_min ? : 1); | ||
2057 | err = wait_for_avail(substream, &avail); | ||
2058 | if (err < 0) | ||
2059 | goto _end_unlock; | ||
2060 | } | ||
2061 | frames = size > avail ? avail : size; | ||
2062 | cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; | ||
2063 | if (frames > cont) | ||
2064 | frames = cont; | ||
2065 | if (snd_BUG_ON(!frames)) { | ||
2066 | runtime->twake = 0; | ||
2067 | snd_pcm_stream_unlock_irq(substream); | ||
2068 | return -EINVAL; | ||
2069 | } | ||
2070 | appl_ptr = runtime->control->appl_ptr; | ||
2071 | appl_ofs = appl_ptr % runtime->buffer_size; | ||
2072 | snd_pcm_stream_unlock_irq(substream); | ||
2073 | err = transfer(substream, appl_ofs, data, offset, frames); | ||
2074 | snd_pcm_stream_lock_irq(substream); | ||
2075 | if (err < 0) | ||
2076 | goto _end_unlock; | ||
2077 | switch (runtime->status->state) { | ||
2078 | case SNDRV_PCM_STATE_XRUN: | ||
2079 | err = -EPIPE; | ||
2080 | goto _end_unlock; | ||
2081 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2082 | err = -ESTRPIPE; | ||
2083 | goto _end_unlock; | ||
2084 | default: | ||
2085 | break; | ||
2086 | } | ||
2087 | appl_ptr += frames; | ||
2088 | if (appl_ptr >= runtime->boundary) | ||
2089 | appl_ptr -= runtime->boundary; | ||
2090 | runtime->control->appl_ptr = appl_ptr; | ||
2091 | if (substream->ops->ack) | ||
2092 | substream->ops->ack(substream); | ||
2093 | 1976 | ||
2094 | offset += frames; | 1977 | /* default copy_kernel ops for read */ |
2095 | size -= frames; | 1978 | static int default_read_copy_kernel(struct snd_pcm_substream *substream, |
2096 | xfer += frames; | 1979 | int channel, unsigned long hwoff, |
2097 | avail -= frames; | 1980 | void *buf, unsigned long bytes) |
2098 | if (runtime->status->state == SNDRV_PCM_STATE_PREPARED && | 1981 | { |
2099 | snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) { | 1982 | memcpy(buf, get_dma_ptr(substream->runtime, channel, hwoff), bytes); |
2100 | err = snd_pcm_start(substream); | 1983 | return 0; |
2101 | if (err < 0) | 1984 | } |
2102 | goto _end_unlock; | 1985 | |
2103 | } | 1986 | /* call transfer function with the converted pointers and sizes; |
1987 | * for interleaved mode, it's one shot for all samples | ||
1988 | */ | ||
1989 | static int interleaved_copy(struct snd_pcm_substream *substream, | ||
1990 | snd_pcm_uframes_t hwoff, void *data, | ||
1991 | snd_pcm_uframes_t off, | ||
1992 | snd_pcm_uframes_t frames, | ||
1993 | pcm_transfer_f transfer) | ||
1994 | { | ||
1995 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1996 | |||
1997 | /* convert to bytes */ | ||
1998 | hwoff = frames_to_bytes(runtime, hwoff); | ||
1999 | off = frames_to_bytes(runtime, off); | ||
2000 | frames = frames_to_bytes(runtime, frames); | ||
2001 | return transfer(substream, 0, hwoff, data + off, frames); | ||
2002 | } | ||
2003 | |||
2004 | /* call transfer function with the converted pointers and sizes for each | ||
2005 | * non-interleaved channel; when buffer is NULL, silencing instead of copying | ||
2006 | */ | ||
2007 | static int noninterleaved_copy(struct snd_pcm_substream *substream, | ||
2008 | snd_pcm_uframes_t hwoff, void *data, | ||
2009 | snd_pcm_uframes_t off, | ||
2010 | snd_pcm_uframes_t frames, | ||
2011 | pcm_transfer_f transfer) | ||
2012 | { | ||
2013 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
2014 | int channels = runtime->channels; | ||
2015 | void **bufs = data; | ||
2016 | int c, err; | ||
2017 | |||
2018 | /* convert to bytes; note that it's not frames_to_bytes() here. | ||
2019 | * in non-interleaved mode, we copy for each channel, thus | ||
2020 | * each copy is n_samples bytes x channels = whole frames. | ||
2021 | */ | ||
2022 | off = samples_to_bytes(runtime, off); | ||
2023 | frames = samples_to_bytes(runtime, frames); | ||
2024 | hwoff = samples_to_bytes(runtime, hwoff); | ||
2025 | for (c = 0; c < channels; ++c, ++bufs) { | ||
2026 | if (!data || !*bufs) | ||
2027 | err = fill_silence(substream, c, hwoff, NULL, frames); | ||
2028 | else | ||
2029 | err = transfer(substream, c, hwoff, *bufs + off, | ||
2030 | frames); | ||
2031 | if (err < 0) | ||
2032 | return err; | ||
2104 | } | 2033 | } |
2105 | _end_unlock: | 2034 | return 0; |
2106 | runtime->twake = 0; | 2035 | } |
2107 | if (xfer > 0 && err >= 0) | 2036 | |
2108 | snd_pcm_update_state(substream, runtime); | 2037 | /* fill silence on the given buffer position; |
2109 | snd_pcm_stream_unlock_irq(substream); | 2038 | * called from snd_pcm_playback_silence() |
2110 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; | 2039 | */ |
2040 | static int fill_silence_frames(struct snd_pcm_substream *substream, | ||
2041 | snd_pcm_uframes_t off, snd_pcm_uframes_t frames) | ||
2042 | { | ||
2043 | if (substream->runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED || | ||
2044 | substream->runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) | ||
2045 | return interleaved_copy(substream, off, NULL, 0, frames, | ||
2046 | fill_silence); | ||
2047 | else | ||
2048 | return noninterleaved_copy(substream, off, NULL, 0, frames, | ||
2049 | fill_silence); | ||
2111 | } | 2050 | } |
2112 | 2051 | ||
2113 | /* sanity-check for read/write methods */ | 2052 | /* sanity-check for read/write methods */ |
@@ -2117,164 +2056,137 @@ static int pcm_sanity_check(struct snd_pcm_substream *substream) | |||
2117 | if (PCM_RUNTIME_CHECK(substream)) | 2056 | if (PCM_RUNTIME_CHECK(substream)) |
2118 | return -ENXIO; | 2057 | return -ENXIO; |
2119 | runtime = substream->runtime; | 2058 | runtime = substream->runtime; |
2120 | if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area)) | 2059 | if (snd_BUG_ON(!substream->ops->copy_user && !runtime->dma_area)) |
2121 | return -EINVAL; | 2060 | return -EINVAL; |
2122 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 2061 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
2123 | return -EBADFD; | 2062 | return -EBADFD; |
2124 | return 0; | 2063 | return 0; |
2125 | } | 2064 | } |
2126 | 2065 | ||
2127 | snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size) | 2066 | static int pcm_accessible_state(struct snd_pcm_runtime *runtime) |
2128 | { | 2067 | { |
2129 | struct snd_pcm_runtime *runtime; | 2068 | switch (runtime->status->state) { |
2130 | int nonblock; | 2069 | case SNDRV_PCM_STATE_PREPARED: |
2131 | int err; | 2070 | case SNDRV_PCM_STATE_RUNNING: |
2132 | 2071 | case SNDRV_PCM_STATE_PAUSED: | |
2133 | err = pcm_sanity_check(substream); | 2072 | return 0; |
2134 | if (err < 0) | 2073 | case SNDRV_PCM_STATE_XRUN: |
2135 | return err; | 2074 | return -EPIPE; |
2136 | runtime = substream->runtime; | 2075 | case SNDRV_PCM_STATE_SUSPENDED: |
2137 | nonblock = !!(substream->f_flags & O_NONBLOCK); | 2076 | return -ESTRPIPE; |
2138 | 2077 | default: | |
2139 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && | 2078 | return -EBADFD; |
2140 | runtime->channels > 1) | 2079 | } |
2141 | return -EINVAL; | ||
2142 | return snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock, | ||
2143 | snd_pcm_lib_write_transfer); | ||
2144 | } | 2080 | } |
2145 | 2081 | ||
2146 | EXPORT_SYMBOL(snd_pcm_lib_write); | 2082 | /* update to the given appl_ptr and call ack callback if needed; |
2147 | 2083 | * when an error is returned, take back to the original value | |
2148 | static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, | 2084 | */ |
2149 | unsigned int hwoff, | 2085 | int pcm_lib_apply_appl_ptr(struct snd_pcm_substream *substream, |
2150 | unsigned long data, unsigned int off, | 2086 | snd_pcm_uframes_t appl_ptr) |
2151 | snd_pcm_uframes_t frames) | ||
2152 | { | 2087 | { |
2153 | struct snd_pcm_runtime *runtime = substream->runtime; | 2088 | struct snd_pcm_runtime *runtime = substream->runtime; |
2154 | int err; | 2089 | snd_pcm_uframes_t old_appl_ptr = runtime->control->appl_ptr; |
2155 | void __user **bufs = (void __user **)data; | 2090 | int ret; |
2156 | int channels = runtime->channels; | 2091 | |
2157 | int c; | 2092 | if (old_appl_ptr == appl_ptr) |
2158 | if (substream->ops->copy) { | 2093 | return 0; |
2159 | if (snd_BUG_ON(!substream->ops->silence)) | 2094 | |
2160 | return -EINVAL; | 2095 | runtime->control->appl_ptr = appl_ptr; |
2161 | for (c = 0; c < channels; ++c, ++bufs) { | 2096 | if (substream->ops->ack) { |
2162 | if (*bufs == NULL) { | 2097 | ret = substream->ops->ack(substream); |
2163 | if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0) | 2098 | if (ret < 0) { |
2164 | return err; | 2099 | runtime->control->appl_ptr = old_appl_ptr; |
2165 | } else { | 2100 | return ret; |
2166 | char __user *buf = *bufs + samples_to_bytes(runtime, off); | ||
2167 | if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0) | ||
2168 | return err; | ||
2169 | } | ||
2170 | } | ||
2171 | } else { | ||
2172 | /* default transfer behaviour */ | ||
2173 | size_t dma_csize = runtime->dma_bytes / channels; | ||
2174 | for (c = 0; c < channels; ++c, ++bufs) { | ||
2175 | char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); | ||
2176 | if (*bufs == NULL) { | ||
2177 | snd_pcm_format_set_silence(runtime->format, hwbuf, frames); | ||
2178 | } else { | ||
2179 | char __user *buf = *bufs + samples_to_bytes(runtime, off); | ||
2180 | if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames))) | ||
2181 | return -EFAULT; | ||
2182 | } | ||
2183 | } | 2101 | } |
2184 | } | 2102 | } |
2103 | |||
2104 | trace_applptr(substream, old_appl_ptr, appl_ptr); | ||
2105 | |||
2185 | return 0; | 2106 | return 0; |
2186 | } | 2107 | } |
2187 | 2108 | ||
2188 | snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, | 2109 | /* the common loop for read/write data */ |
2189 | void __user **bufs, | 2110 | snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, |
2190 | snd_pcm_uframes_t frames) | 2111 | void *data, bool interleaved, |
2112 | snd_pcm_uframes_t size, bool in_kernel) | ||
2191 | { | 2113 | { |
2192 | struct snd_pcm_runtime *runtime; | 2114 | struct snd_pcm_runtime *runtime = substream->runtime; |
2193 | int nonblock; | 2115 | snd_pcm_uframes_t xfer = 0; |
2116 | snd_pcm_uframes_t offset = 0; | ||
2117 | snd_pcm_uframes_t avail; | ||
2118 | pcm_copy_f writer; | ||
2119 | pcm_transfer_f transfer; | ||
2120 | bool nonblock; | ||
2121 | bool is_playback; | ||
2194 | int err; | 2122 | int err; |
2195 | 2123 | ||
2196 | err = pcm_sanity_check(substream); | 2124 | err = pcm_sanity_check(substream); |
2197 | if (err < 0) | 2125 | if (err < 0) |
2198 | return err; | 2126 | return err; |
2199 | runtime = substream->runtime; | ||
2200 | nonblock = !!(substream->f_flags & O_NONBLOCK); | ||
2201 | 2127 | ||
2202 | if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) | 2128 | is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
2203 | return -EINVAL; | 2129 | if (interleaved) { |
2204 | return snd_pcm_lib_write1(substream, (unsigned long)bufs, frames, | 2130 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && |
2205 | nonblock, snd_pcm_lib_writev_transfer); | 2131 | runtime->channels > 1) |
2206 | } | 2132 | return -EINVAL; |
2207 | 2133 | writer = interleaved_copy; | |
2208 | EXPORT_SYMBOL(snd_pcm_lib_writev); | ||
2209 | |||
2210 | static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, | ||
2211 | unsigned int hwoff, | ||
2212 | unsigned long data, unsigned int off, | ||
2213 | snd_pcm_uframes_t frames) | ||
2214 | { | ||
2215 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
2216 | int err; | ||
2217 | char __user *buf = (char __user *) data + frames_to_bytes(runtime, off); | ||
2218 | if (substream->ops->copy) { | ||
2219 | if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0) | ||
2220 | return err; | ||
2221 | } else { | 2134 | } else { |
2222 | char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); | 2135 | if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) |
2223 | if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) | 2136 | return -EINVAL; |
2224 | return -EFAULT; | 2137 | writer = noninterleaved_copy; |
2225 | } | 2138 | } |
2226 | return 0; | ||
2227 | } | ||
2228 | 2139 | ||
2229 | static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | 2140 | if (!data) { |
2230 | unsigned long data, | 2141 | if (is_playback) |
2231 | snd_pcm_uframes_t size, | 2142 | transfer = fill_silence; |
2232 | int nonblock, | 2143 | else |
2233 | transfer_f transfer) | 2144 | return -EINVAL; |
2234 | { | 2145 | } else if (in_kernel) { |
2235 | struct snd_pcm_runtime *runtime = substream->runtime; | 2146 | if (substream->ops->copy_kernel) |
2236 | snd_pcm_uframes_t xfer = 0; | 2147 | transfer = substream->ops->copy_kernel; |
2237 | snd_pcm_uframes_t offset = 0; | 2148 | else |
2238 | snd_pcm_uframes_t avail; | 2149 | transfer = is_playback ? |
2239 | int err = 0; | 2150 | default_write_copy_kernel : default_read_copy_kernel; |
2151 | } else { | ||
2152 | if (substream->ops->copy_user) | ||
2153 | transfer = (pcm_transfer_f)substream->ops->copy_user; | ||
2154 | else | ||
2155 | transfer = is_playback ? | ||
2156 | default_write_copy : default_read_copy; | ||
2157 | } | ||
2240 | 2158 | ||
2241 | if (size == 0) | 2159 | if (size == 0) |
2242 | return 0; | 2160 | return 0; |
2243 | 2161 | ||
2162 | nonblock = !!(substream->f_flags & O_NONBLOCK); | ||
2163 | |||
2244 | snd_pcm_stream_lock_irq(substream); | 2164 | snd_pcm_stream_lock_irq(substream); |
2245 | switch (runtime->status->state) { | 2165 | err = pcm_accessible_state(runtime); |
2246 | case SNDRV_PCM_STATE_PREPARED: | 2166 | if (err < 0) |
2247 | if (size >= runtime->start_threshold) { | ||
2248 | err = snd_pcm_start(substream); | ||
2249 | if (err < 0) | ||
2250 | goto _end_unlock; | ||
2251 | } | ||
2252 | break; | ||
2253 | case SNDRV_PCM_STATE_DRAINING: | ||
2254 | case SNDRV_PCM_STATE_RUNNING: | ||
2255 | case SNDRV_PCM_STATE_PAUSED: | ||
2256 | break; | ||
2257 | case SNDRV_PCM_STATE_XRUN: | ||
2258 | err = -EPIPE; | ||
2259 | goto _end_unlock; | ||
2260 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2261 | err = -ESTRPIPE; | ||
2262 | goto _end_unlock; | ||
2263 | default: | ||
2264 | err = -EBADFD; | ||
2265 | goto _end_unlock; | 2167 | goto _end_unlock; |
2168 | |||
2169 | if (!is_playback && | ||
2170 | runtime->status->state == SNDRV_PCM_STATE_PREPARED && | ||
2171 | size >= runtime->start_threshold) { | ||
2172 | err = snd_pcm_start(substream); | ||
2173 | if (err < 0) | ||
2174 | goto _end_unlock; | ||
2266 | } | 2175 | } |
2267 | 2176 | ||
2268 | runtime->twake = runtime->control->avail_min ? : 1; | 2177 | runtime->twake = runtime->control->avail_min ? : 1; |
2269 | if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) | 2178 | if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) |
2270 | snd_pcm_update_hw_ptr(substream); | 2179 | snd_pcm_update_hw_ptr(substream); |
2271 | avail = snd_pcm_capture_avail(runtime); | 2180 | if (is_playback) |
2181 | avail = snd_pcm_playback_avail(runtime); | ||
2182 | else | ||
2183 | avail = snd_pcm_capture_avail(runtime); | ||
2272 | while (size > 0) { | 2184 | while (size > 0) { |
2273 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; | 2185 | snd_pcm_uframes_t frames, appl_ptr, appl_ofs; |
2274 | snd_pcm_uframes_t cont; | 2186 | snd_pcm_uframes_t cont; |
2275 | if (!avail) { | 2187 | if (!avail) { |
2276 | if (runtime->status->state == | 2188 | if (!is_playback && |
2277 | SNDRV_PCM_STATE_DRAINING) { | 2189 | runtime->status->state == SNDRV_PCM_STATE_DRAINING) { |
2278 | snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); | 2190 | snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); |
2279 | goto _end_unlock; | 2191 | goto _end_unlock; |
2280 | } | 2192 | } |
@@ -2302,31 +2214,32 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
2302 | appl_ptr = runtime->control->appl_ptr; | 2214 | appl_ptr = runtime->control->appl_ptr; |
2303 | appl_ofs = appl_ptr % runtime->buffer_size; | 2215 | appl_ofs = appl_ptr % runtime->buffer_size; |
2304 | snd_pcm_stream_unlock_irq(substream); | 2216 | snd_pcm_stream_unlock_irq(substream); |
2305 | err = transfer(substream, appl_ofs, data, offset, frames); | 2217 | err = writer(substream, appl_ofs, data, offset, frames, |
2218 | transfer); | ||
2306 | snd_pcm_stream_lock_irq(substream); | 2219 | snd_pcm_stream_lock_irq(substream); |
2307 | if (err < 0) | 2220 | if (err < 0) |
2308 | goto _end_unlock; | 2221 | goto _end_unlock; |
2309 | switch (runtime->status->state) { | 2222 | err = pcm_accessible_state(runtime); |
2310 | case SNDRV_PCM_STATE_XRUN: | 2223 | if (err < 0) |
2311 | err = -EPIPE; | ||
2312 | goto _end_unlock; | ||
2313 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2314 | err = -ESTRPIPE; | ||
2315 | goto _end_unlock; | 2224 | goto _end_unlock; |
2316 | default: | ||
2317 | break; | ||
2318 | } | ||
2319 | appl_ptr += frames; | 2225 | appl_ptr += frames; |
2320 | if (appl_ptr >= runtime->boundary) | 2226 | if (appl_ptr >= runtime->boundary) |
2321 | appl_ptr -= runtime->boundary; | 2227 | appl_ptr -= runtime->boundary; |
2322 | runtime->control->appl_ptr = appl_ptr; | 2228 | err = pcm_lib_apply_appl_ptr(substream, appl_ptr); |
2323 | if (substream->ops->ack) | 2229 | if (err < 0) |
2324 | substream->ops->ack(substream); | 2230 | goto _end_unlock; |
2325 | 2231 | ||
2326 | offset += frames; | 2232 | offset += frames; |
2327 | size -= frames; | 2233 | size -= frames; |
2328 | xfer += frames; | 2234 | xfer += frames; |
2329 | avail -= frames; | 2235 | avail -= frames; |
2236 | if (is_playback && | ||
2237 | runtime->status->state == SNDRV_PCM_STATE_PREPARED && | ||
2238 | snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) { | ||
2239 | err = snd_pcm_start(substream); | ||
2240 | if (err < 0) | ||
2241 | goto _end_unlock; | ||
2242 | } | ||
2330 | } | 2243 | } |
2331 | _end_unlock: | 2244 | _end_unlock: |
2332 | runtime->twake = 0; | 2245 | runtime->twake = 0; |
@@ -2335,83 +2248,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, | |||
2335 | snd_pcm_stream_unlock_irq(substream); | 2248 | snd_pcm_stream_unlock_irq(substream); |
2336 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; | 2249 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; |
2337 | } | 2250 | } |
2338 | 2251 | EXPORT_SYMBOL(__snd_pcm_lib_xfer); | |
2339 | snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __user *buf, snd_pcm_uframes_t size) | ||
2340 | { | ||
2341 | struct snd_pcm_runtime *runtime; | ||
2342 | int nonblock; | ||
2343 | int err; | ||
2344 | |||
2345 | err = pcm_sanity_check(substream); | ||
2346 | if (err < 0) | ||
2347 | return err; | ||
2348 | runtime = substream->runtime; | ||
2349 | nonblock = !!(substream->f_flags & O_NONBLOCK); | ||
2350 | if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) | ||
2351 | return -EINVAL; | ||
2352 | return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); | ||
2353 | } | ||
2354 | |||
2355 | EXPORT_SYMBOL(snd_pcm_lib_read); | ||
2356 | |||
2357 | static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, | ||
2358 | unsigned int hwoff, | ||
2359 | unsigned long data, unsigned int off, | ||
2360 | snd_pcm_uframes_t frames) | ||
2361 | { | ||
2362 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
2363 | int err; | ||
2364 | void __user **bufs = (void __user **)data; | ||
2365 | int channels = runtime->channels; | ||
2366 | int c; | ||
2367 | if (substream->ops->copy) { | ||
2368 | for (c = 0; c < channels; ++c, ++bufs) { | ||
2369 | char __user *buf; | ||
2370 | if (*bufs == NULL) | ||
2371 | continue; | ||
2372 | buf = *bufs + samples_to_bytes(runtime, off); | ||
2373 | if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0) | ||
2374 | return err; | ||
2375 | } | ||
2376 | } else { | ||
2377 | snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; | ||
2378 | for (c = 0; c < channels; ++c, ++bufs) { | ||
2379 | char *hwbuf; | ||
2380 | char __user *buf; | ||
2381 | if (*bufs == NULL) | ||
2382 | continue; | ||
2383 | |||
2384 | hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); | ||
2385 | buf = *bufs + samples_to_bytes(runtime, off); | ||
2386 | if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames))) | ||
2387 | return -EFAULT; | ||
2388 | } | ||
2389 | } | ||
2390 | return 0; | ||
2391 | } | ||
2392 | |||
2393 | snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream, | ||
2394 | void __user **bufs, | ||
2395 | snd_pcm_uframes_t frames) | ||
2396 | { | ||
2397 | struct snd_pcm_runtime *runtime; | ||
2398 | int nonblock; | ||
2399 | int err; | ||
2400 | |||
2401 | err = pcm_sanity_check(substream); | ||
2402 | if (err < 0) | ||
2403 | return err; | ||
2404 | runtime = substream->runtime; | ||
2405 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | ||
2406 | return -EBADFD; | ||
2407 | |||
2408 | nonblock = !!(substream->f_flags & O_NONBLOCK); | ||
2409 | if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) | ||
2410 | return -EINVAL; | ||
2411 | return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); | ||
2412 | } | ||
2413 | |||
2414 | EXPORT_SYMBOL(snd_pcm_lib_readv); | ||
2415 | 2252 | ||
2416 | /* | 2253 | /* |
2417 | * standard channel mapping helpers | 2254 | * standard channel mapping helpers |
diff --git a/sound/core/pcm_local.h b/sound/core/pcm_local.h new file mode 100644 index 000000000000..16f254732b2a --- /dev/null +++ b/sound/core/pcm_local.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * pcm_local.h - a local header file for snd-pcm module. | ||
3 | * | ||
4 | * Copyright (c) Takashi Sakamoto <o-takashi@sakamocchi.jp> | ||
5 | * | ||
6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
7 | */ | ||
8 | |||
9 | #ifndef __SOUND_CORE_PCM_LOCAL_H | ||
10 | #define __SOUND_CORE_PCM_LOCAL_H | ||
11 | |||
12 | extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates; | ||
13 | |||
14 | void snd_interval_mul(const struct snd_interval *a, | ||
15 | const struct snd_interval *b, struct snd_interval *c); | ||
16 | void snd_interval_div(const struct snd_interval *a, | ||
17 | const struct snd_interval *b, struct snd_interval *c); | ||
18 | void snd_interval_muldivk(const struct snd_interval *a, | ||
19 | const struct snd_interval *b, | ||
20 | unsigned int k, struct snd_interval *c); | ||
21 | void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k, | ||
22 | const struct snd_interval *b, struct snd_interval *c); | ||
23 | |||
24 | int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream); | ||
25 | int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream); | ||
26 | |||
27 | int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, | ||
28 | snd_pcm_hw_param_t var, u_int32_t mask); | ||
29 | |||
30 | int pcm_lib_apply_appl_ptr(struct snd_pcm_substream *substream, | ||
31 | snd_pcm_uframes_t appl_ptr); | ||
32 | int snd_pcm_update_state(struct snd_pcm_substream *substream, | ||
33 | struct snd_pcm_runtime *runtime); | ||
34 | int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream); | ||
35 | |||
36 | void snd_pcm_playback_silence(struct snd_pcm_substream *substream, | ||
37 | snd_pcm_uframes_t new_hw_ptr); | ||
38 | |||
39 | #ifdef CONFIG_SND_PCM_TIMER | ||
40 | void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream); | ||
41 | void snd_pcm_timer_init(struct snd_pcm_substream *substream); | ||
42 | void snd_pcm_timer_done(struct snd_pcm_substream *substream); | ||
43 | #else | ||
44 | static inline void | ||
45 | snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) {} | ||
46 | static inline void snd_pcm_timer_init(struct snd_pcm_substream *substream) {} | ||
47 | static inline void snd_pcm_timer_done(struct snd_pcm_substream *substream) {} | ||
48 | #endif | ||
49 | |||
50 | #endif /* __SOUND_CORE_PCM_LOCAL_H */ | ||
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index b45f6aa32264..ae33e456708c 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c | |||
@@ -120,7 +120,6 @@ int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm) | |||
120 | snd_pcm_lib_preallocate_free(substream); | 120 | snd_pcm_lib_preallocate_free(substream); |
121 | return 0; | 121 | return 0; |
122 | } | 122 | } |
123 | |||
124 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); | 123 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); |
125 | 124 | ||
126 | #ifdef CONFIG_SND_VERBOSE_PROCFS | 125 | #ifdef CONFIG_SND_VERBOSE_PROCFS |
@@ -263,7 +262,6 @@ int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream, | |||
263 | substream->dma_buffer.dev.dev = data; | 262 | substream->dma_buffer.dev.dev = data; |
264 | return snd_pcm_lib_preallocate_pages1(substream, size, max); | 263 | return snd_pcm_lib_preallocate_pages1(substream, size, max); |
265 | } | 264 | } |
266 | |||
267 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages); | 265 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages); |
268 | 266 | ||
269 | /** | 267 | /** |
@@ -292,7 +290,6 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, | |||
292 | return err; | 290 | return err; |
293 | return 0; | 291 | return 0; |
294 | } | 292 | } |
295 | |||
296 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); | 293 | EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); |
297 | 294 | ||
298 | #ifdef CONFIG_SND_DMA_SGBUF | 295 | #ifdef CONFIG_SND_DMA_SGBUF |
@@ -314,7 +311,6 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne | |||
314 | return NULL; | 311 | return NULL; |
315 | return sgbuf->page_table[idx]; | 312 | return sgbuf->page_table[idx]; |
316 | } | 313 | } |
317 | |||
318 | EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); | 314 | EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); |
319 | #endif /* CONFIG_SND_DMA_SGBUF */ | 315 | #endif /* CONFIG_SND_DMA_SGBUF */ |
320 | 316 | ||
@@ -370,7 +366,6 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size) | |||
370 | runtime->dma_bytes = size; | 366 | runtime->dma_bytes = size; |
371 | return 1; /* area was changed */ | 367 | return 1; /* area was changed */ |
372 | } | 368 | } |
373 | |||
374 | EXPORT_SYMBOL(snd_pcm_lib_malloc_pages); | 369 | EXPORT_SYMBOL(snd_pcm_lib_malloc_pages); |
375 | 370 | ||
376 | /** | 371 | /** |
@@ -398,7 +393,6 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) | |||
398 | snd_pcm_set_runtime_buffer(substream, NULL); | 393 | snd_pcm_set_runtime_buffer(substream, NULL); |
399 | return 0; | 394 | return 0; |
400 | } | 395 | } |
401 | |||
402 | EXPORT_SYMBOL(snd_pcm_lib_free_pages); | 396 | EXPORT_SYMBOL(snd_pcm_lib_free_pages); |
403 | 397 | ||
404 | int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, | 398 | int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, |
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 53dc37357bca..9be81025372f 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c | |||
@@ -23,6 +23,9 @@ | |||
23 | #include <linux/export.h> | 23 | #include <linux/export.h> |
24 | #include <sound/core.h> | 24 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
26 | |||
27 | #include "pcm_local.h" | ||
28 | |||
26 | #define SND_PCM_FORMAT_UNKNOWN (-1) | 29 | #define SND_PCM_FORMAT_UNKNOWN (-1) |
27 | 30 | ||
28 | /* NOTE: "signed" prefix must be given below since the default char is | 31 | /* NOTE: "signed" prefix must be given below since the default char is |
@@ -245,7 +248,6 @@ int snd_pcm_format_signed(snd_pcm_format_t format) | |||
245 | return -EINVAL; | 248 | return -EINVAL; |
246 | return val; | 249 | return val; |
247 | } | 250 | } |
248 | |||
249 | EXPORT_SYMBOL(snd_pcm_format_signed); | 251 | EXPORT_SYMBOL(snd_pcm_format_signed); |
250 | 252 | ||
251 | /** | 253 | /** |
@@ -264,7 +266,6 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format) | |||
264 | return val; | 266 | return val; |
265 | return !val; | 267 | return !val; |
266 | } | 268 | } |
267 | |||
268 | EXPORT_SYMBOL(snd_pcm_format_unsigned); | 269 | EXPORT_SYMBOL(snd_pcm_format_unsigned); |
269 | 270 | ||
270 | /** | 271 | /** |
@@ -277,7 +278,6 @@ int snd_pcm_format_linear(snd_pcm_format_t format) | |||
277 | { | 278 | { |
278 | return snd_pcm_format_signed(format) >= 0; | 279 | return snd_pcm_format_signed(format) >= 0; |
279 | } | 280 | } |
280 | |||
281 | EXPORT_SYMBOL(snd_pcm_format_linear); | 281 | EXPORT_SYMBOL(snd_pcm_format_linear); |
282 | 282 | ||
283 | /** | 283 | /** |
@@ -296,7 +296,6 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format) | |||
296 | return -EINVAL; | 296 | return -EINVAL; |
297 | return val; | 297 | return val; |
298 | } | 298 | } |
299 | |||
300 | EXPORT_SYMBOL(snd_pcm_format_little_endian); | 299 | EXPORT_SYMBOL(snd_pcm_format_little_endian); |
301 | 300 | ||
302 | /** | 301 | /** |
@@ -315,7 +314,6 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format) | |||
315 | return val; | 314 | return val; |
316 | return !val; | 315 | return !val; |
317 | } | 316 | } |
318 | |||
319 | EXPORT_SYMBOL(snd_pcm_format_big_endian); | 317 | EXPORT_SYMBOL(snd_pcm_format_big_endian); |
320 | 318 | ||
321 | /** | 319 | /** |
@@ -334,7 +332,6 @@ int snd_pcm_format_width(snd_pcm_format_t format) | |||
334 | return -EINVAL; | 332 | return -EINVAL; |
335 | return val; | 333 | return val; |
336 | } | 334 | } |
337 | |||
338 | EXPORT_SYMBOL(snd_pcm_format_width); | 335 | EXPORT_SYMBOL(snd_pcm_format_width); |
339 | 336 | ||
340 | /** | 337 | /** |
@@ -353,7 +350,6 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format) | |||
353 | return -EINVAL; | 350 | return -EINVAL; |
354 | return val; | 351 | return val; |
355 | } | 352 | } |
356 | |||
357 | EXPORT_SYMBOL(snd_pcm_format_physical_width); | 353 | EXPORT_SYMBOL(snd_pcm_format_physical_width); |
358 | 354 | ||
359 | /** | 355 | /** |
@@ -371,7 +367,6 @@ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples) | |||
371 | return -EINVAL; | 367 | return -EINVAL; |
372 | return samples * phys_width / 8; | 368 | return samples * phys_width / 8; |
373 | } | 369 | } |
374 | |||
375 | EXPORT_SYMBOL(snd_pcm_format_size); | 370 | EXPORT_SYMBOL(snd_pcm_format_size); |
376 | 371 | ||
377 | /** | 372 | /** |
@@ -388,7 +383,6 @@ const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) | |||
388 | return NULL; | 383 | return NULL; |
389 | return pcm_formats[(INT)format].silence; | 384 | return pcm_formats[(INT)format].silence; |
390 | } | 385 | } |
391 | |||
392 | EXPORT_SYMBOL(snd_pcm_format_silence_64); | 386 | EXPORT_SYMBOL(snd_pcm_format_silence_64); |
393 | 387 | ||
394 | /** | 388 | /** |
@@ -459,7 +453,6 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int | |||
459 | #endif | 453 | #endif |
460 | return 0; | 454 | return 0; |
461 | } | 455 | } |
462 | |||
463 | EXPORT_SYMBOL(snd_pcm_format_set_silence); | 456 | EXPORT_SYMBOL(snd_pcm_format_set_silence); |
464 | 457 | ||
465 | /** | 458 | /** |
@@ -488,7 +481,6 @@ int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime) | |||
488 | } | 481 | } |
489 | return 0; | 482 | return 0; |
490 | } | 483 | } |
491 | |||
492 | EXPORT_SYMBOL(snd_pcm_limit_hw_rates); | 484 | EXPORT_SYMBOL(snd_pcm_limit_hw_rates); |
493 | 485 | ||
494 | /** | 486 | /** |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 13dec5ec93f2..d35c6614fdab 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -37,6 +37,18 @@ | |||
37 | #include <sound/minors.h> | 37 | #include <sound/minors.h> |
38 | #include <linux/uio.h> | 38 | #include <linux/uio.h> |
39 | 39 | ||
40 | #include "pcm_local.h" | ||
41 | |||
42 | #ifdef CONFIG_SND_DEBUG | ||
43 | #define CREATE_TRACE_POINTS | ||
44 | #include "pcm_param_trace.h" | ||
45 | #else | ||
46 | #define trace_hw_mask_param_enabled() 0 | ||
47 | #define trace_hw_interval_param_enabled() 0 | ||
48 | #define trace_hw_mask_param(substream, type, index, prev, curr) | ||
49 | #define trace_hw_interval_param(substream, type, index, prev, curr) | ||
50 | #endif | ||
51 | |||
40 | /* | 52 | /* |
41 | * Compatibility | 53 | * Compatibility |
42 | */ | 54 | */ |
@@ -181,20 +193,6 @@ void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, | |||
181 | } | 193 | } |
182 | EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore); | 194 | EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore); |
183 | 195 | ||
184 | static inline mm_segment_t snd_enter_user(void) | ||
185 | { | ||
186 | mm_segment_t fs = get_fs(); | ||
187 | set_fs(get_ds()); | ||
188 | return fs; | ||
189 | } | ||
190 | |||
191 | static inline void snd_leave_user(mm_segment_t fs) | ||
192 | { | ||
193 | set_fs(fs); | ||
194 | } | ||
195 | |||
196 | |||
197 | |||
198 | int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) | 196 | int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) |
199 | { | 197 | { |
200 | struct snd_pcm_runtime *runtime; | 198 | struct snd_pcm_runtime *runtime; |
@@ -214,11 +212,7 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) | |||
214 | info->subdevices_avail = pstr->substream_count - pstr->substream_opened; | 212 | info->subdevices_avail = pstr->substream_count - pstr->substream_opened; |
215 | strlcpy(info->subname, substream->name, sizeof(info->subname)); | 213 | strlcpy(info->subname, substream->name, sizeof(info->subname)); |
216 | runtime = substream->runtime; | 214 | runtime = substream->runtime; |
217 | /* AB: FIXME!!! This is definitely nonsense */ | 215 | |
218 | if (runtime) { | ||
219 | info->sync = runtime->sync; | ||
220 | substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info); | ||
221 | } | ||
222 | return 0; | 216 | return 0; |
223 | } | 217 | } |
224 | 218 | ||
@@ -255,205 +249,268 @@ static bool hw_support_mmap(struct snd_pcm_substream *substream) | |||
255 | return true; | 249 | return true; |
256 | } | 250 | } |
257 | 251 | ||
258 | #undef RULES_DEBUG | 252 | static int constrain_mask_params(struct snd_pcm_substream *substream, |
259 | 253 | struct snd_pcm_hw_params *params) | |
260 | #ifdef RULES_DEBUG | ||
261 | #define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v | ||
262 | static const char * const snd_pcm_hw_param_names[] = { | ||
263 | HW_PARAM(ACCESS), | ||
264 | HW_PARAM(FORMAT), | ||
265 | HW_PARAM(SUBFORMAT), | ||
266 | HW_PARAM(SAMPLE_BITS), | ||
267 | HW_PARAM(FRAME_BITS), | ||
268 | HW_PARAM(CHANNELS), | ||
269 | HW_PARAM(RATE), | ||
270 | HW_PARAM(PERIOD_TIME), | ||
271 | HW_PARAM(PERIOD_SIZE), | ||
272 | HW_PARAM(PERIOD_BYTES), | ||
273 | HW_PARAM(PERIODS), | ||
274 | HW_PARAM(BUFFER_TIME), | ||
275 | HW_PARAM(BUFFER_SIZE), | ||
276 | HW_PARAM(BUFFER_BYTES), | ||
277 | HW_PARAM(TICK_TIME), | ||
278 | }; | ||
279 | #endif | ||
280 | |||
281 | int snd_pcm_hw_refine(struct snd_pcm_substream *substream, | ||
282 | struct snd_pcm_hw_params *params) | ||
283 | { | 254 | { |
255 | struct snd_pcm_hw_constraints *constrs = | ||
256 | &substream->runtime->hw_constraints; | ||
257 | struct snd_mask *m; | ||
284 | unsigned int k; | 258 | unsigned int k; |
285 | struct snd_pcm_hardware *hw; | 259 | struct snd_mask old_mask; |
286 | struct snd_interval *i = NULL; | 260 | int changed; |
287 | struct snd_mask *m = NULL; | ||
288 | struct snd_pcm_hw_constraints *constrs = &substream->runtime->hw_constraints; | ||
289 | unsigned int rstamps[constrs->rules_num]; | ||
290 | unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1]; | ||
291 | unsigned int stamp = 2; | ||
292 | int changed, again; | ||
293 | |||
294 | params->info = 0; | ||
295 | params->fifo_size = 0; | ||
296 | if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS)) | ||
297 | params->msbits = 0; | ||
298 | if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) { | ||
299 | params->rate_num = 0; | ||
300 | params->rate_den = 0; | ||
301 | } | ||
302 | 261 | ||
303 | for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) { | 262 | for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) { |
304 | m = hw_param_mask(params, k); | 263 | m = hw_param_mask(params, k); |
305 | if (snd_mask_empty(m)) | 264 | if (snd_mask_empty(m)) |
306 | return -EINVAL; | 265 | return -EINVAL; |
266 | |||
267 | /* This parameter is not requested to change by a caller. */ | ||
307 | if (!(params->rmask & (1 << k))) | 268 | if (!(params->rmask & (1 << k))) |
308 | continue; | 269 | continue; |
309 | #ifdef RULES_DEBUG | 270 | |
310 | pr_debug("%s = ", snd_pcm_hw_param_names[k]); | 271 | if (trace_hw_mask_param_enabled()) |
311 | pr_cont("%04x%04x%04x%04x -> ", m->bits[3], m->bits[2], m->bits[1], m->bits[0]); | 272 | old_mask = *m; |
312 | #endif | 273 | |
313 | changed = snd_mask_refine(m, constrs_mask(constrs, k)); | 274 | changed = snd_mask_refine(m, constrs_mask(constrs, k)); |
314 | #ifdef RULES_DEBUG | ||
315 | pr_cont("%04x%04x%04x%04x\n", m->bits[3], m->bits[2], m->bits[1], m->bits[0]); | ||
316 | #endif | ||
317 | if (changed) | ||
318 | params->cmask |= 1 << k; | ||
319 | if (changed < 0) | 275 | if (changed < 0) |
320 | return changed; | 276 | return changed; |
277 | if (changed == 0) | ||
278 | continue; | ||
279 | |||
280 | /* Set corresponding flag so that the caller gets it. */ | ||
281 | trace_hw_mask_param(substream, k, 0, &old_mask, m); | ||
282 | params->cmask |= 1 << k; | ||
321 | } | 283 | } |
322 | 284 | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int constrain_interval_params(struct snd_pcm_substream *substream, | ||
289 | struct snd_pcm_hw_params *params) | ||
290 | { | ||
291 | struct snd_pcm_hw_constraints *constrs = | ||
292 | &substream->runtime->hw_constraints; | ||
293 | struct snd_interval *i; | ||
294 | unsigned int k; | ||
295 | struct snd_interval old_interval; | ||
296 | int changed; | ||
297 | |||
323 | for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) { | 298 | for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) { |
324 | i = hw_param_interval(params, k); | 299 | i = hw_param_interval(params, k); |
325 | if (snd_interval_empty(i)) | 300 | if (snd_interval_empty(i)) |
326 | return -EINVAL; | 301 | return -EINVAL; |
302 | |||
303 | /* This parameter is not requested to change by a caller. */ | ||
327 | if (!(params->rmask & (1 << k))) | 304 | if (!(params->rmask & (1 << k))) |
328 | continue; | 305 | continue; |
329 | #ifdef RULES_DEBUG | 306 | |
330 | pr_debug("%s = ", snd_pcm_hw_param_names[k]); | 307 | if (trace_hw_interval_param_enabled()) |
331 | if (i->empty) | 308 | old_interval = *i; |
332 | pr_cont("empty"); | 309 | |
333 | else | ||
334 | pr_cont("%c%u %u%c", | ||
335 | i->openmin ? '(' : '[', i->min, | ||
336 | i->max, i->openmax ? ')' : ']'); | ||
337 | pr_cont(" -> "); | ||
338 | #endif | ||
339 | changed = snd_interval_refine(i, constrs_interval(constrs, k)); | 310 | changed = snd_interval_refine(i, constrs_interval(constrs, k)); |
340 | #ifdef RULES_DEBUG | ||
341 | if (i->empty) | ||
342 | pr_cont("empty\n"); | ||
343 | else | ||
344 | pr_cont("%c%u %u%c\n", | ||
345 | i->openmin ? '(' : '[', i->min, | ||
346 | i->max, i->openmax ? ')' : ']'); | ||
347 | #endif | ||
348 | if (changed) | ||
349 | params->cmask |= 1 << k; | ||
350 | if (changed < 0) | 311 | if (changed < 0) |
351 | return changed; | 312 | return changed; |
313 | if (changed == 0) | ||
314 | continue; | ||
315 | |||
316 | /* Set corresponding flag so that the caller gets it. */ | ||
317 | trace_hw_interval_param(substream, k, 0, &old_interval, i); | ||
318 | params->cmask |= 1 << k; | ||
352 | } | 319 | } |
353 | 320 | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int constrain_params_by_rules(struct snd_pcm_substream *substream, | ||
325 | struct snd_pcm_hw_params *params) | ||
326 | { | ||
327 | struct snd_pcm_hw_constraints *constrs = | ||
328 | &substream->runtime->hw_constraints; | ||
329 | unsigned int k; | ||
330 | unsigned int rstamps[constrs->rules_num]; | ||
331 | unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1]; | ||
332 | unsigned int stamp; | ||
333 | struct snd_pcm_hw_rule *r; | ||
334 | unsigned int d; | ||
335 | struct snd_mask old_mask; | ||
336 | struct snd_interval old_interval; | ||
337 | bool again; | ||
338 | int changed; | ||
339 | |||
340 | /* | ||
341 | * Each application of rule has own sequence number. | ||
342 | * | ||
343 | * Each member of 'rstamps' array represents the sequence number of | ||
344 | * recent application of corresponding rule. | ||
345 | */ | ||
354 | for (k = 0; k < constrs->rules_num; k++) | 346 | for (k = 0; k < constrs->rules_num; k++) |
355 | rstamps[k] = 0; | 347 | rstamps[k] = 0; |
356 | for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) | 348 | |
349 | /* | ||
350 | * Each member of 'vstamps' array represents the sequence number of | ||
351 | * recent application of rule in which corresponding parameters were | ||
352 | * changed. | ||
353 | * | ||
354 | * In initial state, elements corresponding to parameters requested by | ||
355 | * a caller is 1. For unrequested parameters, corresponding members | ||
356 | * have 0 so that the parameters are never changed anymore. | ||
357 | */ | ||
358 | for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) | ||
357 | vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0; | 359 | vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0; |
358 | do { | 360 | |
359 | again = 0; | 361 | /* Due to the above design, actual sequence number starts at 2. */ |
360 | for (k = 0; k < constrs->rules_num; k++) { | 362 | stamp = 2; |
361 | struct snd_pcm_hw_rule *r = &constrs->rules[k]; | 363 | retry: |
362 | unsigned int d; | 364 | /* Apply all rules in order. */ |
363 | int doit = 0; | 365 | again = false; |
364 | if (r->cond && !(r->cond & params->flags)) | 366 | for (k = 0; k < constrs->rules_num; k++) { |
365 | continue; | 367 | r = &constrs->rules[k]; |
366 | for (d = 0; r->deps[d] >= 0; d++) { | 368 | |
367 | if (vstamps[r->deps[d]] > rstamps[k]) { | 369 | /* |
368 | doit = 1; | 370 | * Check condition bits of this rule. When the rule has |
369 | break; | 371 | * some condition bits, parameter without the bits is |
370 | } | 372 | * never processed. SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP |
371 | } | 373 | * is an example of the condition bits. |
372 | if (!doit) | 374 | */ |
373 | continue; | 375 | if (r->cond && !(r->cond & params->flags)) |
374 | #ifdef RULES_DEBUG | 376 | continue; |
375 | pr_debug("Rule %d [%p]: ", k, r->func); | 377 | |
376 | if (r->var >= 0) { | 378 | /* |
377 | pr_cont("%s = ", snd_pcm_hw_param_names[r->var]); | 379 | * The 'deps' array includes maximum three dependencies |
378 | if (hw_is_mask(r->var)) { | 380 | * to SNDRV_PCM_HW_PARAM_XXXs for this rule. The fourth |
379 | m = hw_param_mask(params, r->var); | 381 | * member of this array is a sentinel and should be |
380 | pr_cont("%x", *m->bits); | 382 | * negative value. |
381 | } else { | 383 | * |
382 | i = hw_param_interval(params, r->var); | 384 | * This rule should be processed in this time when dependent |
383 | if (i->empty) | 385 | * parameters were changed at former applications of the other |
384 | pr_cont("empty"); | 386 | * rules. |
385 | else | 387 | */ |
386 | pr_cont("%c%u %u%c", | 388 | for (d = 0; r->deps[d] >= 0; d++) { |
387 | i->openmin ? '(' : '[', i->min, | 389 | if (vstamps[r->deps[d]] > rstamps[k]) |
388 | i->max, i->openmax ? ')' : ']'); | 390 | break; |
389 | } | 391 | } |
390 | } | 392 | if (r->deps[d] < 0) |
391 | #endif | 393 | continue; |
392 | changed = r->func(params, r); | 394 | |
393 | #ifdef RULES_DEBUG | 395 | if (trace_hw_mask_param_enabled()) { |
394 | if (r->var >= 0) { | 396 | if (hw_is_mask(r->var)) |
395 | pr_cont(" -> "); | 397 | old_mask = *hw_param_mask(params, r->var); |
396 | if (hw_is_mask(r->var)) | 398 | } |
397 | pr_cont("%x", *m->bits); | 399 | if (trace_hw_interval_param_enabled()) { |
398 | else { | 400 | if (hw_is_interval(r->var)) |
399 | if (i->empty) | 401 | old_interval = *hw_param_interval(params, r->var); |
400 | pr_cont("empty"); | 402 | } |
401 | else | 403 | |
402 | pr_cont("%c%u %u%c", | 404 | changed = r->func(params, r); |
403 | i->openmin ? '(' : '[', i->min, | 405 | if (changed < 0) |
404 | i->max, i->openmax ? ')' : ']'); | 406 | return changed; |
405 | } | 407 | |
408 | /* | ||
409 | * When the parameter is changed, notify it to the caller | ||
410 | * by corresponding returned bit, then preparing for next | ||
411 | * iteration. | ||
412 | */ | ||
413 | if (changed && r->var >= 0) { | ||
414 | if (hw_is_mask(r->var)) { | ||
415 | trace_hw_mask_param(substream, r->var, | ||
416 | k + 1, &old_mask, | ||
417 | hw_param_mask(params, r->var)); | ||
406 | } | 418 | } |
407 | pr_cont("\n"); | 419 | if (hw_is_interval(r->var)) { |
408 | #endif | 420 | trace_hw_interval_param(substream, r->var, |
409 | rstamps[k] = stamp; | 421 | k + 1, &old_interval, |
410 | if (changed && r->var >= 0) { | 422 | hw_param_interval(params, r->var)); |
411 | params->cmask |= (1 << r->var); | ||
412 | vstamps[r->var] = stamp; | ||
413 | again = 1; | ||
414 | } | 423 | } |
415 | if (changed < 0) | 424 | |
416 | return changed; | 425 | params->cmask |= (1 << r->var); |
417 | stamp++; | 426 | vstamps[r->var] = stamp; |
427 | again = true; | ||
418 | } | 428 | } |
419 | } while (again); | 429 | |
430 | rstamps[k] = stamp++; | ||
431 | } | ||
432 | |||
433 | /* Iterate to evaluate all rules till no parameters are changed. */ | ||
434 | if (again) | ||
435 | goto retry; | ||
436 | |||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | static int fixup_unreferenced_params(struct snd_pcm_substream *substream, | ||
441 | struct snd_pcm_hw_params *params) | ||
442 | { | ||
443 | const struct snd_interval *i; | ||
444 | const struct snd_mask *m; | ||
445 | int err; | ||
446 | |||
420 | if (!params->msbits) { | 447 | if (!params->msbits) { |
421 | i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); | 448 | i = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); |
422 | if (snd_interval_single(i)) | 449 | if (snd_interval_single(i)) |
423 | params->msbits = snd_interval_value(i); | 450 | params->msbits = snd_interval_value(i); |
424 | } | 451 | } |
425 | 452 | ||
426 | if (!params->rate_den) { | 453 | if (!params->rate_den) { |
427 | i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 454 | i = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); |
428 | if (snd_interval_single(i)) { | 455 | if (snd_interval_single(i)) { |
429 | params->rate_num = snd_interval_value(i); | 456 | params->rate_num = snd_interval_value(i); |
430 | params->rate_den = 1; | 457 | params->rate_den = 1; |
431 | } | 458 | } |
432 | } | 459 | } |
433 | 460 | ||
434 | hw = &substream->runtime->hw; | 461 | if (!params->fifo_size) { |
462 | m = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT); | ||
463 | i = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
464 | if (snd_mask_single(m) && snd_interval_single(i)) { | ||
465 | err = substream->ops->ioctl(substream, | ||
466 | SNDRV_PCM_IOCTL1_FIFO_SIZE, params); | ||
467 | if (err < 0) | ||
468 | return err; | ||
469 | } | ||
470 | } | ||
471 | |||
435 | if (!params->info) { | 472 | if (!params->info) { |
436 | params->info = hw->info & ~(SNDRV_PCM_INFO_FIFO_IN_FRAMES | | 473 | params->info = substream->runtime->hw.info; |
437 | SNDRV_PCM_INFO_DRAIN_TRIGGER); | 474 | params->info &= ~(SNDRV_PCM_INFO_FIFO_IN_FRAMES | |
475 | SNDRV_PCM_INFO_DRAIN_TRIGGER); | ||
438 | if (!hw_support_mmap(substream)) | 476 | if (!hw_support_mmap(substream)) |
439 | params->info &= ~(SNDRV_PCM_INFO_MMAP | | 477 | params->info &= ~(SNDRV_PCM_INFO_MMAP | |
440 | SNDRV_PCM_INFO_MMAP_VALID); | 478 | SNDRV_PCM_INFO_MMAP_VALID); |
441 | } | 479 | } |
442 | if (!params->fifo_size) { | 480 | |
443 | m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 481 | return 0; |
444 | i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | 482 | } |
445 | if (snd_mask_min(m) == snd_mask_max(m) && | 483 | |
446 | snd_interval_min(i) == snd_interval_max(i)) { | 484 | int snd_pcm_hw_refine(struct snd_pcm_substream *substream, |
447 | changed = substream->ops->ioctl(substream, | 485 | struct snd_pcm_hw_params *params) |
448 | SNDRV_PCM_IOCTL1_FIFO_SIZE, params); | 486 | { |
449 | if (changed < 0) | 487 | int err; |
450 | return changed; | 488 | |
451 | } | 489 | params->info = 0; |
490 | params->fifo_size = 0; | ||
491 | if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS)) | ||
492 | params->msbits = 0; | ||
493 | if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) { | ||
494 | params->rate_num = 0; | ||
495 | params->rate_den = 0; | ||
452 | } | 496 | } |
497 | |||
498 | err = constrain_mask_params(substream, params); | ||
499 | if (err < 0) | ||
500 | return err; | ||
501 | |||
502 | err = constrain_interval_params(substream, params); | ||
503 | if (err < 0) | ||
504 | return err; | ||
505 | |||
506 | err = constrain_params_by_rules(substream, params); | ||
507 | if (err < 0) | ||
508 | return err; | ||
509 | |||
453 | params->rmask = 0; | 510 | params->rmask = 0; |
511 | |||
454 | return 0; | 512 | return 0; |
455 | } | 513 | } |
456 | |||
457 | EXPORT_SYMBOL(snd_pcm_hw_refine); | 514 | EXPORT_SYMBOL(snd_pcm_hw_refine); |
458 | 515 | ||
459 | static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, | 516 | static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, |
@@ -467,11 +524,16 @@ static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, | |||
467 | return PTR_ERR(params); | 524 | return PTR_ERR(params); |
468 | 525 | ||
469 | err = snd_pcm_hw_refine(substream, params); | 526 | err = snd_pcm_hw_refine(substream, params); |
470 | if (copy_to_user(_params, params, sizeof(*params))) { | 527 | if (err < 0) |
471 | if (!err) | 528 | goto end; |
472 | err = -EFAULT; | ||
473 | } | ||
474 | 529 | ||
530 | err = fixup_unreferenced_params(substream, params); | ||
531 | if (err < 0) | ||
532 | goto end; | ||
533 | |||
534 | if (copy_to_user(_params, params, sizeof(*params))) | ||
535 | err = -EFAULT; | ||
536 | end: | ||
475 | kfree(params); | 537 | kfree(params); |
476 | return err; | 538 | return err; |
477 | } | 539 | } |
@@ -509,6 +571,70 @@ static inline void snd_pcm_timer_notify(struct snd_pcm_substream *substream, | |||
509 | #endif | 571 | #endif |
510 | } | 572 | } |
511 | 573 | ||
574 | /** | ||
575 | * snd_pcm_hw_param_choose - choose a configuration defined by @params | ||
576 | * @pcm: PCM instance | ||
577 | * @params: the hw_params instance | ||
578 | * | ||
579 | * Choose one configuration from configuration space defined by @params. | ||
580 | * The configuration chosen is that obtained fixing in this order: | ||
581 | * first access, first format, first subformat, min channels, | ||
582 | * min rate, min period time, max buffer size, min tick time | ||
583 | * | ||
584 | * Return: Zero if successful, or a negative error code on failure. | ||
585 | */ | ||
586 | static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, | ||
587 | struct snd_pcm_hw_params *params) | ||
588 | { | ||
589 | static const int vars[] = { | ||
590 | SNDRV_PCM_HW_PARAM_ACCESS, | ||
591 | SNDRV_PCM_HW_PARAM_FORMAT, | ||
592 | SNDRV_PCM_HW_PARAM_SUBFORMAT, | ||
593 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
594 | SNDRV_PCM_HW_PARAM_RATE, | ||
595 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | ||
596 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | ||
597 | SNDRV_PCM_HW_PARAM_TICK_TIME, | ||
598 | -1 | ||
599 | }; | ||
600 | const int *v; | ||
601 | struct snd_mask old_mask; | ||
602 | struct snd_interval old_interval; | ||
603 | int changed; | ||
604 | |||
605 | for (v = vars; *v != -1; v++) { | ||
606 | /* Keep old parameter to trace. */ | ||
607 | if (trace_hw_mask_param_enabled()) { | ||
608 | if (hw_is_mask(*v)) | ||
609 | old_mask = *hw_param_mask(params, *v); | ||
610 | } | ||
611 | if (trace_hw_interval_param_enabled()) { | ||
612 | if (hw_is_interval(*v)) | ||
613 | old_interval = *hw_param_interval(params, *v); | ||
614 | } | ||
615 | if (*v != SNDRV_PCM_HW_PARAM_BUFFER_SIZE) | ||
616 | changed = snd_pcm_hw_param_first(pcm, params, *v, NULL); | ||
617 | else | ||
618 | changed = snd_pcm_hw_param_last(pcm, params, *v, NULL); | ||
619 | if (snd_BUG_ON(changed < 0)) | ||
620 | return changed; | ||
621 | if (changed == 0) | ||
622 | continue; | ||
623 | |||
624 | /* Trace the changed parameter. */ | ||
625 | if (hw_is_mask(*v)) { | ||
626 | trace_hw_mask_param(pcm, *v, 0, &old_mask, | ||
627 | hw_param_mask(params, *v)); | ||
628 | } | ||
629 | if (hw_is_interval(*v)) { | ||
630 | trace_hw_interval_param(pcm, *v, 0, &old_interval, | ||
631 | hw_param_interval(params, *v)); | ||
632 | } | ||
633 | } | ||
634 | |||
635 | return 0; | ||
636 | } | ||
637 | |||
512 | static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | 638 | static int snd_pcm_hw_params(struct snd_pcm_substream *substream, |
513 | struct snd_pcm_hw_params *params) | 639 | struct snd_pcm_hw_params *params) |
514 | { | 640 | { |
@@ -546,6 +672,10 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, | |||
546 | if (err < 0) | 672 | if (err < 0) |
547 | goto _error; | 673 | goto _error; |
548 | 674 | ||
675 | err = fixup_unreferenced_params(substream, params); | ||
676 | if (err < 0) | ||
677 | goto _error; | ||
678 | |||
549 | if (substream->ops->hw_params != NULL) { | 679 | if (substream->ops->hw_params != NULL) { |
550 | err = substream->ops->hw_params(substream, params); | 680 | err = substream->ops->hw_params(substream, params); |
551 | if (err < 0) | 681 | if (err < 0) |
@@ -621,11 +751,12 @@ static int snd_pcm_hw_params_user(struct snd_pcm_substream *substream, | |||
621 | return PTR_ERR(params); | 751 | return PTR_ERR(params); |
622 | 752 | ||
623 | err = snd_pcm_hw_params(substream, params); | 753 | err = snd_pcm_hw_params(substream, params); |
624 | if (copy_to_user(_params, params, sizeof(*params))) { | 754 | if (err < 0) |
625 | if (!err) | 755 | goto end; |
626 | err = -EFAULT; | ||
627 | } | ||
628 | 756 | ||
757 | if (copy_to_user(_params, params, sizeof(*params))) | ||
758 | err = -EFAULT; | ||
759 | end: | ||
629 | kfree(params); | 760 | kfree(params); |
630 | return err; | 761 | return err; |
631 | } | 762 | } |
@@ -1081,6 +1212,7 @@ static const struct action_ops snd_pcm_action_start = { | |||
1081 | * @substream: the PCM substream instance | 1212 | * @substream: the PCM substream instance |
1082 | * | 1213 | * |
1083 | * Return: Zero if successful, or a negative error code. | 1214 | * Return: Zero if successful, or a negative error code. |
1215 | * The stream lock must be acquired before calling this function. | ||
1084 | */ | 1216 | */ |
1085 | int snd_pcm_start(struct snd_pcm_substream *substream) | 1217 | int snd_pcm_start(struct snd_pcm_substream *substream) |
1086 | { | 1218 | { |
@@ -1088,6 +1220,13 @@ int snd_pcm_start(struct snd_pcm_substream *substream) | |||
1088 | SNDRV_PCM_STATE_RUNNING); | 1220 | SNDRV_PCM_STATE_RUNNING); |
1089 | } | 1221 | } |
1090 | 1222 | ||
1223 | /* take the stream lock and start the streams */ | ||
1224 | static int snd_pcm_start_lock_irq(struct snd_pcm_substream *substream) | ||
1225 | { | ||
1226 | return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, | ||
1227 | SNDRV_PCM_STATE_RUNNING); | ||
1228 | } | ||
1229 | |||
1091 | /* | 1230 | /* |
1092 | * stop callbacks | 1231 | * stop callbacks |
1093 | */ | 1232 | */ |
@@ -1139,7 +1278,6 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t state) | |||
1139 | { | 1278 | { |
1140 | return snd_pcm_action(&snd_pcm_action_stop, substream, state); | 1279 | return snd_pcm_action(&snd_pcm_action_stop, substream, state); |
1141 | } | 1280 | } |
1142 | |||
1143 | EXPORT_SYMBOL(snd_pcm_stop); | 1281 | EXPORT_SYMBOL(snd_pcm_stop); |
1144 | 1282 | ||
1145 | /** | 1283 | /** |
@@ -1314,7 +1452,6 @@ int snd_pcm_suspend(struct snd_pcm_substream *substream) | |||
1314 | snd_pcm_stream_unlock_irqrestore(substream, flags); | 1452 | snd_pcm_stream_unlock_irqrestore(substream, flags); |
1315 | return err; | 1453 | return err; |
1316 | } | 1454 | } |
1317 | |||
1318 | EXPORT_SYMBOL(snd_pcm_suspend); | 1455 | EXPORT_SYMBOL(snd_pcm_suspend); |
1319 | 1456 | ||
1320 | /** | 1457 | /** |
@@ -1346,7 +1483,6 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm) | |||
1346 | } | 1483 | } |
1347 | return 0; | 1484 | return 0; |
1348 | } | 1485 | } |
1349 | |||
1350 | EXPORT_SYMBOL(snd_pcm_suspend_all); | 1486 | EXPORT_SYMBOL(snd_pcm_suspend_all); |
1351 | 1487 | ||
1352 | /* resume */ | 1488 | /* resume */ |
@@ -1397,14 +1533,7 @@ static const struct action_ops snd_pcm_action_resume = { | |||
1397 | 1533 | ||
1398 | static int snd_pcm_resume(struct snd_pcm_substream *substream) | 1534 | static int snd_pcm_resume(struct snd_pcm_substream *substream) |
1399 | { | 1535 | { |
1400 | struct snd_card *card = substream->pcm->card; | 1536 | return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0); |
1401 | int res; | ||
1402 | |||
1403 | snd_power_lock(card); | ||
1404 | if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) | ||
1405 | res = snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0); | ||
1406 | snd_power_unlock(card); | ||
1407 | return res; | ||
1408 | } | 1537 | } |
1409 | 1538 | ||
1410 | #else | 1539 | #else |
@@ -1423,17 +1552,9 @@ static int snd_pcm_resume(struct snd_pcm_substream *substream) | |||
1423 | */ | 1552 | */ |
1424 | static int snd_pcm_xrun(struct snd_pcm_substream *substream) | 1553 | static int snd_pcm_xrun(struct snd_pcm_substream *substream) |
1425 | { | 1554 | { |
1426 | struct snd_card *card = substream->pcm->card; | ||
1427 | struct snd_pcm_runtime *runtime = substream->runtime; | 1555 | struct snd_pcm_runtime *runtime = substream->runtime; |
1428 | int result; | 1556 | int result; |
1429 | 1557 | ||
1430 | snd_power_lock(card); | ||
1431 | if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { | ||
1432 | result = snd_power_wait(card, SNDRV_CTL_POWER_D0); | ||
1433 | if (result < 0) | ||
1434 | goto _unlock; | ||
1435 | } | ||
1436 | |||
1437 | snd_pcm_stream_lock_irq(substream); | 1558 | snd_pcm_stream_lock_irq(substream); |
1438 | switch (runtime->status->state) { | 1559 | switch (runtime->status->state) { |
1439 | case SNDRV_PCM_STATE_XRUN: | 1560 | case SNDRV_PCM_STATE_XRUN: |
@@ -1446,8 +1567,6 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream) | |||
1446 | result = -EBADFD; | 1567 | result = -EBADFD; |
1447 | } | 1568 | } |
1448 | snd_pcm_stream_unlock_irq(substream); | 1569 | snd_pcm_stream_unlock_irq(substream); |
1449 | _unlock: | ||
1450 | snd_power_unlock(card); | ||
1451 | return result; | 1570 | return result; |
1452 | } | 1571 | } |
1453 | 1572 | ||
@@ -1551,8 +1670,6 @@ static const struct action_ops snd_pcm_action_prepare = { | |||
1551 | static int snd_pcm_prepare(struct snd_pcm_substream *substream, | 1670 | static int snd_pcm_prepare(struct snd_pcm_substream *substream, |
1552 | struct file *file) | 1671 | struct file *file) |
1553 | { | 1672 | { |
1554 | int res; | ||
1555 | struct snd_card *card = substream->pcm->card; | ||
1556 | int f_flags; | 1673 | int f_flags; |
1557 | 1674 | ||
1558 | if (file) | 1675 | if (file) |
@@ -1560,12 +1677,19 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream, | |||
1560 | else | 1677 | else |
1561 | f_flags = substream->f_flags; | 1678 | f_flags = substream->f_flags; |
1562 | 1679 | ||
1563 | snd_power_lock(card); | 1680 | snd_pcm_stream_lock_irq(substream); |
1564 | if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0) | 1681 | switch (substream->runtime->status->state) { |
1565 | res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare, | 1682 | case SNDRV_PCM_STATE_PAUSED: |
1566 | substream, f_flags); | 1683 | snd_pcm_pause(substream, 0); |
1567 | snd_power_unlock(card); | 1684 | /* fallthru */ |
1568 | return res; | 1685 | case SNDRV_PCM_STATE_SUSPENDED: |
1686 | snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); | ||
1687 | break; | ||
1688 | } | ||
1689 | snd_pcm_stream_unlock_irq(substream); | ||
1690 | |||
1691 | return snd_pcm_action_nonatomic(&snd_pcm_action_prepare, | ||
1692 | substream, f_flags); | ||
1569 | } | 1693 | } |
1570 | 1694 | ||
1571 | /* | 1695 | /* |
@@ -1662,15 +1786,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, | |||
1662 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) | 1786 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) |
1663 | return -EBADFD; | 1787 | return -EBADFD; |
1664 | 1788 | ||
1665 | snd_power_lock(card); | ||
1666 | if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { | ||
1667 | result = snd_power_wait(card, SNDRV_CTL_POWER_D0); | ||
1668 | if (result < 0) { | ||
1669 | snd_power_unlock(card); | ||
1670 | return result; | ||
1671 | } | ||
1672 | } | ||
1673 | |||
1674 | if (file) { | 1789 | if (file) { |
1675 | if (file->f_flags & O_NONBLOCK) | 1790 | if (file->f_flags & O_NONBLOCK) |
1676 | nonblock = 1; | 1791 | nonblock = 1; |
@@ -1753,7 +1868,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, | |||
1753 | unlock: | 1868 | unlock: |
1754 | snd_pcm_stream_unlock_irq(substream); | 1869 | snd_pcm_stream_unlock_irq(substream); |
1755 | up_read(&snd_pcm_link_rwsem); | 1870 | up_read(&snd_pcm_link_rwsem); |
1756 | snd_power_unlock(card); | ||
1757 | 1871 | ||
1758 | return result; | 1872 | return result; |
1759 | } | 1873 | } |
@@ -1773,8 +1887,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream) | |||
1773 | runtime = substream->runtime; | 1887 | runtime = substream->runtime; |
1774 | 1888 | ||
1775 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN || | 1889 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN || |
1776 | runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED || | 1890 | runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) |
1777 | runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) | ||
1778 | return -EBADFD; | 1891 | return -EBADFD; |
1779 | 1892 | ||
1780 | snd_pcm_stream_lock_irq(substream); | 1893 | snd_pcm_stream_lock_irq(substream); |
@@ -1940,7 +2053,8 @@ static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params, | |||
1940 | struct snd_pcm_hw_rule *rule) | 2053 | struct snd_pcm_hw_rule *rule) |
1941 | { | 2054 | { |
1942 | unsigned int k; | 2055 | unsigned int k; |
1943 | struct snd_interval *i = hw_param_interval(params, rule->deps[0]); | 2056 | const struct snd_interval *i = |
2057 | hw_param_interval_c(params, rule->deps[0]); | ||
1944 | struct snd_mask m; | 2058 | struct snd_mask m; |
1945 | struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 2059 | struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
1946 | snd_mask_any(&m); | 2060 | snd_mask_any(&m); |
@@ -1986,8 +2100,10 @@ static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params, | |||
1986 | #error "Change this table" | 2100 | #error "Change this table" |
1987 | #endif | 2101 | #endif |
1988 | 2102 | ||
1989 | static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, | 2103 | static const unsigned int rates[] = { |
1990 | 48000, 64000, 88200, 96000, 176400, 192000 }; | 2104 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, |
2105 | 48000, 64000, 88200, 96000, 176400, 192000 | ||
2106 | }; | ||
1991 | 2107 | ||
1992 | const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = { | 2108 | const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = { |
1993 | .count = ARRAY_SIZE(rates), | 2109 | .count = ARRAY_SIZE(rates), |
@@ -2250,7 +2366,6 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream) | |||
2250 | } | 2366 | } |
2251 | snd_pcm_detach_substream(substream); | 2367 | snd_pcm_detach_substream(substream); |
2252 | } | 2368 | } |
2253 | |||
2254 | EXPORT_SYMBOL(snd_pcm_release_substream); | 2369 | EXPORT_SYMBOL(snd_pcm_release_substream); |
2255 | 2370 | ||
2256 | int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, | 2371 | int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, |
@@ -2292,7 +2407,6 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, | |||
2292 | snd_pcm_release_substream(substream); | 2407 | snd_pcm_release_substream(substream); |
2293 | return err; | 2408 | return err; |
2294 | } | 2409 | } |
2295 | |||
2296 | EXPORT_SYMBOL(snd_pcm_open_substream); | 2410 | EXPORT_SYMBOL(snd_pcm_open_substream); |
2297 | 2411 | ||
2298 | static int snd_pcm_open_file(struct file *file, | 2412 | static int snd_pcm_open_file(struct file *file, |
@@ -2428,50 +2542,84 @@ static int snd_pcm_release(struct inode *inode, struct file *file) | |||
2428 | return 0; | 2542 | return 0; |
2429 | } | 2543 | } |
2430 | 2544 | ||
2431 | static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream, | 2545 | /* check and update PCM state; return 0 or a negative error |
2432 | snd_pcm_uframes_t frames) | 2546 | * call this inside PCM lock |
2547 | */ | ||
2548 | static int do_pcm_hwsync(struct snd_pcm_substream *substream) | ||
2433 | { | 2549 | { |
2434 | struct snd_pcm_runtime *runtime = substream->runtime; | 2550 | switch (substream->runtime->status->state) { |
2435 | snd_pcm_sframes_t appl_ptr; | ||
2436 | snd_pcm_sframes_t ret; | ||
2437 | snd_pcm_sframes_t hw_avail; | ||
2438 | |||
2439 | if (frames == 0) | ||
2440 | return 0; | ||
2441 | |||
2442 | snd_pcm_stream_lock_irq(substream); | ||
2443 | switch (runtime->status->state) { | ||
2444 | case SNDRV_PCM_STATE_PREPARED: | ||
2445 | break; | ||
2446 | case SNDRV_PCM_STATE_DRAINING: | 2551 | case SNDRV_PCM_STATE_DRAINING: |
2447 | case SNDRV_PCM_STATE_RUNNING: | 2552 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
2448 | if (snd_pcm_update_hw_ptr(substream) >= 0) | 2553 | return -EBADFD; |
2449 | break; | ||
2450 | /* Fall through */ | 2554 | /* Fall through */ |
2451 | case SNDRV_PCM_STATE_XRUN: | 2555 | case SNDRV_PCM_STATE_RUNNING: |
2452 | ret = -EPIPE; | 2556 | return snd_pcm_update_hw_ptr(substream); |
2453 | goto __end; | 2557 | case SNDRV_PCM_STATE_PREPARED: |
2558 | case SNDRV_PCM_STATE_PAUSED: | ||
2559 | return 0; | ||
2454 | case SNDRV_PCM_STATE_SUSPENDED: | 2560 | case SNDRV_PCM_STATE_SUSPENDED: |
2455 | ret = -ESTRPIPE; | 2561 | return -ESTRPIPE; |
2456 | goto __end; | 2562 | case SNDRV_PCM_STATE_XRUN: |
2563 | return -EPIPE; | ||
2457 | default: | 2564 | default: |
2458 | ret = -EBADFD; | 2565 | return -EBADFD; |
2459 | goto __end; | ||
2460 | } | 2566 | } |
2567 | } | ||
2461 | 2568 | ||
2462 | hw_avail = snd_pcm_playback_hw_avail(runtime); | 2569 | /* increase the appl_ptr; returns the processed frames or a negative error */ |
2463 | if (hw_avail <= 0) { | 2570 | static snd_pcm_sframes_t forward_appl_ptr(struct snd_pcm_substream *substream, |
2464 | ret = 0; | 2571 | snd_pcm_uframes_t frames, |
2465 | goto __end; | 2572 | snd_pcm_sframes_t avail) |
2466 | } | 2573 | { |
2467 | if (frames > (snd_pcm_uframes_t)hw_avail) | 2574 | struct snd_pcm_runtime *runtime = substream->runtime; |
2468 | frames = hw_avail; | 2575 | snd_pcm_sframes_t appl_ptr; |
2576 | int ret; | ||
2577 | |||
2578 | if (avail <= 0) | ||
2579 | return 0; | ||
2580 | if (frames > (snd_pcm_uframes_t)avail) | ||
2581 | frames = avail; | ||
2582 | appl_ptr = runtime->control->appl_ptr + frames; | ||
2583 | if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary) | ||
2584 | appl_ptr -= runtime->boundary; | ||
2585 | ret = pcm_lib_apply_appl_ptr(substream, appl_ptr); | ||
2586 | return ret < 0 ? ret : frames; | ||
2587 | } | ||
2588 | |||
2589 | /* decrease the appl_ptr; returns the processed frames or a negative error */ | ||
2590 | static snd_pcm_sframes_t rewind_appl_ptr(struct snd_pcm_substream *substream, | ||
2591 | snd_pcm_uframes_t frames, | ||
2592 | snd_pcm_sframes_t avail) | ||
2593 | { | ||
2594 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
2595 | snd_pcm_sframes_t appl_ptr; | ||
2596 | int ret; | ||
2597 | |||
2598 | if (avail <= 0) | ||
2599 | return 0; | ||
2600 | if (frames > (snd_pcm_uframes_t)avail) | ||
2601 | frames = avail; | ||
2469 | appl_ptr = runtime->control->appl_ptr - frames; | 2602 | appl_ptr = runtime->control->appl_ptr - frames; |
2470 | if (appl_ptr < 0) | 2603 | if (appl_ptr < 0) |
2471 | appl_ptr += runtime->boundary; | 2604 | appl_ptr += runtime->boundary; |
2472 | runtime->control->appl_ptr = appl_ptr; | 2605 | ret = pcm_lib_apply_appl_ptr(substream, appl_ptr); |
2473 | ret = frames; | 2606 | return ret < 0 ? ret : frames; |
2474 | __end: | 2607 | } |
2608 | |||
2609 | static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream, | ||
2610 | snd_pcm_uframes_t frames) | ||
2611 | { | ||
2612 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
2613 | snd_pcm_sframes_t ret; | ||
2614 | |||
2615 | if (frames == 0) | ||
2616 | return 0; | ||
2617 | |||
2618 | snd_pcm_stream_lock_irq(substream); | ||
2619 | ret = do_pcm_hwsync(substream); | ||
2620 | if (!ret) | ||
2621 | ret = rewind_appl_ptr(substream, frames, | ||
2622 | snd_pcm_playback_hw_avail(runtime)); | ||
2475 | snd_pcm_stream_unlock_irq(substream); | 2623 | snd_pcm_stream_unlock_irq(substream); |
2476 | return ret; | 2624 | return ret; |
2477 | } | 2625 | } |
@@ -2480,46 +2628,16 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr | |||
2480 | snd_pcm_uframes_t frames) | 2628 | snd_pcm_uframes_t frames) |
2481 | { | 2629 | { |
2482 | struct snd_pcm_runtime *runtime = substream->runtime; | 2630 | struct snd_pcm_runtime *runtime = substream->runtime; |
2483 | snd_pcm_sframes_t appl_ptr; | ||
2484 | snd_pcm_sframes_t ret; | 2631 | snd_pcm_sframes_t ret; |
2485 | snd_pcm_sframes_t hw_avail; | ||
2486 | 2632 | ||
2487 | if (frames == 0) | 2633 | if (frames == 0) |
2488 | return 0; | 2634 | return 0; |
2489 | 2635 | ||
2490 | snd_pcm_stream_lock_irq(substream); | 2636 | snd_pcm_stream_lock_irq(substream); |
2491 | switch (runtime->status->state) { | 2637 | ret = do_pcm_hwsync(substream); |
2492 | case SNDRV_PCM_STATE_PREPARED: | 2638 | if (!ret) |
2493 | case SNDRV_PCM_STATE_DRAINING: | 2639 | ret = rewind_appl_ptr(substream, frames, |
2494 | break; | 2640 | snd_pcm_capture_hw_avail(runtime)); |
2495 | case SNDRV_PCM_STATE_RUNNING: | ||
2496 | if (snd_pcm_update_hw_ptr(substream) >= 0) | ||
2497 | break; | ||
2498 | /* Fall through */ | ||
2499 | case SNDRV_PCM_STATE_XRUN: | ||
2500 | ret = -EPIPE; | ||
2501 | goto __end; | ||
2502 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2503 | ret = -ESTRPIPE; | ||
2504 | goto __end; | ||
2505 | default: | ||
2506 | ret = -EBADFD; | ||
2507 | goto __end; | ||
2508 | } | ||
2509 | |||
2510 | hw_avail = snd_pcm_capture_hw_avail(runtime); | ||
2511 | if (hw_avail <= 0) { | ||
2512 | ret = 0; | ||
2513 | goto __end; | ||
2514 | } | ||
2515 | if (frames > (snd_pcm_uframes_t)hw_avail) | ||
2516 | frames = hw_avail; | ||
2517 | appl_ptr = runtime->control->appl_ptr - frames; | ||
2518 | if (appl_ptr < 0) | ||
2519 | appl_ptr += runtime->boundary; | ||
2520 | runtime->control->appl_ptr = appl_ptr; | ||
2521 | ret = frames; | ||
2522 | __end: | ||
2523 | snd_pcm_stream_unlock_irq(substream); | 2641 | snd_pcm_stream_unlock_irq(substream); |
2524 | return ret; | 2642 | return ret; |
2525 | } | 2643 | } |
@@ -2528,47 +2646,16 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs | |||
2528 | snd_pcm_uframes_t frames) | 2646 | snd_pcm_uframes_t frames) |
2529 | { | 2647 | { |
2530 | struct snd_pcm_runtime *runtime = substream->runtime; | 2648 | struct snd_pcm_runtime *runtime = substream->runtime; |
2531 | snd_pcm_sframes_t appl_ptr; | ||
2532 | snd_pcm_sframes_t ret; | 2649 | snd_pcm_sframes_t ret; |
2533 | snd_pcm_sframes_t avail; | ||
2534 | 2650 | ||
2535 | if (frames == 0) | 2651 | if (frames == 0) |
2536 | return 0; | 2652 | return 0; |
2537 | 2653 | ||
2538 | snd_pcm_stream_lock_irq(substream); | 2654 | snd_pcm_stream_lock_irq(substream); |
2539 | switch (runtime->status->state) { | 2655 | ret = do_pcm_hwsync(substream); |
2540 | case SNDRV_PCM_STATE_PREPARED: | 2656 | if (!ret) |
2541 | case SNDRV_PCM_STATE_PAUSED: | 2657 | ret = forward_appl_ptr(substream, frames, |
2542 | break; | 2658 | snd_pcm_playback_avail(runtime)); |
2543 | case SNDRV_PCM_STATE_DRAINING: | ||
2544 | case SNDRV_PCM_STATE_RUNNING: | ||
2545 | if (snd_pcm_update_hw_ptr(substream) >= 0) | ||
2546 | break; | ||
2547 | /* Fall through */ | ||
2548 | case SNDRV_PCM_STATE_XRUN: | ||
2549 | ret = -EPIPE; | ||
2550 | goto __end; | ||
2551 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2552 | ret = -ESTRPIPE; | ||
2553 | goto __end; | ||
2554 | default: | ||
2555 | ret = -EBADFD; | ||
2556 | goto __end; | ||
2557 | } | ||
2558 | |||
2559 | avail = snd_pcm_playback_avail(runtime); | ||
2560 | if (avail <= 0) { | ||
2561 | ret = 0; | ||
2562 | goto __end; | ||
2563 | } | ||
2564 | if (frames > (snd_pcm_uframes_t)avail) | ||
2565 | frames = avail; | ||
2566 | appl_ptr = runtime->control->appl_ptr + frames; | ||
2567 | if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary) | ||
2568 | appl_ptr -= runtime->boundary; | ||
2569 | runtime->control->appl_ptr = appl_ptr; | ||
2570 | ret = frames; | ||
2571 | __end: | ||
2572 | snd_pcm_stream_unlock_irq(substream); | 2659 | snd_pcm_stream_unlock_irq(substream); |
2573 | return ret; | 2660 | return ret; |
2574 | } | 2661 | } |
@@ -2577,123 +2664,47 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst | |||
2577 | snd_pcm_uframes_t frames) | 2664 | snd_pcm_uframes_t frames) |
2578 | { | 2665 | { |
2579 | struct snd_pcm_runtime *runtime = substream->runtime; | 2666 | struct snd_pcm_runtime *runtime = substream->runtime; |
2580 | snd_pcm_sframes_t appl_ptr; | ||
2581 | snd_pcm_sframes_t ret; | 2667 | snd_pcm_sframes_t ret; |
2582 | snd_pcm_sframes_t avail; | ||
2583 | 2668 | ||
2584 | if (frames == 0) | 2669 | if (frames == 0) |
2585 | return 0; | 2670 | return 0; |
2586 | 2671 | ||
2587 | snd_pcm_stream_lock_irq(substream); | 2672 | snd_pcm_stream_lock_irq(substream); |
2588 | switch (runtime->status->state) { | 2673 | ret = do_pcm_hwsync(substream); |
2589 | case SNDRV_PCM_STATE_PREPARED: | 2674 | if (!ret) |
2590 | case SNDRV_PCM_STATE_DRAINING: | 2675 | ret = forward_appl_ptr(substream, frames, |
2591 | case SNDRV_PCM_STATE_PAUSED: | 2676 | snd_pcm_capture_avail(runtime)); |
2592 | break; | ||
2593 | case SNDRV_PCM_STATE_RUNNING: | ||
2594 | if (snd_pcm_update_hw_ptr(substream) >= 0) | ||
2595 | break; | ||
2596 | /* Fall through */ | ||
2597 | case SNDRV_PCM_STATE_XRUN: | ||
2598 | ret = -EPIPE; | ||
2599 | goto __end; | ||
2600 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2601 | ret = -ESTRPIPE; | ||
2602 | goto __end; | ||
2603 | default: | ||
2604 | ret = -EBADFD; | ||
2605 | goto __end; | ||
2606 | } | ||
2607 | |||
2608 | avail = snd_pcm_capture_avail(runtime); | ||
2609 | if (avail <= 0) { | ||
2610 | ret = 0; | ||
2611 | goto __end; | ||
2612 | } | ||
2613 | if (frames > (snd_pcm_uframes_t)avail) | ||
2614 | frames = avail; | ||
2615 | appl_ptr = runtime->control->appl_ptr + frames; | ||
2616 | if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary) | ||
2617 | appl_ptr -= runtime->boundary; | ||
2618 | runtime->control->appl_ptr = appl_ptr; | ||
2619 | ret = frames; | ||
2620 | __end: | ||
2621 | snd_pcm_stream_unlock_irq(substream); | 2677 | snd_pcm_stream_unlock_irq(substream); |
2622 | return ret; | 2678 | return ret; |
2623 | } | 2679 | } |
2624 | 2680 | ||
2625 | static int snd_pcm_hwsync(struct snd_pcm_substream *substream) | 2681 | static int snd_pcm_hwsync(struct snd_pcm_substream *substream) |
2626 | { | 2682 | { |
2627 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
2628 | int err; | 2683 | int err; |
2629 | 2684 | ||
2630 | snd_pcm_stream_lock_irq(substream); | 2685 | snd_pcm_stream_lock_irq(substream); |
2631 | switch (runtime->status->state) { | 2686 | err = do_pcm_hwsync(substream); |
2632 | case SNDRV_PCM_STATE_DRAINING: | ||
2633 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
2634 | goto __badfd; | ||
2635 | /* Fall through */ | ||
2636 | case SNDRV_PCM_STATE_RUNNING: | ||
2637 | if ((err = snd_pcm_update_hw_ptr(substream)) < 0) | ||
2638 | break; | ||
2639 | /* Fall through */ | ||
2640 | case SNDRV_PCM_STATE_PREPARED: | ||
2641 | err = 0; | ||
2642 | break; | ||
2643 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2644 | err = -ESTRPIPE; | ||
2645 | break; | ||
2646 | case SNDRV_PCM_STATE_XRUN: | ||
2647 | err = -EPIPE; | ||
2648 | break; | ||
2649 | default: | ||
2650 | __badfd: | ||
2651 | err = -EBADFD; | ||
2652 | break; | ||
2653 | } | ||
2654 | snd_pcm_stream_unlock_irq(substream); | 2687 | snd_pcm_stream_unlock_irq(substream); |
2655 | return err; | 2688 | return err; |
2656 | } | 2689 | } |
2657 | 2690 | ||
2658 | static int snd_pcm_delay(struct snd_pcm_substream *substream, | 2691 | static snd_pcm_sframes_t snd_pcm_delay(struct snd_pcm_substream *substream) |
2659 | snd_pcm_sframes_t __user *res) | ||
2660 | { | 2692 | { |
2661 | struct snd_pcm_runtime *runtime = substream->runtime; | 2693 | struct snd_pcm_runtime *runtime = substream->runtime; |
2662 | int err; | 2694 | int err; |
2663 | snd_pcm_sframes_t n = 0; | 2695 | snd_pcm_sframes_t n = 0; |
2664 | 2696 | ||
2665 | snd_pcm_stream_lock_irq(substream); | 2697 | snd_pcm_stream_lock_irq(substream); |
2666 | switch (runtime->status->state) { | 2698 | err = do_pcm_hwsync(substream); |
2667 | case SNDRV_PCM_STATE_DRAINING: | 2699 | if (!err) { |
2668 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
2669 | goto __badfd; | ||
2670 | /* Fall through */ | ||
2671 | case SNDRV_PCM_STATE_RUNNING: | ||
2672 | if ((err = snd_pcm_update_hw_ptr(substream)) < 0) | ||
2673 | break; | ||
2674 | /* Fall through */ | ||
2675 | case SNDRV_PCM_STATE_PREPARED: | ||
2676 | case SNDRV_PCM_STATE_SUSPENDED: | ||
2677 | err = 0; | ||
2678 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 2700 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
2679 | n = snd_pcm_playback_hw_avail(runtime); | 2701 | n = snd_pcm_playback_hw_avail(runtime); |
2680 | else | 2702 | else |
2681 | n = snd_pcm_capture_avail(runtime); | 2703 | n = snd_pcm_capture_avail(runtime); |
2682 | n += runtime->delay; | 2704 | n += runtime->delay; |
2683 | break; | ||
2684 | case SNDRV_PCM_STATE_XRUN: | ||
2685 | err = -EPIPE; | ||
2686 | break; | ||
2687 | default: | ||
2688 | __badfd: | ||
2689 | err = -EBADFD; | ||
2690 | break; | ||
2691 | } | 2705 | } |
2692 | snd_pcm_stream_unlock_irq(substream); | 2706 | snd_pcm_stream_unlock_irq(substream); |
2693 | if (!err) | 2707 | return err < 0 ? err : n; |
2694 | if (put_user(n, res)) | ||
2695 | err = -EFAULT; | ||
2696 | return err; | ||
2697 | } | 2708 | } |
2698 | 2709 | ||
2699 | static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, | 2710 | static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, |
@@ -2718,10 +2729,16 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, | |||
2718 | return err; | 2729 | return err; |
2719 | } | 2730 | } |
2720 | snd_pcm_stream_lock_irq(substream); | 2731 | snd_pcm_stream_lock_irq(substream); |
2721 | if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) | 2732 | if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) { |
2722 | control->appl_ptr = sync_ptr.c.control.appl_ptr; | 2733 | err = pcm_lib_apply_appl_ptr(substream, |
2723 | else | 2734 | sync_ptr.c.control.appl_ptr); |
2735 | if (err < 0) { | ||
2736 | snd_pcm_stream_unlock_irq(substream); | ||
2737 | return err; | ||
2738 | } | ||
2739 | } else { | ||
2724 | sync_ptr.c.control.appl_ptr = control->appl_ptr; | 2740 | sync_ptr.c.control.appl_ptr = control->appl_ptr; |
2741 | } | ||
2725 | if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN)) | 2742 | if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN)) |
2726 | control->avail_min = sync_ptr.c.control.avail_min; | 2743 | control->avail_min = sync_ptr.c.control.avail_min; |
2727 | else | 2744 | else |
@@ -2749,7 +2766,7 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg) | |||
2749 | return 0; | 2766 | return 0; |
2750 | } | 2767 | } |
2751 | 2768 | ||
2752 | static int snd_pcm_common_ioctl1(struct file *file, | 2769 | static int snd_pcm_common_ioctl(struct file *file, |
2753 | struct snd_pcm_substream *substream, | 2770 | struct snd_pcm_substream *substream, |
2754 | unsigned int cmd, void __user *arg) | 2771 | unsigned int cmd, void __user *arg) |
2755 | { | 2772 | { |
@@ -2781,7 +2798,7 @@ static int snd_pcm_common_ioctl1(struct file *file, | |||
2781 | case SNDRV_PCM_IOCTL_RESET: | 2798 | case SNDRV_PCM_IOCTL_RESET: |
2782 | return snd_pcm_reset(substream); | 2799 | return snd_pcm_reset(substream); |
2783 | case SNDRV_PCM_IOCTL_START: | 2800 | case SNDRV_PCM_IOCTL_START: |
2784 | return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, SNDRV_PCM_STATE_RUNNING); | 2801 | return snd_pcm_start_lock_irq(substream); |
2785 | case SNDRV_PCM_IOCTL_LINK: | 2802 | case SNDRV_PCM_IOCTL_LINK: |
2786 | return snd_pcm_link(substream, (int)(unsigned long) arg); | 2803 | return snd_pcm_link(substream, (int)(unsigned long) arg); |
2787 | case SNDRV_PCM_IOCTL_UNLINK: | 2804 | case SNDRV_PCM_IOCTL_UNLINK: |
@@ -2793,7 +2810,16 @@ static int snd_pcm_common_ioctl1(struct file *file, | |||
2793 | case SNDRV_PCM_IOCTL_HWSYNC: | 2810 | case SNDRV_PCM_IOCTL_HWSYNC: |
2794 | return snd_pcm_hwsync(substream); | 2811 | return snd_pcm_hwsync(substream); |
2795 | case SNDRV_PCM_IOCTL_DELAY: | 2812 | case SNDRV_PCM_IOCTL_DELAY: |
2796 | return snd_pcm_delay(substream, arg); | 2813 | { |
2814 | snd_pcm_sframes_t delay = snd_pcm_delay(substream); | ||
2815 | snd_pcm_sframes_t __user *res = arg; | ||
2816 | |||
2817 | if (delay < 0) | ||
2818 | return delay; | ||
2819 | if (put_user(delay, res)) | ||
2820 | return -EFAULT; | ||
2821 | return 0; | ||
2822 | } | ||
2797 | case SNDRV_PCM_IOCTL_SYNC_PTR: | 2823 | case SNDRV_PCM_IOCTL_SYNC_PTR: |
2798 | return snd_pcm_sync_ptr(substream, arg); | 2824 | return snd_pcm_sync_ptr(substream, arg); |
2799 | #ifdef CONFIG_SND_SUPPORT_OLD_API | 2825 | #ifdef CONFIG_SND_SUPPORT_OLD_API |
@@ -2807,23 +2833,34 @@ static int snd_pcm_common_ioctl1(struct file *file, | |||
2807 | case SNDRV_PCM_IOCTL_DROP: | 2833 | case SNDRV_PCM_IOCTL_DROP: |
2808 | return snd_pcm_drop(substream); | 2834 | return snd_pcm_drop(substream); |
2809 | case SNDRV_PCM_IOCTL_PAUSE: | 2835 | case SNDRV_PCM_IOCTL_PAUSE: |
2810 | { | 2836 | return snd_pcm_action_lock_irq(&snd_pcm_action_pause, |
2811 | int res; | 2837 | substream, |
2812 | snd_pcm_stream_lock_irq(substream); | 2838 | (int)(unsigned long)arg); |
2813 | res = snd_pcm_pause(substream, (int)(unsigned long)arg); | ||
2814 | snd_pcm_stream_unlock_irq(substream); | ||
2815 | return res; | ||
2816 | } | ||
2817 | } | 2839 | } |
2818 | pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd); | 2840 | pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd); |
2819 | return -ENOTTY; | 2841 | return -ENOTTY; |
2820 | } | 2842 | } |
2821 | 2843 | ||
2844 | static int snd_pcm_common_ioctl1(struct file *file, | ||
2845 | struct snd_pcm_substream *substream, | ||
2846 | unsigned int cmd, void __user *arg) | ||
2847 | { | ||
2848 | struct snd_card *card = substream->pcm->card; | ||
2849 | int res; | ||
2850 | |||
2851 | snd_power_lock(card); | ||
2852 | res = snd_power_wait(card, SNDRV_CTL_POWER_D0); | ||
2853 | if (res >= 0) | ||
2854 | res = snd_pcm_common_ioctl(file, substream, cmd, arg); | ||
2855 | snd_power_unlock(card); | ||
2856 | return res; | ||
2857 | } | ||
2858 | |||
2822 | static int snd_pcm_playback_ioctl1(struct file *file, | 2859 | static int snd_pcm_playback_ioctl1(struct file *file, |
2823 | struct snd_pcm_substream *substream, | 2860 | struct snd_pcm_substream *substream, |
2824 | unsigned int cmd, void __user *arg) | 2861 | unsigned int cmd, void __user *arg) |
2825 | { | 2862 | { |
2826 | if (snd_BUG_ON(!substream)) | 2863 | if (PCM_RUNTIME_CHECK(substream)) |
2827 | return -ENXIO; | 2864 | return -ENXIO; |
2828 | if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK)) | 2865 | if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK)) |
2829 | return -EINVAL; | 2866 | return -EINVAL; |
@@ -2903,7 +2940,7 @@ static int snd_pcm_capture_ioctl1(struct file *file, | |||
2903 | struct snd_pcm_substream *substream, | 2940 | struct snd_pcm_substream *substream, |
2904 | unsigned int cmd, void __user *arg) | 2941 | unsigned int cmd, void __user *arg) |
2905 | { | 2942 | { |
2906 | if (snd_BUG_ON(!substream)) | 2943 | if (PCM_RUNTIME_CHECK(substream)) |
2907 | return -ENXIO; | 2944 | return -ENXIO; |
2908 | if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE)) | 2945 | if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE)) |
2909 | return -EINVAL; | 2946 | return -EINVAL; |
@@ -3007,30 +3044,55 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, | |||
3007 | (void __user *)arg); | 3044 | (void __user *)arg); |
3008 | } | 3045 | } |
3009 | 3046 | ||
3047 | /** | ||
3048 | * snd_pcm_kernel_ioctl - Execute PCM ioctl in the kernel-space | ||
3049 | * @substream: PCM substream | ||
3050 | * @cmd: IOCTL cmd | ||
3051 | * @arg: IOCTL argument | ||
3052 | * | ||
3053 | * The function is provided primarily for OSS layer and USB gadget drivers, | ||
3054 | * and it allows only the limited set of ioctls (hw_params, sw_params, | ||
3055 | * prepare, start, drain, drop, forward). | ||
3056 | */ | ||
3010 | int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, | 3057 | int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, |
3011 | unsigned int cmd, void *arg) | 3058 | unsigned int cmd, void *arg) |
3012 | { | 3059 | { |
3013 | mm_segment_t fs; | 3060 | snd_pcm_uframes_t *frames = arg; |
3014 | int result; | 3061 | snd_pcm_sframes_t result; |
3015 | 3062 | ||
3016 | fs = snd_enter_user(); | 3063 | switch (cmd) { |
3017 | switch (substream->stream) { | 3064 | case SNDRV_PCM_IOCTL_FORWARD: |
3018 | case SNDRV_PCM_STREAM_PLAYBACK: | 3065 | { |
3019 | result = snd_pcm_playback_ioctl1(NULL, substream, cmd, | 3066 | /* provided only for OSS; capture-only and no value returned */ |
3020 | (void __user *)arg); | 3067 | if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) |
3021 | break; | 3068 | return -EINVAL; |
3022 | case SNDRV_PCM_STREAM_CAPTURE: | 3069 | result = snd_pcm_capture_forward(substream, *frames); |
3023 | result = snd_pcm_capture_ioctl1(NULL, substream, cmd, | 3070 | return result < 0 ? result : 0; |
3024 | (void __user *)arg); | 3071 | } |
3025 | break; | 3072 | case SNDRV_PCM_IOCTL_HW_PARAMS: |
3073 | return snd_pcm_hw_params(substream, arg); | ||
3074 | case SNDRV_PCM_IOCTL_SW_PARAMS: | ||
3075 | return snd_pcm_sw_params(substream, arg); | ||
3076 | case SNDRV_PCM_IOCTL_PREPARE: | ||
3077 | return snd_pcm_prepare(substream, NULL); | ||
3078 | case SNDRV_PCM_IOCTL_START: | ||
3079 | return snd_pcm_start_lock_irq(substream); | ||
3080 | case SNDRV_PCM_IOCTL_DRAIN: | ||
3081 | return snd_pcm_drain(substream, NULL); | ||
3082 | case SNDRV_PCM_IOCTL_DROP: | ||
3083 | return snd_pcm_drop(substream); | ||
3084 | case SNDRV_PCM_IOCTL_DELAY: | ||
3085 | { | ||
3086 | result = snd_pcm_delay(substream); | ||
3087 | if (result < 0) | ||
3088 | return result; | ||
3089 | *frames = result; | ||
3090 | return 0; | ||
3091 | } | ||
3026 | default: | 3092 | default: |
3027 | result = -EINVAL; | 3093 | return -EINVAL; |
3028 | break; | ||
3029 | } | 3094 | } |
3030 | snd_leave_user(fs); | ||
3031 | return result; | ||
3032 | } | 3095 | } |
3033 | |||
3034 | EXPORT_SYMBOL(snd_pcm_kernel_ioctl); | 3096 | EXPORT_SYMBOL(snd_pcm_kernel_ioctl); |
3035 | 3097 | ||
3036 | static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, | 3098 | static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, |
@@ -3437,7 +3499,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | |||
3437 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); | 3499 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); |
3438 | return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); | 3500 | return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); |
3439 | } | 3501 | } |
3440 | |||
3441 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); | 3502 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); |
3442 | #endif /* SNDRV_PCM_INFO_MMAP */ | 3503 | #endif /* SNDRV_PCM_INFO_MMAP */ |
3443 | 3504 | ||
@@ -3486,7 +3547,6 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, | |||
3486 | atomic_inc(&substream->mmap_count); | 3547 | atomic_inc(&substream->mmap_count); |
3487 | return err; | 3548 | return err; |
3488 | } | 3549 | } |
3489 | |||
3490 | EXPORT_SYMBOL(snd_pcm_mmap_data); | 3550 | EXPORT_SYMBOL(snd_pcm_mmap_data); |
3491 | 3551 | ||
3492 | static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) | 3552 | static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) |
@@ -3603,12 +3663,17 @@ static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream, | |||
3603 | } | 3663 | } |
3604 | snd_pcm_hw_convert_from_old_params(params, oparams); | 3664 | snd_pcm_hw_convert_from_old_params(params, oparams); |
3605 | err = snd_pcm_hw_refine(substream, params); | 3665 | err = snd_pcm_hw_refine(substream, params); |
3606 | snd_pcm_hw_convert_to_old_params(oparams, params); | 3666 | if (err < 0) |
3607 | if (copy_to_user(_oparams, oparams, sizeof(*oparams))) { | 3667 | goto out_old; |
3608 | if (!err) | 3668 | |
3609 | err = -EFAULT; | 3669 | err = fixup_unreferenced_params(substream, params); |
3610 | } | 3670 | if (err < 0) |
3671 | goto out_old; | ||
3611 | 3672 | ||
3673 | snd_pcm_hw_convert_to_old_params(oparams, params); | ||
3674 | if (copy_to_user(_oparams, oparams, sizeof(*oparams))) | ||
3675 | err = -EFAULT; | ||
3676 | out_old: | ||
3612 | kfree(oparams); | 3677 | kfree(oparams); |
3613 | out: | 3678 | out: |
3614 | kfree(params); | 3679 | kfree(params); |
@@ -3631,14 +3696,16 @@ static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream, | |||
3631 | err = PTR_ERR(oparams); | 3696 | err = PTR_ERR(oparams); |
3632 | goto out; | 3697 | goto out; |
3633 | } | 3698 | } |
3699 | |||
3634 | snd_pcm_hw_convert_from_old_params(params, oparams); | 3700 | snd_pcm_hw_convert_from_old_params(params, oparams); |
3635 | err = snd_pcm_hw_params(substream, params); | 3701 | err = snd_pcm_hw_params(substream, params); |
3636 | snd_pcm_hw_convert_to_old_params(oparams, params); | 3702 | if (err < 0) |
3637 | if (copy_to_user(_oparams, oparams, sizeof(*oparams))) { | 3703 | goto out_old; |
3638 | if (!err) | ||
3639 | err = -EFAULT; | ||
3640 | } | ||
3641 | 3704 | ||
3705 | snd_pcm_hw_convert_to_old_params(oparams, params); | ||
3706 | if (copy_to_user(_oparams, oparams, sizeof(*oparams))) | ||
3707 | err = -EFAULT; | ||
3708 | out_old: | ||
3642 | kfree(oparams); | 3709 | kfree(oparams); |
3643 | out: | 3710 | out: |
3644 | kfree(params); | 3711 | kfree(params); |
diff --git a/sound/core/pcm_param_trace.h b/sound/core/pcm_param_trace.h new file mode 100644 index 000000000000..86c8d658a25c --- /dev/null +++ b/sound/core/pcm_param_trace.h | |||
@@ -0,0 +1,142 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM snd_pcm | ||
3 | |||
4 | #if !defined(_PCM_PARAMS_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _PCM_PARAMS_TRACE_H | ||
6 | |||
7 | #include <linux/tracepoint.h> | ||
8 | |||
9 | #define HW_PARAM_ENTRY(param) {SNDRV_PCM_HW_PARAM_##param, #param} | ||
10 | #define hw_param_labels \ | ||
11 | HW_PARAM_ENTRY(ACCESS), \ | ||
12 | HW_PARAM_ENTRY(FORMAT), \ | ||
13 | HW_PARAM_ENTRY(SUBFORMAT), \ | ||
14 | HW_PARAM_ENTRY(SAMPLE_BITS), \ | ||
15 | HW_PARAM_ENTRY(FRAME_BITS), \ | ||
16 | HW_PARAM_ENTRY(CHANNELS), \ | ||
17 | HW_PARAM_ENTRY(RATE), \ | ||
18 | HW_PARAM_ENTRY(PERIOD_TIME), \ | ||
19 | HW_PARAM_ENTRY(PERIOD_SIZE), \ | ||
20 | HW_PARAM_ENTRY(PERIOD_BYTES), \ | ||
21 | HW_PARAM_ENTRY(PERIODS), \ | ||
22 | HW_PARAM_ENTRY(BUFFER_TIME), \ | ||
23 | HW_PARAM_ENTRY(BUFFER_SIZE), \ | ||
24 | HW_PARAM_ENTRY(BUFFER_BYTES), \ | ||
25 | HW_PARAM_ENTRY(TICK_TIME) | ||
26 | |||
27 | TRACE_EVENT(hw_mask_param, | ||
28 | TP_PROTO(struct snd_pcm_substream *substream, snd_pcm_hw_param_t type, int index, const struct snd_mask *prev, const struct snd_mask *curr), | ||
29 | TP_ARGS(substream, type, index, prev, curr), | ||
30 | TP_STRUCT__entry( | ||
31 | __field(int, card) | ||
32 | __field(int, device) | ||
33 | __field(int, subdevice) | ||
34 | __field(int, direction) | ||
35 | __field(snd_pcm_hw_param_t, type) | ||
36 | __field(int, index) | ||
37 | __field(int, total) | ||
38 | __array(__u32, prev_bits, 8) | ||
39 | __array(__u32, curr_bits, 8) | ||
40 | ), | ||
41 | TP_fast_assign( | ||
42 | __entry->card = substream->pcm->card->number; | ||
43 | __entry->device = substream->pcm->device; | ||
44 | __entry->subdevice = substream->number; | ||
45 | __entry->direction = substream->stream; | ||
46 | __entry->type = type; | ||
47 | __entry->index = index; | ||
48 | __entry->total = substream->runtime->hw_constraints.rules_num; | ||
49 | memcpy(__entry->prev_bits, prev->bits, sizeof(__u32) * 8); | ||
50 | memcpy(__entry->curr_bits, curr->bits, sizeof(__u32) * 8); | ||
51 | ), | ||
52 | TP_printk("pcmC%dD%d%s:%d %03d/%03d %s %08x%08x%08x%08x %08x%08x%08x%08x", | ||
53 | __entry->card, | ||
54 | __entry->device, | ||
55 | __entry->direction ? "c" : "p", | ||
56 | __entry->subdevice, | ||
57 | __entry->index, | ||
58 | __entry->total, | ||
59 | __print_symbolic(__entry->type, hw_param_labels), | ||
60 | __entry->prev_bits[3], __entry->prev_bits[2], | ||
61 | __entry->prev_bits[1], __entry->prev_bits[0], | ||
62 | __entry->curr_bits[3], __entry->curr_bits[2], | ||
63 | __entry->curr_bits[1], __entry->curr_bits[0] | ||
64 | ) | ||
65 | ); | ||
66 | |||
67 | TRACE_EVENT(hw_interval_param, | ||
68 | TP_PROTO(struct snd_pcm_substream *substream, snd_pcm_hw_param_t type, int index, const struct snd_interval *prev, const struct snd_interval *curr), | ||
69 | TP_ARGS(substream, type, index, prev, curr), | ||
70 | TP_STRUCT__entry( | ||
71 | __field(int, card) | ||
72 | __field(int, device) | ||
73 | __field(int, subdevice) | ||
74 | __field(int, direction) | ||
75 | __field(snd_pcm_hw_param_t, type) | ||
76 | __field(int, index) | ||
77 | __field(int, total) | ||
78 | __field(unsigned int, prev_min) | ||
79 | __field(unsigned int, prev_max) | ||
80 | __field(unsigned int, prev_openmin) | ||
81 | __field(unsigned int, prev_openmax) | ||
82 | __field(unsigned int, prev_integer) | ||
83 | __field(unsigned int, prev_empty) | ||
84 | __field(unsigned int, curr_min) | ||
85 | __field(unsigned int, curr_max) | ||
86 | __field(unsigned int, curr_openmin) | ||
87 | __field(unsigned int, curr_openmax) | ||
88 | __field(unsigned int, curr_integer) | ||
89 | __field(unsigned int, curr_empty) | ||
90 | ), | ||
91 | TP_fast_assign( | ||
92 | __entry->card = substream->pcm->card->number; | ||
93 | __entry->device = substream->pcm->device; | ||
94 | __entry->subdevice = substream->number; | ||
95 | __entry->direction = substream->stream; | ||
96 | __entry->type = type; | ||
97 | __entry->index = index; | ||
98 | __entry->total = substream->runtime->hw_constraints.rules_num; | ||
99 | __entry->prev_min = prev->min; | ||
100 | __entry->prev_max = prev->max; | ||
101 | __entry->prev_openmin = prev->openmin; | ||
102 | __entry->prev_openmax = prev->openmax; | ||
103 | __entry->prev_integer = prev->integer; | ||
104 | __entry->prev_empty = prev->empty; | ||
105 | __entry->curr_min = curr->min; | ||
106 | __entry->curr_max = curr->max; | ||
107 | __entry->curr_openmin = curr->openmin; | ||
108 | __entry->curr_openmax = curr->openmax; | ||
109 | __entry->curr_integer = curr->integer; | ||
110 | __entry->curr_empty = curr->empty; | ||
111 | ), | ||
112 | TP_printk("pcmC%dD%d%s:%d %03d/%03d %s %d %d %s%u %u%s %d %d %s%u %u%s", | ||
113 | __entry->card, | ||
114 | __entry->device, | ||
115 | __entry->direction ? "c" : "p", | ||
116 | __entry->subdevice, | ||
117 | __entry->index, | ||
118 | __entry->total, | ||
119 | __print_symbolic(__entry->type, hw_param_labels), | ||
120 | __entry->prev_empty, | ||
121 | __entry->prev_integer, | ||
122 | __entry->prev_openmin ? "(" : "[", | ||
123 | __entry->prev_min, | ||
124 | __entry->prev_max, | ||
125 | __entry->prev_openmax ? ")" : "]", | ||
126 | __entry->curr_empty, | ||
127 | __entry->curr_integer, | ||
128 | __entry->curr_openmin ? "(" : "[", | ||
129 | __entry->curr_min, | ||
130 | __entry->curr_max, | ||
131 | __entry->curr_openmax ? ")" : "]" | ||
132 | ) | ||
133 | ); | ||
134 | |||
135 | #endif /* _PCM_PARAMS_TRACE_H */ | ||
136 | |||
137 | /* This part must be outside protection */ | ||
138 | #undef TRACE_INCLUDE_PATH | ||
139 | #define TRACE_INCLUDE_PATH . | ||
140 | #undef TRACE_INCLUDE_FILE | ||
141 | #define TRACE_INCLUDE_FILE pcm_param_trace | ||
142 | #include <trace/define_trace.h> | ||
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c index 20ecd8f18080..11389f13de73 100644 --- a/sound/core/pcm_timer.c +++ b/sound/core/pcm_timer.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
26 | #include <sound/timer.h> | 26 | #include <sound/timer.h> |
27 | 27 | ||
28 | #include "pcm_local.h" | ||
29 | |||
28 | /* | 30 | /* |
29 | * Timer functions | 31 | * Timer functions |
30 | */ | 32 | */ |
@@ -33,8 +35,8 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) | |||
33 | { | 35 | { |
34 | unsigned long rate, mult, fsize, l, post; | 36 | unsigned long rate, mult, fsize, l, post; |
35 | struct snd_pcm_runtime *runtime = substream->runtime; | 37 | struct snd_pcm_runtime *runtime = substream->runtime; |
36 | 38 | ||
37 | mult = 1000000000; | 39 | mult = 1000000000; |
38 | rate = runtime->rate; | 40 | rate = runtime->rate; |
39 | if (snd_BUG_ON(!rate)) | 41 | if (snd_BUG_ON(!rate)) |
40 | return; | 42 | return; |
@@ -65,7 +67,7 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) | |||
65 | static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer) | 67 | static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer) |
66 | { | 68 | { |
67 | struct snd_pcm_substream *substream; | 69 | struct snd_pcm_substream *substream; |
68 | 70 | ||
69 | substream = timer->private_data; | 71 | substream = timer->private_data; |
70 | return substream->runtime ? substream->runtime->timer_resolution : 0; | 72 | return substream->runtime ? substream->runtime->timer_resolution : 0; |
71 | } | 73 | } |
@@ -73,7 +75,7 @@ static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer) | |||
73 | static int snd_pcm_timer_start(struct snd_timer * timer) | 75 | static int snd_pcm_timer_start(struct snd_timer * timer) |
74 | { | 76 | { |
75 | struct snd_pcm_substream *substream; | 77 | struct snd_pcm_substream *substream; |
76 | 78 | ||
77 | substream = snd_timer_chip(timer); | 79 | substream = snd_timer_chip(timer); |
78 | substream->timer_running = 1; | 80 | substream->timer_running = 1; |
79 | return 0; | 81 | return 0; |
@@ -82,7 +84,7 @@ static int snd_pcm_timer_start(struct snd_timer * timer) | |||
82 | static int snd_pcm_timer_stop(struct snd_timer * timer) | 84 | static int snd_pcm_timer_stop(struct snd_timer * timer) |
83 | { | 85 | { |
84 | struct snd_pcm_substream *substream; | 86 | struct snd_pcm_substream *substream; |
85 | 87 | ||
86 | substream = snd_timer_chip(timer); | 88 | substream = snd_timer_chip(timer); |
87 | substream->timer_running = 0; | 89 | substream->timer_running = 0; |
88 | return 0; | 90 | return 0; |
@@ -112,7 +114,7 @@ void snd_pcm_timer_init(struct snd_pcm_substream *substream) | |||
112 | { | 114 | { |
113 | struct snd_timer_id tid; | 115 | struct snd_timer_id tid; |
114 | struct snd_timer *timer; | 116 | struct snd_timer *timer; |
115 | 117 | ||
116 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; | 118 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; |
117 | tid.dev_class = SNDRV_TIMER_CLASS_PCM; | 119 | tid.dev_class = SNDRV_TIMER_CLASS_PCM; |
118 | tid.card = substream->pcm->card->number; | 120 | tid.card = substream->pcm->card->number; |
diff --git a/sound/core/pcm_trace.h b/sound/core/pcm_trace.h index b63b654da5ff..3ddec1b8ae46 100644 --- a/sound/core/pcm_trace.h +++ b/sound/core/pcm_trace.h | |||
@@ -34,9 +34,9 @@ TRACE_EVENT(hwptr, | |||
34 | __entry->old_hw_ptr = (substream)->runtime->status->hw_ptr; | 34 | __entry->old_hw_ptr = (substream)->runtime->status->hw_ptr; |
35 | __entry->hw_ptr_base = (substream)->runtime->hw_ptr_base; | 35 | __entry->hw_ptr_base = (substream)->runtime->hw_ptr_base; |
36 | ), | 36 | ), |
37 | TP_printk("pcmC%dD%d%c/sub%d: %s: pos=%lu, old=%lu, base=%lu, period=%lu, buf=%lu", | 37 | TP_printk("pcmC%dD%d%s/sub%d: %s: pos=%lu, old=%lu, base=%lu, period=%lu, buf=%lu", |
38 | __entry->card, __entry->device, | 38 | __entry->card, __entry->device, |
39 | __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c', | 39 | __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? "p" : "c", |
40 | __entry->number, | 40 | __entry->number, |
41 | __entry->in_interrupt ? "IRQ" : "POS", | 41 | __entry->in_interrupt ? "IRQ" : "POS", |
42 | (unsigned long)__entry->pos, | 42 | (unsigned long)__entry->pos, |
@@ -69,9 +69,9 @@ TRACE_EVENT(xrun, | |||
69 | __entry->old_hw_ptr = (substream)->runtime->status->hw_ptr; | 69 | __entry->old_hw_ptr = (substream)->runtime->status->hw_ptr; |
70 | __entry->hw_ptr_base = (substream)->runtime->hw_ptr_base; | 70 | __entry->hw_ptr_base = (substream)->runtime->hw_ptr_base; |
71 | ), | 71 | ), |
72 | TP_printk("pcmC%dD%d%c/sub%d: XRUN: old=%lu, base=%lu, period=%lu, buf=%lu", | 72 | TP_printk("pcmC%dD%d%s/sub%d: XRUN: old=%lu, base=%lu, period=%lu, buf=%lu", |
73 | __entry->card, __entry->device, | 73 | __entry->card, __entry->device, |
74 | __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c', | 74 | __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? "p" : "c", |
75 | __entry->number, | 75 | __entry->number, |
76 | (unsigned long)__entry->old_hw_ptr, | 76 | (unsigned long)__entry->old_hw_ptr, |
77 | (unsigned long)__entry->hw_ptr_base, | 77 | (unsigned long)__entry->hw_ptr_base, |
@@ -96,12 +96,50 @@ TRACE_EVENT(hw_ptr_error, | |||
96 | __entry->stream = (substream)->stream; | 96 | __entry->stream = (substream)->stream; |
97 | __entry->reason = (why); | 97 | __entry->reason = (why); |
98 | ), | 98 | ), |
99 | TP_printk("pcmC%dD%d%c/sub%d: ERROR: %s", | 99 | TP_printk("pcmC%dD%d%s/sub%d: ERROR: %s", |
100 | __entry->card, __entry->device, | 100 | __entry->card, __entry->device, |
101 | __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c', | 101 | __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? "p" : "c", |
102 | __entry->number, __entry->reason) | 102 | __entry->number, __entry->reason) |
103 | ); | 103 | ); |
104 | 104 | ||
105 | TRACE_EVENT(applptr, | ||
106 | TP_PROTO(struct snd_pcm_substream *substream, snd_pcm_uframes_t prev, snd_pcm_uframes_t curr), | ||
107 | TP_ARGS(substream, prev, curr), | ||
108 | TP_STRUCT__entry( | ||
109 | __field( unsigned int, card ) | ||
110 | __field( unsigned int, device ) | ||
111 | __field( unsigned int, number ) | ||
112 | __field( unsigned int, stream ) | ||
113 | __field( snd_pcm_uframes_t, prev ) | ||
114 | __field( snd_pcm_uframes_t, curr ) | ||
115 | __field( snd_pcm_uframes_t, avail ) | ||
116 | __field( snd_pcm_uframes_t, period_size ) | ||
117 | __field( snd_pcm_uframes_t, buffer_size ) | ||
118 | ), | ||
119 | TP_fast_assign( | ||
120 | __entry->card = (substream)->pcm->card->number; | ||
121 | __entry->device = (substream)->pcm->device; | ||
122 | __entry->number = (substream)->number; | ||
123 | __entry->stream = (substream)->stream; | ||
124 | __entry->prev = (prev); | ||
125 | __entry->curr = (curr); | ||
126 | __entry->avail = (substream)->stream ? snd_pcm_capture_avail(substream->runtime) : snd_pcm_playback_avail(substream->runtime); | ||
127 | __entry->period_size = (substream)->runtime->period_size; | ||
128 | __entry->buffer_size = (substream)->runtime->buffer_size; | ||
129 | ), | ||
130 | TP_printk("pcmC%dD%d%s/sub%d: prev=%lu, curr=%lu, avail=%lu, period=%lu, buf=%lu", | ||
131 | __entry->card, | ||
132 | __entry->device, | ||
133 | __entry->stream ? "c" : "p", | ||
134 | __entry->number, | ||
135 | __entry->prev, | ||
136 | __entry->curr, | ||
137 | __entry->avail, | ||
138 | __entry->period_size, | ||
139 | __entry->buffer_size | ||
140 | ) | ||
141 | ); | ||
142 | |||
105 | #endif /* _PCM_TRACE_H */ | 143 | #endif /* _PCM_TRACE_H */ |
106 | 144 | ||
107 | /* This part must be outside protection */ | 145 | /* This part must be outside protection */ |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index ab890336175f..153d78bc79c0 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -1610,7 +1610,7 @@ static int snd_rawmidi_dev_free(struct snd_device *device) | |||
1610 | return snd_rawmidi_free(rmidi); | 1610 | return snd_rawmidi_free(rmidi); |
1611 | } | 1611 | } |
1612 | 1612 | ||
1613 | #if IS_REACHABLE(CONFIG_SND_SEQUENCER) | 1613 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
1614 | static void snd_rawmidi_dev_seq_free(struct snd_seq_device *device) | 1614 | static void snd_rawmidi_dev_seq_free(struct snd_seq_device *device) |
1615 | { | 1615 | { |
1616 | struct snd_rawmidi *rmidi = device->private_data; | 1616 | struct snd_rawmidi *rmidi = device->private_data; |
@@ -1691,7 +1691,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device) | |||
1691 | } | 1691 | } |
1692 | } | 1692 | } |
1693 | rmidi->proc_entry = entry; | 1693 | rmidi->proc_entry = entry; |
1694 | #if IS_REACHABLE(CONFIG_SND_SEQUENCER) | 1694 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
1695 | if (!rmidi->ops || !rmidi->ops->dev_register) { /* own registration mechanism */ | 1695 | if (!rmidi->ops || !rmidi->ops->dev_register) { /* own registration mechanism */ |
1696 | if (snd_seq_device_new(rmidi->card, rmidi->device, SNDRV_SEQ_DEV_ID_MIDISYNTH, 0, &rmidi->seq_dev) >= 0) { | 1696 | if (snd_seq_device_new(rmidi->card, rmidi->device, SNDRV_SEQ_DEV_ID_MIDISYNTH, 0, &rmidi->seq_dev) >= 0) { |
1697 | rmidi->seq_dev->private_data = rmidi; | 1697 | rmidi->seq_dev->private_data = rmidi; |
diff --git a/sound/core/seq/Kconfig b/sound/core/seq/Kconfig index b851fd890a89..a536760a94c2 100644 --- a/sound/core/seq/Kconfig +++ b/sound/core/seq/Kconfig | |||
@@ -1,16 +1,62 @@ | |||
1 | # define SND_XXX_SEQ to min(SND_SEQUENCER,SND_XXX) | 1 | config SND_SEQUENCER |
2 | tristate "Sequencer support" | ||
3 | select SND_TIMER | ||
4 | select SND_SEQ_DEVICE | ||
5 | help | ||
6 | Say Y or M to enable MIDI sequencer and router support. This | ||
7 | feature allows routing and enqueueing of MIDI events. Events | ||
8 | can be processed at a given time. | ||
2 | 9 | ||
3 | config SND_RAWMIDI_SEQ | 10 | Many programs require this feature, so you should enable it |
4 | def_tristate SND_SEQUENCER && SND_RAWMIDI | 11 | unless you know what you're doing. |
5 | 12 | ||
6 | config SND_OPL3_LIB_SEQ | 13 | if SND_SEQUENCER |
7 | def_tristate SND_SEQUENCER && SND_OPL3_LIB | ||
8 | 14 | ||
9 | config SND_OPL4_LIB_SEQ | 15 | config SND_SEQ_DUMMY |
10 | def_tristate SND_SEQUENCER && SND_OPL4_LIB | 16 | tristate "Sequencer dummy client" |
17 | help | ||
18 | Say Y here to enable the dummy sequencer client. This client | ||
19 | is a simple MIDI-through client: all normal input events are | ||
20 | redirected to the output port immediately. | ||
11 | 21 | ||
12 | config SND_SBAWE_SEQ | 22 | You don't need this unless you want to connect many MIDI |
13 | def_tristate SND_SEQUENCER && SND_SBAWE | 23 | devices or applications together. |
14 | 24 | ||
15 | config SND_EMU10K1_SEQ | 25 | To compile this driver as a module, choose M here: the module |
16 | def_tristate SND_SEQUENCER && SND_EMU10K1 | 26 | will be called snd-seq-dummy. |
27 | |||
28 | config SND_SEQUENCER_OSS | ||
29 | tristate "OSS Sequencer API" | ||
30 | depends on SND_OSSEMUL | ||
31 | select SND_SEQ_MIDI_EVENT | ||
32 | help | ||
33 | Say Y here to enable OSS sequencer emulation (both | ||
34 | /dev/sequencer and /dev/music interfaces). | ||
35 | |||
36 | Many programs still use the OSS API, so say Y. | ||
37 | |||
38 | To compile this driver as a module, choose M here: the module | ||
39 | will be called snd-seq-oss. | ||
40 | |||
41 | config SND_SEQ_HRTIMER_DEFAULT | ||
42 | bool "Use HR-timer as default sequencer timer" | ||
43 | depends on SND_HRTIMER | ||
44 | default y | ||
45 | help | ||
46 | Say Y here to use the HR-timer backend as the default sequencer | ||
47 | timer. | ||
48 | |||
49 | config SND_SEQ_MIDI_EVENT | ||
50 | def_tristate SND_RAWMIDI | ||
51 | |||
52 | config SND_SEQ_MIDI | ||
53 | tristate | ||
54 | select SND_SEQ_MIDI_EVENT | ||
55 | |||
56 | config SND_SEQ_MIDI_EMUL | ||
57 | tristate | ||
58 | |||
59 | config SND_SEQ_VIRMIDI | ||
60 | tristate | ||
61 | |||
62 | endif # SND_SEQUENCER | ||
diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile index b65fa5a1943b..68fd367ac39c 100644 --- a/sound/core/seq/Makefile +++ b/sound/core/seq/Makefile | |||
@@ -3,7 +3,6 @@ | |||
3 | # Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz> | 3 | # Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz> |
4 | # | 4 | # |
5 | 5 | ||
6 | snd-seq-device-objs := seq_device.o | ||
7 | snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ | 6 | snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ |
8 | seq_fifo.o seq_prioq.o seq_timer.o \ | 7 | seq_fifo.o seq_prioq.o seq_timer.o \ |
9 | seq_system.o seq_ports.o | 8 | seq_system.o seq_ports.o |
@@ -14,17 +13,11 @@ snd-seq-midi-event-objs := seq_midi_event.o | |||
14 | snd-seq-dummy-objs := seq_dummy.o | 13 | snd-seq-dummy-objs := seq_dummy.o |
15 | snd-seq-virmidi-objs := seq_virmidi.o | 14 | snd-seq-virmidi-objs := seq_virmidi.o |
16 | 15 | ||
17 | obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o snd-seq-device.o | 16 | obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o |
18 | ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) | 17 | obj-$(CONFIG_SND_SEQUENCER_OSS) += oss/ |
19 | obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o | ||
20 | obj-$(CONFIG_SND_SEQUENCER) += oss/ | ||
21 | endif | ||
22 | obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o | ||
23 | 18 | ||
24 | # Toplevel Module Dependency | 19 | obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o |
25 | obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o | 20 | obj-$(CONFIG_SND_SEQ_MIDI) += snd-seq-midi.o |
26 | obj-$(CONFIG_SND_RAWMIDI_SEQ) += snd-seq-midi.o snd-seq-midi-event.o | 21 | obj-$(CONFIG_SND_SEQ_MIDI_EMUL) += snd-seq-midi-emul.o |
27 | obj-$(CONFIG_SND_OPL3_LIB_SEQ) += snd-seq-midi-event.o snd-seq-midi-emul.o | 22 | obj-$(CONFIG_SND_SEQ_MIDI_EVENT) += snd-seq-midi-event.o |
28 | obj-$(CONFIG_SND_OPL4_LIB_SEQ) += snd-seq-midi-event.o snd-seq-midi-emul.o | 23 | obj-$(CONFIG_SND_SEQ_VIRMIDI) += snd-seq-virmidi.o |
29 | obj-$(CONFIG_SND_SBAWE_SEQ) += snd-seq-midi-emul.o snd-seq-virmidi.o | ||
30 | obj-$(CONFIG_SND_EMU10K1_SEQ) += snd-seq-midi-emul.o snd-seq-virmidi.o | ||
diff --git a/sound/core/seq/oss/Makefile b/sound/core/seq/oss/Makefile index b38406b8463c..4ea4e3eea6b7 100644 --- a/sound/core/seq/oss/Makefile +++ b/sound/core/seq/oss/Makefile | |||
@@ -7,4 +7,4 @@ snd-seq-oss-objs := seq_oss.o seq_oss_init.o seq_oss_timer.o seq_oss_ioctl.o \ | |||
7 | seq_oss_event.o seq_oss_rw.o seq_oss_synth.o \ | 7 | seq_oss_event.o seq_oss_rw.o seq_oss_synth.o \ |
8 | seq_oss_midi.o seq_oss_readq.o seq_oss_writeq.o | 8 | seq_oss_midi.o seq_oss_readq.o seq_oss_writeq.o |
9 | 9 | ||
10 | obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o | 10 | obj-$(CONFIG_SND_SEQUENCER_OSS) += snd-seq-oss.o |
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index f3b1d7f50b81..272c55fe17c8 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c | |||
@@ -1668,7 +1668,6 @@ int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo) | |||
1668 | return -EPERM; | 1668 | return -EPERM; |
1669 | return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo); | 1669 | return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo); |
1670 | } | 1670 | } |
1671 | |||
1672 | EXPORT_SYMBOL(snd_seq_set_queue_tempo); | 1671 | EXPORT_SYMBOL(snd_seq_set_queue_tempo); |
1673 | 1672 | ||
1674 | static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, | 1673 | static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client, |
@@ -2200,7 +2199,6 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, | |||
2200 | /* return client number to caller */ | 2199 | /* return client number to caller */ |
2201 | return client->number; | 2200 | return client->number; |
2202 | } | 2201 | } |
2203 | |||
2204 | EXPORT_SYMBOL(snd_seq_create_kernel_client); | 2202 | EXPORT_SYMBOL(snd_seq_create_kernel_client); |
2205 | 2203 | ||
2206 | /* exported to kernel modules */ | 2204 | /* exported to kernel modules */ |
@@ -2219,7 +2217,6 @@ int snd_seq_delete_kernel_client(int client) | |||
2219 | kfree(ptr); | 2217 | kfree(ptr); |
2220 | return 0; | 2218 | return 0; |
2221 | } | 2219 | } |
2222 | |||
2223 | EXPORT_SYMBOL(snd_seq_delete_kernel_client); | 2220 | EXPORT_SYMBOL(snd_seq_delete_kernel_client); |
2224 | 2221 | ||
2225 | /* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue | 2222 | /* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue |
@@ -2269,7 +2266,6 @@ int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event * ev, | |||
2269 | { | 2266 | { |
2270 | return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop); | 2267 | return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop); |
2271 | } | 2268 | } |
2272 | |||
2273 | EXPORT_SYMBOL(snd_seq_kernel_client_enqueue); | 2269 | EXPORT_SYMBOL(snd_seq_kernel_client_enqueue); |
2274 | 2270 | ||
2275 | /* | 2271 | /* |
@@ -2283,7 +2279,6 @@ int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev | |||
2283 | { | 2279 | { |
2284 | return kernel_client_enqueue(client, ev, file, 1, atomic, hop); | 2280 | return kernel_client_enqueue(client, ev, file, 1, atomic, hop); |
2285 | } | 2281 | } |
2286 | |||
2287 | EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking); | 2282 | EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking); |
2288 | 2283 | ||
2289 | /* | 2284 | /* |
@@ -2321,7 +2316,6 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev, | |||
2321 | snd_seq_client_unlock(cptr); | 2316 | snd_seq_client_unlock(cptr); |
2322 | return result; | 2317 | return result; |
2323 | } | 2318 | } |
2324 | |||
2325 | EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); | 2319 | EXPORT_SYMBOL(snd_seq_kernel_client_dispatch); |
2326 | 2320 | ||
2327 | /** | 2321 | /** |
@@ -2354,7 +2348,6 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg) | |||
2354 | cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); | 2348 | cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); |
2355 | return -ENOTTY; | 2349 | return -ENOTTY; |
2356 | } | 2350 | } |
2357 | |||
2358 | EXPORT_SYMBOL(snd_seq_kernel_client_ctl); | 2351 | EXPORT_SYMBOL(snd_seq_kernel_client_ctl); |
2359 | 2352 | ||
2360 | /* exported (for OSS emulator) */ | 2353 | /* exported (for OSS emulator) */ |
@@ -2372,7 +2365,6 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table | |||
2372 | return 1; | 2365 | return 1; |
2373 | return 0; | 2366 | return 0; |
2374 | } | 2367 | } |
2375 | |||
2376 | EXPORT_SYMBOL(snd_seq_kernel_client_write_poll); | 2368 | EXPORT_SYMBOL(snd_seq_kernel_client_write_poll); |
2377 | 2369 | ||
2378 | /*---------------------------------------------------------------------------*/ | 2370 | /*---------------------------------------------------------------------------*/ |
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c index 12ba83367b1b..0ff7926a5a69 100644 --- a/sound/core/seq/seq_lock.c +++ b/sound/core/seq/seq_lock.c | |||
@@ -40,7 +40,6 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) | |||
40 | schedule_timeout_uninterruptible(1); | 40 | schedule_timeout_uninterruptible(1); |
41 | } | 41 | } |
42 | } | 42 | } |
43 | |||
44 | EXPORT_SYMBOL(snd_use_lock_sync_helper); | 43 | EXPORT_SYMBOL(snd_use_lock_sync_helper); |
45 | 44 | ||
46 | #endif | 45 | #endif |
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index d4c61ec9be13..512f78ea13da 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c | |||
@@ -118,7 +118,6 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event, | |||
118 | } | 118 | } |
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | |||
122 | EXPORT_SYMBOL(snd_seq_dump_var_event); | 121 | EXPORT_SYMBOL(snd_seq_dump_var_event); |
123 | 122 | ||
124 | 123 | ||
@@ -169,7 +168,6 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char | |||
169 | &buf); | 168 | &buf); |
170 | return err < 0 ? err : newlen; | 169 | return err < 0 ? err : newlen; |
171 | } | 170 | } |
172 | |||
173 | EXPORT_SYMBOL(snd_seq_expand_var_event); | 171 | EXPORT_SYMBOL(snd_seq_expand_var_event); |
174 | 172 | ||
175 | /* | 173 | /* |
diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c index 7ba937399ac7..9e2912e3e80f 100644 --- a/sound/core/seq/seq_midi_emul.c +++ b/sound/core/seq/seq_midi_emul.c | |||
@@ -236,6 +236,7 @@ snd_midi_process_event(struct snd_midi_op *ops, | |||
236 | break; | 236 | break; |
237 | } | 237 | } |
238 | } | 238 | } |
239 | EXPORT_SYMBOL(snd_midi_process_event); | ||
239 | 240 | ||
240 | 241 | ||
241 | /* | 242 | /* |
@@ -409,6 +410,7 @@ snd_midi_channel_set_clear(struct snd_midi_channel_set *chset) | |||
409 | chan->drum_channel = 0; | 410 | chan->drum_channel = 0; |
410 | } | 411 | } |
411 | } | 412 | } |
413 | EXPORT_SYMBOL(snd_midi_channel_set_clear); | ||
412 | 414 | ||
413 | /* | 415 | /* |
414 | * Process a rpn message. | 416 | * Process a rpn message. |
@@ -701,6 +703,7 @@ struct snd_midi_channel_set *snd_midi_channel_alloc_set(int n) | |||
701 | } | 703 | } |
702 | return chset; | 704 | return chset; |
703 | } | 705 | } |
706 | EXPORT_SYMBOL(snd_midi_channel_alloc_set); | ||
704 | 707 | ||
705 | /* | 708 | /* |
706 | * Reset the midi controllers on a particular channel to default values. | 709 | * Reset the midi controllers on a particular channel to default values. |
@@ -724,6 +727,7 @@ void snd_midi_channel_free_set(struct snd_midi_channel_set *chset) | |||
724 | kfree(chset->channels); | 727 | kfree(chset->channels); |
725 | kfree(chset); | 728 | kfree(chset); |
726 | } | 729 | } |
730 | EXPORT_SYMBOL(snd_midi_channel_free_set); | ||
727 | 731 | ||
728 | static int __init alsa_seq_midi_emul_init(void) | 732 | static int __init alsa_seq_midi_emul_init(void) |
729 | { | 733 | { |
@@ -736,8 +740,3 @@ static void __exit alsa_seq_midi_emul_exit(void) | |||
736 | 740 | ||
737 | module_init(alsa_seq_midi_emul_init) | 741 | module_init(alsa_seq_midi_emul_init) |
738 | module_exit(alsa_seq_midi_emul_exit) | 742 | module_exit(alsa_seq_midi_emul_exit) |
739 | |||
740 | EXPORT_SYMBOL(snd_midi_process_event); | ||
741 | EXPORT_SYMBOL(snd_midi_channel_set_clear); | ||
742 | EXPORT_SYMBOL(snd_midi_channel_alloc_set); | ||
743 | EXPORT_SYMBOL(snd_midi_channel_free_set); | ||
diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c index 37db7ba492a6..90bbbdbeba03 100644 --- a/sound/core/seq/seq_midi_event.c +++ b/sound/core/seq/seq_midi_event.c | |||
@@ -134,6 +134,7 @@ int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev) | |||
134 | *rdev = dev; | 134 | *rdev = dev; |
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
137 | EXPORT_SYMBOL(snd_midi_event_new); | ||
137 | 138 | ||
138 | void snd_midi_event_free(struct snd_midi_event *dev) | 139 | void snd_midi_event_free(struct snd_midi_event *dev) |
139 | { | 140 | { |
@@ -142,6 +143,7 @@ void snd_midi_event_free(struct snd_midi_event *dev) | |||
142 | kfree(dev); | 143 | kfree(dev); |
143 | } | 144 | } |
144 | } | 145 | } |
146 | EXPORT_SYMBOL(snd_midi_event_free); | ||
145 | 147 | ||
146 | /* | 148 | /* |
147 | * initialize record | 149 | * initialize record |
@@ -161,6 +163,7 @@ void snd_midi_event_reset_encode(struct snd_midi_event *dev) | |||
161 | reset_encode(dev); | 163 | reset_encode(dev); |
162 | spin_unlock_irqrestore(&dev->lock, flags); | 164 | spin_unlock_irqrestore(&dev->lock, flags); |
163 | } | 165 | } |
166 | EXPORT_SYMBOL(snd_midi_event_reset_encode); | ||
164 | 167 | ||
165 | void snd_midi_event_reset_decode(struct snd_midi_event *dev) | 168 | void snd_midi_event_reset_decode(struct snd_midi_event *dev) |
166 | { | 169 | { |
@@ -170,6 +173,7 @@ void snd_midi_event_reset_decode(struct snd_midi_event *dev) | |||
170 | dev->lastcmd = 0xff; | 173 | dev->lastcmd = 0xff; |
171 | spin_unlock_irqrestore(&dev->lock, flags); | 174 | spin_unlock_irqrestore(&dev->lock, flags); |
172 | } | 175 | } |
176 | EXPORT_SYMBOL(snd_midi_event_reset_decode); | ||
173 | 177 | ||
174 | #if 0 | 178 | #if 0 |
175 | void snd_midi_event_init(struct snd_midi_event *dev) | 179 | void snd_midi_event_init(struct snd_midi_event *dev) |
@@ -183,6 +187,7 @@ void snd_midi_event_no_status(struct snd_midi_event *dev, int on) | |||
183 | { | 187 | { |
184 | dev->nostat = on ? 1 : 0; | 188 | dev->nostat = on ? 1 : 0; |
185 | } | 189 | } |
190 | EXPORT_SYMBOL(snd_midi_event_no_status); | ||
186 | 191 | ||
187 | /* | 192 | /* |
188 | * resize buffer | 193 | * resize buffer |
@@ -232,6 +237,7 @@ long snd_midi_event_encode(struct snd_midi_event *dev, unsigned char *buf, long | |||
232 | 237 | ||
233 | return result; | 238 | return result; |
234 | } | 239 | } |
240 | EXPORT_SYMBOL(snd_midi_event_encode); | ||
235 | 241 | ||
236 | /* | 242 | /* |
237 | * read one byte and encode to sequencer event: | 243 | * read one byte and encode to sequencer event: |
@@ -307,6 +313,7 @@ int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c, | |||
307 | spin_unlock_irqrestore(&dev->lock, flags); | 313 | spin_unlock_irqrestore(&dev->lock, flags); |
308 | return rc; | 314 | return rc; |
309 | } | 315 | } |
316 | EXPORT_SYMBOL(snd_midi_event_encode_byte); | ||
310 | 317 | ||
311 | /* encode note event */ | 318 | /* encode note event */ |
312 | static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev) | 319 | static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev) |
@@ -408,6 +415,7 @@ long snd_midi_event_decode(struct snd_midi_event *dev, unsigned char *buf, long | |||
408 | return qlen; | 415 | return qlen; |
409 | } | 416 | } |
410 | } | 417 | } |
418 | EXPORT_SYMBOL(snd_midi_event_decode); | ||
411 | 419 | ||
412 | 420 | ||
413 | /* decode note event */ | 421 | /* decode note event */ |
@@ -524,19 +532,6 @@ static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf, | |||
524 | return idx; | 532 | return idx; |
525 | } | 533 | } |
526 | 534 | ||
527 | /* | ||
528 | * exports | ||
529 | */ | ||
530 | |||
531 | EXPORT_SYMBOL(snd_midi_event_new); | ||
532 | EXPORT_SYMBOL(snd_midi_event_free); | ||
533 | EXPORT_SYMBOL(snd_midi_event_reset_encode); | ||
534 | EXPORT_SYMBOL(snd_midi_event_reset_decode); | ||
535 | EXPORT_SYMBOL(snd_midi_event_no_status); | ||
536 | EXPORT_SYMBOL(snd_midi_event_encode); | ||
537 | EXPORT_SYMBOL(snd_midi_event_encode_byte); | ||
538 | EXPORT_SYMBOL(snd_midi_event_decode); | ||
539 | |||
540 | static int __init alsa_seq_midi_event_init(void) | 535 | static int __init alsa_seq_midi_event_init(void) |
541 | { | 536 | { |
542 | return 0; | 537 | return 0; |
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index fe686ee41c6d..0a7020c82bfc 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c | |||
@@ -685,7 +685,6 @@ int snd_seq_event_port_attach(int client, | |||
685 | 685 | ||
686 | return ret; | 686 | return ret; |
687 | } | 687 | } |
688 | |||
689 | EXPORT_SYMBOL(snd_seq_event_port_attach); | 688 | EXPORT_SYMBOL(snd_seq_event_port_attach); |
690 | 689 | ||
691 | /* | 690 | /* |
@@ -706,5 +705,4 @@ int snd_seq_event_port_detach(int client, int port) | |||
706 | 705 | ||
707 | return err; | 706 | return err; |
708 | } | 707 | } |
709 | |||
710 | EXPORT_SYMBOL(snd_seq_event_port_detach); | 708 | EXPORT_SYMBOL(snd_seq_event_port_detach); |
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 52f31f1498f9..8d93a4021c78 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c | |||
@@ -534,6 +534,7 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi | |||
534 | *rrmidi = rmidi; | 534 | *rrmidi = rmidi; |
535 | return 0; | 535 | return 0; |
536 | } | 536 | } |
537 | EXPORT_SYMBOL(snd_virmidi_new); | ||
537 | 538 | ||
538 | /* | 539 | /* |
539 | * ENTRY functions | 540 | * ENTRY functions |
@@ -550,5 +551,3 @@ static void __exit alsa_virmidi_exit(void) | |||
550 | 551 | ||
551 | module_init(alsa_virmidi_init) | 552 | module_init(alsa_virmidi_init) |
552 | module_exit(alsa_virmidi_exit) | 553 | module_exit(alsa_virmidi_exit) |
553 | |||
554 | EXPORT_SYMBOL(snd_virmidi_new); | ||
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq_device.c index c4acf17e9f5e..c4acf17e9f5e 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq_device.c | |||
diff --git a/sound/core/sound.c b/sound/core/sound.c index 175f9e4e01c8..b30f027eb0fe 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -74,7 +74,6 @@ void snd_request_card(int card) | |||
74 | return; | 74 | return; |
75 | request_module("snd-card-%i", card); | 75 | request_module("snd-card-%i", card); |
76 | } | 76 | } |
77 | |||
78 | EXPORT_SYMBOL(snd_request_card); | 77 | EXPORT_SYMBOL(snd_request_card); |
79 | 78 | ||
80 | static void snd_request_other(int minor) | 79 | static void snd_request_other(int minor) |
@@ -124,7 +123,6 @@ void *snd_lookup_minor_data(unsigned int minor, int type) | |||
124 | mutex_unlock(&sound_mutex); | 123 | mutex_unlock(&sound_mutex); |
125 | return private_data; | 124 | return private_data; |
126 | } | 125 | } |
127 | |||
128 | EXPORT_SYMBOL(snd_lookup_minor_data); | 126 | EXPORT_SYMBOL(snd_lookup_minor_data); |
129 | 127 | ||
130 | #ifdef CONFIG_MODULES | 128 | #ifdef CONFIG_MODULES |
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index 0ca9d72b2273..0a5c66229a22 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c | |||
@@ -55,7 +55,6 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) | |||
55 | mutex_unlock(&sound_oss_mutex); | 55 | mutex_unlock(&sound_oss_mutex); |
56 | return private_data; | 56 | return private_data; |
57 | } | 57 | } |
58 | |||
59 | EXPORT_SYMBOL(snd_lookup_oss_minor_data); | 58 | EXPORT_SYMBOL(snd_lookup_oss_minor_data); |
60 | 59 | ||
61 | static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) | 60 | static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) |
@@ -159,7 +158,6 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, | |||
159 | kfree(preg); | 158 | kfree(preg); |
160 | return -EBUSY; | 159 | return -EBUSY; |
161 | } | 160 | } |
162 | |||
163 | EXPORT_SYMBOL(snd_register_oss_device); | 161 | EXPORT_SYMBOL(snd_register_oss_device); |
164 | 162 | ||
165 | int snd_unregister_oss_device(int type, struct snd_card *card, int dev) | 163 | int snd_unregister_oss_device(int type, struct snd_card *card, int dev) |
@@ -200,7 +198,6 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) | |||
200 | kfree(mptr); | 198 | kfree(mptr); |
201 | return 0; | 199 | return 0; |
202 | } | 200 | } |
203 | |||
204 | EXPORT_SYMBOL(snd_unregister_oss_device); | 201 | EXPORT_SYMBOL(snd_unregister_oss_device); |
205 | 202 | ||
206 | /* | 203 | /* |
diff --git a/sound/core/timer.c b/sound/core/timer.c index cd67d1c12cf1..4888203b2dbc 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -319,6 +319,7 @@ int snd_timer_open(struct snd_timer_instance **ti, | |||
319 | *ti = timeri; | 319 | *ti = timeri; |
320 | return 0; | 320 | return 0; |
321 | } | 321 | } |
322 | EXPORT_SYMBOL(snd_timer_open); | ||
322 | 323 | ||
323 | /* | 324 | /* |
324 | * close a timer instance | 325 | * close a timer instance |
@@ -384,6 +385,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) | |||
384 | mutex_unlock(®ister_mutex); | 385 | mutex_unlock(®ister_mutex); |
385 | return 0; | 386 | return 0; |
386 | } | 387 | } |
388 | EXPORT_SYMBOL(snd_timer_close); | ||
387 | 389 | ||
388 | unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) | 390 | unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) |
389 | { | 391 | { |
@@ -398,6 +400,7 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) | |||
398 | } | 400 | } |
399 | return 0; | 401 | return 0; |
400 | } | 402 | } |
403 | EXPORT_SYMBOL(snd_timer_resolution); | ||
401 | 404 | ||
402 | static void snd_timer_notify1(struct snd_timer_instance *ti, int event) | 405 | static void snd_timer_notify1(struct snd_timer_instance *ti, int event) |
403 | { | 406 | { |
@@ -589,6 +592,7 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks) | |||
589 | else | 592 | else |
590 | return snd_timer_start1(timeri, true, ticks); | 593 | return snd_timer_start1(timeri, true, ticks); |
591 | } | 594 | } |
595 | EXPORT_SYMBOL(snd_timer_start); | ||
592 | 596 | ||
593 | /* | 597 | /* |
594 | * stop the timer instance. | 598 | * stop the timer instance. |
@@ -602,6 +606,7 @@ int snd_timer_stop(struct snd_timer_instance *timeri) | |||
602 | else | 606 | else |
603 | return snd_timer_stop1(timeri, true); | 607 | return snd_timer_stop1(timeri, true); |
604 | } | 608 | } |
609 | EXPORT_SYMBOL(snd_timer_stop); | ||
605 | 610 | ||
606 | /* | 611 | /* |
607 | * start again.. the tick is kept. | 612 | * start again.. the tick is kept. |
@@ -617,6 +622,7 @@ int snd_timer_continue(struct snd_timer_instance *timeri) | |||
617 | else | 622 | else |
618 | return snd_timer_start1(timeri, false, 0); | 623 | return snd_timer_start1(timeri, false, 0); |
619 | } | 624 | } |
625 | EXPORT_SYMBOL(snd_timer_continue); | ||
620 | 626 | ||
621 | /* | 627 | /* |
622 | * pause.. remember the ticks left | 628 | * pause.. remember the ticks left |
@@ -628,6 +634,7 @@ int snd_timer_pause(struct snd_timer_instance * timeri) | |||
628 | else | 634 | else |
629 | return snd_timer_stop1(timeri, false); | 635 | return snd_timer_stop1(timeri, false); |
630 | } | 636 | } |
637 | EXPORT_SYMBOL(snd_timer_pause); | ||
631 | 638 | ||
632 | /* | 639 | /* |
633 | * reschedule the timer | 640 | * reschedule the timer |
@@ -809,6 +816,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) | |||
809 | if (use_tasklet) | 816 | if (use_tasklet) |
810 | tasklet_schedule(&timer->task_queue); | 817 | tasklet_schedule(&timer->task_queue); |
811 | } | 818 | } |
819 | EXPORT_SYMBOL(snd_timer_interrupt); | ||
812 | 820 | ||
813 | /* | 821 | /* |
814 | 822 | ||
@@ -859,6 +867,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, | |||
859 | *rtimer = timer; | 867 | *rtimer = timer; |
860 | return 0; | 868 | return 0; |
861 | } | 869 | } |
870 | EXPORT_SYMBOL(snd_timer_new); | ||
862 | 871 | ||
863 | static int snd_timer_free(struct snd_timer *timer) | 872 | static int snd_timer_free(struct snd_timer *timer) |
864 | { | 873 | { |
@@ -978,6 +987,7 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam | |||
978 | } | 987 | } |
979 | spin_unlock_irqrestore(&timer->lock, flags); | 988 | spin_unlock_irqrestore(&timer->lock, flags); |
980 | } | 989 | } |
990 | EXPORT_SYMBOL(snd_timer_notify); | ||
981 | 991 | ||
982 | /* | 992 | /* |
983 | * exported functions for global timers | 993 | * exported functions for global timers |
@@ -993,11 +1003,13 @@ int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer) | |||
993 | tid.subdevice = 0; | 1003 | tid.subdevice = 0; |
994 | return snd_timer_new(NULL, id, &tid, rtimer); | 1004 | return snd_timer_new(NULL, id, &tid, rtimer); |
995 | } | 1005 | } |
1006 | EXPORT_SYMBOL(snd_timer_global_new); | ||
996 | 1007 | ||
997 | int snd_timer_global_free(struct snd_timer *timer) | 1008 | int snd_timer_global_free(struct snd_timer *timer) |
998 | { | 1009 | { |
999 | return snd_timer_free(timer); | 1010 | return snd_timer_free(timer); |
1000 | } | 1011 | } |
1012 | EXPORT_SYMBOL(snd_timer_global_free); | ||
1001 | 1013 | ||
1002 | int snd_timer_global_register(struct snd_timer *timer) | 1014 | int snd_timer_global_register(struct snd_timer *timer) |
1003 | { | 1015 | { |
@@ -1007,6 +1019,7 @@ int snd_timer_global_register(struct snd_timer *timer) | |||
1007 | dev.device_data = timer; | 1019 | dev.device_data = timer; |
1008 | return snd_timer_dev_register(&dev); | 1020 | return snd_timer_dev_register(&dev); |
1009 | } | 1021 | } |
1022 | EXPORT_SYMBOL(snd_timer_global_register); | ||
1010 | 1023 | ||
1011 | /* | 1024 | /* |
1012 | * System timer | 1025 | * System timer |
@@ -1327,6 +1340,33 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri, | |||
1327 | wake_up(&tu->qchange_sleep); | 1340 | wake_up(&tu->qchange_sleep); |
1328 | } | 1341 | } |
1329 | 1342 | ||
1343 | static int realloc_user_queue(struct snd_timer_user *tu, int size) | ||
1344 | { | ||
1345 | struct snd_timer_read *queue = NULL; | ||
1346 | struct snd_timer_tread *tqueue = NULL; | ||
1347 | |||
1348 | if (tu->tread) { | ||
1349 | tqueue = kcalloc(size, sizeof(*tqueue), GFP_KERNEL); | ||
1350 | if (!tqueue) | ||
1351 | return -ENOMEM; | ||
1352 | } else { | ||
1353 | queue = kcalloc(size, sizeof(*queue), GFP_KERNEL); | ||
1354 | if (!queue) | ||
1355 | return -ENOMEM; | ||
1356 | } | ||
1357 | |||
1358 | spin_lock_irq(&tu->qlock); | ||
1359 | kfree(tu->queue); | ||
1360 | kfree(tu->tqueue); | ||
1361 | tu->queue_size = size; | ||
1362 | tu->queue = queue; | ||
1363 | tu->tqueue = tqueue; | ||
1364 | tu->qhead = tu->qtail = tu->qused = 0; | ||
1365 | spin_unlock_irq(&tu->qlock); | ||
1366 | |||
1367 | return 0; | ||
1368 | } | ||
1369 | |||
1330 | static int snd_timer_user_open(struct inode *inode, struct file *file) | 1370 | static int snd_timer_user_open(struct inode *inode, struct file *file) |
1331 | { | 1371 | { |
1332 | struct snd_timer_user *tu; | 1372 | struct snd_timer_user *tu; |
@@ -1343,10 +1383,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) | |||
1343 | init_waitqueue_head(&tu->qchange_sleep); | 1383 | init_waitqueue_head(&tu->qchange_sleep); |
1344 | mutex_init(&tu->ioctl_lock); | 1384 | mutex_init(&tu->ioctl_lock); |
1345 | tu->ticks = 1; | 1385 | tu->ticks = 1; |
1346 | tu->queue_size = 128; | 1386 | if (realloc_user_queue(tu, 128) < 0) { |
1347 | tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), | ||
1348 | GFP_KERNEL); | ||
1349 | if (tu->queue == NULL) { | ||
1350 | kfree(tu); | 1387 | kfree(tu); |
1351 | return -ENOMEM; | 1388 | return -ENOMEM; |
1352 | } | 1389 | } |
@@ -1618,34 +1655,12 @@ static int snd_timer_user_tselect(struct file *file, | |||
1618 | if (err < 0) | 1655 | if (err < 0) |
1619 | goto __err; | 1656 | goto __err; |
1620 | 1657 | ||
1621 | tu->qhead = tu->qtail = tu->qused = 0; | 1658 | tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; |
1622 | kfree(tu->queue); | 1659 | tu->timeri->callback = tu->tread |
1623 | tu->queue = NULL; | ||
1624 | kfree(tu->tqueue); | ||
1625 | tu->tqueue = NULL; | ||
1626 | if (tu->tread) { | ||
1627 | tu->tqueue = kmalloc(tu->queue_size * sizeof(struct snd_timer_tread), | ||
1628 | GFP_KERNEL); | ||
1629 | if (tu->tqueue == NULL) | ||
1630 | err = -ENOMEM; | ||
1631 | } else { | ||
1632 | tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), | ||
1633 | GFP_KERNEL); | ||
1634 | if (tu->queue == NULL) | ||
1635 | err = -ENOMEM; | ||
1636 | } | ||
1637 | |||
1638 | if (err < 0) { | ||
1639 | snd_timer_close(tu->timeri); | ||
1640 | tu->timeri = NULL; | ||
1641 | } else { | ||
1642 | tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; | ||
1643 | tu->timeri->callback = tu->tread | ||
1644 | ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; | 1660 | ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; |
1645 | tu->timeri->ccallback = snd_timer_user_ccallback; | 1661 | tu->timeri->ccallback = snd_timer_user_ccallback; |
1646 | tu->timeri->callback_data = (void *)tu; | 1662 | tu->timeri->callback_data = (void *)tu; |
1647 | tu->timeri->disconnect = snd_timer_user_disconnect; | 1663 | tu->timeri->disconnect = snd_timer_user_disconnect; |
1648 | } | ||
1649 | 1664 | ||
1650 | __err: | 1665 | __err: |
1651 | return err; | 1666 | return err; |
@@ -1687,8 +1702,6 @@ static int snd_timer_user_params(struct file *file, | |||
1687 | struct snd_timer_user *tu; | 1702 | struct snd_timer_user *tu; |
1688 | struct snd_timer_params params; | 1703 | struct snd_timer_params params; |
1689 | struct snd_timer *t; | 1704 | struct snd_timer *t; |
1690 | struct snd_timer_read *tr; | ||
1691 | struct snd_timer_tread *ttr; | ||
1692 | int err; | 1705 | int err; |
1693 | 1706 | ||
1694 | tu = file->private_data; | 1707 | tu = file->private_data; |
@@ -1751,24 +1764,11 @@ static int snd_timer_user_params(struct file *file, | |||
1751 | spin_unlock_irq(&t->lock); | 1764 | spin_unlock_irq(&t->lock); |
1752 | if (params.queue_size > 0 && | 1765 | if (params.queue_size > 0 && |
1753 | (unsigned int)tu->queue_size != params.queue_size) { | 1766 | (unsigned int)tu->queue_size != params.queue_size) { |
1754 | if (tu->tread) { | 1767 | err = realloc_user_queue(tu, params.queue_size); |
1755 | ttr = kmalloc(params.queue_size * sizeof(*ttr), | 1768 | if (err < 0) |
1756 | GFP_KERNEL); | 1769 | goto _end; |
1757 | if (ttr) { | ||
1758 | kfree(tu->tqueue); | ||
1759 | tu->queue_size = params.queue_size; | ||
1760 | tu->tqueue = ttr; | ||
1761 | } | ||
1762 | } else { | ||
1763 | tr = kmalloc(params.queue_size * sizeof(*tr), | ||
1764 | GFP_KERNEL); | ||
1765 | if (tr) { | ||
1766 | kfree(tu->queue); | ||
1767 | tu->queue_size = params.queue_size; | ||
1768 | tu->queue = tr; | ||
1769 | } | ||
1770 | } | ||
1771 | } | 1770 | } |
1771 | spin_lock_irq(&tu->qlock); | ||
1772 | tu->qhead = tu->qtail = tu->qused = 0; | 1772 | tu->qhead = tu->qtail = tu->qused = 0; |
1773 | if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { | 1773 | if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { |
1774 | if (tu->tread) { | 1774 | if (tu->tread) { |
@@ -1789,6 +1789,7 @@ static int snd_timer_user_params(struct file *file, | |||
1789 | } | 1789 | } |
1790 | tu->filter = params.filter; | 1790 | tu->filter = params.filter; |
1791 | tu->ticks = params.ticks; | 1791 | tu->ticks = params.ticks; |
1792 | spin_unlock_irq(&tu->qlock); | ||
1792 | err = 0; | 1793 | err = 0; |
1793 | _end: | 1794 | _end: |
1794 | if (copy_to_user(_params, ¶ms, sizeof(params))) | 1795 | if (copy_to_user(_params, ¶ms, sizeof(params))) |
@@ -1891,13 +1892,19 @@ static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd, | |||
1891 | return snd_timer_user_next_device(argp); | 1892 | return snd_timer_user_next_device(argp); |
1892 | case SNDRV_TIMER_IOCTL_TREAD: | 1893 | case SNDRV_TIMER_IOCTL_TREAD: |
1893 | { | 1894 | { |
1894 | int xarg; | 1895 | int xarg, old_tread; |
1895 | 1896 | ||
1896 | if (tu->timeri) /* too late */ | 1897 | if (tu->timeri) /* too late */ |
1897 | return -EBUSY; | 1898 | return -EBUSY; |
1898 | if (get_user(xarg, p)) | 1899 | if (get_user(xarg, p)) |
1899 | return -EFAULT; | 1900 | return -EFAULT; |
1901 | old_tread = tu->tread; | ||
1900 | tu->tread = xarg ? 1 : 0; | 1902 | tu->tread = xarg ? 1 : 0; |
1903 | if (tu->tread != old_tread && | ||
1904 | realloc_user_queue(tu, tu->queue_size) < 0) { | ||
1905 | tu->tread = old_tread; | ||
1906 | return -ENOMEM; | ||
1907 | } | ||
1901 | return 0; | 1908 | return 0; |
1902 | } | 1909 | } |
1903 | case SNDRV_TIMER_IOCTL_GINFO: | 1910 | case SNDRV_TIMER_IOCTL_GINFO: |
@@ -2030,10 +2037,12 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait) | |||
2030 | poll_wait(file, &tu->qchange_sleep, wait); | 2037 | poll_wait(file, &tu->qchange_sleep, wait); |
2031 | 2038 | ||
2032 | mask = 0; | 2039 | mask = 0; |
2040 | spin_lock_irq(&tu->qlock); | ||
2033 | if (tu->qused) | 2041 | if (tu->qused) |
2034 | mask |= POLLIN | POLLRDNORM; | 2042 | mask |= POLLIN | POLLRDNORM; |
2035 | if (tu->disconnected) | 2043 | if (tu->disconnected) |
2036 | mask |= POLLERR; | 2044 | mask |= POLLERR; |
2045 | spin_unlock_irq(&tu->qlock); | ||
2037 | 2046 | ||
2038 | return mask; | 2047 | return mask; |
2039 | } | 2048 | } |
@@ -2117,17 +2126,3 @@ static void __exit alsa_timer_exit(void) | |||
2117 | 2126 | ||
2118 | module_init(alsa_timer_init) | 2127 | module_init(alsa_timer_init) |
2119 | module_exit(alsa_timer_exit) | 2128 | module_exit(alsa_timer_exit) |
2120 | |||
2121 | EXPORT_SYMBOL(snd_timer_open); | ||
2122 | EXPORT_SYMBOL(snd_timer_close); | ||
2123 | EXPORT_SYMBOL(snd_timer_resolution); | ||
2124 | EXPORT_SYMBOL(snd_timer_start); | ||
2125 | EXPORT_SYMBOL(snd_timer_stop); | ||
2126 | EXPORT_SYMBOL(snd_timer_continue); | ||
2127 | EXPORT_SYMBOL(snd_timer_pause); | ||
2128 | EXPORT_SYMBOL(snd_timer_new); | ||
2129 | EXPORT_SYMBOL(snd_timer_notify); | ||
2130 | EXPORT_SYMBOL(snd_timer_global_new); | ||
2131 | EXPORT_SYMBOL(snd_timer_global_free); | ||
2132 | EXPORT_SYMBOL(snd_timer_global_register); | ||
2133 | EXPORT_SYMBOL(snd_timer_interrupt); | ||
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 8545da99b183..7144cc36e8ae 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig | |||
@@ -6,11 +6,24 @@ config SND_OPL3_LIB | |||
6 | tristate | 6 | tristate |
7 | select SND_TIMER | 7 | select SND_TIMER |
8 | select SND_HWDEP | 8 | select SND_HWDEP |
9 | select SND_SEQ_DEVICE if SND_SEQUENCER != n | ||
9 | 10 | ||
10 | config SND_OPL4_LIB | 11 | config SND_OPL4_LIB |
11 | tristate | 12 | tristate |
12 | select SND_TIMER | 13 | select SND_TIMER |
13 | select SND_HWDEP | 14 | select SND_HWDEP |
15 | select SND_SEQ_DEVICE if SND_SEQUENCER != n | ||
16 | |||
17 | # select SEQ stuff to min(SND_SEQUENCER,SND_XXX) | ||
18 | config SND_OPL3_LIB_SEQ | ||
19 | def_tristate SND_SEQUENCER && SND_OPL3_LIB | ||
20 | select SND_SEQ_MIDI_EMUL | ||
21 | select SND_SEQ_MIDI_EVENT | ||
22 | |||
23 | config SND_OPL4_LIB_SEQ | ||
24 | def_tristate SND_SEQUENCER && SND_OPL4_LIB | ||
25 | select SND_SEQ_MIDI_EMUL | ||
26 | select SND_SEQ_MIDI_EVENT | ||
14 | 27 | ||
15 | config SND_VX_LIB | 28 | config SND_VX_LIB |
16 | tristate | 29 | tristate |
@@ -99,6 +112,8 @@ config SND_VIRMIDI | |||
99 | depends on SND_SEQUENCER | 112 | depends on SND_SEQUENCER |
100 | select SND_TIMER | 113 | select SND_TIMER |
101 | select SND_RAWMIDI | 114 | select SND_RAWMIDI |
115 | select SND_SEQ_VIRMIDI | ||
116 | select SND_SEQ_MIDI_EVENT | ||
102 | help | 117 | help |
103 | Say Y here to include the virtual MIDI driver. This driver | 118 | Say Y here to include the virtual MIDI driver. This driver |
104 | allows to connect applications using raw MIDI devices to | 119 | allows to connect applications using raw MIDI devices to |
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 172dacd925f5..dd5ed037adf2 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -644,15 +644,22 @@ static int alloc_fake_buffer(void) | |||
644 | } | 644 | } |
645 | 645 | ||
646 | static int dummy_pcm_copy(struct snd_pcm_substream *substream, | 646 | static int dummy_pcm_copy(struct snd_pcm_substream *substream, |
647 | int channel, snd_pcm_uframes_t pos, | 647 | int channel, unsigned long pos, |
648 | void __user *dst, snd_pcm_uframes_t count) | 648 | void __user *dst, unsigned long bytes) |
649 | { | ||
650 | return 0; /* do nothing */ | ||
651 | } | ||
652 | |||
653 | static int dummy_pcm_copy_kernel(struct snd_pcm_substream *substream, | ||
654 | int channel, unsigned long pos, | ||
655 | void *dst, unsigned long bytes) | ||
649 | { | 656 | { |
650 | return 0; /* do nothing */ | 657 | return 0; /* do nothing */ |
651 | } | 658 | } |
652 | 659 | ||
653 | static int dummy_pcm_silence(struct snd_pcm_substream *substream, | 660 | static int dummy_pcm_silence(struct snd_pcm_substream *substream, |
654 | int channel, snd_pcm_uframes_t pos, | 661 | int channel, unsigned long pos, |
655 | snd_pcm_uframes_t count) | 662 | unsigned long bytes) |
656 | { | 663 | { |
657 | return 0; /* do nothing */ | 664 | return 0; /* do nothing */ |
658 | } | 665 | } |
@@ -683,8 +690,9 @@ static struct snd_pcm_ops dummy_pcm_ops_no_buf = { | |||
683 | .prepare = dummy_pcm_prepare, | 690 | .prepare = dummy_pcm_prepare, |
684 | .trigger = dummy_pcm_trigger, | 691 | .trigger = dummy_pcm_trigger, |
685 | .pointer = dummy_pcm_pointer, | 692 | .pointer = dummy_pcm_pointer, |
686 | .copy = dummy_pcm_copy, | 693 | .copy_user = dummy_pcm_copy, |
687 | .silence = dummy_pcm_silence, | 694 | .copy_kernel = dummy_pcm_copy_kernel, |
695 | .fill_silence = dummy_pcm_silence, | ||
688 | .page = dummy_pcm_page, | 696 | .page = dummy_pcm_page, |
689 | }; | 697 | }; |
690 | 698 | ||
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c index cd9e9f31720f..d5e5b4657b4b 100644 --- a/sound/drivers/opl3/opl3_lib.c +++ b/sound/drivers/opl3/opl3_lib.c | |||
@@ -528,7 +528,7 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3, | |||
528 | 528 | ||
529 | opl3->hwdep = hw; | 529 | opl3->hwdep = hw; |
530 | opl3->seq_dev_num = seq_device; | 530 | opl3->seq_dev_num = seq_device; |
531 | #if IS_REACHABLE(CONFIG_SND_SEQUENCER) | 531 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
532 | if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3, | 532 | if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3, |
533 | sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) { | 533 | sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) { |
534 | strcpy(opl3->seq_dev->name, hw->name); | 534 | strcpy(opl3->seq_dev->name, hw->name); |
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c index c1cb249acfaa..22c3e4bca220 100644 --- a/sound/drivers/opl3/opl3_oss.c +++ b/sound/drivers/opl3/opl3_oss.c | |||
@@ -27,20 +27,6 @@ static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, | |||
27 | static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, const char __user *buf, int offs, int count); | 27 | static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, const char __user *buf, int offs, int count); |
28 | static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg); | 28 | static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg); |
29 | 29 | ||
30 | /* */ | ||
31 | |||
32 | static inline mm_segment_t snd_enter_user(void) | ||
33 | { | ||
34 | mm_segment_t fs = get_fs(); | ||
35 | set_fs(get_ds()); | ||
36 | return fs; | ||
37 | } | ||
38 | |||
39 | static inline void snd_leave_user(mm_segment_t fs) | ||
40 | { | ||
41 | set_fs(fs); | ||
42 | } | ||
43 | |||
44 | /* operators */ | 30 | /* operators */ |
45 | 31 | ||
46 | extern struct snd_midi_op opl3_ops; | 32 | extern struct snd_midi_op opl3_ops; |
diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c index fdae5d7f421f..d3e91be8b23a 100644 --- a/sound/drivers/opl3/opl3_seq.c +++ b/sound/drivers/opl3/opl3_seq.c | |||
@@ -252,7 +252,7 @@ static int snd_opl3_seq_probe(struct device *_dev) | |||
252 | spin_lock_init(&opl3->sys_timer_lock); | 252 | spin_lock_init(&opl3->sys_timer_lock); |
253 | opl3->sys_timer_status = 0; | 253 | opl3->sys_timer_status = 0; |
254 | 254 | ||
255 | #ifdef CONFIG_SND_SEQUENCER_OSS | 255 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
256 | snd_opl3_init_seq_oss(opl3, name); | 256 | snd_opl3_init_seq_oss(opl3, name); |
257 | #endif | 257 | #endif |
258 | return 0; | 258 | return 0; |
@@ -267,7 +267,7 @@ static int snd_opl3_seq_remove(struct device *_dev) | |||
267 | if (opl3 == NULL) | 267 | if (opl3 == NULL) |
268 | return -EINVAL; | 268 | return -EINVAL; |
269 | 269 | ||
270 | #ifdef CONFIG_SND_SEQUENCER_OSS | 270 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
271 | snd_opl3_free_seq_oss(opl3); | 271 | snd_opl3_free_seq_oss(opl3); |
272 | #endif | 272 | #endif |
273 | if (opl3->seq_client >= 0) { | 273 | if (opl3->seq_client >= 0) { |
diff --git a/sound/drivers/opl3/opl3_voice.h b/sound/drivers/opl3/opl3_voice.h index a371c075ac87..eaef435e0528 100644 --- a/sound/drivers/opl3/opl3_voice.h +++ b/sound/drivers/opl3/opl3_voice.h | |||
@@ -44,9 +44,12 @@ void snd_opl3_load_drums(struct snd_opl3 *opl3); | |||
44 | void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int on_off, int vel, struct snd_midi_channel *chan); | 44 | void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int on_off, int vel, struct snd_midi_channel *chan); |
45 | 45 | ||
46 | /* Prototypes for opl3_oss.c */ | 46 | /* Prototypes for opl3_oss.c */ |
47 | #ifdef CONFIG_SND_SEQUENCER_OSS | 47 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
48 | void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name); | 48 | void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name); |
49 | void snd_opl3_free_seq_oss(struct snd_opl3 *opl3); | 49 | void snd_opl3_free_seq_oss(struct snd_opl3 *opl3); |
50 | #else | ||
51 | #define snd_opl3_init_seq_oss(opl3, name) /* NOP */ | ||
52 | #define snd_opl3_free_seq_oss(opl3) /* NOP */ | ||
50 | #endif | 53 | #endif |
51 | 54 | ||
52 | #endif | 55 | #endif |
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c index 89c7aa04b3bc..bc345d564f8d 100644 --- a/sound/drivers/opl4/opl4_lib.c +++ b/sound/drivers/opl4/opl4_lib.c | |||
@@ -153,7 +153,7 @@ static int snd_opl4_detect(struct snd_opl4 *opl4) | |||
153 | return 0; | 153 | return 0; |
154 | } | 154 | } |
155 | 155 | ||
156 | #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) | 156 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
157 | static void snd_opl4_seq_dev_free(struct snd_seq_device *seq_dev) | 157 | static void snd_opl4_seq_dev_free(struct snd_seq_device *seq_dev) |
158 | { | 158 | { |
159 | struct snd_opl4 *opl4 = seq_dev->private_data; | 159 | struct snd_opl4 *opl4 = seq_dev->private_data; |
@@ -249,7 +249,7 @@ int snd_opl4_create(struct snd_card *card, | |||
249 | snd_opl4_create_mixer(opl4); | 249 | snd_opl4_create_mixer(opl4); |
250 | snd_opl4_create_proc(opl4); | 250 | snd_opl4_create_proc(opl4); |
251 | 251 | ||
252 | #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) | 252 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
253 | opl4->seq_client = -1; | 253 | opl4->seq_client = -1; |
254 | if (opl4->hardware < OPL3_HW_OPL4_ML) | 254 | if (opl4->hardware < OPL3_HW_OPL4_ML) |
255 | snd_opl4_create_seq_dev(opl4, seq_device); | 255 | snd_opl4_create_seq_dev(opl4, seq_device); |
diff --git a/sound/drivers/opl4/opl4_local.h b/sound/drivers/opl4/opl4_local.h index 9a41bdebce6b..a16b4677c1e9 100644 --- a/sound/drivers/opl4/opl4_local.h +++ b/sound/drivers/opl4/opl4_local.h | |||
@@ -184,7 +184,7 @@ struct snd_opl4 { | |||
184 | #endif | 184 | #endif |
185 | struct mutex access_mutex; | 185 | struct mutex access_mutex; |
186 | 186 | ||
187 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) | 187 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
188 | int used; | 188 | int used; |
189 | 189 | ||
190 | int seq_dev_num; | 190 | int seq_dev_num; |
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index aca2d7d5f059..44b3632f6940 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c | |||
@@ -323,7 +323,7 @@ static int snd_pcsp_playback_open(struct snd_pcm_substream *substream) | |||
323 | return 0; | 323 | return 0; |
324 | } | 324 | } |
325 | 325 | ||
326 | static struct snd_pcm_ops snd_pcsp_playback_ops = { | 326 | static const struct snd_pcm_ops snd_pcsp_playback_ops = { |
327 | .open = snd_pcsp_playback_open, | 327 | .open = snd_pcsp_playback_open, |
328 | .close = snd_pcsp_playback_close, | 328 | .close = snd_pcsp_playback_close, |
329 | .ioctl = snd_pcm_lib_ioctl, | 329 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c index be9477e30739..98a41ac40b60 100644 --- a/sound/drivers/vx/vx_mixer.c +++ b/sound/drivers/vx/vx_mixer.c | |||
@@ -455,7 +455,7 @@ static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
455 | return 0; | 455 | return 0; |
456 | } | 456 | } |
457 | 457 | ||
458 | static struct snd_kcontrol_new vx_control_output_level = { | 458 | static const struct snd_kcontrol_new vx_control_output_level = { |
459 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 459 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
460 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 460 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
461 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), | 461 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), |
@@ -514,7 +514,7 @@ static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
514 | return 0; | 514 | return 0; |
515 | } | 515 | } |
516 | 516 | ||
517 | static struct snd_kcontrol_new vx_control_audio_src = { | 517 | static const struct snd_kcontrol_new vx_control_audio_src = { |
518 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 518 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
519 | .name = "Capture Source", | 519 | .name = "Capture Source", |
520 | .info = vx_audio_src_info, | 520 | .info = vx_audio_src_info, |
@@ -558,7 +558,7 @@ static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
558 | return 0; | 558 | return 0; |
559 | } | 559 | } |
560 | 560 | ||
561 | static struct snd_kcontrol_new vx_control_clock_mode = { | 561 | static const struct snd_kcontrol_new vx_control_clock_mode = { |
562 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 562 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
563 | .name = "Clock Mode", | 563 | .name = "Clock Mode", |
564 | .info = vx_clock_mode_info, | 564 | .info = vx_clock_mode_info, |
@@ -717,7 +717,7 @@ static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
717 | 717 | ||
718 | static const DECLARE_TLV_DB_SCALE(db_scale_audio_gain, -10975, 25, 0); | 718 | static const DECLARE_TLV_DB_SCALE(db_scale_audio_gain, -10975, 25, 0); |
719 | 719 | ||
720 | static struct snd_kcontrol_new vx_control_audio_gain = { | 720 | static const struct snd_kcontrol_new vx_control_audio_gain = { |
721 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 721 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
722 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 722 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
723 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), | 723 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), |
@@ -727,14 +727,14 @@ static struct snd_kcontrol_new vx_control_audio_gain = { | |||
727 | .put = vx_audio_gain_put, | 727 | .put = vx_audio_gain_put, |
728 | .tlv = { .p = db_scale_audio_gain }, | 728 | .tlv = { .p = db_scale_audio_gain }, |
729 | }; | 729 | }; |
730 | static struct snd_kcontrol_new vx_control_output_switch = { | 730 | static const struct snd_kcontrol_new vx_control_output_switch = { |
731 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 731 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
732 | .name = "PCM Playback Switch", | 732 | .name = "PCM Playback Switch", |
733 | .info = vx_audio_sw_info, | 733 | .info = vx_audio_sw_info, |
734 | .get = vx_audio_sw_get, | 734 | .get = vx_audio_sw_get, |
735 | .put = vx_audio_sw_put | 735 | .put = vx_audio_sw_put |
736 | }; | 736 | }; |
737 | static struct snd_kcontrol_new vx_control_monitor_gain = { | 737 | static const struct snd_kcontrol_new vx_control_monitor_gain = { |
738 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 738 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
739 | .name = "Monitoring Volume", | 739 | .name = "Monitoring Volume", |
740 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 740 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
@@ -744,7 +744,7 @@ static struct snd_kcontrol_new vx_control_monitor_gain = { | |||
744 | .put = vx_audio_monitor_put, | 744 | .put = vx_audio_monitor_put, |
745 | .tlv = { .p = db_scale_audio_gain }, | 745 | .tlv = { .p = db_scale_audio_gain }, |
746 | }; | 746 | }; |
747 | static struct snd_kcontrol_new vx_control_monitor_switch = { | 747 | static const struct snd_kcontrol_new vx_control_monitor_switch = { |
748 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 748 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
749 | .name = "Monitoring Switch", | 749 | .name = "Monitoring Switch", |
750 | .info = vx_audio_sw_info, /* shared */ | 750 | .info = vx_audio_sw_info, /* shared */ |
@@ -805,7 +805,7 @@ static int vx_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
805 | return 0; | 805 | return 0; |
806 | } | 806 | } |
807 | 807 | ||
808 | static struct snd_kcontrol_new vx_control_iec958_mask = { | 808 | static const struct snd_kcontrol_new vx_control_iec958_mask = { |
809 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 809 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
810 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 810 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
811 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), | 811 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), |
@@ -813,7 +813,7 @@ static struct snd_kcontrol_new vx_control_iec958_mask = { | |||
813 | .get = vx_iec958_mask_get, | 813 | .get = vx_iec958_mask_get, |
814 | }; | 814 | }; |
815 | 815 | ||
816 | static struct snd_kcontrol_new vx_control_iec958 = { | 816 | static const struct snd_kcontrol_new vx_control_iec958 = { |
817 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 817 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
818 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 818 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
819 | .info = vx_iec958_info, | 819 | .info = vx_iec958_info, |
@@ -878,7 +878,7 @@ static int vx_saturation_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
878 | return 0; | 878 | return 0; |
879 | } | 879 | } |
880 | 880 | ||
881 | static struct snd_kcontrol_new vx_control_vu_meter = { | 881 | static const struct snd_kcontrol_new vx_control_vu_meter = { |
882 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 882 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
883 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 883 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
884 | /* name will be filled later */ | 884 | /* name will be filled later */ |
@@ -886,7 +886,7 @@ static struct snd_kcontrol_new vx_control_vu_meter = { | |||
886 | .get = vx_vu_meter_get, | 886 | .get = vx_vu_meter_get, |
887 | }; | 887 | }; |
888 | 888 | ||
889 | static struct snd_kcontrol_new vx_control_peak_meter = { | 889 | static const struct snd_kcontrol_new vx_control_peak_meter = { |
890 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 890 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
891 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 891 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
892 | /* name will be filled later */ | 892 | /* name will be filled later */ |
@@ -894,7 +894,7 @@ static struct snd_kcontrol_new vx_control_peak_meter = { | |||
894 | .get = vx_peak_meter_get, | 894 | .get = vx_peak_meter_get, |
895 | }; | 895 | }; |
896 | 896 | ||
897 | static struct snd_kcontrol_new vx_control_saturation = { | 897 | static const struct snd_kcontrol_new vx_control_saturation = { |
898 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 898 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
899 | .name = "Input Saturation", | 899 | .name = "Input Saturation", |
900 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 900 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index ea7b377f0378..d318a33b6cfb 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c | |||
@@ -873,7 +873,7 @@ static int vx_pcm_prepare(struct snd_pcm_substream *subs) | |||
873 | /* | 873 | /* |
874 | * operators for PCM playback | 874 | * operators for PCM playback |
875 | */ | 875 | */ |
876 | static struct snd_pcm_ops vx_pcm_playback_ops = { | 876 | static const struct snd_pcm_ops vx_pcm_playback_ops = { |
877 | .open = vx_pcm_playback_open, | 877 | .open = vx_pcm_playback_open, |
878 | .close = vx_pcm_playback_close, | 878 | .close = vx_pcm_playback_close, |
879 | .ioctl = snd_pcm_lib_ioctl, | 879 | .ioctl = snd_pcm_lib_ioctl, |
@@ -1095,7 +1095,7 @@ static snd_pcm_uframes_t vx_pcm_capture_pointer(struct snd_pcm_substream *subs) | |||
1095 | /* | 1095 | /* |
1096 | * operators for PCM capture | 1096 | * operators for PCM capture |
1097 | */ | 1097 | */ |
1098 | static struct snd_pcm_ops vx_pcm_capture_ops = { | 1098 | static const struct snd_pcm_ops vx_pcm_capture_ops = { |
1099 | .open = vx_pcm_capture_open, | 1099 | .open = vx_pcm_capture_open, |
1100 | .close = vx_pcm_capture_close, | 1100 | .close = vx_pcm_capture_close, |
1101 | .ioctl = snd_pcm_lib_ioctl, | 1101 | .ioctl = snd_pcm_lib_ioctl, |
diff --git a/sound/firewire/amdtp-am824.c b/sound/firewire/amdtp-am824.c index bebddc60fde8..23ccddb20de1 100644 --- a/sound/firewire/amdtp-am824.c +++ b/sound/firewire/amdtp-am824.c | |||
@@ -38,10 +38,6 @@ struct amdtp_am824 { | |||
38 | u8 pcm_positions[AM824_MAX_CHANNELS_FOR_PCM]; | 38 | u8 pcm_positions[AM824_MAX_CHANNELS_FOR_PCM]; |
39 | u8 midi_position; | 39 | u8 midi_position; |
40 | 40 | ||
41 | void (*transfer_samples)(struct amdtp_stream *s, | ||
42 | struct snd_pcm_substream *pcm, | ||
43 | __be32 *buffer, unsigned int frames); | ||
44 | |||
45 | unsigned int frame_multiplier; | 41 | unsigned int frame_multiplier; |
46 | }; | 42 | }; |
47 | 43 | ||
@@ -177,32 +173,6 @@ static void write_pcm_s32(struct amdtp_stream *s, | |||
177 | } | 173 | } |
178 | } | 174 | } |
179 | 175 | ||
180 | static void write_pcm_s16(struct amdtp_stream *s, | ||
181 | struct snd_pcm_substream *pcm, | ||
182 | __be32 *buffer, unsigned int frames) | ||
183 | { | ||
184 | struct amdtp_am824 *p = s->protocol; | ||
185 | struct snd_pcm_runtime *runtime = pcm->runtime; | ||
186 | unsigned int channels, remaining_frames, i, c; | ||
187 | const u16 *src; | ||
188 | |||
189 | channels = p->pcm_channels; | ||
190 | src = (void *)runtime->dma_area + | ||
191 | frames_to_bytes(runtime, s->pcm_buffer_pointer); | ||
192 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; | ||
193 | |||
194 | for (i = 0; i < frames; ++i) { | ||
195 | for (c = 0; c < channels; ++c) { | ||
196 | buffer[p->pcm_positions[c]] = | ||
197 | cpu_to_be32((*src << 8) | 0x42000000); | ||
198 | src++; | ||
199 | } | ||
200 | buffer += s->data_block_quadlets; | ||
201 | if (--remaining_frames == 0) | ||
202 | src = (void *)runtime->dma_area; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | static void read_pcm_s32(struct amdtp_stream *s, | 176 | static void read_pcm_s32(struct amdtp_stream *s, |
207 | struct snd_pcm_substream *pcm, | 177 | struct snd_pcm_substream *pcm, |
208 | __be32 *buffer, unsigned int frames) | 178 | __be32 *buffer, unsigned int frames) |
@@ -242,43 +212,6 @@ static void write_pcm_silence(struct amdtp_stream *s, | |||
242 | } | 212 | } |
243 | 213 | ||
244 | /** | 214 | /** |
245 | * amdtp_am824_set_pcm_format - set the PCM format | ||
246 | * @s: the AMDTP stream to configure | ||
247 | * @format: the format of the ALSA PCM device | ||
248 | * | ||
249 | * The sample format must be set after the other parameters (rate/PCM channels/ | ||
250 | * MIDI) and before the stream is started, and must not be changed while the | ||
251 | * stream is running. | ||
252 | */ | ||
253 | void amdtp_am824_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format) | ||
254 | { | ||
255 | struct amdtp_am824 *p = s->protocol; | ||
256 | |||
257 | if (WARN_ON(amdtp_stream_pcm_running(s))) | ||
258 | return; | ||
259 | |||
260 | switch (format) { | ||
261 | default: | ||
262 | WARN_ON(1); | ||
263 | /* fall through */ | ||
264 | case SNDRV_PCM_FORMAT_S16: | ||
265 | if (s->direction == AMDTP_OUT_STREAM) { | ||
266 | p->transfer_samples = write_pcm_s16; | ||
267 | break; | ||
268 | } | ||
269 | WARN_ON(1); | ||
270 | /* fall through */ | ||
271 | case SNDRV_PCM_FORMAT_S32: | ||
272 | if (s->direction == AMDTP_OUT_STREAM) | ||
273 | p->transfer_samples = write_pcm_s32; | ||
274 | else | ||
275 | p->transfer_samples = read_pcm_s32; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | EXPORT_SYMBOL_GPL(amdtp_am824_set_pcm_format); | ||
280 | |||
281 | /** | ||
282 | * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream | 215 | * amdtp_am824_add_pcm_hw_constraints - add hw constraints for PCM substream |
283 | * @s: the AMDTP stream for AM824 data block, must be initialized. | 216 | * @s: the AMDTP stream for AM824 data block, must be initialized. |
284 | * @runtime: the PCM substream runtime | 217 | * @runtime: the PCM substream runtime |
@@ -407,7 +340,7 @@ static unsigned int process_rx_data_blocks(struct amdtp_stream *s, __be32 *buffe | |||
407 | unsigned int pcm_frames; | 340 | unsigned int pcm_frames; |
408 | 341 | ||
409 | if (pcm) { | 342 | if (pcm) { |
410 | p->transfer_samples(s, pcm, buffer, data_blocks); | 343 | write_pcm_s32(s, pcm, buffer, data_blocks); |
411 | pcm_frames = data_blocks * p->frame_multiplier; | 344 | pcm_frames = data_blocks * p->frame_multiplier; |
412 | } else { | 345 | } else { |
413 | write_pcm_silence(s, buffer, data_blocks); | 346 | write_pcm_silence(s, buffer, data_blocks); |
@@ -428,7 +361,7 @@ static unsigned int process_tx_data_blocks(struct amdtp_stream *s, __be32 *buffe | |||
428 | unsigned int pcm_frames; | 361 | unsigned int pcm_frames; |
429 | 362 | ||
430 | if (pcm) { | 363 | if (pcm) { |
431 | p->transfer_samples(s, pcm, buffer, data_blocks); | 364 | read_pcm_s32(s, pcm, buffer, data_blocks); |
432 | pcm_frames = data_blocks * p->frame_multiplier; | 365 | pcm_frames = data_blocks * p->frame_multiplier; |
433 | } else { | 366 | } else { |
434 | pcm_frames = 0; | 367 | pcm_frames = 0; |
diff --git a/sound/firewire/amdtp-am824.h b/sound/firewire/amdtp-am824.h index 73b07b3109db..b56e61fc997d 100644 --- a/sound/firewire/amdtp-am824.h +++ b/sound/firewire/amdtp-am824.h | |||
@@ -8,8 +8,7 @@ | |||
8 | 8 | ||
9 | #define AM824_IN_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32 | 9 | #define AM824_IN_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32 |
10 | 10 | ||
11 | #define AM824_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \ | 11 | #define AM824_OUT_PCM_FORMAT_BITS SNDRV_PCM_FMTBIT_S32 |
12 | SNDRV_PCM_FMTBIT_S32) | ||
13 | 12 | ||
14 | /* | 13 | /* |
15 | * This module supports maximum 64 PCM channels for one PCM stream | 14 | * This module supports maximum 64 PCM channels for one PCM stream |
@@ -41,9 +40,6 @@ void amdtp_am824_set_midi_position(struct amdtp_stream *s, | |||
41 | int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s, | 40 | int amdtp_am824_add_pcm_hw_constraints(struct amdtp_stream *s, |
42 | struct snd_pcm_runtime *runtime); | 41 | struct snd_pcm_runtime *runtime); |
43 | 42 | ||
44 | void amdtp_am824_set_pcm_format(struct amdtp_stream *s, | ||
45 | snd_pcm_format_t format); | ||
46 | |||
47 | void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port, | 43 | void amdtp_am824_midi_trigger(struct amdtp_stream *s, unsigned int port, |
48 | struct snd_rawmidi_substream *midi); | 44 | struct snd_rawmidi_substream *midi); |
49 | 45 | ||
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index 1e26854b3425..3fc581a5ad62 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c | |||
@@ -148,8 +148,27 @@ EXPORT_SYMBOL(amdtp_rate_table); | |||
148 | int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, | 148 | int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, |
149 | struct snd_pcm_runtime *runtime) | 149 | struct snd_pcm_runtime *runtime) |
150 | { | 150 | { |
151 | struct snd_pcm_hardware *hw = &runtime->hw; | ||
151 | int err; | 152 | int err; |
152 | 153 | ||
154 | hw->info = SNDRV_PCM_INFO_BATCH | | ||
155 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
156 | SNDRV_PCM_INFO_INTERLEAVED | | ||
157 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
158 | SNDRV_PCM_INFO_MMAP | | ||
159 | SNDRV_PCM_INFO_MMAP_VALID; | ||
160 | |||
161 | /* SNDRV_PCM_INFO_BATCH */ | ||
162 | hw->periods_min = 2; | ||
163 | hw->periods_max = UINT_MAX; | ||
164 | |||
165 | /* bytes for a frame */ | ||
166 | hw->period_bytes_min = 4 * hw->channels_max; | ||
167 | |||
168 | /* Just to prevent from allocating much pages. */ | ||
169 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
170 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
171 | |||
153 | /* | 172 | /* |
154 | * Currently firewire-lib processes 16 packets in one software | 173 | * Currently firewire-lib processes 16 packets in one software |
155 | * interrupt callback. This equals to 2msec but actually the | 174 | * interrupt callback. This equals to 2msec but actually the |
@@ -933,6 +952,25 @@ unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s) | |||
933 | EXPORT_SYMBOL(amdtp_stream_pcm_pointer); | 952 | EXPORT_SYMBOL(amdtp_stream_pcm_pointer); |
934 | 953 | ||
935 | /** | 954 | /** |
955 | * amdtp_stream_pcm_ack - acknowledge queued PCM frames | ||
956 | * @s: the AMDTP stream that transfers the PCM frames | ||
957 | * | ||
958 | * Returns zero always. | ||
959 | */ | ||
960 | int amdtp_stream_pcm_ack(struct amdtp_stream *s) | ||
961 | { | ||
962 | /* | ||
963 | * Process isochronous packets for recent isochronous cycle to handle | ||
964 | * queued PCM frames. | ||
965 | */ | ||
966 | if (amdtp_stream_running(s)) | ||
967 | fw_iso_context_flush_completions(s->context); | ||
968 | |||
969 | return 0; | ||
970 | } | ||
971 | EXPORT_SYMBOL(amdtp_stream_pcm_ack); | ||
972 | |||
973 | /** | ||
936 | * amdtp_stream_update - update the stream after a bus reset | 974 | * amdtp_stream_update - update the stream after a bus reset |
937 | * @s: the AMDTP stream | 975 | * @s: the AMDTP stream |
938 | */ | 976 | */ |
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h index ea1a91e99875..ed6eafd10992 100644 --- a/sound/firewire/amdtp-stream.h +++ b/sound/firewire/amdtp-stream.h | |||
@@ -168,6 +168,7 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, | |||
168 | 168 | ||
169 | void amdtp_stream_pcm_prepare(struct amdtp_stream *s); | 169 | void amdtp_stream_pcm_prepare(struct amdtp_stream *s); |
170 | unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s); | 170 | unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s); |
171 | int amdtp_stream_pcm_ack(struct amdtp_stream *s); | ||
171 | void amdtp_stream_pcm_abort(struct amdtp_stream *s); | 172 | void amdtp_stream_pcm_abort(struct amdtp_stream *s); |
172 | 173 | ||
173 | extern const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT]; | 174 | extern const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT]; |
diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c index 07e5abdbceb5..d10208f92edf 100644 --- a/sound/firewire/bebob/bebob_maudio.c +++ b/sound/firewire/bebob/bebob_maudio.c | |||
@@ -396,7 +396,7 @@ static int special_clk_ctl_put(struct snd_kcontrol *kctl, | |||
396 | 396 | ||
397 | return err; | 397 | return err; |
398 | } | 398 | } |
399 | static struct snd_kcontrol_new special_clk_ctl = { | 399 | static const struct snd_kcontrol_new special_clk_ctl = { |
400 | .name = "Clock Source", | 400 | .name = "Clock Source", |
401 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 401 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
402 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 402 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -429,7 +429,7 @@ static int special_sync_ctl_get(struct snd_kcontrol *kctl, | |||
429 | 429 | ||
430 | return 0; | 430 | return 0; |
431 | } | 431 | } |
432 | static struct snd_kcontrol_new special_sync_ctl = { | 432 | static const struct snd_kcontrol_new special_sync_ctl = { |
433 | .name = "Sync Status", | 433 | .name = "Sync Status", |
434 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 434 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
435 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 435 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
@@ -521,7 +521,7 @@ end: | |||
521 | mutex_unlock(&bebob->mutex); | 521 | mutex_unlock(&bebob->mutex); |
522 | return err; | 522 | return err; |
523 | } | 523 | } |
524 | static struct snd_kcontrol_new special_dig_in_iface_ctl = { | 524 | static const struct snd_kcontrol_new special_dig_in_iface_ctl = { |
525 | .name = "Digital Input Interface", | 525 | .name = "Digital Input Interface", |
526 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 526 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
527 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 527 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -577,7 +577,7 @@ static int special_dig_out_iface_ctl_set(struct snd_kcontrol *kctl, | |||
577 | mutex_unlock(&bebob->mutex); | 577 | mutex_unlock(&bebob->mutex); |
578 | return err; | 578 | return err; |
579 | } | 579 | } |
580 | static struct snd_kcontrol_new special_dig_out_iface_ctl = { | 580 | static const struct snd_kcontrol_new special_dig_out_iface_ctl = { |
581 | .name = "Digital Output Interface", | 581 | .name = "Digital Output Interface", |
582 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 582 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
583 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 583 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
diff --git a/sound/firewire/bebob/bebob_pcm.c b/sound/firewire/bebob/bebob_pcm.c index 9e27eb8e1dd4..e6adab3ef42e 100644 --- a/sound/firewire/bebob/bebob_pcm.c +++ b/sound/firewire/bebob/bebob_pcm.c | |||
@@ -92,19 +92,6 @@ limit_channels_and_rates(struct snd_pcm_hardware *hw, | |||
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
95 | static void | ||
96 | limit_period_and_buffer(struct snd_pcm_hardware *hw) | ||
97 | { | ||
98 | hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ | ||
99 | hw->periods_max = UINT_MAX; | ||
100 | |||
101 | hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */ | ||
102 | |||
103 | /* Just to prevent from allocating much pages. */ | ||
104 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
105 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
106 | } | ||
107 | |||
108 | static int | 95 | static int |
109 | pcm_init_hw_params(struct snd_bebob *bebob, | 96 | pcm_init_hw_params(struct snd_bebob *bebob, |
110 | struct snd_pcm_substream *substream) | 97 | struct snd_pcm_substream *substream) |
@@ -114,13 +101,6 @@ pcm_init_hw_params(struct snd_bebob *bebob, | |||
114 | struct snd_bebob_stream_formation *formations; | 101 | struct snd_bebob_stream_formation *formations; |
115 | int err; | 102 | int err; |
116 | 103 | ||
117 | runtime->hw.info = SNDRV_PCM_INFO_BATCH | | ||
118 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
119 | SNDRV_PCM_INFO_INTERLEAVED | | ||
120 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
121 | SNDRV_PCM_INFO_MMAP | | ||
122 | SNDRV_PCM_INFO_MMAP_VALID; | ||
123 | |||
124 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 104 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
125 | runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS; | 105 | runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS; |
126 | s = &bebob->tx_stream; | 106 | s = &bebob->tx_stream; |
@@ -132,7 +112,6 @@ pcm_init_hw_params(struct snd_bebob *bebob, | |||
132 | } | 112 | } |
133 | 113 | ||
134 | limit_channels_and_rates(&runtime->hw, formations); | 114 | limit_channels_and_rates(&runtime->hw, formations); |
135 | limit_period_and_buffer(&runtime->hw); | ||
136 | 115 | ||
137 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 116 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
138 | hw_rule_channels, formations, | 117 | hw_rule_channels, formations, |
@@ -224,8 +203,6 @@ pcm_capture_hw_params(struct snd_pcm_substream *substream, | |||
224 | mutex_unlock(&bebob->mutex); | 203 | mutex_unlock(&bebob->mutex); |
225 | } | 204 | } |
226 | 205 | ||
227 | amdtp_am824_set_pcm_format(&bebob->tx_stream, params_format(hw_params)); | ||
228 | |||
229 | return 0; | 206 | return 0; |
230 | } | 207 | } |
231 | static int | 208 | static int |
@@ -246,8 +223,6 @@ pcm_playback_hw_params(struct snd_pcm_substream *substream, | |||
246 | mutex_unlock(&bebob->mutex); | 223 | mutex_unlock(&bebob->mutex); |
247 | } | 224 | } |
248 | 225 | ||
249 | amdtp_am824_set_pcm_format(&bebob->rx_stream, params_format(hw_params)); | ||
250 | |||
251 | return 0; | 226 | return 0; |
252 | } | 227 | } |
253 | 228 | ||
@@ -359,6 +334,20 @@ pcm_playback_pointer(struct snd_pcm_substream *sbstrm) | |||
359 | return amdtp_stream_pcm_pointer(&bebob->rx_stream); | 334 | return amdtp_stream_pcm_pointer(&bebob->rx_stream); |
360 | } | 335 | } |
361 | 336 | ||
337 | static int pcm_capture_ack(struct snd_pcm_substream *substream) | ||
338 | { | ||
339 | struct snd_bebob *bebob = substream->private_data; | ||
340 | |||
341 | return amdtp_stream_pcm_ack(&bebob->tx_stream); | ||
342 | } | ||
343 | |||
344 | static int pcm_playback_ack(struct snd_pcm_substream *substream) | ||
345 | { | ||
346 | struct snd_bebob *bebob = substream->private_data; | ||
347 | |||
348 | return amdtp_stream_pcm_ack(&bebob->rx_stream); | ||
349 | } | ||
350 | |||
362 | int snd_bebob_create_pcm_devices(struct snd_bebob *bebob) | 351 | int snd_bebob_create_pcm_devices(struct snd_bebob *bebob) |
363 | { | 352 | { |
364 | static const struct snd_pcm_ops capture_ops = { | 353 | static const struct snd_pcm_ops capture_ops = { |
@@ -370,6 +359,7 @@ int snd_bebob_create_pcm_devices(struct snd_bebob *bebob) | |||
370 | .prepare = pcm_capture_prepare, | 359 | .prepare = pcm_capture_prepare, |
371 | .trigger = pcm_capture_trigger, | 360 | .trigger = pcm_capture_trigger, |
372 | .pointer = pcm_capture_pointer, | 361 | .pointer = pcm_capture_pointer, |
362 | .ack = pcm_capture_ack, | ||
373 | .page = snd_pcm_lib_get_vmalloc_page, | 363 | .page = snd_pcm_lib_get_vmalloc_page, |
374 | }; | 364 | }; |
375 | static const struct snd_pcm_ops playback_ops = { | 365 | static const struct snd_pcm_ops playback_ops = { |
@@ -381,6 +371,7 @@ int snd_bebob_create_pcm_devices(struct snd_bebob *bebob) | |||
381 | .prepare = pcm_playback_prepare, | 371 | .prepare = pcm_playback_prepare, |
382 | .trigger = pcm_playback_trigger, | 372 | .trigger = pcm_playback_trigger, |
383 | .pointer = pcm_playback_pointer, | 373 | .pointer = pcm_playback_pointer, |
374 | .ack = pcm_playback_ack, | ||
384 | .page = snd_pcm_lib_get_vmalloc_page, | 375 | .page = snd_pcm_lib_get_vmalloc_page, |
385 | .mmap = snd_pcm_lib_mmap_vmalloc, | 376 | .mmap = snd_pcm_lib_mmap_vmalloc, |
386 | }; | 377 | }; |
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c index 6074fe1f00f7..7cb9e9713ac3 100644 --- a/sound/firewire/dice/dice-pcm.c +++ b/sound/firewire/dice/dice-pcm.c | |||
@@ -51,18 +51,6 @@ static int limit_channels_and_rates(struct snd_dice *dice, | |||
51 | return 0; | 51 | return 0; |
52 | } | 52 | } |
53 | 53 | ||
54 | static void limit_period_and_buffer(struct snd_pcm_hardware *hw) | ||
55 | { | ||
56 | hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ | ||
57 | hw->periods_max = UINT_MAX; | ||
58 | |||
59 | hw->period_bytes_min = 4 * hw->channels_max; /* byte for a frame */ | ||
60 | |||
61 | /* Just to prevent from allocating much pages. */ | ||
62 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
63 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
64 | } | ||
65 | |||
66 | static int init_hw_info(struct snd_dice *dice, | 54 | static int init_hw_info(struct snd_dice *dice, |
67 | struct snd_pcm_substream *substream) | 55 | struct snd_pcm_substream *substream) |
68 | { | 56 | { |
@@ -74,13 +62,6 @@ static int init_hw_info(struct snd_dice *dice, | |||
74 | unsigned int count, size; | 62 | unsigned int count, size; |
75 | int err; | 63 | int err; |
76 | 64 | ||
77 | hw->info = SNDRV_PCM_INFO_MMAP | | ||
78 | SNDRV_PCM_INFO_MMAP_VALID | | ||
79 | SNDRV_PCM_INFO_BATCH | | ||
80 | SNDRV_PCM_INFO_INTERLEAVED | | ||
81 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
82 | SNDRV_PCM_INFO_BLOCK_TRANSFER; | ||
83 | |||
84 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 65 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
85 | hw->formats = AM824_IN_PCM_FORMAT_BITS; | 66 | hw->formats = AM824_IN_PCM_FORMAT_BITS; |
86 | dir = AMDTP_IN_STREAM; | 67 | dir = AMDTP_IN_STREAM; |
@@ -107,7 +88,6 @@ static int init_hw_info(struct snd_dice *dice, | |||
107 | substream->pcm->device, size); | 88 | substream->pcm->device, size); |
108 | if (err < 0) | 89 | if (err < 0) |
109 | return err; | 90 | return err; |
110 | limit_period_and_buffer(hw); | ||
111 | 91 | ||
112 | return amdtp_am824_add_pcm_hw_constraints(stream, runtime); | 92 | return amdtp_am824_add_pcm_hw_constraints(stream, runtime); |
113 | } | 93 | } |
@@ -146,7 +126,6 @@ static int capture_hw_params(struct snd_pcm_substream *substream, | |||
146 | struct snd_pcm_hw_params *hw_params) | 126 | struct snd_pcm_hw_params *hw_params) |
147 | { | 127 | { |
148 | struct snd_dice *dice = substream->private_data; | 128 | struct snd_dice *dice = substream->private_data; |
149 | struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device]; | ||
150 | int err; | 129 | int err; |
151 | 130 | ||
152 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, | 131 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, |
@@ -160,15 +139,12 @@ static int capture_hw_params(struct snd_pcm_substream *substream, | |||
160 | mutex_unlock(&dice->mutex); | 139 | mutex_unlock(&dice->mutex); |
161 | } | 140 | } |
162 | 141 | ||
163 | amdtp_am824_set_pcm_format(stream, params_format(hw_params)); | ||
164 | |||
165 | return 0; | 142 | return 0; |
166 | } | 143 | } |
167 | static int playback_hw_params(struct snd_pcm_substream *substream, | 144 | static int playback_hw_params(struct snd_pcm_substream *substream, |
168 | struct snd_pcm_hw_params *hw_params) | 145 | struct snd_pcm_hw_params *hw_params) |
169 | { | 146 | { |
170 | struct snd_dice *dice = substream->private_data; | 147 | struct snd_dice *dice = substream->private_data; |
171 | struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device]; | ||
172 | int err; | 148 | int err; |
173 | 149 | ||
174 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, | 150 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, |
@@ -182,8 +158,6 @@ static int playback_hw_params(struct snd_pcm_substream *substream, | |||
182 | mutex_unlock(&dice->mutex); | 158 | mutex_unlock(&dice->mutex); |
183 | } | 159 | } |
184 | 160 | ||
185 | amdtp_am824_set_pcm_format(stream, params_format(hw_params)); | ||
186 | |||
187 | return 0; | 161 | return 0; |
188 | } | 162 | } |
189 | 163 | ||
@@ -300,6 +274,22 @@ static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream) | |||
300 | return amdtp_stream_pcm_pointer(stream); | 274 | return amdtp_stream_pcm_pointer(stream); |
301 | } | 275 | } |
302 | 276 | ||
277 | static int capture_ack(struct snd_pcm_substream *substream) | ||
278 | { | ||
279 | struct snd_dice *dice = substream->private_data; | ||
280 | struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device]; | ||
281 | |||
282 | return amdtp_stream_pcm_ack(stream); | ||
283 | } | ||
284 | |||
285 | static int playback_ack(struct snd_pcm_substream *substream) | ||
286 | { | ||
287 | struct snd_dice *dice = substream->private_data; | ||
288 | struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device]; | ||
289 | |||
290 | return amdtp_stream_pcm_ack(stream); | ||
291 | } | ||
292 | |||
303 | int snd_dice_create_pcm(struct snd_dice *dice) | 293 | int snd_dice_create_pcm(struct snd_dice *dice) |
304 | { | 294 | { |
305 | static const struct snd_pcm_ops capture_ops = { | 295 | static const struct snd_pcm_ops capture_ops = { |
@@ -311,6 +301,7 @@ int snd_dice_create_pcm(struct snd_dice *dice) | |||
311 | .prepare = capture_prepare, | 301 | .prepare = capture_prepare, |
312 | .trigger = capture_trigger, | 302 | .trigger = capture_trigger, |
313 | .pointer = capture_pointer, | 303 | .pointer = capture_pointer, |
304 | .ack = capture_ack, | ||
314 | .page = snd_pcm_lib_get_vmalloc_page, | 305 | .page = snd_pcm_lib_get_vmalloc_page, |
315 | .mmap = snd_pcm_lib_mmap_vmalloc, | 306 | .mmap = snd_pcm_lib_mmap_vmalloc, |
316 | }; | 307 | }; |
@@ -323,6 +314,7 @@ int snd_dice_create_pcm(struct snd_dice *dice) | |||
323 | .prepare = playback_prepare, | 314 | .prepare = playback_prepare, |
324 | .trigger = playback_trigger, | 315 | .trigger = playback_trigger, |
325 | .pointer = playback_pointer, | 316 | .pointer = playback_pointer, |
317 | .ack = playback_ack, | ||
326 | .page = snd_pcm_lib_get_vmalloc_page, | 318 | .page = snd_pcm_lib_get_vmalloc_page, |
327 | .mmap = snd_pcm_lib_mmap_vmalloc, | 319 | .mmap = snd_pcm_lib_mmap_vmalloc, |
328 | }; | 320 | }; |
diff --git a/sound/firewire/digi00x/amdtp-dot.c b/sound/firewire/digi00x/amdtp-dot.c index a4688545339c..1453c34ce99f 100644 --- a/sound/firewire/digi00x/amdtp-dot.c +++ b/sound/firewire/digi00x/amdtp-dot.c | |||
@@ -48,10 +48,6 @@ struct amdtp_dot { | |||
48 | struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS]; | 48 | struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS]; |
49 | int midi_fifo_used[MAX_MIDI_PORTS]; | 49 | int midi_fifo_used[MAX_MIDI_PORTS]; |
50 | int midi_fifo_limit; | 50 | int midi_fifo_limit; |
51 | |||
52 | void (*transfer_samples)(struct amdtp_stream *s, | ||
53 | struct snd_pcm_substream *pcm, | ||
54 | __be32 *buffer, unsigned int frames); | ||
55 | }; | 51 | }; |
56 | 52 | ||
57 | /* | 53 | /* |
@@ -173,32 +169,6 @@ static void write_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, | |||
173 | } | 169 | } |
174 | } | 170 | } |
175 | 171 | ||
176 | static void write_pcm_s16(struct amdtp_stream *s, struct snd_pcm_substream *pcm, | ||
177 | __be32 *buffer, unsigned int frames) | ||
178 | { | ||
179 | struct amdtp_dot *p = s->protocol; | ||
180 | struct snd_pcm_runtime *runtime = pcm->runtime; | ||
181 | unsigned int channels, remaining_frames, i, c; | ||
182 | const u16 *src; | ||
183 | |||
184 | channels = p->pcm_channels; | ||
185 | src = (void *)runtime->dma_area + | ||
186 | frames_to_bytes(runtime, s->pcm_buffer_pointer); | ||
187 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; | ||
188 | |||
189 | buffer++; | ||
190 | for (i = 0; i < frames; ++i) { | ||
191 | for (c = 0; c < channels; ++c) { | ||
192 | buffer[c] = cpu_to_be32((*src << 8) | 0x40000000); | ||
193 | dot_encode_step(&p->state, &buffer[c]); | ||
194 | src++; | ||
195 | } | ||
196 | buffer += s->data_block_quadlets; | ||
197 | if (--remaining_frames == 0) | ||
198 | src = (void *)runtime->dma_area; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, | 172 | static void read_pcm_s32(struct amdtp_stream *s, struct snd_pcm_substream *pcm, |
203 | __be32 *buffer, unsigned int frames) | 173 | __be32 *buffer, unsigned int frames) |
204 | { | 174 | { |
@@ -351,33 +321,6 @@ int amdtp_dot_add_pcm_hw_constraints(struct amdtp_stream *s, | |||
351 | return amdtp_stream_add_pcm_hw_constraints(s, runtime); | 321 | return amdtp_stream_add_pcm_hw_constraints(s, runtime); |
352 | } | 322 | } |
353 | 323 | ||
354 | void amdtp_dot_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format) | ||
355 | { | ||
356 | struct amdtp_dot *p = s->protocol; | ||
357 | |||
358 | if (WARN_ON(amdtp_stream_pcm_running(s))) | ||
359 | return; | ||
360 | |||
361 | switch (format) { | ||
362 | default: | ||
363 | WARN_ON(1); | ||
364 | /* fall through */ | ||
365 | case SNDRV_PCM_FORMAT_S16: | ||
366 | if (s->direction == AMDTP_OUT_STREAM) { | ||
367 | p->transfer_samples = write_pcm_s16; | ||
368 | break; | ||
369 | } | ||
370 | WARN_ON(1); | ||
371 | /* fall through */ | ||
372 | case SNDRV_PCM_FORMAT_S32: | ||
373 | if (s->direction == AMDTP_OUT_STREAM) | ||
374 | p->transfer_samples = write_pcm_s32; | ||
375 | else | ||
376 | p->transfer_samples = read_pcm_s32; | ||
377 | break; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port, | 324 | void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port, |
382 | struct snd_rawmidi_substream *midi) | 325 | struct snd_rawmidi_substream *midi) |
383 | { | 326 | { |
@@ -392,13 +335,12 @@ static unsigned int process_tx_data_blocks(struct amdtp_stream *s, | |||
392 | unsigned int data_blocks, | 335 | unsigned int data_blocks, |
393 | unsigned int *syt) | 336 | unsigned int *syt) |
394 | { | 337 | { |
395 | struct amdtp_dot *p = (struct amdtp_dot *)s->protocol; | ||
396 | struct snd_pcm_substream *pcm; | 338 | struct snd_pcm_substream *pcm; |
397 | unsigned int pcm_frames; | 339 | unsigned int pcm_frames; |
398 | 340 | ||
399 | pcm = ACCESS_ONCE(s->pcm); | 341 | pcm = ACCESS_ONCE(s->pcm); |
400 | if (pcm) { | 342 | if (pcm) { |
401 | p->transfer_samples(s, pcm, buffer, data_blocks); | 343 | read_pcm_s32(s, pcm, buffer, data_blocks); |
402 | pcm_frames = data_blocks; | 344 | pcm_frames = data_blocks; |
403 | } else { | 345 | } else { |
404 | pcm_frames = 0; | 346 | pcm_frames = 0; |
@@ -414,13 +356,12 @@ static unsigned int process_rx_data_blocks(struct amdtp_stream *s, | |||
414 | unsigned int data_blocks, | 356 | unsigned int data_blocks, |
415 | unsigned int *syt) | 357 | unsigned int *syt) |
416 | { | 358 | { |
417 | struct amdtp_dot *p = (struct amdtp_dot *)s->protocol; | ||
418 | struct snd_pcm_substream *pcm; | 359 | struct snd_pcm_substream *pcm; |
419 | unsigned int pcm_frames; | 360 | unsigned int pcm_frames; |
420 | 361 | ||
421 | pcm = ACCESS_ONCE(s->pcm); | 362 | pcm = ACCESS_ONCE(s->pcm); |
422 | if (pcm) { | 363 | if (pcm) { |
423 | p->transfer_samples(s, pcm, buffer, data_blocks); | 364 | write_pcm_s32(s, pcm, buffer, data_blocks); |
424 | pcm_frames = data_blocks; | 365 | pcm_frames = data_blocks; |
425 | } else { | 366 | } else { |
426 | write_pcm_silence(s, buffer, data_blocks); | 367 | write_pcm_silence(s, buffer, data_blocks); |
diff --git a/sound/firewire/digi00x/digi00x-pcm.c b/sound/firewire/digi00x/digi00x-pcm.c index 68d1c52db051..796f4b4645f5 100644 --- a/sound/firewire/digi00x/digi00x-pcm.c +++ b/sound/firewire/digi00x/digi00x-pcm.c | |||
@@ -58,41 +58,29 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params, | |||
58 | static int pcm_init_hw_params(struct snd_dg00x *dg00x, | 58 | static int pcm_init_hw_params(struct snd_dg00x *dg00x, |
59 | struct snd_pcm_substream *substream) | 59 | struct snd_pcm_substream *substream) |
60 | { | 60 | { |
61 | static const struct snd_pcm_hardware hardware = { | 61 | struct snd_pcm_runtime *runtime = substream->runtime; |
62 | .info = SNDRV_PCM_INFO_BATCH | | 62 | struct snd_pcm_hardware *hw = &runtime->hw; |
63 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
64 | SNDRV_PCM_INFO_INTERLEAVED | | ||
65 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
66 | SNDRV_PCM_INFO_MMAP | | ||
67 | SNDRV_PCM_INFO_MMAP_VALID, | ||
68 | .rates = SNDRV_PCM_RATE_44100 | | ||
69 | SNDRV_PCM_RATE_48000 | | ||
70 | SNDRV_PCM_RATE_88200 | | ||
71 | SNDRV_PCM_RATE_96000, | ||
72 | .rate_min = 44100, | ||
73 | .rate_max = 96000, | ||
74 | .channels_min = 10, | ||
75 | .channels_max = 18, | ||
76 | .period_bytes_min = 4 * 18, | ||
77 | .period_bytes_max = 4 * 18 * 2048, | ||
78 | .buffer_bytes_max = 4 * 18 * 2048 * 2, | ||
79 | .periods_min = 2, | ||
80 | .periods_max = UINT_MAX, | ||
81 | }; | ||
82 | struct amdtp_stream *s; | 63 | struct amdtp_stream *s; |
83 | int err; | 64 | int err; |
84 | 65 | ||
85 | substream->runtime->hw = hardware; | ||
86 | 66 | ||
87 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 67 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
88 | substream->runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; | 68 | substream->runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; |
89 | s = &dg00x->tx_stream; | 69 | s = &dg00x->tx_stream; |
90 | } else { | 70 | } else { |
91 | substream->runtime->hw.formats = SNDRV_PCM_FMTBIT_S16 | | 71 | substream->runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; |
92 | SNDRV_PCM_FMTBIT_S32; | ||
93 | s = &dg00x->rx_stream; | 72 | s = &dg00x->rx_stream; |
94 | } | 73 | } |
95 | 74 | ||
75 | hw->channels_min = 10; | ||
76 | hw->channels_max = 18; | ||
77 | |||
78 | hw->rates = SNDRV_PCM_RATE_44100 | | ||
79 | SNDRV_PCM_RATE_48000 | | ||
80 | SNDRV_PCM_RATE_88200 | | ||
81 | SNDRV_PCM_RATE_96000; | ||
82 | snd_pcm_limit_hw_rates(runtime); | ||
83 | |||
96 | err = snd_pcm_hw_rule_add(substream->runtime, 0, | 84 | err = snd_pcm_hw_rule_add(substream->runtime, 0, |
97 | SNDRV_PCM_HW_PARAM_CHANNELS, | 85 | SNDRV_PCM_HW_PARAM_CHANNELS, |
98 | hw_rule_channels, NULL, | 86 | hw_rule_channels, NULL, |
@@ -184,8 +172,6 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream, | |||
184 | mutex_unlock(&dg00x->mutex); | 172 | mutex_unlock(&dg00x->mutex); |
185 | } | 173 | } |
186 | 174 | ||
187 | amdtp_dot_set_pcm_format(&dg00x->tx_stream, params_format(hw_params)); | ||
188 | |||
189 | return 0; | 175 | return 0; |
190 | } | 176 | } |
191 | 177 | ||
@@ -206,8 +192,6 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream, | |||
206 | mutex_unlock(&dg00x->mutex); | 192 | mutex_unlock(&dg00x->mutex); |
207 | } | 193 | } |
208 | 194 | ||
209 | amdtp_dot_set_pcm_format(&dg00x->rx_stream, params_format(hw_params)); | ||
210 | |||
211 | return 0; | 195 | return 0; |
212 | } | 196 | } |
213 | 197 | ||
@@ -329,6 +313,20 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) | |||
329 | return amdtp_stream_pcm_pointer(&dg00x->rx_stream); | 313 | return amdtp_stream_pcm_pointer(&dg00x->rx_stream); |
330 | } | 314 | } |
331 | 315 | ||
316 | static int pcm_capture_ack(struct snd_pcm_substream *substream) | ||
317 | { | ||
318 | struct snd_dg00x *dg00x = substream->private_data; | ||
319 | |||
320 | return amdtp_stream_pcm_ack(&dg00x->tx_stream); | ||
321 | } | ||
322 | |||
323 | static int pcm_playback_ack(struct snd_pcm_substream *substream) | ||
324 | { | ||
325 | struct snd_dg00x *dg00x = substream->private_data; | ||
326 | |||
327 | return amdtp_stream_pcm_ack(&dg00x->rx_stream); | ||
328 | } | ||
329 | |||
332 | int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x) | 330 | int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x) |
333 | { | 331 | { |
334 | static const struct snd_pcm_ops capture_ops = { | 332 | static const struct snd_pcm_ops capture_ops = { |
@@ -340,6 +338,7 @@ int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x) | |||
340 | .prepare = pcm_capture_prepare, | 338 | .prepare = pcm_capture_prepare, |
341 | .trigger = pcm_capture_trigger, | 339 | .trigger = pcm_capture_trigger, |
342 | .pointer = pcm_capture_pointer, | 340 | .pointer = pcm_capture_pointer, |
341 | .ack = pcm_capture_ack, | ||
343 | .page = snd_pcm_lib_get_vmalloc_page, | 342 | .page = snd_pcm_lib_get_vmalloc_page, |
344 | }; | 343 | }; |
345 | static const struct snd_pcm_ops playback_ops = { | 344 | static const struct snd_pcm_ops playback_ops = { |
@@ -351,6 +350,7 @@ int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x) | |||
351 | .prepare = pcm_playback_prepare, | 350 | .prepare = pcm_playback_prepare, |
352 | .trigger = pcm_playback_trigger, | 351 | .trigger = pcm_playback_trigger, |
353 | .pointer = pcm_playback_pointer, | 352 | .pointer = pcm_playback_pointer, |
353 | .ack = pcm_playback_ack, | ||
354 | .page = snd_pcm_lib_get_vmalloc_page, | 354 | .page = snd_pcm_lib_get_vmalloc_page, |
355 | .mmap = snd_pcm_lib_mmap_vmalloc, | 355 | .mmap = snd_pcm_lib_mmap_vmalloc, |
356 | }; | 356 | }; |
diff --git a/sound/firewire/digi00x/digi00x.h b/sound/firewire/digi00x/digi00x.h index 1275a50956c0..4dd1bbf2ed3c 100644 --- a/sound/firewire/digi00x/digi00x.h +++ b/sound/firewire/digi00x/digi00x.h | |||
@@ -121,7 +121,6 @@ int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate, | |||
121 | void amdtp_dot_reset(struct amdtp_stream *s); | 121 | void amdtp_dot_reset(struct amdtp_stream *s); |
122 | int amdtp_dot_add_pcm_hw_constraints(struct amdtp_stream *s, | 122 | int amdtp_dot_add_pcm_hw_constraints(struct amdtp_stream *s, |
123 | struct snd_pcm_runtime *runtime); | 123 | struct snd_pcm_runtime *runtime); |
124 | void amdtp_dot_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format); | ||
125 | void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port, | 124 | void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port, |
126 | struct snd_rawmidi_substream *midi); | 125 | struct snd_rawmidi_substream *midi); |
127 | 126 | ||
diff --git a/sound/firewire/fireface/ff-midi.c b/sound/firewire/fireface/ff-midi.c index 29ee0a7365c3..949ee56b4e0e 100644 --- a/sound/firewire/fireface/ff-midi.c +++ b/sound/firewire/fireface/ff-midi.c | |||
@@ -74,18 +74,6 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substream, | |||
74 | spin_unlock_irqrestore(&ff->lock, flags); | 74 | spin_unlock_irqrestore(&ff->lock, flags); |
75 | } | 75 | } |
76 | 76 | ||
77 | static struct snd_rawmidi_ops midi_capture_ops = { | ||
78 | .open = midi_capture_open, | ||
79 | .close = midi_capture_close, | ||
80 | .trigger = midi_capture_trigger, | ||
81 | }; | ||
82 | |||
83 | static struct snd_rawmidi_ops midi_playback_ops = { | ||
84 | .open = midi_playback_open, | ||
85 | .close = midi_playback_close, | ||
86 | .trigger = midi_playback_trigger, | ||
87 | }; | ||
88 | |||
89 | static void set_midi_substream_names(struct snd_rawmidi_str *stream, | 77 | static void set_midi_substream_names(struct snd_rawmidi_str *stream, |
90 | const char *const name) | 78 | const char *const name) |
91 | { | 79 | { |
@@ -99,6 +87,16 @@ static void set_midi_substream_names(struct snd_rawmidi_str *stream, | |||
99 | 87 | ||
100 | int snd_ff_create_midi_devices(struct snd_ff *ff) | 88 | int snd_ff_create_midi_devices(struct snd_ff *ff) |
101 | { | 89 | { |
90 | static const struct snd_rawmidi_ops midi_capture_ops = { | ||
91 | .open = midi_capture_open, | ||
92 | .close = midi_capture_close, | ||
93 | .trigger = midi_capture_trigger, | ||
94 | }; | ||
95 | static const struct snd_rawmidi_ops midi_playback_ops = { | ||
96 | .open = midi_playback_open, | ||
97 | .close = midi_playback_close, | ||
98 | .trigger = midi_playback_trigger, | ||
99 | }; | ||
102 | struct snd_rawmidi *rmidi; | 100 | struct snd_rawmidi *rmidi; |
103 | struct snd_rawmidi_str *stream; | 101 | struct snd_rawmidi_str *stream; |
104 | int err; | 102 | int err; |
diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c index 93cee1978e8e..d12a0e3a4219 100644 --- a/sound/firewire/fireface/ff-pcm.c +++ b/sound/firewire/fireface/ff-pcm.c | |||
@@ -91,18 +91,6 @@ static void limit_channels_and_rates(struct snd_pcm_hardware *hw, | |||
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | static void limit_period_and_buffer(struct snd_pcm_hardware *hw) | ||
95 | { | ||
96 | hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ | ||
97 | hw->periods_max = UINT_MAX; | ||
98 | |||
99 | hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */ | ||
100 | |||
101 | /* Just to prevent from allocating much pages. */ | ||
102 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
103 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
104 | } | ||
105 | |||
106 | static int pcm_init_hw_params(struct snd_ff *ff, | 94 | static int pcm_init_hw_params(struct snd_ff *ff, |
107 | struct snd_pcm_substream *substream) | 95 | struct snd_pcm_substream *substream) |
108 | { | 96 | { |
@@ -111,13 +99,6 @@ static int pcm_init_hw_params(struct snd_ff *ff, | |||
111 | const unsigned int *pcm_channels; | 99 | const unsigned int *pcm_channels; |
112 | int err; | 100 | int err; |
113 | 101 | ||
114 | runtime->hw.info = SNDRV_PCM_INFO_BATCH | | ||
115 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
116 | SNDRV_PCM_INFO_INTERLEAVED | | ||
117 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
118 | SNDRV_PCM_INFO_MMAP | | ||
119 | SNDRV_PCM_INFO_MMAP_VALID; | ||
120 | |||
121 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 102 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
122 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; | 103 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; |
123 | s = &ff->tx_stream; | 104 | s = &ff->tx_stream; |
@@ -128,9 +109,7 @@ static int pcm_init_hw_params(struct snd_ff *ff, | |||
128 | pcm_channels = ff->spec->pcm_playback_channels; | 109 | pcm_channels = ff->spec->pcm_playback_channels; |
129 | } | 110 | } |
130 | 111 | ||
131 | /* limit rates */ | ||
132 | limit_channels_and_rates(&runtime->hw, pcm_channels); | 112 | limit_channels_and_rates(&runtime->hw, pcm_channels); |
133 | limit_period_and_buffer(&runtime->hw); | ||
134 | 113 | ||
135 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 114 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
136 | hw_rule_channels, (void *)pcm_channels, | 115 | hw_rule_channels, (void *)pcm_channels, |
@@ -365,33 +344,47 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) | |||
365 | return amdtp_stream_pcm_pointer(&ff->rx_stream); | 344 | return amdtp_stream_pcm_pointer(&ff->rx_stream); |
366 | } | 345 | } |
367 | 346 | ||
368 | static struct snd_pcm_ops pcm_capture_ops = { | 347 | static int pcm_capture_ack(struct snd_pcm_substream *substream) |
369 | .open = pcm_open, | 348 | { |
370 | .close = pcm_close, | 349 | struct snd_ff *ff = substream->private_data; |
371 | .ioctl = snd_pcm_lib_ioctl, | 350 | |
372 | .hw_params = pcm_capture_hw_params, | 351 | return amdtp_stream_pcm_ack(&ff->tx_stream); |
373 | .hw_free = pcm_capture_hw_free, | 352 | } |
374 | .prepare = pcm_capture_prepare, | 353 | |
375 | .trigger = pcm_capture_trigger, | 354 | static int pcm_playback_ack(struct snd_pcm_substream *substream) |
376 | .pointer = pcm_capture_pointer, | 355 | { |
377 | .page = snd_pcm_lib_get_vmalloc_page, | 356 | struct snd_ff *ff = substream->private_data; |
378 | }; | 357 | |
379 | 358 | return amdtp_stream_pcm_ack(&ff->rx_stream); | |
380 | static struct snd_pcm_ops pcm_playback_ops = { | 359 | } |
381 | .open = pcm_open, | ||
382 | .close = pcm_close, | ||
383 | .ioctl = snd_pcm_lib_ioctl, | ||
384 | .hw_params = pcm_playback_hw_params, | ||
385 | .hw_free = pcm_playback_hw_free, | ||
386 | .prepare = pcm_playback_prepare, | ||
387 | .trigger = pcm_playback_trigger, | ||
388 | .pointer = pcm_playback_pointer, | ||
389 | .page = snd_pcm_lib_get_vmalloc_page, | ||
390 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
391 | }; | ||
392 | 360 | ||
393 | int snd_ff_create_pcm_devices(struct snd_ff *ff) | 361 | int snd_ff_create_pcm_devices(struct snd_ff *ff) |
394 | { | 362 | { |
363 | static const struct snd_pcm_ops pcm_capture_ops = { | ||
364 | .open = pcm_open, | ||
365 | .close = pcm_close, | ||
366 | .ioctl = snd_pcm_lib_ioctl, | ||
367 | .hw_params = pcm_capture_hw_params, | ||
368 | .hw_free = pcm_capture_hw_free, | ||
369 | .prepare = pcm_capture_prepare, | ||
370 | .trigger = pcm_capture_trigger, | ||
371 | .pointer = pcm_capture_pointer, | ||
372 | .ack = pcm_capture_ack, | ||
373 | .page = snd_pcm_lib_get_vmalloc_page, | ||
374 | }; | ||
375 | static const struct snd_pcm_ops pcm_playback_ops = { | ||
376 | .open = pcm_open, | ||
377 | .close = pcm_close, | ||
378 | .ioctl = snd_pcm_lib_ioctl, | ||
379 | .hw_params = pcm_playback_hw_params, | ||
380 | .hw_free = pcm_playback_hw_free, | ||
381 | .prepare = pcm_playback_prepare, | ||
382 | .trigger = pcm_playback_trigger, | ||
383 | .pointer = pcm_playback_pointer, | ||
384 | .ack = pcm_playback_ack, | ||
385 | .page = snd_pcm_lib_get_vmalloc_page, | ||
386 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
387 | }; | ||
395 | struct snd_pcm *pcm; | 388 | struct snd_pcm *pcm; |
396 | int err; | 389 | int err; |
397 | 390 | ||
diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c index 9171702f7d0b..40faed5e6968 100644 --- a/sound/firewire/fireworks/fireworks_pcm.c +++ b/sound/firewire/fireworks/fireworks_pcm.c | |||
@@ -129,19 +129,6 @@ limit_channels(struct snd_pcm_hardware *hw, unsigned int *pcm_channels) | |||
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | static void | ||
133 | limit_period_and_buffer(struct snd_pcm_hardware *hw) | ||
134 | { | ||
135 | hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ | ||
136 | hw->periods_max = UINT_MAX; | ||
137 | |||
138 | hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */ | ||
139 | |||
140 | /* Just to prevent from allocating much pages. */ | ||
141 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
142 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
143 | } | ||
144 | |||
145 | static int | 132 | static int |
146 | pcm_init_hw_params(struct snd_efw *efw, | 133 | pcm_init_hw_params(struct snd_efw *efw, |
147 | struct snd_pcm_substream *substream) | 134 | struct snd_pcm_substream *substream) |
@@ -151,13 +138,6 @@ pcm_init_hw_params(struct snd_efw *efw, | |||
151 | unsigned int *pcm_channels; | 138 | unsigned int *pcm_channels; |
152 | int err; | 139 | int err; |
153 | 140 | ||
154 | runtime->hw.info = SNDRV_PCM_INFO_BATCH | | ||
155 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
156 | SNDRV_PCM_INFO_INTERLEAVED | | ||
157 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
158 | SNDRV_PCM_INFO_MMAP | | ||
159 | SNDRV_PCM_INFO_MMAP_VALID; | ||
160 | |||
161 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 141 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
162 | runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS; | 142 | runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS; |
163 | s = &efw->tx_stream; | 143 | s = &efw->tx_stream; |
@@ -173,7 +153,6 @@ pcm_init_hw_params(struct snd_efw *efw, | |||
173 | snd_pcm_limit_hw_rates(runtime); | 153 | snd_pcm_limit_hw_rates(runtime); |
174 | 154 | ||
175 | limit_channels(&runtime->hw, pcm_channels); | 155 | limit_channels(&runtime->hw, pcm_channels); |
176 | limit_period_and_buffer(&runtime->hw); | ||
177 | 156 | ||
178 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 157 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
179 | hw_rule_channels, pcm_channels, | 158 | hw_rule_channels, pcm_channels, |
@@ -257,8 +236,6 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream, | |||
257 | mutex_unlock(&efw->mutex); | 236 | mutex_unlock(&efw->mutex); |
258 | } | 237 | } |
259 | 238 | ||
260 | amdtp_am824_set_pcm_format(&efw->tx_stream, params_format(hw_params)); | ||
261 | |||
262 | return 0; | 239 | return 0; |
263 | } | 240 | } |
264 | static int pcm_playback_hw_params(struct snd_pcm_substream *substream, | 241 | static int pcm_playback_hw_params(struct snd_pcm_substream *substream, |
@@ -278,8 +255,6 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream, | |||
278 | mutex_unlock(&efw->mutex); | 255 | mutex_unlock(&efw->mutex); |
279 | } | 256 | } |
280 | 257 | ||
281 | amdtp_am824_set_pcm_format(&efw->rx_stream, params_format(hw_params)); | ||
282 | |||
283 | return 0; | 258 | return 0; |
284 | } | 259 | } |
285 | 260 | ||
@@ -383,6 +358,20 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) | |||
383 | return amdtp_stream_pcm_pointer(&efw->rx_stream); | 358 | return amdtp_stream_pcm_pointer(&efw->rx_stream); |
384 | } | 359 | } |
385 | 360 | ||
361 | static int pcm_capture_ack(struct snd_pcm_substream *substream) | ||
362 | { | ||
363 | struct snd_efw *efw = substream->private_data; | ||
364 | |||
365 | return amdtp_stream_pcm_ack(&efw->tx_stream); | ||
366 | } | ||
367 | |||
368 | static int pcm_playback_ack(struct snd_pcm_substream *substream) | ||
369 | { | ||
370 | struct snd_efw *efw = substream->private_data; | ||
371 | |||
372 | return amdtp_stream_pcm_ack(&efw->rx_stream); | ||
373 | } | ||
374 | |||
386 | int snd_efw_create_pcm_devices(struct snd_efw *efw) | 375 | int snd_efw_create_pcm_devices(struct snd_efw *efw) |
387 | { | 376 | { |
388 | static const struct snd_pcm_ops capture_ops = { | 377 | static const struct snd_pcm_ops capture_ops = { |
@@ -394,6 +383,7 @@ int snd_efw_create_pcm_devices(struct snd_efw *efw) | |||
394 | .prepare = pcm_capture_prepare, | 383 | .prepare = pcm_capture_prepare, |
395 | .trigger = pcm_capture_trigger, | 384 | .trigger = pcm_capture_trigger, |
396 | .pointer = pcm_capture_pointer, | 385 | .pointer = pcm_capture_pointer, |
386 | .ack = pcm_capture_ack, | ||
397 | .page = snd_pcm_lib_get_vmalloc_page, | 387 | .page = snd_pcm_lib_get_vmalloc_page, |
398 | }; | 388 | }; |
399 | static const struct snd_pcm_ops playback_ops = { | 389 | static const struct snd_pcm_ops playback_ops = { |
@@ -405,6 +395,7 @@ int snd_efw_create_pcm_devices(struct snd_efw *efw) | |||
405 | .prepare = pcm_playback_prepare, | 395 | .prepare = pcm_playback_prepare, |
406 | .trigger = pcm_playback_trigger, | 396 | .trigger = pcm_playback_trigger, |
407 | .pointer = pcm_playback_pointer, | 397 | .pointer = pcm_playback_pointer, |
398 | .ack = pcm_playback_ack, | ||
408 | .page = snd_pcm_lib_get_vmalloc_page, | 399 | .page = snd_pcm_lib_get_vmalloc_page, |
409 | .mmap = snd_pcm_lib_mmap_vmalloc, | 400 | .mmap = snd_pcm_lib_mmap_vmalloc, |
410 | }; | 401 | }; |
diff --git a/sound/firewire/motu/motu-pcm.c b/sound/firewire/motu/motu-pcm.c index 94558f3d218b..a2b50df70874 100644 --- a/sound/firewire/motu/motu-pcm.c +++ b/sound/firewire/motu/motu-pcm.c | |||
@@ -96,18 +96,6 @@ static void limit_channels_and_rates(struct snd_motu *motu, | |||
96 | snd_pcm_limit_hw_rates(runtime); | 96 | snd_pcm_limit_hw_rates(runtime); |
97 | } | 97 | } |
98 | 98 | ||
99 | static void limit_period_and_buffer(struct snd_pcm_hardware *hw) | ||
100 | { | ||
101 | hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ | ||
102 | hw->periods_max = UINT_MAX; | ||
103 | |||
104 | hw->period_bytes_min = 4 * hw->channels_max; /* byte for a frame */ | ||
105 | |||
106 | /* Just to prevent from allocating much pages. */ | ||
107 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
108 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
109 | } | ||
110 | |||
111 | static int init_hw_info(struct snd_motu *motu, | 99 | static int init_hw_info(struct snd_motu *motu, |
112 | struct snd_pcm_substream *substream) | 100 | struct snd_pcm_substream *substream) |
113 | { | 101 | { |
@@ -117,13 +105,6 @@ static int init_hw_info(struct snd_motu *motu, | |||
117 | struct snd_motu_packet_format *formats; | 105 | struct snd_motu_packet_format *formats; |
118 | int err; | 106 | int err; |
119 | 107 | ||
120 | hw->info = SNDRV_PCM_INFO_MMAP | | ||
121 | SNDRV_PCM_INFO_MMAP_VALID | | ||
122 | SNDRV_PCM_INFO_BATCH | | ||
123 | SNDRV_PCM_INFO_INTERLEAVED | | ||
124 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
125 | SNDRV_PCM_INFO_BLOCK_TRANSFER; | ||
126 | |||
127 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 108 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
128 | hw->formats = SNDRV_PCM_FMTBIT_S32; | 109 | hw->formats = SNDRV_PCM_FMTBIT_S32; |
129 | stream = &motu->tx_stream; | 110 | stream = &motu->tx_stream; |
@@ -135,7 +116,6 @@ static int init_hw_info(struct snd_motu *motu, | |||
135 | } | 116 | } |
136 | 117 | ||
137 | limit_channels_and_rates(motu, runtime, formats); | 118 | limit_channels_and_rates(motu, runtime, formats); |
138 | limit_period_and_buffer(hw); | ||
139 | 119 | ||
140 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 120 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
141 | motu_rate_constraint, formats, | 121 | motu_rate_constraint, formats, |
@@ -356,6 +336,20 @@ static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream) | |||
356 | return amdtp_stream_pcm_pointer(&motu->rx_stream); | 336 | return amdtp_stream_pcm_pointer(&motu->rx_stream); |
357 | } | 337 | } |
358 | 338 | ||
339 | static int capture_ack(struct snd_pcm_substream *substream) | ||
340 | { | ||
341 | struct snd_motu *motu = substream->private_data; | ||
342 | |||
343 | return amdtp_stream_pcm_ack(&motu->tx_stream); | ||
344 | } | ||
345 | |||
346 | static int playback_ack(struct snd_pcm_substream *substream) | ||
347 | { | ||
348 | struct snd_motu *motu = substream->private_data; | ||
349 | |||
350 | return amdtp_stream_pcm_ack(&motu->rx_stream); | ||
351 | } | ||
352 | |||
359 | int snd_motu_create_pcm_devices(struct snd_motu *motu) | 353 | int snd_motu_create_pcm_devices(struct snd_motu *motu) |
360 | { | 354 | { |
361 | static struct snd_pcm_ops capture_ops = { | 355 | static struct snd_pcm_ops capture_ops = { |
@@ -367,6 +361,7 @@ int snd_motu_create_pcm_devices(struct snd_motu *motu) | |||
367 | .prepare = capture_prepare, | 361 | .prepare = capture_prepare, |
368 | .trigger = capture_trigger, | 362 | .trigger = capture_trigger, |
369 | .pointer = capture_pointer, | 363 | .pointer = capture_pointer, |
364 | .ack = capture_ack, | ||
370 | .page = snd_pcm_lib_get_vmalloc_page, | 365 | .page = snd_pcm_lib_get_vmalloc_page, |
371 | .mmap = snd_pcm_lib_mmap_vmalloc, | 366 | .mmap = snd_pcm_lib_mmap_vmalloc, |
372 | }; | 367 | }; |
@@ -379,6 +374,7 @@ int snd_motu_create_pcm_devices(struct snd_motu *motu) | |||
379 | .prepare = playback_prepare, | 374 | .prepare = playback_prepare, |
380 | .trigger = playback_trigger, | 375 | .trigger = playback_trigger, |
381 | .pointer = playback_pointer, | 376 | .pointer = playback_pointer, |
377 | .ack = playback_ack, | ||
382 | .page = snd_pcm_lib_get_vmalloc_page, | 378 | .page = snd_pcm_lib_get_vmalloc_page, |
383 | .mmap = snd_pcm_lib_mmap_vmalloc, | 379 | .mmap = snd_pcm_lib_mmap_vmalloc, |
384 | }; | 380 | }; |
diff --git a/sound/firewire/oxfw/oxfw-pcm.c b/sound/firewire/oxfw/oxfw-pcm.c index f3530f89a025..3dd46285c0e2 100644 --- a/sound/firewire/oxfw/oxfw-pcm.c +++ b/sound/firewire/oxfw/oxfw-pcm.c | |||
@@ -106,18 +106,6 @@ static void limit_channels_and_rates(struct snd_pcm_hardware *hw, u8 **formats) | |||
106 | } | 106 | } |
107 | } | 107 | } |
108 | 108 | ||
109 | static void limit_period_and_buffer(struct snd_pcm_hardware *hw) | ||
110 | { | ||
111 | hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ | ||
112 | hw->periods_max = UINT_MAX; | ||
113 | |||
114 | hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */ | ||
115 | |||
116 | /* Just to prevent from allocating much pages. */ | ||
117 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
118 | hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; | ||
119 | } | ||
120 | |||
121 | static int init_hw_params(struct snd_oxfw *oxfw, | 109 | static int init_hw_params(struct snd_oxfw *oxfw, |
122 | struct snd_pcm_substream *substream) | 110 | struct snd_pcm_substream *substream) |
123 | { | 111 | { |
@@ -126,13 +114,6 @@ static int init_hw_params(struct snd_oxfw *oxfw, | |||
126 | struct amdtp_stream *stream; | 114 | struct amdtp_stream *stream; |
127 | int err; | 115 | int err; |
128 | 116 | ||
129 | runtime->hw.info = SNDRV_PCM_INFO_BATCH | | ||
130 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
131 | SNDRV_PCM_INFO_INTERLEAVED | | ||
132 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
133 | SNDRV_PCM_INFO_MMAP | | ||
134 | SNDRV_PCM_INFO_MMAP_VALID; | ||
135 | |||
136 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 117 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
137 | runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS; | 118 | runtime->hw.formats = AM824_IN_PCM_FORMAT_BITS; |
138 | stream = &oxfw->tx_stream; | 119 | stream = &oxfw->tx_stream; |
@@ -144,7 +125,6 @@ static int init_hw_params(struct snd_oxfw *oxfw, | |||
144 | } | 125 | } |
145 | 126 | ||
146 | limit_channels_and_rates(&runtime->hw, formats); | 127 | limit_channels_and_rates(&runtime->hw, formats); |
147 | limit_period_and_buffer(&runtime->hw); | ||
148 | 128 | ||
149 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 129 | err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
150 | hw_rule_channels, formats, | 130 | hw_rule_channels, formats, |
@@ -244,8 +224,6 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream, | |||
244 | mutex_unlock(&oxfw->mutex); | 224 | mutex_unlock(&oxfw->mutex); |
245 | } | 225 | } |
246 | 226 | ||
247 | amdtp_am824_set_pcm_format(&oxfw->tx_stream, params_format(hw_params)); | ||
248 | |||
249 | return 0; | 227 | return 0; |
250 | } | 228 | } |
251 | static int pcm_playback_hw_params(struct snd_pcm_substream *substream, | 229 | static int pcm_playback_hw_params(struct snd_pcm_substream *substream, |
@@ -265,8 +243,6 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream, | |||
265 | mutex_unlock(&oxfw->mutex); | 243 | mutex_unlock(&oxfw->mutex); |
266 | } | 244 | } |
267 | 245 | ||
268 | amdtp_am824_set_pcm_format(&oxfw->rx_stream, params_format(hw_params)); | ||
269 | |||
270 | return 0; | 246 | return 0; |
271 | } | 247 | } |
272 | 248 | ||
@@ -386,6 +362,20 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstm) | |||
386 | return amdtp_stream_pcm_pointer(&oxfw->rx_stream); | 362 | return amdtp_stream_pcm_pointer(&oxfw->rx_stream); |
387 | } | 363 | } |
388 | 364 | ||
365 | static int pcm_capture_ack(struct snd_pcm_substream *substream) | ||
366 | { | ||
367 | struct snd_oxfw *oxfw = substream->private_data; | ||
368 | |||
369 | return amdtp_stream_pcm_ack(&oxfw->tx_stream); | ||
370 | } | ||
371 | |||
372 | static int pcm_playback_ack(struct snd_pcm_substream *substream) | ||
373 | { | ||
374 | struct snd_oxfw *oxfw = substream->private_data; | ||
375 | |||
376 | return amdtp_stream_pcm_ack(&oxfw->rx_stream); | ||
377 | } | ||
378 | |||
389 | int snd_oxfw_create_pcm(struct snd_oxfw *oxfw) | 379 | int snd_oxfw_create_pcm(struct snd_oxfw *oxfw) |
390 | { | 380 | { |
391 | static const struct snd_pcm_ops capture_ops = { | 381 | static const struct snd_pcm_ops capture_ops = { |
@@ -397,6 +387,7 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw) | |||
397 | .prepare = pcm_capture_prepare, | 387 | .prepare = pcm_capture_prepare, |
398 | .trigger = pcm_capture_trigger, | 388 | .trigger = pcm_capture_trigger, |
399 | .pointer = pcm_capture_pointer, | 389 | .pointer = pcm_capture_pointer, |
390 | .ack = pcm_capture_ack, | ||
400 | .page = snd_pcm_lib_get_vmalloc_page, | 391 | .page = snd_pcm_lib_get_vmalloc_page, |
401 | .mmap = snd_pcm_lib_mmap_vmalloc, | 392 | .mmap = snd_pcm_lib_mmap_vmalloc, |
402 | }; | 393 | }; |
@@ -409,6 +400,7 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw) | |||
409 | .prepare = pcm_playback_prepare, | 400 | .prepare = pcm_playback_prepare, |
410 | .trigger = pcm_playback_trigger, | 401 | .trigger = pcm_playback_trigger, |
411 | .pointer = pcm_playback_pointer, | 402 | .pointer = pcm_playback_pointer, |
403 | .ack = pcm_playback_ack, | ||
412 | .page = snd_pcm_lib_get_vmalloc_page, | 404 | .page = snd_pcm_lib_get_vmalloc_page, |
413 | .mmap = snd_pcm_lib_mmap_vmalloc, | 405 | .mmap = snd_pcm_lib_mmap_vmalloc, |
414 | }; | 406 | }; |
diff --git a/sound/firewire/tascam/amdtp-tascam.c b/sound/firewire/tascam/amdtp-tascam.c index 9dd0fccd5ccc..6aff1fc1c72d 100644 --- a/sound/firewire/tascam/amdtp-tascam.c +++ b/sound/firewire/tascam/amdtp-tascam.c | |||
@@ -14,10 +14,6 @@ | |||
14 | 14 | ||
15 | struct amdtp_tscm { | 15 | struct amdtp_tscm { |
16 | unsigned int pcm_channels; | 16 | unsigned int pcm_channels; |
17 | |||
18 | void (*transfer_samples)(struct amdtp_stream *s, | ||
19 | struct snd_pcm_substream *pcm, | ||
20 | __be32 *buffer, unsigned int frames); | ||
21 | }; | 17 | }; |
22 | 18 | ||
23 | int amdtp_tscm_set_parameters(struct amdtp_stream *s, unsigned int rate) | 19 | int amdtp_tscm_set_parameters(struct amdtp_stream *s, unsigned int rate) |
@@ -62,31 +58,6 @@ static void write_pcm_s32(struct amdtp_stream *s, | |||
62 | } | 58 | } |
63 | } | 59 | } |
64 | 60 | ||
65 | static void write_pcm_s16(struct amdtp_stream *s, | ||
66 | struct snd_pcm_substream *pcm, | ||
67 | __be32 *buffer, unsigned int frames) | ||
68 | { | ||
69 | struct amdtp_tscm *p = s->protocol; | ||
70 | struct snd_pcm_runtime *runtime = pcm->runtime; | ||
71 | unsigned int channels, remaining_frames, i, c; | ||
72 | const u16 *src; | ||
73 | |||
74 | channels = p->pcm_channels; | ||
75 | src = (void *)runtime->dma_area + | ||
76 | frames_to_bytes(runtime, s->pcm_buffer_pointer); | ||
77 | remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; | ||
78 | |||
79 | for (i = 0; i < frames; ++i) { | ||
80 | for (c = 0; c < channels; ++c) { | ||
81 | buffer[c] = cpu_to_be32(*src << 16); | ||
82 | src++; | ||
83 | } | ||
84 | buffer += s->data_block_quadlets; | ||
85 | if (--remaining_frames == 0) | ||
86 | src = (void *)runtime->dma_area; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static void read_pcm_s32(struct amdtp_stream *s, | 61 | static void read_pcm_s32(struct amdtp_stream *s, |
91 | struct snd_pcm_substream *pcm, | 62 | struct snd_pcm_substream *pcm, |
92 | __be32 *buffer, unsigned int frames) | 63 | __be32 *buffer, unsigned int frames) |
@@ -146,44 +117,16 @@ int amdtp_tscm_add_pcm_hw_constraints(struct amdtp_stream *s, | |||
146 | return amdtp_stream_add_pcm_hw_constraints(s, runtime); | 117 | return amdtp_stream_add_pcm_hw_constraints(s, runtime); |
147 | } | 118 | } |
148 | 119 | ||
149 | void amdtp_tscm_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format) | ||
150 | { | ||
151 | struct amdtp_tscm *p = s->protocol; | ||
152 | |||
153 | if (WARN_ON(amdtp_stream_pcm_running(s))) | ||
154 | return; | ||
155 | |||
156 | switch (format) { | ||
157 | default: | ||
158 | WARN_ON(1); | ||
159 | /* fall through */ | ||
160 | case SNDRV_PCM_FORMAT_S16: | ||
161 | if (s->direction == AMDTP_OUT_STREAM) { | ||
162 | p->transfer_samples = write_pcm_s16; | ||
163 | break; | ||
164 | } | ||
165 | WARN_ON(1); | ||
166 | /* fall through */ | ||
167 | case SNDRV_PCM_FORMAT_S32: | ||
168 | if (s->direction == AMDTP_OUT_STREAM) | ||
169 | p->transfer_samples = write_pcm_s32; | ||
170 | else | ||
171 | p->transfer_samples = read_pcm_s32; | ||
172 | break; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | static unsigned int process_tx_data_blocks(struct amdtp_stream *s, | 120 | static unsigned int process_tx_data_blocks(struct amdtp_stream *s, |
177 | __be32 *buffer, | 121 | __be32 *buffer, |
178 | unsigned int data_blocks, | 122 | unsigned int data_blocks, |
179 | unsigned int *syt) | 123 | unsigned int *syt) |
180 | { | 124 | { |
181 | struct amdtp_tscm *p = (struct amdtp_tscm *)s->protocol; | ||
182 | struct snd_pcm_substream *pcm; | 125 | struct snd_pcm_substream *pcm; |
183 | 126 | ||
184 | pcm = ACCESS_ONCE(s->pcm); | 127 | pcm = ACCESS_ONCE(s->pcm); |
185 | if (data_blocks > 0 && pcm) | 128 | if (data_blocks > 0 && pcm) |
186 | p->transfer_samples(s, pcm, buffer, data_blocks); | 129 | read_pcm_s32(s, pcm, buffer, data_blocks); |
187 | 130 | ||
188 | /* A place holder for control messages. */ | 131 | /* A place holder for control messages. */ |
189 | 132 | ||
@@ -195,7 +138,6 @@ static unsigned int process_rx_data_blocks(struct amdtp_stream *s, | |||
195 | unsigned int data_blocks, | 138 | unsigned int data_blocks, |
196 | unsigned int *syt) | 139 | unsigned int *syt) |
197 | { | 140 | { |
198 | struct amdtp_tscm *p = (struct amdtp_tscm *)s->protocol; | ||
199 | struct snd_pcm_substream *pcm; | 141 | struct snd_pcm_substream *pcm; |
200 | 142 | ||
201 | /* This field is not used. */ | 143 | /* This field is not used. */ |
@@ -203,7 +145,7 @@ static unsigned int process_rx_data_blocks(struct amdtp_stream *s, | |||
203 | 145 | ||
204 | pcm = ACCESS_ONCE(s->pcm); | 146 | pcm = ACCESS_ONCE(s->pcm); |
205 | if (pcm) | 147 | if (pcm) |
206 | p->transfer_samples(s, pcm, buffer, data_blocks); | 148 | write_pcm_s32(s, pcm, buffer, data_blocks); |
207 | else | 149 | else |
208 | write_pcm_silence(s, buffer, data_blocks); | 150 | write_pcm_silence(s, buffer, data_blocks); |
209 | 151 | ||
diff --git a/sound/firewire/tascam/tascam-pcm.c b/sound/firewire/tascam/tascam-pcm.c index f5dd6ce6b6f1..6ec8ec634d4d 100644 --- a/sound/firewire/tascam/tascam-pcm.c +++ b/sound/firewire/tascam/tascam-pcm.c | |||
@@ -8,48 +8,20 @@ | |||
8 | 8 | ||
9 | #include "tascam.h" | 9 | #include "tascam.h" |
10 | 10 | ||
11 | static void set_buffer_params(struct snd_pcm_hardware *hw) | ||
12 | { | ||
13 | hw->period_bytes_min = 4 * hw->channels_min; | ||
14 | hw->period_bytes_max = hw->period_bytes_min * 2048; | ||
15 | hw->buffer_bytes_max = hw->period_bytes_max * 2; | ||
16 | |||
17 | hw->periods_min = 2; | ||
18 | hw->periods_max = UINT_MAX; | ||
19 | } | ||
20 | |||
21 | static int pcm_init_hw_params(struct snd_tscm *tscm, | 11 | static int pcm_init_hw_params(struct snd_tscm *tscm, |
22 | struct snd_pcm_substream *substream) | 12 | struct snd_pcm_substream *substream) |
23 | { | 13 | { |
24 | static const struct snd_pcm_hardware hardware = { | ||
25 | .info = SNDRV_PCM_INFO_BATCH | | ||
26 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
27 | SNDRV_PCM_INFO_INTERLEAVED | | ||
28 | SNDRV_PCM_INFO_JOINT_DUPLEX | | ||
29 | SNDRV_PCM_INFO_MMAP | | ||
30 | SNDRV_PCM_INFO_MMAP_VALID, | ||
31 | .rates = SNDRV_PCM_RATE_44100 | | ||
32 | SNDRV_PCM_RATE_48000 | | ||
33 | SNDRV_PCM_RATE_88200 | | ||
34 | SNDRV_PCM_RATE_96000, | ||
35 | .rate_min = 44100, | ||
36 | .rate_max = 96000, | ||
37 | .channels_min = 10, | ||
38 | .channels_max = 18, | ||
39 | }; | ||
40 | struct snd_pcm_runtime *runtime = substream->runtime; | 14 | struct snd_pcm_runtime *runtime = substream->runtime; |
15 | struct snd_pcm_hardware *hw = &runtime->hw; | ||
41 | struct amdtp_stream *stream; | 16 | struct amdtp_stream *stream; |
42 | unsigned int pcm_channels; | 17 | unsigned int pcm_channels; |
43 | 18 | ||
44 | runtime->hw = hardware; | ||
45 | |||
46 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 19 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
47 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; | 20 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; |
48 | stream = &tscm->tx_stream; | 21 | stream = &tscm->tx_stream; |
49 | pcm_channels = tscm->spec->pcm_capture_analog_channels; | 22 | pcm_channels = tscm->spec->pcm_capture_analog_channels; |
50 | } else { | 23 | } else { |
51 | runtime->hw.formats = | 24 | runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; |
52 | SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S32; | ||
53 | stream = &tscm->rx_stream; | 25 | stream = &tscm->rx_stream; |
54 | pcm_channels = tscm->spec->pcm_playback_analog_channels; | 26 | pcm_channels = tscm->spec->pcm_playback_analog_channels; |
55 | } | 27 | } |
@@ -60,7 +32,11 @@ static int pcm_init_hw_params(struct snd_tscm *tscm, | |||
60 | pcm_channels += 2; | 32 | pcm_channels += 2; |
61 | runtime->hw.channels_min = runtime->hw.channels_max = pcm_channels; | 33 | runtime->hw.channels_min = runtime->hw.channels_max = pcm_channels; |
62 | 34 | ||
63 | set_buffer_params(&runtime->hw); | 35 | hw->rates = SNDRV_PCM_RATE_44100 | |
36 | SNDRV_PCM_RATE_48000 | | ||
37 | SNDRV_PCM_RATE_88200 | | ||
38 | SNDRV_PCM_RATE_96000; | ||
39 | snd_pcm_limit_hw_rates(runtime); | ||
64 | 40 | ||
65 | return amdtp_tscm_add_pcm_hw_constraints(stream, runtime); | 41 | return amdtp_tscm_add_pcm_hw_constraints(stream, runtime); |
66 | } | 42 | } |
@@ -125,8 +101,6 @@ static int pcm_capture_hw_params(struct snd_pcm_substream *substream, | |||
125 | mutex_unlock(&tscm->mutex); | 101 | mutex_unlock(&tscm->mutex); |
126 | } | 102 | } |
127 | 103 | ||
128 | amdtp_tscm_set_pcm_format(&tscm->tx_stream, params_format(hw_params)); | ||
129 | |||
130 | return 0; | 104 | return 0; |
131 | } | 105 | } |
132 | 106 | ||
@@ -147,8 +121,6 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream, | |||
147 | mutex_unlock(&tscm->mutex); | 121 | mutex_unlock(&tscm->mutex); |
148 | } | 122 | } |
149 | 123 | ||
150 | amdtp_tscm_set_pcm_format(&tscm->rx_stream, params_format(hw_params)); | ||
151 | |||
152 | return 0; | 124 | return 0; |
153 | } | 125 | } |
154 | 126 | ||
@@ -268,6 +240,20 @@ static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) | |||
268 | return amdtp_stream_pcm_pointer(&tscm->rx_stream); | 240 | return amdtp_stream_pcm_pointer(&tscm->rx_stream); |
269 | } | 241 | } |
270 | 242 | ||
243 | static int pcm_capture_ack(struct snd_pcm_substream *substream) | ||
244 | { | ||
245 | struct snd_tscm *tscm = substream->private_data; | ||
246 | |||
247 | return amdtp_stream_pcm_ack(&tscm->tx_stream); | ||
248 | } | ||
249 | |||
250 | static int pcm_playback_ack(struct snd_pcm_substream *substream) | ||
251 | { | ||
252 | struct snd_tscm *tscm = substream->private_data; | ||
253 | |||
254 | return amdtp_stream_pcm_ack(&tscm->rx_stream); | ||
255 | } | ||
256 | |||
271 | int snd_tscm_create_pcm_devices(struct snd_tscm *tscm) | 257 | int snd_tscm_create_pcm_devices(struct snd_tscm *tscm) |
272 | { | 258 | { |
273 | static const struct snd_pcm_ops capture_ops = { | 259 | static const struct snd_pcm_ops capture_ops = { |
@@ -279,6 +265,7 @@ int snd_tscm_create_pcm_devices(struct snd_tscm *tscm) | |||
279 | .prepare = pcm_capture_prepare, | 265 | .prepare = pcm_capture_prepare, |
280 | .trigger = pcm_capture_trigger, | 266 | .trigger = pcm_capture_trigger, |
281 | .pointer = pcm_capture_pointer, | 267 | .pointer = pcm_capture_pointer, |
268 | .ack = pcm_capture_ack, | ||
282 | .page = snd_pcm_lib_get_vmalloc_page, | 269 | .page = snd_pcm_lib_get_vmalloc_page, |
283 | }; | 270 | }; |
284 | static const struct snd_pcm_ops playback_ops = { | 271 | static const struct snd_pcm_ops playback_ops = { |
@@ -290,6 +277,7 @@ int snd_tscm_create_pcm_devices(struct snd_tscm *tscm) | |||
290 | .prepare = pcm_playback_prepare, | 277 | .prepare = pcm_playback_prepare, |
291 | .trigger = pcm_playback_trigger, | 278 | .trigger = pcm_playback_trigger, |
292 | .pointer = pcm_playback_pointer, | 279 | .pointer = pcm_playback_pointer, |
280 | .ack = pcm_playback_ack, | ||
293 | .page = snd_pcm_lib_get_vmalloc_page, | 281 | .page = snd_pcm_lib_get_vmalloc_page, |
294 | .mmap = snd_pcm_lib_mmap_vmalloc, | 282 | .mmap = snd_pcm_lib_mmap_vmalloc, |
295 | }; | 283 | }; |
diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h index 08ecfae5c584..a5bd167eb5d9 100644 --- a/sound/firewire/tascam/tascam.h +++ b/sound/firewire/tascam/tascam.h | |||
@@ -131,7 +131,6 @@ int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit, | |||
131 | int amdtp_tscm_set_parameters(struct amdtp_stream *s, unsigned int rate); | 131 | int amdtp_tscm_set_parameters(struct amdtp_stream *s, unsigned int rate); |
132 | int amdtp_tscm_add_pcm_hw_constraints(struct amdtp_stream *s, | 132 | int amdtp_tscm_add_pcm_hw_constraints(struct amdtp_stream *s, |
133 | struct snd_pcm_runtime *runtime); | 133 | struct snd_pcm_runtime *runtime); |
134 | void amdtp_tscm_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format); | ||
135 | 134 | ||
136 | int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate); | 135 | int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate); |
137 | int snd_tscm_stream_get_clock(struct snd_tscm *tscm, | 136 | int snd_tscm_stream_get_clock(struct snd_tscm *tscm, |
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c index 2183e9ebaa6d..4099e6062d3c 100644 --- a/sound/i2c/other/ak4113.c +++ b/sound/i2c/other/ak4113.c | |||
@@ -199,12 +199,11 @@ static int snd_ak4113_in_error_get(struct snd_kcontrol *kcontrol, | |||
199 | struct snd_ctl_elem_value *ucontrol) | 199 | struct snd_ctl_elem_value *ucontrol) |
200 | { | 200 | { |
201 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); | 201 | struct ak4113 *chip = snd_kcontrol_chip(kcontrol); |
202 | long *ptr; | ||
203 | 202 | ||
204 | spin_lock_irq(&chip->lock); | 203 | spin_lock_irq(&chip->lock); |
205 | ptr = (long *)(((char *)chip) + kcontrol->private_value); | 204 | ucontrol->value.integer.value[0] = |
206 | ucontrol->value.integer.value[0] = *ptr; | 205 | chip->errors[kcontrol->private_value]; |
207 | *ptr = 0; | 206 | chip->errors[kcontrol->private_value] = 0; |
208 | spin_unlock_irq(&chip->lock); | 207 | spin_unlock_irq(&chip->lock); |
209 | return 0; | 208 | return 0; |
210 | } | 209 | } |
@@ -373,7 +372,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { | |||
373 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 372 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
374 | .info = snd_ak4113_in_error_info, | 373 | .info = snd_ak4113_in_error_info, |
375 | .get = snd_ak4113_in_error_get, | 374 | .get = snd_ak4113_in_error_get, |
376 | .private_value = offsetof(struct ak4113, parity_errors), | 375 | .private_value = AK4113_PARITY_ERRORS, |
377 | }, | 376 | }, |
378 | { | 377 | { |
379 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 378 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -382,7 +381,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { | |||
382 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 381 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
383 | .info = snd_ak4113_in_error_info, | 382 | .info = snd_ak4113_in_error_info, |
384 | .get = snd_ak4113_in_error_get, | 383 | .get = snd_ak4113_in_error_get, |
385 | .private_value = offsetof(struct ak4113, v_bit_errors), | 384 | .private_value = AK4113_V_BIT_ERRORS, |
386 | }, | 385 | }, |
387 | { | 386 | { |
388 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 387 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -391,7 +390,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { | |||
391 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 390 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
392 | .info = snd_ak4113_in_error_info, | 391 | .info = snd_ak4113_in_error_info, |
393 | .get = snd_ak4113_in_error_get, | 392 | .get = snd_ak4113_in_error_get, |
394 | .private_value = offsetof(struct ak4113, ccrc_errors), | 393 | .private_value = AK4113_CCRC_ERRORS, |
395 | }, | 394 | }, |
396 | { | 395 | { |
397 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 396 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -400,7 +399,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { | |||
400 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 399 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
401 | .info = snd_ak4113_in_error_info, | 400 | .info = snd_ak4113_in_error_info, |
402 | .get = snd_ak4113_in_error_get, | 401 | .get = snd_ak4113_in_error_get, |
403 | .private_value = offsetof(struct ak4113, qcrc_errors), | 402 | .private_value = AK4113_QCRC_ERRORS, |
404 | }, | 403 | }, |
405 | { | 404 | { |
406 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 405 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -551,13 +550,13 @@ int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags) | |||
551 | rcs2 = reg_read(ak4113, AK4113_REG_RCS2); | 550 | rcs2 = reg_read(ak4113, AK4113_REG_RCS2); |
552 | spin_lock_irqsave(&ak4113->lock, _flags); | 551 | spin_lock_irqsave(&ak4113->lock, _flags); |
553 | if (rcs0 & AK4113_PAR) | 552 | if (rcs0 & AK4113_PAR) |
554 | ak4113->parity_errors++; | 553 | ak4113->errors[AK4113_PARITY_ERRORS]++; |
555 | if (rcs0 & AK4113_V) | 554 | if (rcs0 & AK4113_V) |
556 | ak4113->v_bit_errors++; | 555 | ak4113->errors[AK4113_V_BIT_ERRORS]++; |
557 | if (rcs2 & AK4113_CCRC) | 556 | if (rcs2 & AK4113_CCRC) |
558 | ak4113->ccrc_errors++; | 557 | ak4113->errors[AK4113_CCRC_ERRORS]++; |
559 | if (rcs2 & AK4113_QCRC) | 558 | if (rcs2 & AK4113_QCRC) |
560 | ak4113->qcrc_errors++; | 559 | ak4113->errors[AK4113_QCRC_ERRORS]++; |
561 | c0 = (ak4113->rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC | | 560 | c0 = (ak4113->rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC | |
562 | AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)) ^ | 561 | AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)) ^ |
563 | (rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC | | 562 | (rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC | |
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c index d53c9bb36281..7fb1aeb46915 100644 --- a/sound/i2c/other/ak4114.c +++ b/sound/i2c/other/ak4114.c | |||
@@ -194,12 +194,11 @@ static int snd_ak4114_in_error_get(struct snd_kcontrol *kcontrol, | |||
194 | struct snd_ctl_elem_value *ucontrol) | 194 | struct snd_ctl_elem_value *ucontrol) |
195 | { | 195 | { |
196 | struct ak4114 *chip = snd_kcontrol_chip(kcontrol); | 196 | struct ak4114 *chip = snd_kcontrol_chip(kcontrol); |
197 | long *ptr; | ||
198 | 197 | ||
199 | spin_lock_irq(&chip->lock); | 198 | spin_lock_irq(&chip->lock); |
200 | ptr = (long *)(((char *)chip) + kcontrol->private_value); | 199 | ucontrol->value.integer.value[0] = |
201 | ucontrol->value.integer.value[0] = *ptr; | 200 | chip->errors[kcontrol->private_value]; |
202 | *ptr = 0; | 201 | chip->errors[kcontrol->private_value] = 0; |
203 | spin_unlock_irq(&chip->lock); | 202 | spin_unlock_irq(&chip->lock); |
204 | return 0; | 203 | return 0; |
205 | } | 204 | } |
@@ -341,7 +340,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { | |||
341 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 340 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
342 | .info = snd_ak4114_in_error_info, | 341 | .info = snd_ak4114_in_error_info, |
343 | .get = snd_ak4114_in_error_get, | 342 | .get = snd_ak4114_in_error_get, |
344 | .private_value = offsetof(struct ak4114, parity_errors), | 343 | .private_value = AK4114_PARITY_ERRORS, |
345 | }, | 344 | }, |
346 | { | 345 | { |
347 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 346 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -349,7 +348,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { | |||
349 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 348 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
350 | .info = snd_ak4114_in_error_info, | 349 | .info = snd_ak4114_in_error_info, |
351 | .get = snd_ak4114_in_error_get, | 350 | .get = snd_ak4114_in_error_get, |
352 | .private_value = offsetof(struct ak4114, v_bit_errors), | 351 | .private_value = AK4114_V_BIT_ERRORS, |
353 | }, | 352 | }, |
354 | { | 353 | { |
355 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 354 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -357,7 +356,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { | |||
357 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 356 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
358 | .info = snd_ak4114_in_error_info, | 357 | .info = snd_ak4114_in_error_info, |
359 | .get = snd_ak4114_in_error_get, | 358 | .get = snd_ak4114_in_error_get, |
360 | .private_value = offsetof(struct ak4114, ccrc_errors), | 359 | .private_value = AK4114_CCRC_ERRORS, |
361 | }, | 360 | }, |
362 | { | 361 | { |
363 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 362 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -365,7 +364,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { | |||
365 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 364 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
366 | .info = snd_ak4114_in_error_info, | 365 | .info = snd_ak4114_in_error_info, |
367 | .get = snd_ak4114_in_error_get, | 366 | .get = snd_ak4114_in_error_get, |
368 | .private_value = offsetof(struct ak4114, qcrc_errors), | 367 | .private_value = AK4114_QCRC_ERRORS, |
369 | }, | 368 | }, |
370 | { | 369 | { |
371 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 370 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -581,13 +580,13 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags) | |||
581 | rcs0 = reg_read(ak4114, AK4114_REG_RCS0); | 580 | rcs0 = reg_read(ak4114, AK4114_REG_RCS0); |
582 | spin_lock_irqsave(&ak4114->lock, _flags); | 581 | spin_lock_irqsave(&ak4114->lock, _flags); |
583 | if (rcs0 & AK4114_PAR) | 582 | if (rcs0 & AK4114_PAR) |
584 | ak4114->parity_errors++; | 583 | ak4114->errors[AK4114_PARITY_ERRORS]++; |
585 | if (rcs1 & AK4114_V) | 584 | if (rcs1 & AK4114_V) |
586 | ak4114->v_bit_errors++; | 585 | ak4114->errors[AK4114_V_BIT_ERRORS]++; |
587 | if (rcs1 & AK4114_CCRC) | 586 | if (rcs1 & AK4114_CCRC) |
588 | ak4114->ccrc_errors++; | 587 | ak4114->errors[AK4114_CCRC_ERRORS]++; |
589 | if (rcs1 & AK4114_QCRC) | 588 | if (rcs1 & AK4114_QCRC) |
590 | ak4114->qcrc_errors++; | 589 | ak4114->errors[AK4114_QCRC_ERRORS]++; |
591 | c0 = (ak4114->rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)) ^ | 590 | c0 = (ak4114->rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)) ^ |
592 | (rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)); | 591 | (rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)); |
593 | c1 = (ak4114->rcs1 & 0xf0) ^ (rcs1 & 0xf0); | 592 | c1 = (ak4114->rcs1 & 0xf0) ^ (rcs1 & 0xf0); |
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c index 0702f0552d19..3ab099fb8c15 100644 --- a/sound/i2c/other/ak4117.c +++ b/sound/i2c/other/ak4117.c | |||
@@ -168,12 +168,11 @@ static int snd_ak4117_in_error_get(struct snd_kcontrol *kcontrol, | |||
168 | struct snd_ctl_elem_value *ucontrol) | 168 | struct snd_ctl_elem_value *ucontrol) |
169 | { | 169 | { |
170 | struct ak4117 *chip = snd_kcontrol_chip(kcontrol); | 170 | struct ak4117 *chip = snd_kcontrol_chip(kcontrol); |
171 | long *ptr; | ||
172 | 171 | ||
173 | spin_lock_irq(&chip->lock); | 172 | spin_lock_irq(&chip->lock); |
174 | ptr = (long *)(((char *)chip) + kcontrol->private_value); | 173 | ucontrol->value.integer.value[0] = |
175 | ucontrol->value.integer.value[0] = *ptr; | 174 | chip->errors[kcontrol->private_value]; |
176 | *ptr = 0; | 175 | chip->errors[kcontrol->private_value] = 0; |
177 | spin_unlock_irq(&chip->lock); | 176 | spin_unlock_irq(&chip->lock); |
178 | return 0; | 177 | return 0; |
179 | } | 178 | } |
@@ -328,7 +327,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { | |||
328 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 327 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
329 | .info = snd_ak4117_in_error_info, | 328 | .info = snd_ak4117_in_error_info, |
330 | .get = snd_ak4117_in_error_get, | 329 | .get = snd_ak4117_in_error_get, |
331 | .private_value = offsetof(struct ak4117, parity_errors), | 330 | .private_value = AK4117_PARITY_ERRORS, |
332 | }, | 331 | }, |
333 | { | 332 | { |
334 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 333 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -336,7 +335,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { | |||
336 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 335 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
337 | .info = snd_ak4117_in_error_info, | 336 | .info = snd_ak4117_in_error_info, |
338 | .get = snd_ak4117_in_error_get, | 337 | .get = snd_ak4117_in_error_get, |
339 | .private_value = offsetof(struct ak4117, v_bit_errors), | 338 | .private_value = AK4117_V_BIT_ERRORS, |
340 | }, | 339 | }, |
341 | { | 340 | { |
342 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 341 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -344,7 +343,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { | |||
344 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 343 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
345 | .info = snd_ak4117_in_error_info, | 344 | .info = snd_ak4117_in_error_info, |
346 | .get = snd_ak4117_in_error_get, | 345 | .get = snd_ak4117_in_error_get, |
347 | .private_value = offsetof(struct ak4117, ccrc_errors), | 346 | .private_value = AK4117_CCRC_ERRORS, |
348 | }, | 347 | }, |
349 | { | 348 | { |
350 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 349 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -352,7 +351,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { | |||
352 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 351 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
353 | .info = snd_ak4117_in_error_info, | 352 | .info = snd_ak4117_in_error_info, |
354 | .get = snd_ak4117_in_error_get, | 353 | .get = snd_ak4117_in_error_get, |
355 | .private_value = offsetof(struct ak4117, qcrc_errors), | 354 | .private_value = AK4117_QCRC_ERRORS, |
356 | }, | 355 | }, |
357 | { | 356 | { |
358 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 357 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
@@ -470,13 +469,13 @@ int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags) | |||
470 | // printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2); | 469 | // printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2); |
471 | spin_lock_irqsave(&ak4117->lock, _flags); | 470 | spin_lock_irqsave(&ak4117->lock, _flags); |
472 | if (rcs0 & AK4117_PAR) | 471 | if (rcs0 & AK4117_PAR) |
473 | ak4117->parity_errors++; | 472 | ak4117->errors[AK4117_PARITY_ERRORS]++; |
474 | if (rcs0 & AK4117_V) | 473 | if (rcs0 & AK4117_V) |
475 | ak4117->v_bit_errors++; | 474 | ak4117->errors[AK4117_V_BIT_ERRORS]++; |
476 | if (rcs2 & AK4117_CCRC) | 475 | if (rcs2 & AK4117_CCRC) |
477 | ak4117->ccrc_errors++; | 476 | ak4117->errors[AK4117_CCRC_ERRORS]++; |
478 | if (rcs2 & AK4117_QCRC) | 477 | if (rcs2 & AK4117_QCRC) |
479 | ak4117->qcrc_errors++; | 478 | ak4117->errors[AK4117_QCRC_ERRORS]++; |
480 | c0 = (ak4117->rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)) ^ | 479 | c0 = (ak4117->rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)) ^ |
481 | (rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)); | 480 | (rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)); |
482 | c1 = (ak4117->rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)) ^ | 481 | c1 = (ak4117->rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)) ^ |
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 37adcc6cbe6b..cb54d9c0a77f 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig | |||
@@ -377,6 +377,7 @@ config SND_SBAWE | |||
377 | select SND_OPL3_LIB | 377 | select SND_OPL3_LIB |
378 | select SND_MPU401_UART | 378 | select SND_MPU401_UART |
379 | select SND_SB16_DSP | 379 | select SND_SB16_DSP |
380 | select SND_SEQ_DEVICE if SND_SEQUENCER != n | ||
380 | help | 381 | help |
381 | Say Y here to include support for Sound Blaster AWE soundcards | 382 | Say Y here to include support for Sound Blaster AWE soundcards |
382 | (including the Plug and Play version). | 383 | (including the Plug and Play version). |
@@ -384,6 +385,13 @@ config SND_SBAWE | |||
384 | To compile this driver as a module, choose M here: the module | 385 | To compile this driver as a module, choose M here: the module |
385 | will be called snd-sbawe. | 386 | will be called snd-sbawe. |
386 | 387 | ||
388 | # select SEQ stuff to min(SND_SEQUENCER,SND_XXX) | ||
389 | config SND_SBAWE_SEQ | ||
390 | def_tristate SND_SEQUENCER && SND_SBAWE | ||
391 | select SND_SEQ_MIDI_EMUL | ||
392 | select SND_SEQ_VIRMIDI | ||
393 | select SND_SYNTH_EMUX | ||
394 | |||
387 | config SND_SB16_CSP | 395 | config SND_SB16_CSP |
388 | bool "Sound Blaster 16/AWE CSP support" | 396 | bool "Sound Blaster 16/AWE CSP support" |
389 | depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) | 397 | depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) |
diff --git a/sound/isa/cmi8328.c b/sound/isa/cmi8328.c index 8e1756c3b9bb..d09e456107ad 100644 --- a/sound/isa/cmi8328.c +++ b/sound/isa/cmi8328.c | |||
@@ -26,7 +26,7 @@ MODULE_AUTHOR("Ondrej Zary <linux@rainbow-software.org>"); | |||
26 | MODULE_DESCRIPTION("C-Media CMI8328"); | 26 | MODULE_DESCRIPTION("C-Media CMI8328"); |
27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
28 | 28 | ||
29 | #if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) | 29 | #if IS_ENABLED(CONFIG_GAMEPORT) |
30 | #define SUPPORT_JOYSTICK 1 | 30 | #define SUPPORT_JOYSTICK 1 |
31 | #endif | 31 | #endif |
32 | 32 | ||
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c index 2b7cc596f4c6..2012936f6756 100644 --- a/sound/isa/cs423x/cs4236_lib.c +++ b/sound/isa/cs423x/cs4236_lib.c | |||
@@ -138,7 +138,7 @@ static unsigned char snd_cs4236_ctrl_in(struct snd_wss *chip, unsigned char reg) | |||
138 | 138 | ||
139 | #define CLOCKS 8 | 139 | #define CLOCKS 8 |
140 | 140 | ||
141 | static struct snd_ratnum clocks[CLOCKS] = { | 141 | static const struct snd_ratnum clocks[CLOCKS] = { |
142 | { .num = 16934400, .den_min = 353, .den_max = 353, .den_step = 1 }, | 142 | { .num = 16934400, .den_min = 353, .den_max = 353, .den_step = 1 }, |
143 | { .num = 16934400, .den_min = 529, .den_max = 529, .den_step = 1 }, | 143 | { .num = 16934400, .den_min = 529, .den_max = 529, .den_step = 1 }, |
144 | { .num = 16934400, .den_min = 617, .den_max = 617, .den_step = 1 }, | 144 | { .num = 16934400, .den_min = 617, .den_max = 617, .den_step = 1 }, |
@@ -149,7 +149,7 @@ static struct snd_ratnum clocks[CLOCKS] = { | |||
149 | { .num = 16934400/16, .den_min = 21, .den_max = 192, .den_step = 1 } | 149 | { .num = 16934400/16, .den_min = 21, .den_max = 192, .den_step = 1 } |
150 | }; | 150 | }; |
151 | 151 | ||
152 | static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = { | 152 | static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = { |
153 | .nrats = CLOCKS, | 153 | .nrats = CLOCKS, |
154 | .rats = clocks, | 154 | .rats = clocks, |
155 | }; | 155 | }; |
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index 81cf26fa28d6..5d3df96c5e5b 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c | |||
@@ -290,7 +290,7 @@ static int snd_es1688_init(struct snd_es1688 * chip, int enable) | |||
290 | 290 | ||
291 | */ | 291 | */ |
292 | 292 | ||
293 | static struct snd_ratnum clocks[2] = { | 293 | static const struct snd_ratnum clocks[2] = { |
294 | { | 294 | { |
295 | .num = 795444, | 295 | .num = 795444, |
296 | .den_min = 1, | 296 | .den_min = 1, |
@@ -305,7 +305,7 @@ static struct snd_ratnum clocks[2] = { | |||
305 | } | 305 | } |
306 | }; | 306 | }; |
307 | 307 | ||
308 | static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = { | 308 | static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = { |
309 | .nrats = 2, | 309 | .nrats = 2, |
310 | .rats = clocks, | 310 | .rats = clocks, |
311 | }; | 311 | }; |
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 0cabe2b8974f..ae17a6584061 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -369,7 +369,7 @@ static int snd_es18xx_reset_fifo(struct snd_es18xx *chip) | |||
369 | return 0; | 369 | return 0; |
370 | } | 370 | } |
371 | 371 | ||
372 | static struct snd_ratnum new_clocks[2] = { | 372 | static const struct snd_ratnum new_clocks[2] = { |
373 | { | 373 | { |
374 | .num = 793800, | 374 | .num = 793800, |
375 | .den_min = 1, | 375 | .den_min = 1, |
@@ -384,12 +384,12 @@ static struct snd_ratnum new_clocks[2] = { | |||
384 | } | 384 | } |
385 | }; | 385 | }; |
386 | 386 | ||
387 | static struct snd_pcm_hw_constraint_ratnums new_hw_constraints_clocks = { | 387 | static const struct snd_pcm_hw_constraint_ratnums new_hw_constraints_clocks = { |
388 | .nrats = 2, | 388 | .nrats = 2, |
389 | .rats = new_clocks, | 389 | .rats = new_clocks, |
390 | }; | 390 | }; |
391 | 391 | ||
392 | static struct snd_ratnum old_clocks[2] = { | 392 | static const struct snd_ratnum old_clocks[2] = { |
393 | { | 393 | { |
394 | .num = 795444, | 394 | .num = 795444, |
395 | .den_min = 1, | 395 | .den_min = 1, |
@@ -404,7 +404,7 @@ static struct snd_ratnum old_clocks[2] = { | |||
404 | } | 404 | } |
405 | }; | 405 | }; |
406 | 406 | ||
407 | static struct snd_pcm_hw_constraint_ratnums old_hw_constraints_clocks = { | 407 | static const struct snd_pcm_hw_constraint_ratnums old_hw_constraints_clocks = { |
408 | .nrats = 2, | 408 | .nrats = 2, |
409 | .rats = old_clocks, | 409 | .rats = old_clocks, |
410 | }; | 410 | }; |
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index 4490ee442ff4..3cf9b13c780a 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c | |||
@@ -82,7 +82,7 @@ static int snd_gus_joystick_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
82 | return change; | 82 | return change; |
83 | } | 83 | } |
84 | 84 | ||
85 | static struct snd_kcontrol_new snd_gus_joystick_control = { | 85 | static const struct snd_kcontrol_new snd_gus_joystick_control = { |
86 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | 86 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, |
87 | .name = "Joystick Speed", | 87 | .name = "Joystick Speed", |
88 | .info = snd_gus_joystick_info, | 88 | .info = snd_gus_joystick_info, |
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index 06505999155f..6b3da01a93b7 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c | |||
@@ -61,8 +61,6 @@ struct gus_pcm_private { | |||
61 | int final_volume; | 61 | int final_volume; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | static int snd_gf1_pcm_use_dma = 1; | ||
65 | |||
66 | static void snd_gf1_pcm_block_change_ack(struct snd_gus_card * gus, void *private_data) | 64 | static void snd_gf1_pcm_block_change_ack(struct snd_gus_card * gus, void *private_data) |
67 | { | 65 | { |
68 | struct gus_pcm_private *pcmp = private_data; | 66 | struct gus_pcm_private *pcmp = private_data; |
@@ -355,66 +353,83 @@ static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf, | |||
355 | return 0; | 353 | return 0; |
356 | } | 354 | } |
357 | 355 | ||
358 | static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream, | 356 | static int get_bpos(struct gus_pcm_private *pcmp, int voice, unsigned int pos, |
359 | int voice, | 357 | unsigned int len) |
360 | snd_pcm_uframes_t pos, | ||
361 | void __user *src, | ||
362 | snd_pcm_uframes_t count) | ||
363 | { | 358 | { |
364 | struct snd_pcm_runtime *runtime = substream->runtime; | 359 | unsigned int bpos = pos + (voice * (pcmp->dma_size / 2)); |
365 | struct gus_pcm_private *pcmp = runtime->private_data; | ||
366 | unsigned int bpos, len; | ||
367 | |||
368 | bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2)); | ||
369 | len = samples_to_bytes(runtime, count); | ||
370 | if (snd_BUG_ON(bpos > pcmp->dma_size)) | 360 | if (snd_BUG_ON(bpos > pcmp->dma_size)) |
371 | return -EIO; | 361 | return -EIO; |
372 | if (snd_BUG_ON(bpos + len > pcmp->dma_size)) | 362 | if (snd_BUG_ON(bpos + len > pcmp->dma_size)) |
373 | return -EIO; | 363 | return -EIO; |
364 | return bpos; | ||
365 | } | ||
366 | |||
367 | static int playback_copy_ack(struct snd_pcm_substream *substream, | ||
368 | unsigned int bpos, unsigned int len) | ||
369 | { | ||
370 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
371 | struct gus_pcm_private *pcmp = runtime->private_data; | ||
372 | struct snd_gus_card *gus = pcmp->gus; | ||
373 | int w16, invert; | ||
374 | |||
375 | if (len > 32) | ||
376 | return snd_gf1_pcm_block_change(substream, bpos, | ||
377 | pcmp->memory + bpos, len); | ||
378 | |||
379 | w16 = (snd_pcm_format_width(runtime->format) == 16); | ||
380 | invert = snd_pcm_format_unsigned(runtime->format); | ||
381 | return snd_gf1_pcm_poke_block(gus, runtime->dma_area + bpos, | ||
382 | pcmp->memory + bpos, len, w16, invert); | ||
383 | } | ||
384 | |||
385 | static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream, | ||
386 | int voice, unsigned long pos, | ||
387 | void __user *src, unsigned long count) | ||
388 | { | ||
389 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
390 | struct gus_pcm_private *pcmp = runtime->private_data; | ||
391 | unsigned int len = count; | ||
392 | int bpos; | ||
393 | |||
394 | bpos = get_bpos(pcmp, voice, pos, len); | ||
395 | if (bpos < 0) | ||
396 | return pos; | ||
374 | if (copy_from_user(runtime->dma_area + bpos, src, len)) | 397 | if (copy_from_user(runtime->dma_area + bpos, src, len)) |
375 | return -EFAULT; | 398 | return -EFAULT; |
376 | if (snd_gf1_pcm_use_dma && len > 32) { | 399 | return playback_copy_ack(substream, bpos, len); |
377 | return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len); | 400 | } |
378 | } else { | ||
379 | struct snd_gus_card *gus = pcmp->gus; | ||
380 | int err, w16, invert; | ||
381 | 401 | ||
382 | w16 = (snd_pcm_format_width(runtime->format) == 16); | 402 | static int snd_gf1_pcm_playback_copy_kernel(struct snd_pcm_substream *substream, |
383 | invert = snd_pcm_format_unsigned(runtime->format); | 403 | int voice, unsigned long pos, |
384 | if ((err = snd_gf1_pcm_poke_block(gus, runtime->dma_area + bpos, pcmp->memory + bpos, len, w16, invert)) < 0) | 404 | void *src, unsigned long count) |
385 | return err; | 405 | { |
386 | } | 406 | struct snd_pcm_runtime *runtime = substream->runtime; |
387 | return 0; | 407 | struct gus_pcm_private *pcmp = runtime->private_data; |
408 | unsigned int len = count; | ||
409 | int bpos; | ||
410 | |||
411 | bpos = get_bpos(pcmp, voice, pos, len); | ||
412 | if (bpos < 0) | ||
413 | return pos; | ||
414 | memcpy(runtime->dma_area + bpos, src, len); | ||
415 | return playback_copy_ack(substream, bpos, len); | ||
388 | } | 416 | } |
389 | 417 | ||
390 | static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream, | 418 | static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream, |
391 | int voice, | 419 | int voice, unsigned long pos, |
392 | snd_pcm_uframes_t pos, | 420 | unsigned long count) |
393 | snd_pcm_uframes_t count) | ||
394 | { | 421 | { |
395 | struct snd_pcm_runtime *runtime = substream->runtime; | 422 | struct snd_pcm_runtime *runtime = substream->runtime; |
396 | struct gus_pcm_private *pcmp = runtime->private_data; | 423 | struct gus_pcm_private *pcmp = runtime->private_data; |
397 | unsigned int bpos, len; | 424 | unsigned int len = count; |
425 | int bpos; | ||
398 | 426 | ||
399 | bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2)); | 427 | bpos = get_bpos(pcmp, voice, pos, len); |
400 | len = samples_to_bytes(runtime, count); | 428 | if (bpos < 0) |
401 | if (snd_BUG_ON(bpos > pcmp->dma_size)) | 429 | return pos; |
402 | return -EIO; | 430 | snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos, |
403 | if (snd_BUG_ON(bpos + len > pcmp->dma_size)) | 431 | bytes_to_samples(runtime, count)); |
404 | return -EIO; | 432 | return playback_copy_ack(substream, bpos, len); |
405 | snd_pcm_format_set_silence(runtime->format, runtime->dma_area + bpos, count); | ||
406 | if (snd_gf1_pcm_use_dma && len > 32) { | ||
407 | return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len); | ||
408 | } else { | ||
409 | struct snd_gus_card *gus = pcmp->gus; | ||
410 | int err, w16, invert; | ||
411 | |||
412 | w16 = (snd_pcm_format_width(runtime->format) == 16); | ||
413 | invert = snd_pcm_format_unsigned(runtime->format); | ||
414 | if ((err = snd_gf1_pcm_poke_block(gus, runtime->dma_area + bpos, pcmp->memory + bpos, len, w16, invert)) < 0) | ||
415 | return err; | ||
416 | } | ||
417 | return 0; | ||
418 | } | 433 | } |
419 | 434 | ||
420 | static int snd_gf1_pcm_playback_hw_params(struct snd_pcm_substream *substream, | 435 | static int snd_gf1_pcm_playback_hw_params(struct snd_pcm_substream *substream, |
@@ -547,14 +562,14 @@ static snd_pcm_uframes_t snd_gf1_pcm_playback_pointer(struct snd_pcm_substream * | |||
547 | return pos; | 562 | return pos; |
548 | } | 563 | } |
549 | 564 | ||
550 | static struct snd_ratnum clock = { | 565 | static const struct snd_ratnum clock = { |
551 | .num = 9878400/16, | 566 | .num = 9878400/16, |
552 | .den_min = 2, | 567 | .den_min = 2, |
553 | .den_max = 257, | 568 | .den_max = 257, |
554 | .den_step = 1, | 569 | .den_step = 1, |
555 | }; | 570 | }; |
556 | 571 | ||
557 | static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = { | 572 | static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = { |
558 | .nrats = 1, | 573 | .nrats = 1, |
559 | .rats = &clock, | 574 | .rats = &clock, |
560 | }; | 575 | }; |
@@ -809,7 +824,7 @@ static int snd_gf1_pcm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
809 | return change; | 824 | return change; |
810 | } | 825 | } |
811 | 826 | ||
812 | static struct snd_kcontrol_new snd_gf1_pcm_volume_control = | 827 | static const struct snd_kcontrol_new snd_gf1_pcm_volume_control = |
813 | { | 828 | { |
814 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 829 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
815 | .name = "PCM Playback Volume", | 830 | .name = "PCM Playback Volume", |
@@ -818,7 +833,7 @@ static struct snd_kcontrol_new snd_gf1_pcm_volume_control = | |||
818 | .put = snd_gf1_pcm_volume_put | 833 | .put = snd_gf1_pcm_volume_put |
819 | }; | 834 | }; |
820 | 835 | ||
821 | static struct snd_kcontrol_new snd_gf1_pcm_volume_control1 = | 836 | static const struct snd_kcontrol_new snd_gf1_pcm_volume_control1 = |
822 | { | 837 | { |
823 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 838 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
824 | .name = "GPCM Playback Volume", | 839 | .name = "GPCM Playback Volume", |
@@ -836,8 +851,9 @@ static struct snd_pcm_ops snd_gf1_pcm_playback_ops = { | |||
836 | .prepare = snd_gf1_pcm_playback_prepare, | 851 | .prepare = snd_gf1_pcm_playback_prepare, |
837 | .trigger = snd_gf1_pcm_playback_trigger, | 852 | .trigger = snd_gf1_pcm_playback_trigger, |
838 | .pointer = snd_gf1_pcm_playback_pointer, | 853 | .pointer = snd_gf1_pcm_playback_pointer, |
839 | .copy = snd_gf1_pcm_playback_copy, | 854 | .copy_user = snd_gf1_pcm_playback_copy, |
840 | .silence = snd_gf1_pcm_playback_silence, | 855 | .copy_kernel = snd_gf1_pcm_playback_copy_kernel, |
856 | .fill_silence = snd_gf1_pcm_playback_silence, | ||
841 | }; | 857 | }; |
842 | 858 | ||
843 | static struct snd_pcm_ops snd_gf1_pcm_capture_ops = { | 859 | static struct snd_pcm_ops snd_gf1_pcm_capture_ops = { |
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c index ec180708f160..d56973b770c7 100644 --- a/sound/isa/sb/emu8000.c +++ b/sound/isa/sb/emu8000.c | |||
@@ -1138,7 +1138,7 @@ snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports, | |||
1138 | snd_emu8000_free(hw); | 1138 | snd_emu8000_free(hw); |
1139 | return err; | 1139 | return err; |
1140 | } | 1140 | } |
1141 | #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) | 1141 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
1142 | if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000, | 1142 | if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000, |
1143 | sizeof(struct snd_emu8000*), &awe) >= 0) { | 1143 | sizeof(struct snd_emu8000*), &awe) >= 0) { |
1144 | strcpy(awe->name, "EMU-8000"); | 1144 | strcpy(awe->name, "EMU-8000"); |
diff --git a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c index 72a9ac5efb40..d28d712f99f4 100644 --- a/sound/isa/sb/emu8000_callback.c +++ b/sound/isa/sb/emu8000_callback.c | |||
@@ -36,7 +36,7 @@ static void reset_voice(struct snd_emux *emu, int ch); | |||
36 | static void terminate_voice(struct snd_emux_voice *vp); | 36 | static void terminate_voice(struct snd_emux_voice *vp); |
37 | static void sysex(struct snd_emux *emu, char *buf, int len, int parsed, | 37 | static void sysex(struct snd_emux *emu, char *buf, int len, int parsed, |
38 | struct snd_midi_channel_set *chset); | 38 | struct snd_midi_channel_set *chset); |
39 | #ifdef CONFIG_SND_SEQUENCER_OSS | 39 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
40 | static int oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2); | 40 | static int oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2); |
41 | #endif | 41 | #endif |
42 | static int load_fx(struct snd_emux *emu, int type, int mode, | 42 | static int load_fx(struct snd_emux *emu, int type, int mode, |
@@ -76,7 +76,7 @@ static struct snd_emux_operators emu8000_ops = { | |||
76 | .sample_reset = snd_emu8000_sample_reset, | 76 | .sample_reset = snd_emu8000_sample_reset, |
77 | .load_fx = load_fx, | 77 | .load_fx = load_fx, |
78 | .sysex = sysex, | 78 | .sysex = sysex, |
79 | #ifdef CONFIG_SND_SEQUENCER_OSS | 79 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
80 | .oss_ioctl = oss_ioctl, | 80 | .oss_ioctl = oss_ioctl, |
81 | #endif | 81 | #endif |
82 | }; | 82 | }; |
@@ -477,7 +477,7 @@ sysex(struct snd_emux *emu, char *buf, int len, int parsed, struct snd_midi_chan | |||
477 | } | 477 | } |
478 | 478 | ||
479 | 479 | ||
480 | #ifdef CONFIG_SND_SEQUENCER_OSS | 480 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
481 | /* | 481 | /* |
482 | * OSS ioctl callback | 482 | * OSS ioctl callback |
483 | */ | 483 | */ |
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c index 32f234f494e5..2ee8d67871ec 100644 --- a/sound/isa/sb/emu8000_pcm.c +++ b/sound/isa/sb/emu8000_pcm.c | |||
@@ -422,143 +422,148 @@ do { \ | |||
422 | return -EAGAIN;\ | 422 | return -EAGAIN;\ |
423 | } while (0) | 423 | } while (0) |
424 | 424 | ||
425 | enum { | ||
426 | COPY_USER, COPY_KERNEL, FILL_SILENCE, | ||
427 | }; | ||
428 | |||
429 | #define GET_VAL(sval, buf, mode) \ | ||
430 | do { \ | ||
431 | switch (mode) { \ | ||
432 | case FILL_SILENCE: \ | ||
433 | sval = 0; \ | ||
434 | break; \ | ||
435 | case COPY_KERNEL: \ | ||
436 | sval = *buf++; \ | ||
437 | break; \ | ||
438 | default: \ | ||
439 | if (get_user(sval, (unsigned short __user *)buf)) \ | ||
440 | return -EFAULT; \ | ||
441 | buf++; \ | ||
442 | break; \ | ||
443 | } \ | ||
444 | } while (0) | ||
425 | 445 | ||
426 | #ifdef USE_NONINTERLEAVE | 446 | #ifdef USE_NONINTERLEAVE |
447 | |||
448 | #define LOOP_WRITE(rec, offset, _buf, count, mode) \ | ||
449 | do { \ | ||
450 | struct snd_emu8000 *emu = (rec)->emu; \ | ||
451 | unsigned short *buf = (unsigned short *)(_buf); \ | ||
452 | snd_emu8000_write_wait(emu, 1); \ | ||
453 | EMU8000_SMALW_WRITE(emu, offset); \ | ||
454 | while (count > 0) { \ | ||
455 | unsigned short sval; \ | ||
456 | CHECK_SCHEDULER(); \ | ||
457 | GET_VAL(sval, buf, mode); \ | ||
458 | EMU8000_SMLD_WRITE(emu, sval); \ | ||
459 | count--; \ | ||
460 | } \ | ||
461 | } while (0) | ||
462 | |||
427 | /* copy one channel block */ | 463 | /* copy one channel block */ |
428 | static int emu8k_transfer_block(struct snd_emu8000 *emu, int offset, unsigned short *buf, int count) | 464 | static int emu8k_pcm_copy(struct snd_pcm_substream *subs, |
465 | int voice, unsigned long pos, | ||
466 | void __user *src, unsigned long count) | ||
429 | { | 467 | { |
430 | EMU8000_SMALW_WRITE(emu, offset); | 468 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; |
431 | while (count > 0) { | 469 | |
432 | unsigned short sval; | 470 | /* convert to word unit */ |
433 | CHECK_SCHEDULER(); | 471 | pos = (pos << 1) + rec->loop_start[voice]; |
434 | if (get_user(sval, buf)) | 472 | count <<= 1; |
435 | return -EFAULT; | 473 | LOOP_WRITE(rec, pos, src, count, COPY_UESR); |
436 | EMU8000_SMLD_WRITE(emu, sval); | ||
437 | buf++; | ||
438 | count--; | ||
439 | } | ||
440 | return 0; | 474 | return 0; |
441 | } | 475 | } |
442 | 476 | ||
443 | static int emu8k_pcm_copy(struct snd_pcm_substream *subs, | 477 | static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs, |
444 | int voice, | 478 | int voice, unsigned long pos, |
445 | snd_pcm_uframes_t pos, | 479 | void *src, unsigned long count) |
446 | void *src, | ||
447 | snd_pcm_uframes_t count) | ||
448 | { | 480 | { |
449 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; | 481 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; |
450 | struct snd_emu8000 *emu = rec->emu; | ||
451 | |||
452 | snd_emu8000_write_wait(emu, 1); | ||
453 | if (voice == -1) { | ||
454 | unsigned short *buf = src; | ||
455 | int i, err; | ||
456 | count /= rec->voices; | ||
457 | for (i = 0; i < rec->voices; i++) { | ||
458 | err = emu8k_transfer_block(emu, pos + rec->loop_start[i], buf, count); | ||
459 | if (err < 0) | ||
460 | return err; | ||
461 | buf += count; | ||
462 | } | ||
463 | return 0; | ||
464 | } else { | ||
465 | return emu8k_transfer_block(emu, pos + rec->loop_start[voice], src, count); | ||
466 | } | ||
467 | } | ||
468 | 482 | ||
469 | /* make a channel block silence */ | 483 | /* convert to word unit */ |
470 | static int emu8k_silence_block(struct snd_emu8000 *emu, int offset, int count) | 484 | pos = (pos << 1) + rec->loop_start[voice]; |
471 | { | 485 | count <<= 1; |
472 | EMU8000_SMALW_WRITE(emu, offset); | 486 | LOOP_WRITE(rec, pos, src, count, COPY_KERNEL); |
473 | while (count > 0) { | ||
474 | CHECK_SCHEDULER(); | ||
475 | EMU8000_SMLD_WRITE(emu, 0); | ||
476 | count--; | ||
477 | } | ||
478 | return 0; | 487 | return 0; |
479 | } | 488 | } |
480 | 489 | ||
490 | /* make a channel block silence */ | ||
481 | static int emu8k_pcm_silence(struct snd_pcm_substream *subs, | 491 | static int emu8k_pcm_silence(struct snd_pcm_substream *subs, |
482 | int voice, | 492 | int voice, unsigned long pos, unsigned long count) |
483 | snd_pcm_uframes_t pos, | ||
484 | snd_pcm_uframes_t count) | ||
485 | { | 493 | { |
486 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; | 494 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; |
487 | struct snd_emu8000 *emu = rec->emu; | 495 | |
488 | 496 | /* convert to word unit */ | |
489 | snd_emu8000_write_wait(emu, 1); | 497 | pos = (pos << 1) + rec->loop_start[voice]; |
490 | if (voice == -1 && rec->voices == 1) | 498 | count <<= 1; |
491 | voice = 0; | 499 | LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE); |
492 | if (voice == -1) { | 500 | return 0; |
493 | int err; | ||
494 | err = emu8k_silence_block(emu, pos + rec->loop_start[0], count / 2); | ||
495 | if (err < 0) | ||
496 | return err; | ||
497 | return emu8k_silence_block(emu, pos + rec->loop_start[1], count / 2); | ||
498 | } else { | ||
499 | return emu8k_silence_block(emu, pos + rec->loop_start[voice], count); | ||
500 | } | ||
501 | } | 501 | } |
502 | 502 | ||
503 | #else /* interleave */ | 503 | #else /* interleave */ |
504 | 504 | ||
505 | #define LOOP_WRITE(rec, pos, _buf, count, mode) \ | ||
506 | do { \ | ||
507 | struct snd_emu8000 *emu = rec->emu; \ | ||
508 | unsigned short *buf = (unsigned short *)(_buf); \ | ||
509 | snd_emu8000_write_wait(emu, 1); \ | ||
510 | EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \ | ||
511 | if (rec->voices > 1) \ | ||
512 | EMU8000_SMARW_WRITE(emu, pos + rec->loop_start[1]); \ | ||
513 | while (count > 0) { \ | ||
514 | unsigned short sval; \ | ||
515 | CHECK_SCHEDULER(); \ | ||
516 | GET_VAL(sval, buf, mode); \ | ||
517 | EMU8000_SMLD_WRITE(emu, sval); \ | ||
518 | if (rec->voices > 1) { \ | ||
519 | CHECK_SCHEDULER(); \ | ||
520 | GET_VAL(sval, buf, mode); \ | ||
521 | EMU8000_SMRD_WRITE(emu, sval); \ | ||
522 | } \ | ||
523 | count--; \ | ||
524 | } \ | ||
525 | } while (0) | ||
526 | |||
527 | |||
505 | /* | 528 | /* |
506 | * copy the interleaved data can be done easily by using | 529 | * copy the interleaved data can be done easily by using |
507 | * DMA "left" and "right" channels on emu8k engine. | 530 | * DMA "left" and "right" channels on emu8k engine. |
508 | */ | 531 | */ |
509 | static int emu8k_pcm_copy(struct snd_pcm_substream *subs, | 532 | static int emu8k_pcm_copy(struct snd_pcm_substream *subs, |
510 | int voice, | 533 | int voice, unsigned long pos, |
511 | snd_pcm_uframes_t pos, | 534 | void __user *src, unsigned long count) |
512 | void __user *src, | ||
513 | snd_pcm_uframes_t count) | ||
514 | { | 535 | { |
515 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; | 536 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; |
516 | struct snd_emu8000 *emu = rec->emu; | ||
517 | unsigned short __user *buf = src; | ||
518 | 537 | ||
519 | snd_emu8000_write_wait(emu, 1); | 538 | /* convert to frames */ |
520 | EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); | 539 | pos = bytes_to_frames(subs->runtime, pos); |
521 | if (rec->voices > 1) | 540 | count = bytes_to_frames(subs->runtime, count); |
522 | EMU8000_SMARW_WRITE(emu, pos + rec->loop_start[1]); | 541 | LOOP_WRITE(rec, pos, src, count, COPY_USER); |
523 | 542 | return 0; | |
524 | while (count-- > 0) { | 543 | } |
525 | unsigned short sval; | 544 | |
526 | CHECK_SCHEDULER(); | 545 | static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs, |
527 | if (get_user(sval, buf)) | 546 | int voice, unsigned long pos, |
528 | return -EFAULT; | 547 | void *src, unsigned long count) |
529 | EMU8000_SMLD_WRITE(emu, sval); | 548 | { |
530 | buf++; | 549 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; |
531 | if (rec->voices > 1) { | 550 | |
532 | CHECK_SCHEDULER(); | 551 | /* convert to frames */ |
533 | if (get_user(sval, buf)) | 552 | pos = bytes_to_frames(subs->runtime, pos); |
534 | return -EFAULT; | 553 | count = bytes_to_frames(subs->runtime, count); |
535 | EMU8000_SMRD_WRITE(emu, sval); | 554 | LOOP_WRITE(rec, pos, src, count, COPY_KERNEL); |
536 | buf++; | ||
537 | } | ||
538 | } | ||
539 | return 0; | 555 | return 0; |
540 | } | 556 | } |
541 | 557 | ||
542 | static int emu8k_pcm_silence(struct snd_pcm_substream *subs, | 558 | static int emu8k_pcm_silence(struct snd_pcm_substream *subs, |
543 | int voice, | 559 | int voice, unsigned long pos, unsigned long count) |
544 | snd_pcm_uframes_t pos, | ||
545 | snd_pcm_uframes_t count) | ||
546 | { | 560 | { |
547 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; | 561 | struct snd_emu8k_pcm *rec = subs->runtime->private_data; |
548 | struct snd_emu8000 *emu = rec->emu; | ||
549 | 562 | ||
550 | snd_emu8000_write_wait(emu, 1); | 563 | /* convert to frames */ |
551 | EMU8000_SMALW_WRITE(emu, rec->loop_start[0] + pos); | 564 | pos = bytes_to_frames(subs->runtime, pos); |
552 | if (rec->voices > 1) | 565 | count = bytes_to_frames(subs->runtime, count); |
553 | EMU8000_SMARW_WRITE(emu, rec->loop_start[1] + pos); | 566 | LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE); |
554 | while (count-- > 0) { | ||
555 | CHECK_SCHEDULER(); | ||
556 | EMU8000_SMLD_WRITE(emu, 0); | ||
557 | if (rec->voices > 1) { | ||
558 | CHECK_SCHEDULER(); | ||
559 | EMU8000_SMRD_WRITE(emu, 0); | ||
560 | } | ||
561 | } | ||
562 | return 0; | 567 | return 0; |
563 | } | 568 | } |
564 | #endif | 569 | #endif |
@@ -674,8 +679,9 @@ static struct snd_pcm_ops emu8k_pcm_ops = { | |||
674 | .prepare = emu8k_pcm_prepare, | 679 | .prepare = emu8k_pcm_prepare, |
675 | .trigger = emu8k_pcm_trigger, | 680 | .trigger = emu8k_pcm_trigger, |
676 | .pointer = emu8k_pcm_pointer, | 681 | .pointer = emu8k_pcm_pointer, |
677 | .copy = emu8k_pcm_copy, | 682 | .copy_user = emu8k_pcm_copy, |
678 | .silence = emu8k_pcm_silence, | 683 | .copy_kernel = emu8k_pcm_copy_kernel, |
684 | .fill_silence = emu8k_pcm_silence, | ||
679 | }; | 685 | }; |
680 | 686 | ||
681 | 687 | ||
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 3b2e4f405ff2..917a93d696c3 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c | |||
@@ -62,7 +62,7 @@ MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB AWE 32}," | |||
62 | #define SNDRV_DEBUG_IRQ | 62 | #define SNDRV_DEBUG_IRQ |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | #if defined(SNDRV_SBAWE) && (defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))) | 65 | #if defined(SNDRV_SBAWE) && IS_ENABLED(CONFIG_SND_SEQUENCER) |
66 | #define SNDRV_SBAWE_EMU8000 | 66 | #define SNDRV_SBAWE_EMU8000 |
67 | #endif | 67 | #endif |
68 | 68 | ||
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index 48da2276683d..fa5780bb0c68 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c | |||
@@ -1029,7 +1029,7 @@ static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
1029 | return change; | 1029 | return change; |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | static struct snd_kcontrol_new snd_sb_qsound_switch = { | 1032 | static const struct snd_kcontrol_new snd_sb_qsound_switch = { |
1033 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1033 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1034 | .name = "3D Control - Switch", | 1034 | .name = "3D Control - Switch", |
1035 | .info = snd_sb_qsound_switch_info, | 1035 | .info = snd_sb_qsound_switch_info, |
@@ -1037,7 +1037,7 @@ static struct snd_kcontrol_new snd_sb_qsound_switch = { | |||
1037 | .put = snd_sb_qsound_switch_put | 1037 | .put = snd_sb_qsound_switch_put |
1038 | }; | 1038 | }; |
1039 | 1039 | ||
1040 | static struct snd_kcontrol_new snd_sb_qsound_space = { | 1040 | static const struct snd_kcontrol_new snd_sb_qsound_space = { |
1041 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1041 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1042 | .name = "3D Control - Space", | 1042 | .name = "3D Control - Space", |
1043 | .info = snd_sb_qsound_space_info, | 1043 | .info = snd_sb_qsound_space_info, |
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index 8b2d6c6bfe97..4be1350f6649 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c | |||
@@ -737,7 +737,7 @@ static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ct | |||
737 | return change; | 737 | return change; |
738 | } | 738 | } |
739 | 739 | ||
740 | static struct snd_kcontrol_new snd_sb16_dma_control = { | 740 | static const struct snd_kcontrol_new snd_sb16_dma_control = { |
741 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | 741 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, |
742 | .name = "16-bit DMA Allocation", | 742 | .name = "16-bit DMA Allocation", |
743 | .info = snd_sb16_dma_control_info, | 743 | .info = snd_sb16_dma_control_info, |
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 9043397fe62f..0f302be4fb6d 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c | |||
@@ -46,19 +46,19 @@ MODULE_LICENSE("GPL"); | |||
46 | #define SB8_DEN(v) ((SB8_CLOCK + (v) / 2) / (v)) | 46 | #define SB8_DEN(v) ((SB8_CLOCK + (v) / 2) / (v)) |
47 | #define SB8_RATE(v) (SB8_CLOCK / SB8_DEN(v)) | 47 | #define SB8_RATE(v) (SB8_CLOCK / SB8_DEN(v)) |
48 | 48 | ||
49 | static struct snd_ratnum clock = { | 49 | static const struct snd_ratnum clock = { |
50 | .num = SB8_CLOCK, | 50 | .num = SB8_CLOCK, |
51 | .den_min = 1, | 51 | .den_min = 1, |
52 | .den_max = 256, | 52 | .den_max = 256, |
53 | .den_step = 1, | 53 | .den_step = 1, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct snd_pcm_hw_constraint_ratnums hw_constraints_clock = { | 56 | static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clock = { |
57 | .nrats = 1, | 57 | .nrats = 1, |
58 | .rats = &clock, | 58 | .rats = &clock, |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct snd_ratnum stereo_clocks[] = { | 61 | static const struct snd_ratnum stereo_clocks[] = { |
62 | { | 62 | { |
63 | .num = SB8_CLOCK, | 63 | .num = SB8_CLOCK, |
64 | .den_min = SB8_DEN(22050), | 64 | .den_min = SB8_DEN(22050), |
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 54f5758a1bb3..1cd2908e4f12 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
@@ -671,7 +671,7 @@ __skip_change: | |||
671 | return change; | 671 | return change; |
672 | } | 672 | } |
673 | 673 | ||
674 | static struct snd_kcontrol_new midi_mixer_ctl = { | 674 | static const struct snd_kcontrol_new midi_mixer_ctl = { |
675 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 675 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
676 | .name = "MIDI", | 676 | .name = "MIDI", |
677 | .info = sscape_midi_info, | 677 | .info = sscape_midi_info, |
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 913b731d2236..9f4e2e34cbe1 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c | |||
@@ -69,12 +69,12 @@ static unsigned char freq_bits[14] = { | |||
69 | /* 48000 */ 0x0C | CS4231_XTAL1 | 69 | /* 48000 */ 0x0C | CS4231_XTAL1 |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static unsigned int rates[14] = { | 72 | static const unsigned int rates[14] = { |
73 | 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050, | 73 | 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050, |
74 | 27042, 32000, 33075, 37800, 44100, 48000 | 74 | 27042, 32000, 33075, 37800, 44100, 48000 |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 77 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
78 | .count = ARRAY_SIZE(rates), | 78 | .count = ARRAY_SIZE(rates), |
79 | .list = rates, | 79 | .list = rates, |
80 | .mask = 0, | 80 | .mask = 0, |
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index 00fc9241d266..3318c15e324a 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c | |||
@@ -264,7 +264,7 @@ static int hal2_gain_put(struct snd_kcontrol *kcontrol, | |||
264 | return old != new; | 264 | return old != new; |
265 | } | 265 | } |
266 | 266 | ||
267 | static struct snd_kcontrol_new hal2_ctrl_headphone = { | 267 | static const struct snd_kcontrol_new hal2_ctrl_headphone = { |
268 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 268 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
269 | .name = "Headphone Playback Volume", | 269 | .name = "Headphone Playback Volume", |
270 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 270 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -274,7 +274,7 @@ static struct snd_kcontrol_new hal2_ctrl_headphone = { | |||
274 | .put = hal2_gain_put, | 274 | .put = hal2_gain_put, |
275 | }; | 275 | }; |
276 | 276 | ||
277 | static struct snd_kcontrol_new hal2_ctrl_mic = { | 277 | static const struct snd_kcontrol_new hal2_ctrl_mic = { |
278 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 278 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
279 | .name = "Mic Capture Volume", | 279 | .name = "Mic Capture Volume", |
280 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 280 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -461,15 +461,15 @@ static int hal2_alloc_dmabuf(struct hal2_codec *codec) | |||
461 | int count = H2_BUF_SIZE / H2_BLOCK_SIZE; | 461 | int count = H2_BUF_SIZE / H2_BLOCK_SIZE; |
462 | int i; | 462 | int i; |
463 | 463 | ||
464 | codec->buffer = dma_alloc_noncoherent(NULL, H2_BUF_SIZE, | 464 | codec->buffer = dma_alloc_attrs(NULL, H2_BUF_SIZE, &buffer_dma, |
465 | &buffer_dma, GFP_KERNEL); | 465 | GFP_KERNEL, DMA_ATTR_NON_CONSISTENT); |
466 | if (!codec->buffer) | 466 | if (!codec->buffer) |
467 | return -ENOMEM; | 467 | return -ENOMEM; |
468 | desc = dma_alloc_noncoherent(NULL, count * sizeof(struct hal2_desc), | 468 | desc = dma_alloc_attrs(NULL, count * sizeof(struct hal2_desc), |
469 | &desc_dma, GFP_KERNEL); | 469 | &desc_dma, GFP_KERNEL, DMA_ATTR_NON_CONSISTENT); |
470 | if (!desc) { | 470 | if (!desc) { |
471 | dma_free_noncoherent(NULL, H2_BUF_SIZE, | 471 | dma_free_attrs(NULL, H2_BUF_SIZE, codec->buffer, buffer_dma, |
472 | codec->buffer, buffer_dma); | 472 | DMA_ATTR_NON_CONSISTENT); |
473 | return -ENOMEM; | 473 | return -ENOMEM; |
474 | } | 474 | } |
475 | codec->buffer_dma = buffer_dma; | 475 | codec->buffer_dma = buffer_dma; |
@@ -490,10 +490,10 @@ static int hal2_alloc_dmabuf(struct hal2_codec *codec) | |||
490 | 490 | ||
491 | static void hal2_free_dmabuf(struct hal2_codec *codec) | 491 | static void hal2_free_dmabuf(struct hal2_codec *codec) |
492 | { | 492 | { |
493 | dma_free_noncoherent(NULL, codec->desc_count * sizeof(struct hal2_desc), | 493 | dma_free_attrs(NULL, codec->desc_count * sizeof(struct hal2_desc), |
494 | codec->desc, codec->desc_dma); | 494 | codec->desc, codec->desc_dma, DMA_ATTR_NON_CONSISTENT); |
495 | dma_free_noncoherent(NULL, H2_BUF_SIZE, codec->buffer, | 495 | dma_free_attrs(NULL, H2_BUF_SIZE, codec->buffer, codec->buffer_dma, |
496 | codec->buffer_dma); | 496 | DMA_ATTR_NON_CONSISTENT); |
497 | } | 497 | } |
498 | 498 | ||
499 | static struct snd_pcm_hardware hal2_pcm_hw = { | 499 | static struct snd_pcm_hardware hal2_pcm_hw = { |
@@ -616,10 +616,9 @@ static int hal2_playback_ack(struct snd_pcm_substream *substream) | |||
616 | struct hal2_codec *dac = &hal2->dac; | 616 | struct hal2_codec *dac = &hal2->dac; |
617 | 617 | ||
618 | dac->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2; | 618 | dac->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2; |
619 | snd_pcm_indirect_playback_transfer(substream, | 619 | return snd_pcm_indirect_playback_transfer(substream, |
620 | &dac->pcm_indirect, | 620 | &dac->pcm_indirect, |
621 | hal2_playback_transfer); | 621 | hal2_playback_transfer); |
622 | return 0; | ||
623 | } | 622 | } |
624 | 623 | ||
625 | static int hal2_capture_open(struct snd_pcm_substream *substream) | 624 | static int hal2_capture_open(struct snd_pcm_substream *substream) |
@@ -707,10 +706,9 @@ static int hal2_capture_ack(struct snd_pcm_substream *substream) | |||
707 | struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); | 706 | struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream); |
708 | struct hal2_codec *adc = &hal2->adc; | 707 | struct hal2_codec *adc = &hal2->adc; |
709 | 708 | ||
710 | snd_pcm_indirect_capture_transfer(substream, | 709 | return snd_pcm_indirect_capture_transfer(substream, |
711 | &adc->pcm_indirect, | 710 | &adc->pcm_indirect, |
712 | hal2_capture_transfer); | 711 | hal2_capture_transfer); |
713 | return 0; | ||
714 | } | 712 | } |
715 | 713 | ||
716 | static struct snd_pcm_ops hal2_playback_ops = { | 714 | static struct snd_pcm_ops hal2_playback_ops = { |
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index f07aa3993f83..0ebc1c3727df 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c | |||
@@ -230,7 +230,7 @@ static int sgio2audio_source_put(struct snd_kcontrol *kcontrol, | |||
230 | } | 230 | } |
231 | 231 | ||
232 | /* dac1/pcm0 mixer control */ | 232 | /* dac1/pcm0 mixer control */ |
233 | static struct snd_kcontrol_new sgio2audio_ctrl_pcm0 = { | 233 | static const struct snd_kcontrol_new sgio2audio_ctrl_pcm0 = { |
234 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 234 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
235 | .name = "PCM Playback Volume", | 235 | .name = "PCM Playback Volume", |
236 | .index = 0, | 236 | .index = 0, |
@@ -242,7 +242,7 @@ static struct snd_kcontrol_new sgio2audio_ctrl_pcm0 = { | |||
242 | }; | 242 | }; |
243 | 243 | ||
244 | /* dac2/pcm1 mixer control */ | 244 | /* dac2/pcm1 mixer control */ |
245 | static struct snd_kcontrol_new sgio2audio_ctrl_pcm1 = { | 245 | static const struct snd_kcontrol_new sgio2audio_ctrl_pcm1 = { |
246 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 246 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
247 | .name = "PCM Playback Volume", | 247 | .name = "PCM Playback Volume", |
248 | .index = 1, | 248 | .index = 1, |
@@ -254,7 +254,7 @@ static struct snd_kcontrol_new sgio2audio_ctrl_pcm1 = { | |||
254 | }; | 254 | }; |
255 | 255 | ||
256 | /* record level mixer control */ | 256 | /* record level mixer control */ |
257 | static struct snd_kcontrol_new sgio2audio_ctrl_reclevel = { | 257 | static const struct snd_kcontrol_new sgio2audio_ctrl_reclevel = { |
258 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 258 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
259 | .name = "Capture Volume", | 259 | .name = "Capture Volume", |
260 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 260 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -265,7 +265,7 @@ static struct snd_kcontrol_new sgio2audio_ctrl_reclevel = { | |||
265 | }; | 265 | }; |
266 | 266 | ||
267 | /* record level source control */ | 267 | /* record level source control */ |
268 | static struct snd_kcontrol_new sgio2audio_ctrl_recsource = { | 268 | static const struct snd_kcontrol_new sgio2audio_ctrl_recsource = { |
269 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 269 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
270 | .name = "Capture Source", | 270 | .name = "Capture Source", |
271 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 271 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -275,7 +275,7 @@ static struct snd_kcontrol_new sgio2audio_ctrl_recsource = { | |||
275 | }; | 275 | }; |
276 | 276 | ||
277 | /* line mixer control */ | 277 | /* line mixer control */ |
278 | static struct snd_kcontrol_new sgio2audio_ctrl_line = { | 278 | static const struct snd_kcontrol_new sgio2audio_ctrl_line = { |
279 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 279 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
280 | .name = "Line Playback Volume", | 280 | .name = "Line Playback Volume", |
281 | .index = 0, | 281 | .index = 0, |
@@ -287,7 +287,7 @@ static struct snd_kcontrol_new sgio2audio_ctrl_line = { | |||
287 | }; | 287 | }; |
288 | 288 | ||
289 | /* cd mixer control */ | 289 | /* cd mixer control */ |
290 | static struct snd_kcontrol_new sgio2audio_ctrl_cd = { | 290 | static const struct snd_kcontrol_new sgio2audio_ctrl_cd = { |
291 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 291 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
292 | .name = "Line Playback Volume", | 292 | .name = "Line Playback Volume", |
293 | .index = 1, | 293 | .index = 1, |
@@ -299,7 +299,7 @@ static struct snd_kcontrol_new sgio2audio_ctrl_cd = { | |||
299 | }; | 299 | }; |
300 | 300 | ||
301 | /* mic mixer control */ | 301 | /* mic mixer control */ |
302 | static struct snd_kcontrol_new sgio2audio_ctrl_mic = { | 302 | static const struct snd_kcontrol_new sgio2audio_ctrl_mic = { |
303 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 303 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
304 | .name = "Mic Playback Volume", | 304 | .name = "Mic Playback Volume", |
305 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 305 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 99b64cb3cef8..5911eb35c2a3 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c | |||
@@ -83,14 +83,14 @@ MODULE_DEVICE_TABLE(parisc, snd_harmony_devtable); | |||
83 | #define NAME "harmony" | 83 | #define NAME "harmony" |
84 | #define PFX NAME ": " | 84 | #define PFX NAME ": " |
85 | 85 | ||
86 | static unsigned int snd_harmony_rates[] = { | 86 | static const unsigned int snd_harmony_rates[] = { |
87 | 5512, 6615, 8000, 9600, | 87 | 5512, 6615, 8000, 9600, |
88 | 11025, 16000, 18900, 22050, | 88 | 11025, 16000, 18900, 22050, |
89 | 27428, 32000, 33075, 37800, | 89 | 27428, 32000, 33075, 37800, |
90 | 44100, 48000 | 90 | 44100, 48000 |
91 | }; | 91 | }; |
92 | 92 | ||
93 | static unsigned int rate_bits[14] = { | 93 | static const unsigned int rate_bits[14] = { |
94 | HARMONY_SR_5KHZ, HARMONY_SR_6KHZ, HARMONY_SR_8KHZ, | 94 | HARMONY_SR_5KHZ, HARMONY_SR_6KHZ, HARMONY_SR_8KHZ, |
95 | HARMONY_SR_9KHZ, HARMONY_SR_11KHZ, HARMONY_SR_16KHZ, | 95 | HARMONY_SR_9KHZ, HARMONY_SR_11KHZ, HARMONY_SR_16KHZ, |
96 | HARMONY_SR_18KHZ, HARMONY_SR_22KHZ, HARMONY_SR_27KHZ, | 96 | HARMONY_SR_18KHZ, HARMONY_SR_22KHZ, HARMONY_SR_27KHZ, |
@@ -98,7 +98,7 @@ static unsigned int rate_bits[14] = { | |||
98 | HARMONY_SR_44KHZ, HARMONY_SR_48KHZ | 98 | HARMONY_SR_44KHZ, HARMONY_SR_48KHZ |
99 | }; | 99 | }; |
100 | 100 | ||
101 | static struct snd_pcm_hw_constraint_list hw_constraint_rates = { | 101 | static const struct snd_pcm_hw_constraint_list hw_constraint_rates = { |
102 | .count = ARRAY_SIZE(snd_harmony_rates), | 102 | .count = ARRAY_SIZE(snd_harmony_rates), |
103 | .list = snd_harmony_rates, | 103 | .list = snd_harmony_rates, |
104 | .mask = 0, | 104 | .mask = 0, |
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 32151d8c6bb8..d9f3fdb777e4 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -465,6 +465,7 @@ config SND_EMU10K1 | |||
465 | select SND_RAWMIDI | 465 | select SND_RAWMIDI |
466 | select SND_AC97_CODEC | 466 | select SND_AC97_CODEC |
467 | select SND_TIMER | 467 | select SND_TIMER |
468 | select SND_SEQ_DEVICE if SND_SEQUENCER != n | ||
468 | depends on ZONE_DMA | 469 | depends on ZONE_DMA |
469 | help | 470 | help |
470 | Say Y to include support for Sound Blaster PCI 512, Live!, | 471 | Say Y to include support for Sound Blaster PCI 512, Live!, |
@@ -477,6 +478,13 @@ config SND_EMU10K1 | |||
477 | To compile this driver as a module, choose M here: the module | 478 | To compile this driver as a module, choose M here: the module |
478 | will be called snd-emu10k1. | 479 | will be called snd-emu10k1. |
479 | 480 | ||
481 | # select SEQ stuff to min(SND_SEQUENCER,SND_XXX) | ||
482 | config SND_EMU10K1_SEQ | ||
483 | def_tristate SND_SEQUENCER && SND_EMU10K1 | ||
484 | select SND_SEQ_MIDI_EMUL | ||
485 | select SND_SEQ_VIRMIDI | ||
486 | select SND_SYNTH_EMUX | ||
487 | |||
480 | config SND_EMU10K1X | 488 | config SND_EMU10K1X |
481 | tristate "Emu10k1X (Dell OEM Version)" | 489 | tristate "Emu10k1X (Dell OEM Version)" |
482 | select SND_AC97_CODEC | 490 | select SND_AC97_CODEC |
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 34bbc2e730a6..8567f1e5b9cf 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -1602,8 +1602,8 @@ static struct snd_pcm_hardware snd_ali_modem = | |||
1602 | static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, | 1602 | static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, |
1603 | int channel) | 1603 | int channel) |
1604 | { | 1604 | { |
1605 | static unsigned int rates[] = {8000, 9600, 12000, 16000}; | 1605 | static const unsigned int rates[] = {8000, 9600, 12000, 16000}; |
1606 | static struct snd_pcm_hw_constraint_list hw_constraint_rates = { | 1606 | static const struct snd_pcm_hw_constraint_list hw_constraint_rates = { |
1607 | .count = ARRAY_SIZE(rates), | 1607 | .count = ARRAY_SIZE(rates), |
1608 | .list = rates, | 1608 | .list = rates, |
1609 | .mask = 0, | 1609 | .mask = 0, |
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 40152feef1e7..52e0ea7b9b80 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -860,8 +860,8 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream, | |||
860 | struct atiixp_modem *chip = snd_pcm_substream_chip(substream); | 860 | struct atiixp_modem *chip = snd_pcm_substream_chip(substream); |
861 | struct snd_pcm_runtime *runtime = substream->runtime; | 861 | struct snd_pcm_runtime *runtime = substream->runtime; |
862 | int err; | 862 | int err; |
863 | static unsigned int rates[] = { 8000, 9600, 12000, 16000 }; | 863 | static const unsigned int rates[] = { 8000, 9600, 12000, 16000 }; |
864 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 864 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
865 | .count = ARRAY_SIZE(rates), | 865 | .count = ARRAY_SIZE(rates), |
866 | .list = rates, | 866 | .list = rates, |
867 | .mask = 0, | 867 | .mask = 0, |
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 335979a753fe..1aa97012451d 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c | |||
@@ -112,11 +112,11 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_wt = { | |||
112 | }; | 112 | }; |
113 | #endif | 113 | #endif |
114 | #ifdef CHIP_AU8830 | 114 | #ifdef CHIP_AU8830 |
115 | static unsigned int au8830_channels[3] = { | 115 | static const unsigned int au8830_channels[3] = { |
116 | 1, 2, 4, | 116 | 1, 2, 4, |
117 | }; | 117 | }; |
118 | 118 | ||
119 | static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = { | 119 | static const struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = { |
120 | .count = ARRAY_SIZE(au8830_channels), | 120 | .count = ARRAY_SIZE(au8830_channels), |
121 | .list = au8830_channels, | 121 | .list = au8830_channels, |
122 | .mask = 0, | 122 | .mask = 0, |
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 79b2e6b7d88b..fc18c29a8173 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
@@ -2014,7 +2014,7 @@ static const struct snd_pcm_hardware snd_azf3328_hardware = | |||
2014 | }; | 2014 | }; |
2015 | 2015 | ||
2016 | 2016 | ||
2017 | static unsigned int snd_azf3328_fixed_rates[] = { | 2017 | static const unsigned int snd_azf3328_fixed_rates[] = { |
2018 | AZF_FREQ_4000, | 2018 | AZF_FREQ_4000, |
2019 | AZF_FREQ_4800, | 2019 | AZF_FREQ_4800, |
2020 | AZF_FREQ_5512, | 2020 | AZF_FREQ_5512, |
@@ -2031,7 +2031,7 @@ static unsigned int snd_azf3328_fixed_rates[] = { | |||
2031 | AZF_FREQ_66200 | 2031 | AZF_FREQ_66200 |
2032 | }; | 2032 | }; |
2033 | 2033 | ||
2034 | static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = { | 2034 | static const struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = { |
2035 | .count = ARRAY_SIZE(snd_azf3328_fixed_rates), | 2035 | .count = ARRAY_SIZE(snd_azf3328_fixed_rates), |
2036 | .list = snd_azf3328_fixed_rates, | 2036 | .list = snd_azf3328_fixed_rates, |
2037 | .mask = 0, | 2037 | .mask = 0, |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 099efb046b1c..de0234294c25 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -401,13 +401,13 @@ static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runti | |||
401 | 401 | ||
402 | static int snd_bt87x_set_analog_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime) | 402 | static int snd_bt87x_set_analog_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime) |
403 | { | 403 | { |
404 | static struct snd_ratnum analog_clock = { | 404 | static const struct snd_ratnum analog_clock = { |
405 | .num = ANALOG_CLOCK, | 405 | .num = ANALOG_CLOCK, |
406 | .den_min = CLOCK_DIV_MIN, | 406 | .den_min = CLOCK_DIV_MIN, |
407 | .den_max = CLOCK_DIV_MAX, | 407 | .den_max = CLOCK_DIV_MAX, |
408 | .den_step = 1 | 408 | .den_step = 1 |
409 | }; | 409 | }; |
410 | static struct snd_pcm_hw_constraint_ratnums constraint_rates = { | 410 | static const struct snd_pcm_hw_constraint_ratnums constraint_rates = { |
411 | .nrats = 1, | 411 | .nrats = 1, |
412 | .rats = &analog_clock | 412 | .rats = &analog_clock |
413 | }; | 413 | }; |
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 745a0a3743b4..a460cb63e971 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -719,18 +719,18 @@ static int snd_cmipci_hw_free(struct snd_pcm_substream *substream) | |||
719 | /* | 719 | /* |
720 | */ | 720 | */ |
721 | 721 | ||
722 | static unsigned int hw_channels[] = {1, 2, 4, 6, 8}; | 722 | static const unsigned int hw_channels[] = {1, 2, 4, 6, 8}; |
723 | static struct snd_pcm_hw_constraint_list hw_constraints_channels_4 = { | 723 | static const struct snd_pcm_hw_constraint_list hw_constraints_channels_4 = { |
724 | .count = 3, | 724 | .count = 3, |
725 | .list = hw_channels, | 725 | .list = hw_channels, |
726 | .mask = 0, | 726 | .mask = 0, |
727 | }; | 727 | }; |
728 | static struct snd_pcm_hw_constraint_list hw_constraints_channels_6 = { | 728 | static const struct snd_pcm_hw_constraint_list hw_constraints_channels_6 = { |
729 | .count = 4, | 729 | .count = 4, |
730 | .list = hw_channels, | 730 | .list = hw_channels, |
731 | .mask = 0, | 731 | .mask = 0, |
732 | }; | 732 | }; |
733 | static struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = { | 733 | static const struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = { |
734 | .count = 5, | 734 | .count = 5, |
735 | .list = hw_channels, | 735 | .list = hw_channels, |
736 | .mask = 0, | 736 | .mask = 0, |
@@ -1597,9 +1597,9 @@ static struct snd_pcm_hardware snd_cmipci_capture_spdif = | |||
1597 | .fifo_size = 0, | 1597 | .fifo_size = 0, |
1598 | }; | 1598 | }; |
1599 | 1599 | ||
1600 | static unsigned int rate_constraints[] = { 5512, 8000, 11025, 16000, 22050, | 1600 | static const unsigned int rate_constraints[] = { 5512, 8000, 11025, 16000, 22050, |
1601 | 32000, 44100, 48000, 88200, 96000, 128000 }; | 1601 | 32000, 44100, 48000, 88200, 96000, 128000 }; |
1602 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 1602 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
1603 | .count = ARRAY_SIZE(rate_constraints), | 1603 | .count = ARRAY_SIZE(rate_constraints), |
1604 | .list = rate_constraints, | 1604 | .list = rate_constraints, |
1605 | .mask = 0, | 1605 | .mask = 0, |
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index f870697aca67..ee7ba4b0b47b 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c | |||
@@ -1296,7 +1296,7 @@ static void snd_cs4281_free_gameport(struct cs4281 *chip) | |||
1296 | #else | 1296 | #else |
1297 | static inline int snd_cs4281_create_gameport(struct cs4281 *chip) { return -ENOSYS; } | 1297 | static inline int snd_cs4281_create_gameport(struct cs4281 *chip) { return -ENOSYS; } |
1298 | static inline void snd_cs4281_free_gameport(struct cs4281 *chip) { } | 1298 | static inline void snd_cs4281_free_gameport(struct cs4281 *chip) { } |
1299 | #endif /* CONFIG_GAMEPORT || (MODULE && CONFIG_GAMEPORT_MODULE) */ | 1299 | #endif /* IS_REACHABLE(CONFIG_GAMEPORT) */ |
1300 | 1300 | ||
1301 | static int snd_cs4281_free(struct cs4281 *chip) | 1301 | static int snd_cs4281_free(struct cs4281 *chip) |
1302 | { | 1302 | { |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index e4cf3187b4dd..709fb1a503b7 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
@@ -887,8 +887,8 @@ static int snd_cs46xx_playback_transfer(struct snd_pcm_substream *substream) | |||
887 | { | 887 | { |
888 | struct snd_pcm_runtime *runtime = substream->runtime; | 888 | struct snd_pcm_runtime *runtime = substream->runtime; |
889 | struct snd_cs46xx_pcm * cpcm = runtime->private_data; | 889 | struct snd_cs46xx_pcm * cpcm = runtime->private_data; |
890 | snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy); | 890 | return snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, |
891 | return 0; | 891 | snd_cs46xx_pb_trans_copy); |
892 | } | 892 | } |
893 | 893 | ||
894 | static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream, | 894 | static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream, |
@@ -903,8 +903,8 @@ static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream, | |||
903 | static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream) | 903 | static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream) |
904 | { | 904 | { |
905 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); | 905 | struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); |
906 | snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy); | 906 | return snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, |
907 | return 0; | 907 | snd_cs46xx_cp_trans_copy); |
908 | } | 908 | } |
909 | 909 | ||
910 | static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_substream *substream) | 910 | static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_substream *substream) |
@@ -1482,9 +1482,9 @@ static struct snd_pcm_hardware snd_cs46xx_capture = | |||
1482 | 1482 | ||
1483 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1483 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1484 | 1484 | ||
1485 | static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 }; | 1485 | static const unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 }; |
1486 | 1486 | ||
1487 | static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = { | 1487 | static const struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = { |
1488 | .count = ARRAY_SIZE(period_sizes), | 1488 | .count = ARRAY_SIZE(period_sizes), |
1489 | .list = period_sizes, | 1489 | .list = period_sizes, |
1490 | .mask = 0 | 1490 | .mask = 0 |
@@ -2371,7 +2371,7 @@ static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol, | |||
2371 | ucontrol->value.integer.value[0] ? 0 : 0x200); | 2371 | ucontrol->value.integer.value[0] ? 0 : 0x200); |
2372 | } | 2372 | } |
2373 | 2373 | ||
2374 | static struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = { | 2374 | static const struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = { |
2375 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2375 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2376 | .name = "Duplicate Front", | 2376 | .name = "Duplicate Front", |
2377 | .info = snd_mixer_boolean_info, | 2377 | .info = snd_mixer_boolean_info, |
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 6a0e49ac5273..d3203df50a1a 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
@@ -37,7 +37,7 @@ MODULE_LICENSE("GPL"); | |||
37 | MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS}," | 37 | MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS}," |
38 | "{Creative Labs,SB Audigy}}"); | 38 | "{Creative Labs,SB Audigy}}"); |
39 | 39 | ||
40 | #if IS_REACHABLE(CONFIG_SND_SEQUENCER) | 40 | #if IS_ENABLED(CONFIG_SND_SEQUENCER) |
41 | #define ENABLE_SYNTH | 41 | #define ENABLE_SYNTH |
42 | #include <sound/emu10k1_synth.h> | 42 | #include <sound/emu10k1_synth.h> |
43 | #endif | 43 | #endif |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 56fc47bd6dba..dc585959ca32 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -311,21 +311,6 @@ static const u32 onoff_table[2] = { | |||
311 | }; | 311 | }; |
312 | 312 | ||
313 | /* | 313 | /* |
314 | */ | ||
315 | |||
316 | static inline mm_segment_t snd_enter_user(void) | ||
317 | { | ||
318 | mm_segment_t fs = get_fs(); | ||
319 | set_fs(get_ds()); | ||
320 | return fs; | ||
321 | } | ||
322 | |||
323 | static inline void snd_leave_user(mm_segment_t fs) | ||
324 | { | ||
325 | set_fs(fs); | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * controls | 314 | * controls |
330 | */ | 315 | */ |
331 | 316 | ||
@@ -538,7 +523,8 @@ unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc) | |||
538 | } | 523 | } |
539 | 524 | ||
540 | static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu, | 525 | static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu, |
541 | struct snd_emu10k1_fx8010_code *icode) | 526 | struct snd_emu10k1_fx8010_code *icode, |
527 | bool in_kernel) | ||
542 | { | 528 | { |
543 | int gpr; | 529 | int gpr; |
544 | u32 val; | 530 | u32 val; |
@@ -546,7 +532,9 @@ static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu, | |||
546 | for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) { | 532 | for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) { |
547 | if (!test_bit(gpr, icode->gpr_valid)) | 533 | if (!test_bit(gpr, icode->gpr_valid)) |
548 | continue; | 534 | continue; |
549 | if (get_user(val, &icode->gpr_map[gpr])) | 535 | if (in_kernel) |
536 | val = *(u32 *)&icode->gpr_map[gpr]; | ||
537 | else if (get_user(val, &icode->gpr_map[gpr])) | ||
550 | return -EFAULT; | 538 | return -EFAULT; |
551 | snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val); | 539 | snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val); |
552 | } | 540 | } |
@@ -569,7 +557,8 @@ static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu, | |||
569 | } | 557 | } |
570 | 558 | ||
571 | static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu, | 559 | static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu, |
572 | struct snd_emu10k1_fx8010_code *icode) | 560 | struct snd_emu10k1_fx8010_code *icode, |
561 | bool in_kernel) | ||
573 | { | 562 | { |
574 | int tram; | 563 | int tram; |
575 | u32 addr, val; | 564 | u32 addr, val; |
@@ -577,9 +566,14 @@ static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu, | |||
577 | for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) { | 566 | for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) { |
578 | if (!test_bit(tram, icode->tram_valid)) | 567 | if (!test_bit(tram, icode->tram_valid)) |
579 | continue; | 568 | continue; |
580 | if (get_user(val, &icode->tram_data_map[tram]) || | 569 | if (in_kernel) { |
581 | get_user(addr, &icode->tram_addr_map[tram])) | 570 | val = *(u32 *)&icode->tram_data_map[tram]; |
582 | return -EFAULT; | 571 | addr = *(u32 *)&icode->tram_addr_map[tram]; |
572 | } else { | ||
573 | if (get_user(val, &icode->tram_data_map[tram]) || | ||
574 | get_user(addr, &icode->tram_addr_map[tram])) | ||
575 | return -EFAULT; | ||
576 | } | ||
583 | snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val); | 577 | snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val); |
584 | if (!emu->audigy) { | 578 | if (!emu->audigy) { |
585 | snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr); | 579 | snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr); |
@@ -615,16 +609,22 @@ static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu, | |||
615 | } | 609 | } |
616 | 610 | ||
617 | static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu, | 611 | static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu, |
618 | struct snd_emu10k1_fx8010_code *icode) | 612 | struct snd_emu10k1_fx8010_code *icode, |
613 | bool in_kernel) | ||
619 | { | 614 | { |
620 | u32 pc, lo, hi; | 615 | u32 pc, lo, hi; |
621 | 616 | ||
622 | for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) { | 617 | for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) { |
623 | if (!test_bit(pc / 2, icode->code_valid)) | 618 | if (!test_bit(pc / 2, icode->code_valid)) |
624 | continue; | 619 | continue; |
625 | if (get_user(lo, &icode->code[pc + 0]) || | 620 | if (in_kernel) { |
626 | get_user(hi, &icode->code[pc + 1])) | 621 | lo = *(u32 *)&icode->code[pc + 0]; |
627 | return -EFAULT; | 622 | hi = *(u32 *)&icode->code[pc + 1]; |
623 | } else { | ||
624 | if (get_user(lo, &icode->code[pc + 0]) || | ||
625 | get_user(hi, &icode->code[pc + 1])) | ||
626 | return -EFAULT; | ||
627 | } | ||
628 | snd_emu10k1_efx_write(emu, pc + 0, lo); | 628 | snd_emu10k1_efx_write(emu, pc + 0, lo); |
629 | snd_emu10k1_efx_write(emu, pc + 1, hi); | 629 | snd_emu10k1_efx_write(emu, pc + 1, hi); |
630 | } | 630 | } |
@@ -665,14 +665,16 @@ snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id) | |||
665 | 665 | ||
666 | #define MAX_TLV_SIZE 256 | 666 | #define MAX_TLV_SIZE 256 |
667 | 667 | ||
668 | static unsigned int *copy_tlv(const unsigned int __user *_tlv) | 668 | static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel) |
669 | { | 669 | { |
670 | unsigned int data[2]; | 670 | unsigned int data[2]; |
671 | unsigned int *tlv; | 671 | unsigned int *tlv; |
672 | 672 | ||
673 | if (!_tlv) | 673 | if (!_tlv) |
674 | return NULL; | 674 | return NULL; |
675 | if (copy_from_user(data, _tlv, sizeof(data))) | 675 | if (in_kernel) |
676 | memcpy(data, (void *)_tlv, sizeof(data)); | ||
677 | else if (copy_from_user(data, _tlv, sizeof(data))) | ||
676 | return NULL; | 678 | return NULL; |
677 | if (data[1] >= MAX_TLV_SIZE) | 679 | if (data[1] >= MAX_TLV_SIZE) |
678 | return NULL; | 680 | return NULL; |
@@ -680,7 +682,9 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv) | |||
680 | if (!tlv) | 682 | if (!tlv) |
681 | return NULL; | 683 | return NULL; |
682 | memcpy(tlv, data, sizeof(data)); | 684 | memcpy(tlv, data, sizeof(data)); |
683 | if (copy_from_user(tlv + 2, _tlv + 2, data[1])) { | 685 | if (in_kernel) { |
686 | memcpy(tlv + 2, (void *)(_tlv + 2), data[1]); | ||
687 | } else if (copy_from_user(tlv + 2, _tlv + 2, data[1])) { | ||
684 | kfree(tlv); | 688 | kfree(tlv); |
685 | return NULL; | 689 | return NULL; |
686 | } | 690 | } |
@@ -690,7 +694,7 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv) | |||
690 | static int copy_gctl(struct snd_emu10k1 *emu, | 694 | static int copy_gctl(struct snd_emu10k1 *emu, |
691 | struct snd_emu10k1_fx8010_control_gpr *gctl, | 695 | struct snd_emu10k1_fx8010_control_gpr *gctl, |
692 | struct snd_emu10k1_fx8010_control_gpr __user *_gctl, | 696 | struct snd_emu10k1_fx8010_control_gpr __user *_gctl, |
693 | int idx) | 697 | int idx, bool in_kernel) |
694 | { | 698 | { |
695 | struct snd_emu10k1_fx8010_control_old_gpr __user *octl; | 699 | struct snd_emu10k1_fx8010_control_old_gpr __user *octl; |
696 | 700 | ||
@@ -718,7 +722,8 @@ static int copy_gctl_to_user(struct snd_emu10k1 *emu, | |||
718 | } | 722 | } |
719 | 723 | ||
720 | static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, | 724 | static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, |
721 | struct snd_emu10k1_fx8010_code *icode) | 725 | struct snd_emu10k1_fx8010_code *icode, |
726 | bool in_kernel) | ||
722 | { | 727 | { |
723 | unsigned int i; | 728 | unsigned int i; |
724 | struct snd_ctl_elem_id __user *_id; | 729 | struct snd_ctl_elem_id __user *_id; |
@@ -728,7 +733,9 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, | |||
728 | 733 | ||
729 | for (i = 0, _id = icode->gpr_del_controls; | 734 | for (i = 0, _id = icode->gpr_del_controls; |
730 | i < icode->gpr_del_control_count; i++, _id++) { | 735 | i < icode->gpr_del_control_count; i++, _id++) { |
731 | if (copy_from_user(&id, _id, sizeof(id))) | 736 | if (in_kernel) |
737 | id = *(struct snd_ctl_elem_id *)_id; | ||
738 | else if (copy_from_user(&id, _id, sizeof(id))) | ||
732 | return -EFAULT; | 739 | return -EFAULT; |
733 | if (snd_emu10k1_look_for_ctl(emu, &id) == NULL) | 740 | if (snd_emu10k1_look_for_ctl(emu, &id) == NULL) |
734 | return -ENOENT; | 741 | return -ENOENT; |
@@ -738,7 +745,8 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, | |||
738 | return -ENOMEM; | 745 | return -ENOMEM; |
739 | err = 0; | 746 | err = 0; |
740 | for (i = 0; i < icode->gpr_add_control_count; i++) { | 747 | for (i = 0; i < icode->gpr_add_control_count; i++) { |
741 | if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) { | 748 | if (copy_gctl(emu, gctl, icode->gpr_add_controls, i, |
749 | in_kernel)) { | ||
742 | err = -EFAULT; | 750 | err = -EFAULT; |
743 | goto __error; | 751 | goto __error; |
744 | } | 752 | } |
@@ -759,7 +767,8 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, | |||
759 | } | 767 | } |
760 | for (i = 0; i < icode->gpr_list_control_count; i++) { | 768 | for (i = 0; i < icode->gpr_list_control_count; i++) { |
761 | /* FIXME: we need to check the WRITE access */ | 769 | /* FIXME: we need to check the WRITE access */ |
762 | if (copy_gctl(emu, gctl, icode->gpr_list_controls, i)) { | 770 | if (copy_gctl(emu, gctl, icode->gpr_list_controls, i, |
771 | in_kernel)) { | ||
763 | err = -EFAULT; | 772 | err = -EFAULT; |
764 | goto __error; | 773 | goto __error; |
765 | } | 774 | } |
@@ -781,7 +790,8 @@ static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl) | |||
781 | } | 790 | } |
782 | 791 | ||
783 | static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, | 792 | static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, |
784 | struct snd_emu10k1_fx8010_code *icode) | 793 | struct snd_emu10k1_fx8010_code *icode, |
794 | bool in_kernel) | ||
785 | { | 795 | { |
786 | unsigned int i, j; | 796 | unsigned int i, j; |
787 | struct snd_emu10k1_fx8010_control_gpr *gctl; | 797 | struct snd_emu10k1_fx8010_control_gpr *gctl; |
@@ -800,7 +810,8 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, | |||
800 | } | 810 | } |
801 | 811 | ||
802 | for (i = 0; i < icode->gpr_add_control_count; i++) { | 812 | for (i = 0; i < icode->gpr_add_control_count; i++) { |
803 | if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) { | 813 | if (copy_gctl(emu, gctl, icode->gpr_add_controls, i, |
814 | in_kernel)) { | ||
804 | err = -EFAULT; | 815 | err = -EFAULT; |
805 | goto __error; | 816 | goto __error; |
806 | } | 817 | } |
@@ -821,7 +832,7 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, | |||
821 | knew.device = gctl->id.device; | 832 | knew.device = gctl->id.device; |
822 | knew.subdevice = gctl->id.subdevice; | 833 | knew.subdevice = gctl->id.subdevice; |
823 | knew.info = snd_emu10k1_gpr_ctl_info; | 834 | knew.info = snd_emu10k1_gpr_ctl_info; |
824 | knew.tlv.p = copy_tlv(gctl->tlv); | 835 | knew.tlv.p = copy_tlv(gctl->tlv, in_kernel); |
825 | if (knew.tlv.p) | 836 | if (knew.tlv.p) |
826 | knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | 837 | knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | |
827 | SNDRV_CTL_ELEM_ACCESS_TLV_READ; | 838 | SNDRV_CTL_ELEM_ACCESS_TLV_READ; |
@@ -873,7 +884,8 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, | |||
873 | } | 884 | } |
874 | 885 | ||
875 | static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu, | 886 | static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu, |
876 | struct snd_emu10k1_fx8010_code *icode) | 887 | struct snd_emu10k1_fx8010_code *icode, |
888 | bool in_kernel) | ||
877 | { | 889 | { |
878 | unsigned int i; | 890 | unsigned int i; |
879 | struct snd_ctl_elem_id id; | 891 | struct snd_ctl_elem_id id; |
@@ -883,7 +895,9 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu, | |||
883 | 895 | ||
884 | for (i = 0, _id = icode->gpr_del_controls; | 896 | for (i = 0, _id = icode->gpr_del_controls; |
885 | i < icode->gpr_del_control_count; i++, _id++) { | 897 | i < icode->gpr_del_control_count; i++, _id++) { |
886 | if (copy_from_user(&id, _id, sizeof(id))) | 898 | if (in_kernel) |
899 | id = *(struct snd_ctl_elem_id *)_id; | ||
900 | else if (copy_from_user(&id, _id, sizeof(id))) | ||
887 | return -EFAULT; | 901 | return -EFAULT; |
888 | down_write(&card->controls_rwsem); | 902 | down_write(&card->controls_rwsem); |
889 | ctl = snd_emu10k1_look_for_ctl(emu, &id); | 903 | ctl = snd_emu10k1_look_for_ctl(emu, &id); |
@@ -941,12 +955,14 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu, | |||
941 | } | 955 | } |
942 | 956 | ||
943 | static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, | 957 | static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, |
944 | struct snd_emu10k1_fx8010_code *icode) | 958 | struct snd_emu10k1_fx8010_code *icode, |
959 | bool in_kernel) | ||
945 | { | 960 | { |
946 | int err = 0; | 961 | int err = 0; |
947 | 962 | ||
948 | mutex_lock(&emu->fx8010.lock); | 963 | mutex_lock(&emu->fx8010.lock); |
949 | if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0) | 964 | err = snd_emu10k1_verify_controls(emu, icode, in_kernel); |
965 | if (err < 0) | ||
950 | goto __error; | 966 | goto __error; |
951 | strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name)); | 967 | strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name)); |
952 | /* stop FX processor - this may be dangerous, but it's better to miss | 968 | /* stop FX processor - this may be dangerous, but it's better to miss |
@@ -956,11 +972,20 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, | |||
956 | else | 972 | else |
957 | snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP); | 973 | snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP); |
958 | /* ok, do the main job */ | 974 | /* ok, do the main job */ |
959 | if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 || | 975 | err = snd_emu10k1_del_controls(emu, icode, in_kernel); |
960 | (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 || | 976 | if (err < 0) |
961 | (err = snd_emu10k1_tram_poke(emu, icode)) < 0 || | 977 | goto __error; |
962 | (err = snd_emu10k1_code_poke(emu, icode)) < 0 || | 978 | err = snd_emu10k1_gpr_poke(emu, icode, in_kernel); |
963 | (err = snd_emu10k1_add_controls(emu, icode)) < 0) | 979 | if (err < 0) |
980 | goto __error; | ||
981 | err = snd_emu10k1_tram_poke(emu, icode, in_kernel); | ||
982 | if (err < 0) | ||
983 | goto __error; | ||
984 | err = snd_emu10k1_code_poke(emu, icode, in_kernel); | ||
985 | if (err < 0) | ||
986 | goto __error; | ||
987 | err = snd_emu10k1_add_controls(emu, icode, in_kernel); | ||
988 | if (err < 0) | ||
964 | goto __error; | 989 | goto __error; |
965 | /* start FX processor when the DSP code is updated */ | 990 | /* start FX processor when the DSP code is updated */ |
966 | if (emu->audigy) | 991 | if (emu->audigy) |
@@ -1179,7 +1204,6 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | |||
1179 | struct snd_emu10k1_fx8010_code *icode = NULL; | 1204 | struct snd_emu10k1_fx8010_code *icode = NULL; |
1180 | struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl; | 1205 | struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl; |
1181 | u32 *gpr_map; | 1206 | u32 *gpr_map; |
1182 | mm_segment_t seg; | ||
1183 | 1207 | ||
1184 | err = -ENOMEM; | 1208 | err = -ENOMEM; |
1185 | icode = kzalloc(sizeof(*icode), GFP_KERNEL); | 1209 | icode = kzalloc(sizeof(*icode), GFP_KERNEL); |
@@ -1739,13 +1763,11 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1739 | while (ptr < 0x400) | 1763 | while (ptr < 0x400) |
1740 | A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0); | 1764 | A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0); |
1741 | 1765 | ||
1742 | seg = snd_enter_user(); | ||
1743 | icode->gpr_add_control_count = nctl; | 1766 | icode->gpr_add_control_count = nctl; |
1744 | icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; | 1767 | icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; |
1745 | emu->support_tlv = 1; /* support TLV */ | 1768 | emu->support_tlv = 1; /* support TLV */ |
1746 | err = snd_emu10k1_icode_poke(emu, icode); | 1769 | err = snd_emu10k1_icode_poke(emu, icode, true); |
1747 | emu->support_tlv = 0; /* clear again */ | 1770 | emu->support_tlv = 0; /* clear again */ |
1748 | snd_leave_user(seg); | ||
1749 | 1771 | ||
1750 | __err: | 1772 | __err: |
1751 | kfree(controls); | 1773 | kfree(controls); |
@@ -1817,7 +1839,6 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) | |||
1817 | struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL; | 1839 | struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL; |
1818 | struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl; | 1840 | struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl; |
1819 | u32 *gpr_map; | 1841 | u32 *gpr_map; |
1820 | mm_segment_t seg; | ||
1821 | 1842 | ||
1822 | err = -ENOMEM; | 1843 | err = -ENOMEM; |
1823 | icode = kzalloc(sizeof(*icode), GFP_KERNEL); | 1844 | icode = kzalloc(sizeof(*icode), GFP_KERNEL); |
@@ -2368,13 +2389,11 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) | |||
2368 | 2389 | ||
2369 | if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0) | 2390 | if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0) |
2370 | goto __err; | 2391 | goto __err; |
2371 | seg = snd_enter_user(); | ||
2372 | icode->gpr_add_control_count = i; | 2392 | icode->gpr_add_control_count = i; |
2373 | icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; | 2393 | icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; |
2374 | emu->support_tlv = 1; /* support TLV */ | 2394 | emu->support_tlv = 1; /* support TLV */ |
2375 | err = snd_emu10k1_icode_poke(emu, icode); | 2395 | err = snd_emu10k1_icode_poke(emu, icode, true); |
2376 | emu->support_tlv = 0; /* clear again */ | 2396 | emu->support_tlv = 0; /* clear again */ |
2377 | snd_leave_user(seg); | ||
2378 | if (err >= 0) | 2397 | if (err >= 0) |
2379 | err = snd_emu10k1_ipcm_poke(emu, ipcm); | 2398 | err = snd_emu10k1_ipcm_poke(emu, ipcm); |
2380 | __err: | 2399 | __err: |
@@ -2537,7 +2556,7 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un | |||
2537 | icode = memdup_user(argp, sizeof(*icode)); | 2556 | icode = memdup_user(argp, sizeof(*icode)); |
2538 | if (IS_ERR(icode)) | 2557 | if (IS_ERR(icode)) |
2539 | return PTR_ERR(icode); | 2558 | return PTR_ERR(icode); |
2540 | res = snd_emu10k1_icode_poke(emu, icode); | 2559 | res = snd_emu10k1_icode_poke(emu, icode, false); |
2541 | kfree(icode); | 2560 | kfree(icode); |
2542 | return res; | 2561 | return res; |
2543 | case SNDRV_EMU10K1_IOCTL_CODE_PEEK: | 2562 | case SNDRV_EMU10K1_IOCTL_CODE_PEEK: |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index ef1cf530c929..5c9054a9f69e 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
@@ -164,7 +164,7 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic | |||
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
167 | static unsigned int capture_period_sizes[31] = { | 167 | static const unsigned int capture_period_sizes[31] = { |
168 | 384, 448, 512, 640, | 168 | 384, 448, 512, 640, |
169 | 384*2, 448*2, 512*2, 640*2, | 169 | 384*2, 448*2, 512*2, 640*2, |
170 | 384*4, 448*4, 512*4, 640*4, | 170 | 384*4, 448*4, 512*4, 640*4, |
@@ -175,17 +175,17 @@ static unsigned int capture_period_sizes[31] = { | |||
175 | 384*128,448*128,512*128 | 175 | 384*128,448*128,512*128 |
176 | }; | 176 | }; |
177 | 177 | ||
178 | static struct snd_pcm_hw_constraint_list hw_constraints_capture_period_sizes = { | 178 | static const struct snd_pcm_hw_constraint_list hw_constraints_capture_period_sizes = { |
179 | .count = 31, | 179 | .count = 31, |
180 | .list = capture_period_sizes, | 180 | .list = capture_period_sizes, |
181 | .mask = 0 | 181 | .mask = 0 |
182 | }; | 182 | }; |
183 | 183 | ||
184 | static unsigned int capture_rates[8] = { | 184 | static const unsigned int capture_rates[8] = { |
185 | 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000 | 185 | 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000 |
186 | }; | 186 | }; |
187 | 187 | ||
188 | static struct snd_pcm_hw_constraint_list hw_constraints_capture_rates = { | 188 | static const struct snd_pcm_hw_constraint_list hw_constraints_capture_rates = { |
189 | .count = 8, | 189 | .count = 8, |
190 | .list = capture_rates, | 190 | .list = capture_rates, |
191 | .mask = 0 | 191 | .mask = 0 |
@@ -1632,8 +1632,8 @@ static int snd_emu10k1_fx8010_playback_transfer(struct snd_pcm_substream *substr | |||
1632 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); | 1632 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); |
1633 | struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number]; | 1633 | struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number]; |
1634 | 1634 | ||
1635 | snd_pcm_indirect_playback_transfer(substream, &pcm->pcm_rec, fx8010_pb_trans_copy); | 1635 | return snd_pcm_indirect_playback_transfer(substream, &pcm->pcm_rec, |
1636 | return 0; | 1636 | fx8010_pb_trans_copy); |
1637 | } | 1637 | } |
1638 | 1638 | ||
1639 | static int snd_emu10k1_fx8010_playback_hw_params(struct snd_pcm_substream *substream, | 1639 | static int snd_emu10k1_fx8010_playback_hw_params(struct snd_pcm_substream *substream, |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 09a63ef41ef2..f0d978e3b274 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -467,41 +467,41 @@ MODULE_DEVICE_TABLE(pci, snd_audiopci_ids); | |||
467 | #define POLL_COUNT 0xa000 | 467 | #define POLL_COUNT 0xa000 |
468 | 468 | ||
469 | #ifdef CHIP1370 | 469 | #ifdef CHIP1370 |
470 | static unsigned int snd_es1370_fixed_rates[] = | 470 | static const unsigned int snd_es1370_fixed_rates[] = |
471 | {5512, 11025, 22050, 44100}; | 471 | {5512, 11025, 22050, 44100}; |
472 | static struct snd_pcm_hw_constraint_list snd_es1370_hw_constraints_rates = { | 472 | static const struct snd_pcm_hw_constraint_list snd_es1370_hw_constraints_rates = { |
473 | .count = 4, | 473 | .count = 4, |
474 | .list = snd_es1370_fixed_rates, | 474 | .list = snd_es1370_fixed_rates, |
475 | .mask = 0, | 475 | .mask = 0, |
476 | }; | 476 | }; |
477 | static struct snd_ratnum es1370_clock = { | 477 | static const struct snd_ratnum es1370_clock = { |
478 | .num = ES_1370_SRCLOCK, | 478 | .num = ES_1370_SRCLOCK, |
479 | .den_min = 29, | 479 | .den_min = 29, |
480 | .den_max = 353, | 480 | .den_max = 353, |
481 | .den_step = 1, | 481 | .den_step = 1, |
482 | }; | 482 | }; |
483 | static struct snd_pcm_hw_constraint_ratnums snd_es1370_hw_constraints_clock = { | 483 | static const struct snd_pcm_hw_constraint_ratnums snd_es1370_hw_constraints_clock = { |
484 | .nrats = 1, | 484 | .nrats = 1, |
485 | .rats = &es1370_clock, | 485 | .rats = &es1370_clock, |
486 | }; | 486 | }; |
487 | #else | 487 | #else |
488 | static struct snd_ratden es1371_dac_clock = { | 488 | static const struct snd_ratden es1371_dac_clock = { |
489 | .num_min = 3000 * (1 << 15), | 489 | .num_min = 3000 * (1 << 15), |
490 | .num_max = 48000 * (1 << 15), | 490 | .num_max = 48000 * (1 << 15), |
491 | .num_step = 3000, | 491 | .num_step = 3000, |
492 | .den = 1 << 15, | 492 | .den = 1 << 15, |
493 | }; | 493 | }; |
494 | static struct snd_pcm_hw_constraint_ratdens snd_es1371_hw_constraints_dac_clock = { | 494 | static const struct snd_pcm_hw_constraint_ratdens snd_es1371_hw_constraints_dac_clock = { |
495 | .nrats = 1, | 495 | .nrats = 1, |
496 | .rats = &es1371_dac_clock, | 496 | .rats = &es1371_dac_clock, |
497 | }; | 497 | }; |
498 | static struct snd_ratnum es1371_adc_clock = { | 498 | static const struct snd_ratnum es1371_adc_clock = { |
499 | .num = 48000 << 15, | 499 | .num = 48000 << 15, |
500 | .den_min = 32768, | 500 | .den_min = 32768, |
501 | .den_max = 393216, | 501 | .den_max = 393216, |
502 | .den_step = 1, | 502 | .den_step = 1, |
503 | }; | 503 | }; |
504 | static struct snd_pcm_hw_constraint_ratnums snd_es1371_hw_constraints_adc_clock = { | 504 | static const struct snd_pcm_hw_constraint_ratnums snd_es1371_hw_constraints_adc_clock = { |
505 | .nrats = 1, | 505 | .nrats = 1, |
506 | .rats = &es1371_adc_clock, | 506 | .rats = &es1371_adc_clock, |
507 | }; | 507 | }; |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index e8d943071a8c..069902a06f00 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
@@ -436,7 +436,7 @@ static void snd_es1938_reset_fifo(struct es1938 *chip) | |||
436 | outb(0, SLSB_REG(chip, RESET)); | 436 | outb(0, SLSB_REG(chip, RESET)); |
437 | } | 437 | } |
438 | 438 | ||
439 | static struct snd_ratnum clocks[2] = { | 439 | static const struct snd_ratnum clocks[2] = { |
440 | { | 440 | { |
441 | .num = 793800, | 441 | .num = 793800, |
442 | .den_min = 1, | 442 | .den_min = 1, |
@@ -451,7 +451,7 @@ static struct snd_ratnum clocks[2] = { | |||
451 | } | 451 | } |
452 | }; | 452 | }; |
453 | 453 | ||
454 | static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = { | 454 | static const struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = { |
455 | .nrats = 2, | 455 | .nrats = 2, |
456 | .rats = clocks, | 456 | .rats = clocks, |
457 | }; | 457 | }; |
@@ -839,15 +839,12 @@ static snd_pcm_uframes_t snd_es1938_playback_pointer(struct snd_pcm_substream *s | |||
839 | } | 839 | } |
840 | 840 | ||
841 | static int snd_es1938_capture_copy(struct snd_pcm_substream *substream, | 841 | static int snd_es1938_capture_copy(struct snd_pcm_substream *substream, |
842 | int channel, | 842 | int channel, unsigned long pos, |
843 | snd_pcm_uframes_t pos, | 843 | void __user *dst, unsigned long count) |
844 | void __user *dst, | ||
845 | snd_pcm_uframes_t count) | ||
846 | { | 844 | { |
847 | struct snd_pcm_runtime *runtime = substream->runtime; | 845 | struct snd_pcm_runtime *runtime = substream->runtime; |
848 | struct es1938 *chip = snd_pcm_substream_chip(substream); | 846 | struct es1938 *chip = snd_pcm_substream_chip(substream); |
849 | pos <<= chip->dma1_shift; | 847 | |
850 | count <<= chip->dma1_shift; | ||
851 | if (snd_BUG_ON(pos + count > chip->dma1_size)) | 848 | if (snd_BUG_ON(pos + count > chip->dma1_size)) |
852 | return -EINVAL; | 849 | return -EINVAL; |
853 | if (pos + count < chip->dma1_size) { | 850 | if (pos + count < chip->dma1_size) { |
@@ -856,12 +853,31 @@ static int snd_es1938_capture_copy(struct snd_pcm_substream *substream, | |||
856 | } else { | 853 | } else { |
857 | if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1)) | 854 | if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1)) |
858 | return -EFAULT; | 855 | return -EFAULT; |
859 | if (put_user(runtime->dma_area[0], ((unsigned char __user *)dst) + count - 1)) | 856 | if (put_user(runtime->dma_area[0], |
857 | ((unsigned char __user *)dst) + count - 1)) | ||
860 | return -EFAULT; | 858 | return -EFAULT; |
861 | } | 859 | } |
862 | return 0; | 860 | return 0; |
863 | } | 861 | } |
864 | 862 | ||
863 | static int snd_es1938_capture_copy_kernel(struct snd_pcm_substream *substream, | ||
864 | int channel, unsigned long pos, | ||
865 | void *dst, unsigned long count) | ||
866 | { | ||
867 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
868 | struct es1938 *chip = snd_pcm_substream_chip(substream); | ||
869 | |||
870 | if (snd_BUG_ON(pos + count > chip->dma1_size)) | ||
871 | return -EINVAL; | ||
872 | if (pos + count < chip->dma1_size) { | ||
873 | memcpy(dst, runtime->dma_area + pos + 1, count); | ||
874 | } else { | ||
875 | memcpy(dst, runtime->dma_area + pos + 1, count - 1); | ||
876 | runtime->dma_area[0] = *((unsigned char *)dst + count - 1); | ||
877 | } | ||
878 | return 0; | ||
879 | } | ||
880 | |||
865 | /* | 881 | /* |
866 | * buffer management | 882 | * buffer management |
867 | */ | 883 | */ |
@@ -1012,7 +1028,8 @@ static const struct snd_pcm_ops snd_es1938_capture_ops = { | |||
1012 | .prepare = snd_es1938_capture_prepare, | 1028 | .prepare = snd_es1938_capture_prepare, |
1013 | .trigger = snd_es1938_capture_trigger, | 1029 | .trigger = snd_es1938_capture_trigger, |
1014 | .pointer = snd_es1938_capture_pointer, | 1030 | .pointer = snd_es1938_capture_pointer, |
1015 | .copy = snd_es1938_capture_copy, | 1031 | .copy_user = snd_es1938_capture_copy, |
1032 | .copy_kernel = snd_es1938_capture_copy_kernel, | ||
1016 | }; | 1033 | }; |
1017 | 1034 | ||
1018 | static int snd_es1938_new_pcm(struct es1938 *chip, int device) | 1035 | static int snd_es1938_new_pcm(struct es1938 *chip, int device) |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index c47287d79306..2e402ece4c86 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -334,23 +334,23 @@ static unsigned short snd_fm801_codec_read(struct snd_ac97 *ac97, unsigned short | |||
334 | return fm801_readw(chip, AC97_DATA); | 334 | return fm801_readw(chip, AC97_DATA); |
335 | } | 335 | } |
336 | 336 | ||
337 | static unsigned int rates[] = { | 337 | static const unsigned int rates[] = { |
338 | 5500, 8000, 9600, 11025, | 338 | 5500, 8000, 9600, 11025, |
339 | 16000, 19200, 22050, 32000, | 339 | 16000, 19200, 22050, 32000, |
340 | 38400, 44100, 48000 | 340 | 38400, 44100, 48000 |
341 | }; | 341 | }; |
342 | 342 | ||
343 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 343 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
344 | .count = ARRAY_SIZE(rates), | 344 | .count = ARRAY_SIZE(rates), |
345 | .list = rates, | 345 | .list = rates, |
346 | .mask = 0, | 346 | .mask = 0, |
347 | }; | 347 | }; |
348 | 348 | ||
349 | static unsigned int channels[] = { | 349 | static const unsigned int channels[] = { |
350 | 2, 4, 6 | 350 | 2, 4, 6 |
351 | }; | 351 | }; |
352 | 352 | ||
353 | static struct snd_pcm_hw_constraint_list hw_constraints_channels = { | 353 | static const struct snd_pcm_hw_constraint_list hw_constraints_channels = { |
354 | .count = ARRAY_SIZE(channels), | 354 | .count = ARRAY_SIZE(channels), |
355 | .list = channels, | 355 | .list = channels, |
356 | .mask = 0, | 356 | .mask = 0, |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 70bb365a08d2..821aad374a06 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -19,13 +19,11 @@ | |||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/mm.h> | ||
23 | #include <linux/init.h> | 22 | #include <linux/init.h> |
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
26 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
28 | #include <linux/async.h> | ||
29 | #include <linux/pm.h> | 27 | #include <linux/pm.h> |
30 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
31 | #include <sound/core.h> | 29 | #include <sound/core.h> |
@@ -1477,18 +1475,8 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, | |||
1477 | } | 1475 | } |
1478 | EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put); | 1476 | EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put); |
1479 | 1477 | ||
1480 | /** | 1478 | /* inquiry the amp caps and convert to TLV */ |
1481 | * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume | 1479 | static void get_ctl_amp_tlv(struct snd_kcontrol *kcontrol, unsigned int *tlv) |
1482 | * @kcontrol: ctl element | ||
1483 | * @op_flag: operation flag | ||
1484 | * @size: byte size of input TLV | ||
1485 | * @_tlv: TLV data | ||
1486 | * | ||
1487 | * The control element is supposed to have the private_value field | ||
1488 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. | ||
1489 | */ | ||
1490 | int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
1491 | unsigned int size, unsigned int __user *_tlv) | ||
1492 | { | 1480 | { |
1493 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1481 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1494 | hda_nid_t nid = get_amp_nid(kcontrol); | 1482 | hda_nid_t nid = get_amp_nid(kcontrol); |
@@ -1497,8 +1485,6 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
1497 | bool min_mute = get_amp_min_mute(kcontrol); | 1485 | bool min_mute = get_amp_min_mute(kcontrol); |
1498 | u32 caps, val1, val2; | 1486 | u32 caps, val1, val2; |
1499 | 1487 | ||
1500 | if (size < 4 * sizeof(unsigned int)) | ||
1501 | return -ENOMEM; | ||
1502 | caps = query_amp_caps(codec, nid, dir); | 1488 | caps = query_amp_caps(codec, nid, dir); |
1503 | val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT; | 1489 | val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT; |
1504 | val2 = (val2 + 1) * 25; | 1490 | val2 = (val2 + 1) * 25; |
@@ -1507,13 +1493,31 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
1507 | val1 = ((int)val1) * ((int)val2); | 1493 | val1 = ((int)val1) * ((int)val2); |
1508 | if (min_mute || (caps & AC_AMPCAP_MIN_MUTE)) | 1494 | if (min_mute || (caps & AC_AMPCAP_MIN_MUTE)) |
1509 | val2 |= TLV_DB_SCALE_MUTE; | 1495 | val2 |= TLV_DB_SCALE_MUTE; |
1510 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) | 1496 | tlv[0] = SNDRV_CTL_TLVT_DB_SCALE; |
1511 | return -EFAULT; | 1497 | tlv[1] = 2 * sizeof(unsigned int); |
1512 | if (put_user(2 * sizeof(unsigned int), _tlv + 1)) | 1498 | tlv[2] = val1; |
1513 | return -EFAULT; | 1499 | tlv[3] = val2; |
1514 | if (put_user(val1, _tlv + 2)) | 1500 | } |
1515 | return -EFAULT; | 1501 | |
1516 | if (put_user(val2, _tlv + 3)) | 1502 | /** |
1503 | * snd_hda_mixer_amp_tlv - TLV callback for a standard AMP mixer volume | ||
1504 | * @kcontrol: ctl element | ||
1505 | * @op_flag: operation flag | ||
1506 | * @size: byte size of input TLV | ||
1507 | * @_tlv: TLV data | ||
1508 | * | ||
1509 | * The control element is supposed to have the private_value field | ||
1510 | * set up via HDA_COMPOSE_AMP_VAL*() or related macros. | ||
1511 | */ | ||
1512 | int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
1513 | unsigned int size, unsigned int __user *_tlv) | ||
1514 | { | ||
1515 | unsigned int tlv[4]; | ||
1516 | |||
1517 | if (size < 4 * sizeof(unsigned int)) | ||
1518 | return -ENOMEM; | ||
1519 | get_ctl_amp_tlv(kcontrol, tlv); | ||
1520 | if (copy_to_user(_tlv, tlv, sizeof(tlv))) | ||
1517 | return -EFAULT; | 1521 | return -EFAULT; |
1518 | return 0; | 1522 | return 0; |
1519 | } | 1523 | } |
@@ -1807,13 +1811,10 @@ static int get_kctl_0dB_offset(struct hda_codec *codec, | |||
1807 | const int *tlv = NULL; | 1811 | const int *tlv = NULL; |
1808 | int val = -1; | 1812 | int val = -1; |
1809 | 1813 | ||
1810 | if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { | 1814 | if ((kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) && |
1811 | /* FIXME: set_fs() hack for obtaining user-space TLV data */ | 1815 | kctl->tlv.c == snd_hda_mixer_amp_tlv) { |
1812 | mm_segment_t fs = get_fs(); | 1816 | get_ctl_amp_tlv(kctl, _tlv); |
1813 | set_fs(get_ds()); | 1817 | tlv = _tlv; |
1814 | if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv)) | ||
1815 | tlv = _tlv; | ||
1816 | set_fs(fs); | ||
1817 | } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) | 1818 | } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) |
1818 | tlv = kctl->tlv.p; | 1819 | tlv = kctl->tlv.p; |
1819 | if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) { | 1820 | if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) { |
@@ -2118,196 +2119,6 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | |||
2118 | EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_put); | 2119 | EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_put); |
2119 | 2120 | ||
2120 | /* | 2121 | /* |
2121 | * bound volume controls | ||
2122 | * | ||
2123 | * bind multiple volumes (# indices, from 0) | ||
2124 | */ | ||
2125 | |||
2126 | #define AMP_VAL_IDX_SHIFT 19 | ||
2127 | #define AMP_VAL_IDX_MASK (0x0f<<19) | ||
2128 | |||
2129 | /** | ||
2130 | * snd_hda_mixer_bind_switch_get - Get callback for a bound volume control | ||
2131 | * @kcontrol: ctl element | ||
2132 | * @ucontrol: pointer to get/store the data | ||
2133 | * | ||
2134 | * The control element is supposed to have the private_value field | ||
2135 | * set up via HDA_BIND_MUTE*() macros. | ||
2136 | */ | ||
2137 | int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, | ||
2138 | struct snd_ctl_elem_value *ucontrol) | ||
2139 | { | ||
2140 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2141 | unsigned long pval; | ||
2142 | int err; | ||
2143 | |||
2144 | mutex_lock(&codec->control_mutex); | ||
2145 | pval = kcontrol->private_value; | ||
2146 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ | ||
2147 | err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | ||
2148 | kcontrol->private_value = pval; | ||
2149 | mutex_unlock(&codec->control_mutex); | ||
2150 | return err; | ||
2151 | } | ||
2152 | EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_switch_get); | ||
2153 | |||
2154 | /** | ||
2155 | * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control | ||
2156 | * @kcontrol: ctl element | ||
2157 | * @ucontrol: pointer to get/store the data | ||
2158 | * | ||
2159 | * The control element is supposed to have the private_value field | ||
2160 | * set up via HDA_BIND_MUTE*() macros. | ||
2161 | */ | ||
2162 | int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, | ||
2163 | struct snd_ctl_elem_value *ucontrol) | ||
2164 | { | ||
2165 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2166 | unsigned long pval; | ||
2167 | int i, indices, err = 0, change = 0; | ||
2168 | |||
2169 | mutex_lock(&codec->control_mutex); | ||
2170 | pval = kcontrol->private_value; | ||
2171 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; | ||
2172 | for (i = 0; i < indices; i++) { | ||
2173 | kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | | ||
2174 | (i << AMP_VAL_IDX_SHIFT); | ||
2175 | err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
2176 | if (err < 0) | ||
2177 | break; | ||
2178 | change |= err; | ||
2179 | } | ||
2180 | kcontrol->private_value = pval; | ||
2181 | mutex_unlock(&codec->control_mutex); | ||
2182 | return err < 0 ? err : change; | ||
2183 | } | ||
2184 | EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_switch_put); | ||
2185 | |||
2186 | /** | ||
2187 | * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control | ||
2188 | * @kcontrol: referred ctl element | ||
2189 | * @uinfo: pointer to get/store the data | ||
2190 | * | ||
2191 | * The control element is supposed to have the private_value field | ||
2192 | * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. | ||
2193 | */ | ||
2194 | int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, | ||
2195 | struct snd_ctl_elem_info *uinfo) | ||
2196 | { | ||
2197 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2198 | struct hda_bind_ctls *c; | ||
2199 | int err; | ||
2200 | |||
2201 | mutex_lock(&codec->control_mutex); | ||
2202 | c = (struct hda_bind_ctls *)kcontrol->private_value; | ||
2203 | kcontrol->private_value = *c->values; | ||
2204 | err = c->ops->info(kcontrol, uinfo); | ||
2205 | kcontrol->private_value = (long)c; | ||
2206 | mutex_unlock(&codec->control_mutex); | ||
2207 | return err; | ||
2208 | } | ||
2209 | EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_info); | ||
2210 | |||
2211 | /** | ||
2212 | * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control | ||
2213 | * @kcontrol: ctl element | ||
2214 | * @ucontrol: pointer to get/store the data | ||
2215 | * | ||
2216 | * The control element is supposed to have the private_value field | ||
2217 | * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. | ||
2218 | */ | ||
2219 | int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, | ||
2220 | struct snd_ctl_elem_value *ucontrol) | ||
2221 | { | ||
2222 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2223 | struct hda_bind_ctls *c; | ||
2224 | int err; | ||
2225 | |||
2226 | mutex_lock(&codec->control_mutex); | ||
2227 | c = (struct hda_bind_ctls *)kcontrol->private_value; | ||
2228 | kcontrol->private_value = *c->values; | ||
2229 | err = c->ops->get(kcontrol, ucontrol); | ||
2230 | kcontrol->private_value = (long)c; | ||
2231 | mutex_unlock(&codec->control_mutex); | ||
2232 | return err; | ||
2233 | } | ||
2234 | EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_get); | ||
2235 | |||
2236 | /** | ||
2237 | * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control | ||
2238 | * @kcontrol: ctl element | ||
2239 | * @ucontrol: pointer to get/store the data | ||
2240 | * | ||
2241 | * The control element is supposed to have the private_value field | ||
2242 | * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros. | ||
2243 | */ | ||
2244 | int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, | ||
2245 | struct snd_ctl_elem_value *ucontrol) | ||
2246 | { | ||
2247 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2248 | struct hda_bind_ctls *c; | ||
2249 | unsigned long *vals; | ||
2250 | int err = 0, change = 0; | ||
2251 | |||
2252 | mutex_lock(&codec->control_mutex); | ||
2253 | c = (struct hda_bind_ctls *)kcontrol->private_value; | ||
2254 | for (vals = c->values; *vals; vals++) { | ||
2255 | kcontrol->private_value = *vals; | ||
2256 | err = c->ops->put(kcontrol, ucontrol); | ||
2257 | if (err < 0) | ||
2258 | break; | ||
2259 | change |= err; | ||
2260 | } | ||
2261 | kcontrol->private_value = (long)c; | ||
2262 | mutex_unlock(&codec->control_mutex); | ||
2263 | return err < 0 ? err : change; | ||
2264 | } | ||
2265 | EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_put); | ||
2266 | |||
2267 | /** | ||
2268 | * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control | ||
2269 | * @kcontrol: ctl element | ||
2270 | * @op_flag: operation flag | ||
2271 | * @size: byte size of input TLV | ||
2272 | * @tlv: TLV data | ||
2273 | * | ||
2274 | * The control element is supposed to have the private_value field | ||
2275 | * set up via HDA_BIND_VOL() macro. | ||
2276 | */ | ||
2277 | int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
2278 | unsigned int size, unsigned int __user *tlv) | ||
2279 | { | ||
2280 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2281 | struct hda_bind_ctls *c; | ||
2282 | int err; | ||
2283 | |||
2284 | mutex_lock(&codec->control_mutex); | ||
2285 | c = (struct hda_bind_ctls *)kcontrol->private_value; | ||
2286 | kcontrol->private_value = *c->values; | ||
2287 | err = c->ops->tlv(kcontrol, op_flag, size, tlv); | ||
2288 | kcontrol->private_value = (long)c; | ||
2289 | mutex_unlock(&codec->control_mutex); | ||
2290 | return err; | ||
2291 | } | ||
2292 | EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_tlv); | ||
2293 | |||
2294 | struct hda_ctl_ops snd_hda_bind_vol = { | ||
2295 | .info = snd_hda_mixer_amp_volume_info, | ||
2296 | .get = snd_hda_mixer_amp_volume_get, | ||
2297 | .put = snd_hda_mixer_amp_volume_put, | ||
2298 | .tlv = snd_hda_mixer_amp_tlv | ||
2299 | }; | ||
2300 | EXPORT_SYMBOL_GPL(snd_hda_bind_vol); | ||
2301 | |||
2302 | struct hda_ctl_ops snd_hda_bind_sw = { | ||
2303 | .info = snd_hda_mixer_amp_switch_info, | ||
2304 | .get = snd_hda_mixer_amp_switch_get, | ||
2305 | .put = snd_hda_mixer_amp_switch_put, | ||
2306 | .tlv = snd_hda_mixer_amp_tlv | ||
2307 | }; | ||
2308 | EXPORT_SYMBOL_GPL(snd_hda_bind_sw); | ||
2309 | |||
2310 | /* | ||
2311 | * SPDIF out controls | 2122 | * SPDIF out controls |
2312 | */ | 2123 | */ |
2313 | 2124 | ||
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 2842c82363c0..557ecfcad158 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -948,6 +948,8 @@ static void resume_path_from_idx(struct hda_codec *codec, int path_idx) | |||
948 | 948 | ||
949 | static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, | 949 | static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, |
950 | struct snd_ctl_elem_value *ucontrol); | 950 | struct snd_ctl_elem_value *ucontrol); |
951 | static int hda_gen_bind_mute_get(struct snd_kcontrol *kcontrol, | ||
952 | struct snd_ctl_elem_value *ucontrol); | ||
951 | static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol, | 953 | static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol, |
952 | struct snd_ctl_elem_value *ucontrol); | 954 | struct snd_ctl_elem_value *ucontrol); |
953 | 955 | ||
@@ -970,7 +972,7 @@ static const struct snd_kcontrol_new control_templates[] = { | |||
970 | { | 972 | { |
971 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 973 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
972 | .info = snd_hda_mixer_amp_switch_info, | 974 | .info = snd_hda_mixer_amp_switch_info, |
973 | .get = snd_hda_mixer_bind_switch_get, | 975 | .get = hda_gen_bind_mute_get, |
974 | .put = hda_gen_bind_mute_put, /* replaced */ | 976 | .put = hda_gen_bind_mute_put, /* replaced */ |
975 | .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0), | 977 | .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0), |
976 | }, | 978 | }, |
@@ -1101,11 +1103,51 @@ static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, | |||
1101 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | 1103 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); |
1102 | } | 1104 | } |
1103 | 1105 | ||
1106 | /* | ||
1107 | * Bound mute controls | ||
1108 | */ | ||
1109 | #define AMP_VAL_IDX_SHIFT 19 | ||
1110 | #define AMP_VAL_IDX_MASK (0x0f<<19) | ||
1111 | |||
1112 | static int hda_gen_bind_mute_get(struct snd_kcontrol *kcontrol, | ||
1113 | struct snd_ctl_elem_value *ucontrol) | ||
1114 | { | ||
1115 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1116 | unsigned long pval; | ||
1117 | int err; | ||
1118 | |||
1119 | mutex_lock(&codec->control_mutex); | ||
1120 | pval = kcontrol->private_value; | ||
1121 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ | ||
1122 | err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | ||
1123 | kcontrol->private_value = pval; | ||
1124 | mutex_unlock(&codec->control_mutex); | ||
1125 | return err; | ||
1126 | } | ||
1127 | |||
1104 | static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol, | 1128 | static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol, |
1105 | struct snd_ctl_elem_value *ucontrol) | 1129 | struct snd_ctl_elem_value *ucontrol) |
1106 | { | 1130 | { |
1131 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1132 | unsigned long pval; | ||
1133 | int i, indices, err = 0, change = 0; | ||
1134 | |||
1107 | sync_auto_mute_bits(kcontrol, ucontrol); | 1135 | sync_auto_mute_bits(kcontrol, ucontrol); |
1108 | return snd_hda_mixer_bind_switch_put(kcontrol, ucontrol); | 1136 | |
1137 | mutex_lock(&codec->control_mutex); | ||
1138 | pval = kcontrol->private_value; | ||
1139 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; | ||
1140 | for (i = 0; i < indices; i++) { | ||
1141 | kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | | ||
1142 | (i << AMP_VAL_IDX_SHIFT); | ||
1143 | err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
1144 | if (err < 0) | ||
1145 | break; | ||
1146 | change |= err; | ||
1147 | } | ||
1148 | kcontrol->private_value = pval; | ||
1149 | mutex_unlock(&codec->control_mutex); | ||
1150 | return err < 0 ? err : change; | ||
1109 | } | 1151 | } |
1110 | 1152 | ||
1111 | /* any ctl assigned to the path with the given index? */ | 1153 | /* any ctl assigned to the path with the given index? */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index d0e066e4c985..5b5c324c99b9 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -178,67 +178,6 @@ void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook); | |||
178 | #define HDA_AMP_UNMUTE 0x00 | 178 | #define HDA_AMP_UNMUTE 0x00 |
179 | #define HDA_AMP_VOLMASK 0x7f | 179 | #define HDA_AMP_VOLMASK 0x7f |
180 | 180 | ||
181 | /* mono switch binding multiple inputs */ | ||
182 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ | ||
183 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
184 | .info = snd_hda_mixer_amp_switch_info, \ | ||
185 | .get = snd_hda_mixer_bind_switch_get, \ | ||
186 | .put = snd_hda_mixer_bind_switch_put, \ | ||
187 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } | ||
188 | |||
189 | /* stereo switch binding multiple inputs */ | ||
190 | #define HDA_BIND_MUTE(xname,nid,indices,dir) \ | ||
191 | HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) | ||
192 | |||
193 | int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, | ||
194 | struct snd_ctl_elem_value *ucontrol); | ||
195 | int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, | ||
196 | struct snd_ctl_elem_value *ucontrol); | ||
197 | |||
198 | /* more generic bound controls */ | ||
199 | struct hda_ctl_ops { | ||
200 | snd_kcontrol_info_t *info; | ||
201 | snd_kcontrol_get_t *get; | ||
202 | snd_kcontrol_put_t *put; | ||
203 | snd_kcontrol_tlv_rw_t *tlv; | ||
204 | }; | ||
205 | |||
206 | extern struct hda_ctl_ops snd_hda_bind_vol; /* for bind-volume with TLV */ | ||
207 | extern struct hda_ctl_ops snd_hda_bind_sw; /* for bind-switch */ | ||
208 | |||
209 | struct hda_bind_ctls { | ||
210 | struct hda_ctl_ops *ops; | ||
211 | unsigned long values[]; | ||
212 | }; | ||
213 | |||
214 | int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, | ||
215 | struct snd_ctl_elem_info *uinfo); | ||
216 | int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, | ||
217 | struct snd_ctl_elem_value *ucontrol); | ||
218 | int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, | ||
219 | struct snd_ctl_elem_value *ucontrol); | ||
220 | int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
221 | unsigned int size, unsigned int __user *tlv); | ||
222 | |||
223 | #define HDA_BIND_VOL(xname, bindrec) \ | ||
224 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
225 | .name = xname, \ | ||
226 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | ||
227 | SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | ||
228 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,\ | ||
229 | .info = snd_hda_mixer_bind_ctls_info,\ | ||
230 | .get = snd_hda_mixer_bind_ctls_get,\ | ||
231 | .put = snd_hda_mixer_bind_ctls_put,\ | ||
232 | .tlv = { .c = snd_hda_mixer_bind_tlv },\ | ||
233 | .private_value = (long) (bindrec) } | ||
234 | #define HDA_BIND_SW(xname, bindrec) \ | ||
235 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\ | ||
236 | .name = xname, \ | ||
237 | .info = snd_hda_mixer_bind_ctls_info,\ | ||
238 | .get = snd_hda_mixer_bind_ctls_get,\ | ||
239 | .put = snd_hda_mixer_bind_ctls_put,\ | ||
240 | .private_value = (long) (bindrec) } | ||
241 | |||
242 | /* | 181 | /* |
243 | * SPDIF I/O | 182 | * SPDIF I/O |
244 | */ | 183 | */ |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 90e4ff87445e..0d7955eec201 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -2782,21 +2782,21 @@ static int nvhdmi_7x_init_8ch(struct hda_codec *codec) | |||
2782 | return 0; | 2782 | return 0; |
2783 | } | 2783 | } |
2784 | 2784 | ||
2785 | static unsigned int channels_2_6_8[] = { | 2785 | static const unsigned int channels_2_6_8[] = { |
2786 | 2, 6, 8 | 2786 | 2, 6, 8 |
2787 | }; | 2787 | }; |
2788 | 2788 | ||
2789 | static unsigned int channels_2_8[] = { | 2789 | static const unsigned int channels_2_8[] = { |
2790 | 2, 8 | 2790 | 2, 8 |
2791 | }; | 2791 | }; |
2792 | 2792 | ||
2793 | static struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = { | 2793 | static const struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = { |
2794 | .count = ARRAY_SIZE(channels_2_6_8), | 2794 | .count = ARRAY_SIZE(channels_2_6_8), |
2795 | .list = channels_2_6_8, | 2795 | .list = channels_2_6_8, |
2796 | .mask = 0, | 2796 | .mask = 0, |
2797 | }; | 2797 | }; |
2798 | 2798 | ||
2799 | static struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = { | 2799 | static const struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = { |
2800 | .count = ARRAY_SIZE(channels_2_8), | 2800 | .count = ARRAY_SIZE(channels_2_8), |
2801 | .list = channels_2_8, | 2801 | .list = channels_2_8, |
2802 | .mask = 0, | 2802 | .mask = 0, |
@@ -2807,7 +2807,7 @@ static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo, | |||
2807 | struct snd_pcm_substream *substream) | 2807 | struct snd_pcm_substream *substream) |
2808 | { | 2808 | { |
2809 | struct hdmi_spec *spec = codec->spec; | 2809 | struct hdmi_spec *spec = codec->spec; |
2810 | struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL; | 2810 | const struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL; |
2811 | 2811 | ||
2812 | switch (codec->preset->vendor_id) { | 2812 | switch (codec->preset->vendor_id) { |
2813 | case 0x10de0002: | 2813 | case 0x10de0002: |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cbeebc0a9711..17fe05da0119 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -2575,18 +2575,37 @@ static int patch_alc262(struct hda_codec *codec) | |||
2575 | * ALC268 | 2575 | * ALC268 |
2576 | */ | 2576 | */ |
2577 | /* bind Beep switches of both NID 0x0f and 0x10 */ | 2577 | /* bind Beep switches of both NID 0x0f and 0x10 */ |
2578 | static const struct hda_bind_ctls alc268_bind_beep_sw = { | 2578 | static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol, |
2579 | .ops = &snd_hda_bind_sw, | 2579 | struct snd_ctl_elem_value *ucontrol) |
2580 | .values = { | 2580 | { |
2581 | HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), | 2581 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2582 | HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), | 2582 | unsigned long pval; |
2583 | 0 | 2583 | int err; |
2584 | }, | 2584 | |
2585 | }; | 2585 | mutex_lock(&codec->control_mutex); |
2586 | pval = kcontrol->private_value; | ||
2587 | kcontrol->private_value = (pval & ~0xff) | 0x0f; | ||
2588 | err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
2589 | if (err >= 0) { | ||
2590 | kcontrol->private_value = (pval & ~0xff) | 0x10; | ||
2591 | err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
2592 | } | ||
2593 | kcontrol->private_value = pval; | ||
2594 | mutex_unlock(&codec->control_mutex); | ||
2595 | return err; | ||
2596 | } | ||
2586 | 2597 | ||
2587 | static const struct snd_kcontrol_new alc268_beep_mixer[] = { | 2598 | static const struct snd_kcontrol_new alc268_beep_mixer[] = { |
2588 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), | 2599 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), |
2589 | HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), | 2600 | { |
2601 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2602 | .name = "Beep Playback Switch", | ||
2603 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
2604 | .info = snd_hda_mixer_amp_switch_info, | ||
2605 | .get = snd_hda_mixer_amp_switch_get, | ||
2606 | .put = alc268_beep_switch_put, | ||
2607 | .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT) | ||
2608 | }, | ||
2590 | { } | 2609 | { } |
2591 | }; | 2610 | }; |
2592 | 2611 | ||
@@ -3043,6 +3062,74 @@ static void alc283_shutup(struct hda_codec *codec) | |||
3043 | alc_write_coef_idx(codec, 0x43, 0x9614); | 3062 | alc_write_coef_idx(codec, 0x43, 0x9614); |
3044 | } | 3063 | } |
3045 | 3064 | ||
3065 | static void alc256_init(struct hda_codec *codec) | ||
3066 | { | ||
3067 | struct alc_spec *spec = codec->spec; | ||
3068 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
3069 | bool hp_pin_sense; | ||
3070 | |||
3071 | if (!hp_pin) | ||
3072 | return; | ||
3073 | |||
3074 | msleep(30); | ||
3075 | |||
3076 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | ||
3077 | |||
3078 | if (hp_pin_sense) | ||
3079 | msleep(2); | ||
3080 | |||
3081 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ | ||
3082 | |||
3083 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3084 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3085 | |||
3086 | if (hp_pin_sense) | ||
3087 | msleep(85); | ||
3088 | |||
3089 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3090 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
3091 | |||
3092 | if (hp_pin_sense) | ||
3093 | msleep(100); | ||
3094 | |||
3095 | alc_update_coef_idx(codec, 0x46, 3 << 12, 0); | ||
3096 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ | ||
3097 | } | ||
3098 | |||
3099 | static void alc256_shutup(struct hda_codec *codec) | ||
3100 | { | ||
3101 | struct alc_spec *spec = codec->spec; | ||
3102 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
3103 | bool hp_pin_sense; | ||
3104 | |||
3105 | if (!hp_pin) { | ||
3106 | alc269_shutup(codec); | ||
3107 | return; | ||
3108 | } | ||
3109 | |||
3110 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | ||
3111 | |||
3112 | if (hp_pin_sense) | ||
3113 | msleep(2); | ||
3114 | |||
3115 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3116 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3117 | |||
3118 | if (hp_pin_sense) | ||
3119 | msleep(85); | ||
3120 | |||
3121 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3122 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
3123 | |||
3124 | alc_update_coef_idx(codec, 0x46, 0, 3 << 12); /* 3k pull low control for Headset jack. */ | ||
3125 | |||
3126 | if (hp_pin_sense) | ||
3127 | msleep(100); | ||
3128 | |||
3129 | alc_auto_setup_eapd(codec, false); | ||
3130 | snd_hda_shutup_pins(codec); | ||
3131 | } | ||
3132 | |||
3046 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, | 3133 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, |
3047 | unsigned int val) | 3134 | unsigned int val) |
3048 | { | 3135 | { |
@@ -6464,6 +6551,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
6464 | break; | 6551 | break; |
6465 | case 0x10ec0256: | 6552 | case 0x10ec0256: |
6466 | spec->codec_variant = ALC269_TYPE_ALC256; | 6553 | spec->codec_variant = ALC269_TYPE_ALC256; |
6554 | spec->shutup = alc256_shutup; | ||
6555 | spec->init_hook = alc256_init; | ||
6467 | spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */ | 6556 | spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */ |
6468 | alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ | 6557 | alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/ |
6469 | break; | 6558 | break; |
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index ffda38c45509..f63acb1b965c 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c | |||
@@ -169,8 +169,8 @@ static int si3054_pcm_open(struct hda_pcm_stream *hinfo, | |||
169 | struct hda_codec *codec, | 169 | struct hda_codec *codec, |
170 | struct snd_pcm_substream *substream) | 170 | struct snd_pcm_substream *substream) |
171 | { | 171 | { |
172 | static unsigned int rates[] = { 8000, 9600, 16000 }; | 172 | static const unsigned int rates[] = { 8000, 9600, 16000 }; |
173 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 173 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
174 | .count = ARRAY_SIZE(rates), | 174 | .count = ARRAY_SIZE(rates), |
175 | .list = rates, | 175 | .list = rates, |
176 | .mask = 0, | 176 | .mask = 0, |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 1d8612cabb9e..0e66afa403a3 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -932,10 +932,10 @@ static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device) | |||
932 | * PCM code - professional part (multitrack) | 932 | * PCM code - professional part (multitrack) |
933 | */ | 933 | */ |
934 | 934 | ||
935 | static unsigned int rates[] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000, | 935 | static const unsigned int rates[] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000, |
936 | 32000, 44100, 48000, 64000, 88200, 96000 }; | 936 | 32000, 44100, 48000, 64000, 88200, 96000 }; |
937 | 937 | ||
938 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 938 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
939 | .count = ARRAY_SIZE(rates), | 939 | .count = ARRAY_SIZE(rates), |
940 | .list = rates, | 940 | .list = rates, |
941 | .mask = 0, | 941 | .mask = 0, |
@@ -1401,7 +1401,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] = { | |||
1401 | }, | 1401 | }, |
1402 | }; | 1402 | }; |
1403 | 1403 | ||
1404 | static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch = { | 1404 | static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch = { |
1405 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1405 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1406 | .name = "H/W Multi Capture Switch", | 1406 | .name = "H/W Multi Capture Switch", |
1407 | .info = snd_ice1712_pro_mixer_switch_info, | 1407 | .info = snd_ice1712_pro_mixer_switch_info, |
@@ -1420,7 +1420,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch = { | |||
1420 | .count = 2, | 1420 | .count = 2, |
1421 | }; | 1421 | }; |
1422 | 1422 | ||
1423 | static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume = { | 1423 | static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume = { |
1424 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1424 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1425 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 1425 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
1426 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), | 1426 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), |
@@ -2165,7 +2165,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol, | |||
2165 | return change; | 2165 | return change; |
2166 | } | 2166 | } |
2167 | 2167 | ||
2168 | static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route = { | 2168 | static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route = { |
2169 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2169 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2170 | .name = "H/W Playback Route", | 2170 | .name = "H/W Playback Route", |
2171 | .info = snd_ice1712_pro_route_info, | 2171 | .info = snd_ice1712_pro_route_info, |
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index 58f8f2ae758d..5cfba09c9761 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h | |||
@@ -348,7 +348,7 @@ struct snd_ice1712 { | |||
348 | 348 | ||
349 | struct mutex open_mutex; | 349 | struct mutex open_mutex; |
350 | struct snd_pcm_substream *pcm_reserved[4]; | 350 | struct snd_pcm_substream *pcm_reserved[4]; |
351 | struct snd_pcm_hw_constraint_list *hw_rates; /* card-specific rate constraints */ | 351 | const struct snd_pcm_hw_constraint_list *hw_rates; /* card-specific rate constraints */ |
352 | 352 | ||
353 | unsigned int akm_codecs; | 353 | unsigned int akm_codecs; |
354 | struct snd_akm4xxx *akm; | 354 | struct snd_akm4xxx *akm; |
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 9cd6e55c0642..057c2f394ea7 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -521,25 +521,25 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) | |||
521 | * PCM code - professional part (multitrack) | 521 | * PCM code - professional part (multitrack) |
522 | */ | 522 | */ |
523 | 523 | ||
524 | static unsigned int rates[] = { | 524 | static const unsigned int rates[] = { |
525 | 8000, 9600, 11025, 12000, 16000, 22050, 24000, | 525 | 8000, 9600, 11025, 12000, 16000, 22050, 24000, |
526 | 32000, 44100, 48000, 64000, 88200, 96000, | 526 | 32000, 44100, 48000, 64000, 88200, 96000, |
527 | 176400, 192000, | 527 | 176400, 192000, |
528 | }; | 528 | }; |
529 | 529 | ||
530 | static struct snd_pcm_hw_constraint_list hw_constraints_rates_96 = { | 530 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates_96 = { |
531 | .count = ARRAY_SIZE(rates) - 2, /* up to 96000 */ | 531 | .count = ARRAY_SIZE(rates) - 2, /* up to 96000 */ |
532 | .list = rates, | 532 | .list = rates, |
533 | .mask = 0, | 533 | .mask = 0, |
534 | }; | 534 | }; |
535 | 535 | ||
536 | static struct snd_pcm_hw_constraint_list hw_constraints_rates_48 = { | 536 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates_48 = { |
537 | .count = ARRAY_SIZE(rates) - 5, /* up to 48000 */ | 537 | .count = ARRAY_SIZE(rates) - 5, /* up to 48000 */ |
538 | .list = rates, | 538 | .list = rates, |
539 | .mask = 0, | 539 | .mask = 0, |
540 | }; | 540 | }; |
541 | 541 | ||
542 | static struct snd_pcm_hw_constraint_list hw_constraints_rates_192 = { | 542 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates_192 = { |
543 | .count = ARRAY_SIZE(rates), | 543 | .count = ARRAY_SIZE(rates), |
544 | .list = rates, | 544 | .list = rates, |
545 | .mask = 0, | 545 | .mask = 0, |
@@ -2142,7 +2142,7 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol, | |||
2142 | digital_route_shift(idx)); | 2142 | digital_route_shift(idx)); |
2143 | } | 2143 | } |
2144 | 2144 | ||
2145 | static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route = | 2145 | static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route = |
2146 | { | 2146 | { |
2147 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2147 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2148 | .name = "H/W Playback Route", | 2148 | .name = "H/W Playback Route", |
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 4f0213427152..5bb146703738 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c | |||
@@ -133,19 +133,19 @@ struct juli_spec { | |||
133 | /* | 133 | /* |
134 | * Initial setup of the conversion array GPIO <-> rate | 134 | * Initial setup of the conversion array GPIO <-> rate |
135 | */ | 135 | */ |
136 | static unsigned int juli_rates[] = { | 136 | static const unsigned int juli_rates[] = { |
137 | 16000, 22050, 24000, 32000, | 137 | 16000, 22050, 24000, 32000, |
138 | 44100, 48000, 64000, 88200, | 138 | 44100, 48000, 64000, 88200, |
139 | 96000, 176400, 192000, | 139 | 96000, 176400, 192000, |
140 | }; | 140 | }; |
141 | 141 | ||
142 | static unsigned int gpio_vals[] = { | 142 | static const unsigned int gpio_vals[] = { |
143 | GPIO_RATE_16000, GPIO_RATE_22050, GPIO_RATE_24000, GPIO_RATE_32000, | 143 | GPIO_RATE_16000, GPIO_RATE_22050, GPIO_RATE_24000, GPIO_RATE_32000, |
144 | GPIO_RATE_44100, GPIO_RATE_48000, GPIO_RATE_64000, GPIO_RATE_88200, | 144 | GPIO_RATE_44100, GPIO_RATE_48000, GPIO_RATE_64000, GPIO_RATE_88200, |
145 | GPIO_RATE_96000, GPIO_RATE_176400, GPIO_RATE_192000, | 145 | GPIO_RATE_96000, GPIO_RATE_176400, GPIO_RATE_192000, |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static struct snd_pcm_hw_constraint_list juli_rates_info = { | 148 | static const struct snd_pcm_hw_constraint_list juli_rates_info = { |
149 | .count = ARRAY_SIZE(juli_rates), | 149 | .count = ARRAY_SIZE(juli_rates), |
150 | .list = juli_rates, | 150 | .list = juli_rates, |
151 | .mask = 0, | 151 | .mask = 0, |
diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c index 7de25c4807fd..0e30419f6bbd 100644 --- a/sound/pci/ice1712/maya44.c +++ b/sound/pci/ice1712/maya44.c | |||
@@ -661,12 +661,12 @@ static void set_rate(struct snd_ice1712 *ice, unsigned int rate) | |||
661 | * supported sample rates (to override the default one) | 661 | * supported sample rates (to override the default one) |
662 | */ | 662 | */ |
663 | 663 | ||
664 | static unsigned int rates[] = { | 664 | static const unsigned int rates[] = { |
665 | 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000 | 665 | 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000 |
666 | }; | 666 | }; |
667 | 667 | ||
668 | /* playback rates: 32..192 kHz */ | 668 | /* playback rates: 32..192 kHz */ |
669 | static struct snd_pcm_hw_constraint_list dac_rates = { | 669 | static const struct snd_pcm_hw_constraint_list dac_rates = { |
670 | .count = ARRAY_SIZE(rates), | 670 | .count = ARRAY_SIZE(rates), |
671 | .list = rates, | 671 | .list = rates, |
672 | .mask = 0 | 672 | .mask = 0 |
diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c index 7c387b04067e..f1b3732cc6d2 100644 --- a/sound/pci/ice1712/quartet.c +++ b/sound/pci/ice1712/quartet.c | |||
@@ -231,17 +231,17 @@ static char *get_binary(char *buffer, int value) | |||
231 | /* | 231 | /* |
232 | * Initial setup of the conversion array GPIO <-> rate | 232 | * Initial setup of the conversion array GPIO <-> rate |
233 | */ | 233 | */ |
234 | static unsigned int qtet_rates[] = { | 234 | static const unsigned int qtet_rates[] = { |
235 | 44100, 48000, 88200, | 235 | 44100, 48000, 88200, |
236 | 96000, 176400, 192000, | 236 | 96000, 176400, 192000, |
237 | }; | 237 | }; |
238 | 238 | ||
239 | static unsigned int cks_vals[] = { | 239 | static const unsigned int cks_vals[] = { |
240 | CPLD_CKS_44100HZ, CPLD_CKS_48000HZ, CPLD_CKS_88200HZ, | 240 | CPLD_CKS_44100HZ, CPLD_CKS_48000HZ, CPLD_CKS_88200HZ, |
241 | CPLD_CKS_96000HZ, CPLD_CKS_176400HZ, CPLD_CKS_192000HZ, | 241 | CPLD_CKS_96000HZ, CPLD_CKS_176400HZ, CPLD_CKS_192000HZ, |
242 | }; | 242 | }; |
243 | 243 | ||
244 | static struct snd_pcm_hw_constraint_list qtet_rates_info = { | 244 | static const struct snd_pcm_hw_constraint_list qtet_rates_info = { |
245 | .count = ARRAY_SIZE(qtet_rates), | 245 | .count = ARRAY_SIZE(qtet_rates), |
246 | .list = qtet_rates, | 246 | .list = qtet_rates, |
247 | .mask = 0, | 247 | .mask = 0, |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 6d17b171c17b..a8d7092e93dd 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -1136,31 +1136,31 @@ static struct snd_pcm_hardware snd_intel8x0_stream = | |||
1136 | .fifo_size = 0, | 1136 | .fifo_size = 0, |
1137 | }; | 1137 | }; |
1138 | 1138 | ||
1139 | static unsigned int channels4[] = { | 1139 | static const unsigned int channels4[] = { |
1140 | 2, 4, | 1140 | 2, 4, |
1141 | }; | 1141 | }; |
1142 | 1142 | ||
1143 | static struct snd_pcm_hw_constraint_list hw_constraints_channels4 = { | 1143 | static const struct snd_pcm_hw_constraint_list hw_constraints_channels4 = { |
1144 | .count = ARRAY_SIZE(channels4), | 1144 | .count = ARRAY_SIZE(channels4), |
1145 | .list = channels4, | 1145 | .list = channels4, |
1146 | .mask = 0, | 1146 | .mask = 0, |
1147 | }; | 1147 | }; |
1148 | 1148 | ||
1149 | static unsigned int channels6[] = { | 1149 | static const unsigned int channels6[] = { |
1150 | 2, 4, 6, | 1150 | 2, 4, 6, |
1151 | }; | 1151 | }; |
1152 | 1152 | ||
1153 | static struct snd_pcm_hw_constraint_list hw_constraints_channels6 = { | 1153 | static const struct snd_pcm_hw_constraint_list hw_constraints_channels6 = { |
1154 | .count = ARRAY_SIZE(channels6), | 1154 | .count = ARRAY_SIZE(channels6), |
1155 | .list = channels6, | 1155 | .list = channels6, |
1156 | .mask = 0, | 1156 | .mask = 0, |
1157 | }; | 1157 | }; |
1158 | 1158 | ||
1159 | static unsigned int channels8[] = { | 1159 | static const unsigned int channels8[] = { |
1160 | 2, 4, 6, 8, | 1160 | 2, 4, 6, 8, |
1161 | }; | 1161 | }; |
1162 | 1162 | ||
1163 | static struct snd_pcm_hw_constraint_list hw_constraints_channels8 = { | 1163 | static const struct snd_pcm_hw_constraint_list hw_constraints_channels8 = { |
1164 | .count = ARRAY_SIZE(channels8), | 1164 | .count = ARRAY_SIZE(channels8), |
1165 | .list = channels8, | 1165 | .list = channels8, |
1166 | .mask = 0, | 1166 | .mask = 0, |
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 1bc98c867133..18ff668ce7a5 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c | |||
@@ -635,8 +635,8 @@ static struct snd_pcm_hardware snd_intel8x0m_stream = | |||
635 | 635 | ||
636 | static int snd_intel8x0m_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev) | 636 | static int snd_intel8x0m_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev) |
637 | { | 637 | { |
638 | static unsigned int rates[] = { 8000, 9600, 12000, 16000 }; | 638 | static const unsigned int rates[] = { 8000, 9600, 12000, 16000 }; |
639 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 639 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
640 | .count = ARRAY_SIZE(rates), | 640 | .count = ARRAY_SIZE(rates), |
641 | .list = rates, | 641 | .list = rates, |
642 | .mask = 0, | 642 | .mask = 0, |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 1e25095fd144..b28fe4914d6b 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -1299,13 +1299,21 @@ static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int coun | |||
1299 | return 0; | 1299 | return 0; |
1300 | } | 1300 | } |
1301 | 1301 | ||
1302 | static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst, int pos, int count, int offset, int size) | 1302 | static int snd_korg1212_copy_to(struct snd_pcm_substream *substream, |
1303 | void __user *dst, int pos, int count, | ||
1304 | bool in_kernel) | ||
1303 | { | 1305 | { |
1304 | struct KorgAudioFrame * src = korg1212->recordDataBufsPtr[0].bufferData + pos; | 1306 | struct snd_pcm_runtime *runtime = substream->runtime; |
1305 | int i, rc; | 1307 | struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream); |
1306 | 1308 | struct KorgAudioFrame *src; | |
1307 | K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n", | 1309 | int i, size; |
1308 | pos, offset, size); | 1310 | |
1311 | pos = bytes_to_frames(runtime, pos); | ||
1312 | count = bytes_to_frames(runtime, count); | ||
1313 | size = korg1212->channels * 2; | ||
1314 | src = korg1212->recordDataBufsPtr[0].bufferData + pos; | ||
1315 | K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d size=%d count=%d\n", | ||
1316 | pos, size, count); | ||
1309 | if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES)) | 1317 | if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES)) |
1310 | return -EINVAL; | 1318 | return -EINVAL; |
1311 | 1319 | ||
@@ -1317,11 +1325,10 @@ static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst, | |||
1317 | return -EFAULT; | 1325 | return -EFAULT; |
1318 | } | 1326 | } |
1319 | #endif | 1327 | #endif |
1320 | rc = copy_to_user(dst + offset, src, size); | 1328 | if (in_kernel) |
1321 | if (rc) { | 1329 | memcpy((void *)dst, src, size); |
1322 | K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i); | 1330 | else if (copy_to_user(dst, src, size)) |
1323 | return -EFAULT; | 1331 | return -EFAULT; |
1324 | } | ||
1325 | src++; | 1332 | src++; |
1326 | dst += size; | 1333 | dst += size; |
1327 | } | 1334 | } |
@@ -1329,13 +1336,22 @@ static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst, | |||
1329 | return 0; | 1336 | return 0; |
1330 | } | 1337 | } |
1331 | 1338 | ||
1332 | static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *src, int pos, int count, int offset, int size) | 1339 | static int snd_korg1212_copy_from(struct snd_pcm_substream *substream, |
1340 | void __user *src, int pos, int count, | ||
1341 | bool in_kernel) | ||
1333 | { | 1342 | { |
1334 | struct KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos; | 1343 | struct snd_pcm_runtime *runtime = substream->runtime; |
1335 | int i, rc; | 1344 | struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream); |
1345 | struct KorgAudioFrame *dst; | ||
1346 | int i, size; | ||
1336 | 1347 | ||
1337 | K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n", | 1348 | pos = bytes_to_frames(runtime, pos); |
1338 | pos, offset, size, count); | 1349 | count = bytes_to_frames(runtime, count); |
1350 | size = korg1212->channels * 2; | ||
1351 | dst = korg1212->playDataBufsPtr[0].bufferData + pos; | ||
1352 | |||
1353 | K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d size=%d count=%d\n", | ||
1354 | pos, size, count); | ||
1339 | 1355 | ||
1340 | if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES)) | 1356 | if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES)) |
1341 | return -EINVAL; | 1357 | return -EINVAL; |
@@ -1348,11 +1364,10 @@ static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *sr | |||
1348 | return -EFAULT; | 1364 | return -EFAULT; |
1349 | } | 1365 | } |
1350 | #endif | 1366 | #endif |
1351 | rc = copy_from_user((void*) dst + offset, src, size); | 1367 | if (in_kernel) |
1352 | if (rc) { | 1368 | memcpy((void *)dst, src, size); |
1353 | K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i); | 1369 | else if (copy_from_user(dst, src, size)) |
1354 | return -EFAULT; | 1370 | return -EFAULT; |
1355 | } | ||
1356 | dst++; | 1371 | dst++; |
1357 | src += size; | 1372 | src += size; |
1358 | } | 1373 | } |
@@ -1640,45 +1655,46 @@ static snd_pcm_uframes_t snd_korg1212_capture_pointer(struct snd_pcm_substream * | |||
1640 | } | 1655 | } |
1641 | 1656 | ||
1642 | static int snd_korg1212_playback_copy(struct snd_pcm_substream *substream, | 1657 | static int snd_korg1212_playback_copy(struct snd_pcm_substream *substream, |
1643 | int channel, /* not used (interleaved data) */ | 1658 | int channel, unsigned long pos, |
1644 | snd_pcm_uframes_t pos, | 1659 | void __user *src, unsigned long count) |
1645 | void __user *src, | ||
1646 | snd_pcm_uframes_t count) | ||
1647 | { | 1660 | { |
1648 | struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream); | 1661 | return snd_korg1212_copy_from(substream, src, pos, count, false); |
1649 | 1662 | } | |
1650 | K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_copy [%s] %ld %ld\n", | ||
1651 | stateName[korg1212->cardState], pos, count); | ||
1652 | |||
1653 | return snd_korg1212_copy_from(korg1212, src, pos, count, 0, korg1212->channels * 2); | ||
1654 | 1663 | ||
1664 | static int snd_korg1212_playback_copy_kernel(struct snd_pcm_substream *substream, | ||
1665 | int channel, unsigned long pos, | ||
1666 | void *src, unsigned long count) | ||
1667 | { | ||
1668 | return snd_korg1212_copy_from(substream, (void __user *)src, | ||
1669 | pos, count, true); | ||
1655 | } | 1670 | } |
1656 | 1671 | ||
1657 | static int snd_korg1212_playback_silence(struct snd_pcm_substream *substream, | 1672 | static int snd_korg1212_playback_silence(struct snd_pcm_substream *substream, |
1658 | int channel, /* not used (interleaved data) */ | 1673 | int channel, /* not used (interleaved data) */ |
1659 | snd_pcm_uframes_t pos, | 1674 | unsigned long pos, |
1660 | snd_pcm_uframes_t count) | 1675 | unsigned long count) |
1661 | { | 1676 | { |
1677 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1662 | struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream); | 1678 | struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream); |
1663 | 1679 | ||
1664 | K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_silence [%s]\n", | 1680 | return snd_korg1212_silence(korg1212, bytes_to_frames(runtime, pos), |
1665 | stateName[korg1212->cardState]); | 1681 | bytes_to_frames(runtime, count), |
1666 | 1682 | 0, korg1212->channels * 2); | |
1667 | return snd_korg1212_silence(korg1212, pos, count, 0, korg1212->channels * 2); | ||
1668 | } | 1683 | } |
1669 | 1684 | ||
1670 | static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream, | 1685 | static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream, |
1671 | int channel, /* not used (interleaved data) */ | 1686 | int channel, unsigned long pos, |
1672 | snd_pcm_uframes_t pos, | 1687 | void __user *dst, unsigned long count) |
1673 | void __user *dst, | ||
1674 | snd_pcm_uframes_t count) | ||
1675 | { | 1688 | { |
1676 | struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream); | 1689 | return snd_korg1212_copy_to(substream, dst, pos, count, false); |
1677 | 1690 | } | |
1678 | K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_capture_copy [%s] %ld %ld\n", | ||
1679 | stateName[korg1212->cardState], pos, count); | ||
1680 | 1691 | ||
1681 | return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2); | 1692 | static int snd_korg1212_capture_copy_kernel(struct snd_pcm_substream *substream, |
1693 | int channel, unsigned long pos, | ||
1694 | void *dst, unsigned long count) | ||
1695 | { | ||
1696 | return snd_korg1212_copy_to(substream, (void __user *)dst, | ||
1697 | pos, count, true); | ||
1682 | } | 1698 | } |
1683 | 1699 | ||
1684 | static const struct snd_pcm_ops snd_korg1212_playback_ops = { | 1700 | static const struct snd_pcm_ops snd_korg1212_playback_ops = { |
@@ -1689,8 +1705,9 @@ static const struct snd_pcm_ops snd_korg1212_playback_ops = { | |||
1689 | .prepare = snd_korg1212_prepare, | 1705 | .prepare = snd_korg1212_prepare, |
1690 | .trigger = snd_korg1212_trigger, | 1706 | .trigger = snd_korg1212_trigger, |
1691 | .pointer = snd_korg1212_playback_pointer, | 1707 | .pointer = snd_korg1212_playback_pointer, |
1692 | .copy = snd_korg1212_playback_copy, | 1708 | .copy_user = snd_korg1212_playback_copy, |
1693 | .silence = snd_korg1212_playback_silence, | 1709 | .copy_kernel = snd_korg1212_playback_copy_kernel, |
1710 | .fill_silence = snd_korg1212_playback_silence, | ||
1694 | }; | 1711 | }; |
1695 | 1712 | ||
1696 | static const struct snd_pcm_ops snd_korg1212_capture_ops = { | 1713 | static const struct snd_pcm_ops snd_korg1212_capture_ops = { |
@@ -1701,7 +1718,8 @@ static const struct snd_pcm_ops snd_korg1212_capture_ops = { | |||
1701 | .prepare = snd_korg1212_prepare, | 1718 | .prepare = snd_korg1212_prepare, |
1702 | .trigger = snd_korg1212_trigger, | 1719 | .trigger = snd_korg1212_trigger, |
1703 | .pointer = snd_korg1212_capture_pointer, | 1720 | .pointer = snd_korg1212_capture_pointer, |
1704 | .copy = snd_korg1212_capture_copy, | 1721 | .copy_user = snd_korg1212_capture_copy, |
1722 | .copy_kernel = snd_korg1212_capture_copy_kernel, | ||
1705 | }; | 1723 | }; |
1706 | 1724 | ||
1707 | /* | 1725 | /* |
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c index 4a4616aac787..2b9496a66c77 100644 --- a/sound/pci/mixart/mixart_mixer.c +++ b/sound/pci/mixart/mixart_mixer.c | |||
@@ -404,7 +404,7 @@ static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
404 | 404 | ||
405 | static const DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0); | 405 | static const DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0); |
406 | 406 | ||
407 | static struct snd_kcontrol_new mixart_control_analog_level = { | 407 | static const struct snd_kcontrol_new mixart_control_analog_level = { |
408 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 408 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
409 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 409 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
410 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), | 410 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), |
@@ -897,7 +897,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
897 | 897 | ||
898 | static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); | 898 | static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); |
899 | 899 | ||
900 | static struct snd_kcontrol_new snd_mixart_pcm_vol = | 900 | static const struct snd_kcontrol_new snd_mixart_pcm_vol = |
901 | { | 901 | { |
902 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 902 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
903 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 903 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
@@ -951,7 +951,7 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
951 | return changed; | 951 | return changed; |
952 | } | 952 | } |
953 | 953 | ||
954 | static struct snd_kcontrol_new mixart_control_pcm_switch = { | 954 | static const struct snd_kcontrol_new mixart_control_pcm_switch = { |
955 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 955 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
956 | /* name will be filled later */ | 956 | /* name will be filled later */ |
957 | .count = MIXART_PLAYBACK_STREAMS, | 957 | .count = MIXART_PLAYBACK_STREAMS, |
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 103fe311e5a9..0ef8054c3936 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -398,10 +398,10 @@ snd_nm256_load_coefficient(struct nm256 *chip, int stream, int number) | |||
398 | 398 | ||
399 | 399 | ||
400 | /* The actual rates supported by the card. */ | 400 | /* The actual rates supported by the card. */ |
401 | static unsigned int samplerates[8] = { | 401 | static const unsigned int samplerates[8] = { |
402 | 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, | 402 | 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, |
403 | }; | 403 | }; |
404 | static struct snd_pcm_hw_constraint_list constraints_rates = { | 404 | static const struct snd_pcm_hw_constraint_list constraints_rates = { |
405 | .count = ARRAY_SIZE(samplerates), | 405 | .count = ARRAY_SIZE(samplerates), |
406 | .list = samplerates, | 406 | .list = samplerates, |
407 | .mask = 0, | 407 | .mask = 0, |
@@ -695,53 +695,68 @@ snd_nm256_capture_pointer(struct snd_pcm_substream *substream) | |||
695 | */ | 695 | */ |
696 | static int | 696 | static int |
697 | snd_nm256_playback_silence(struct snd_pcm_substream *substream, | 697 | snd_nm256_playback_silence(struct snd_pcm_substream *substream, |
698 | int channel, /* not used (interleaved data) */ | 698 | int channel, unsigned long pos, unsigned long count) |
699 | snd_pcm_uframes_t pos, | ||
700 | snd_pcm_uframes_t count) | ||
701 | { | 699 | { |
702 | struct snd_pcm_runtime *runtime = substream->runtime; | 700 | struct snd_pcm_runtime *runtime = substream->runtime; |
703 | struct nm256_stream *s = runtime->private_data; | 701 | struct nm256_stream *s = runtime->private_data; |
704 | count = frames_to_bytes(runtime, count); | 702 | |
705 | pos = frames_to_bytes(runtime, pos); | ||
706 | memset_io(s->bufptr + pos, 0, count); | 703 | memset_io(s->bufptr + pos, 0, count); |
707 | return 0; | 704 | return 0; |
708 | } | 705 | } |
709 | 706 | ||
710 | static int | 707 | static int |
711 | snd_nm256_playback_copy(struct snd_pcm_substream *substream, | 708 | snd_nm256_playback_copy(struct snd_pcm_substream *substream, |
712 | int channel, /* not used (interleaved data) */ | 709 | int channel, unsigned long pos, |
713 | snd_pcm_uframes_t pos, | 710 | void __user *src, unsigned long count) |
714 | void __user *src, | ||
715 | snd_pcm_uframes_t count) | ||
716 | { | 711 | { |
717 | struct snd_pcm_runtime *runtime = substream->runtime; | 712 | struct snd_pcm_runtime *runtime = substream->runtime; |
718 | struct nm256_stream *s = runtime->private_data; | 713 | struct nm256_stream *s = runtime->private_data; |
719 | count = frames_to_bytes(runtime, count); | 714 | |
720 | pos = frames_to_bytes(runtime, pos); | ||
721 | if (copy_from_user_toio(s->bufptr + pos, src, count)) | 715 | if (copy_from_user_toio(s->bufptr + pos, src, count)) |
722 | return -EFAULT; | 716 | return -EFAULT; |
723 | return 0; | 717 | return 0; |
724 | } | 718 | } |
725 | 719 | ||
720 | static int | ||
721 | snd_nm256_playback_copy_kernel(struct snd_pcm_substream *substream, | ||
722 | int channel, unsigned long pos, | ||
723 | void *src, unsigned long count) | ||
724 | { | ||
725 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
726 | struct nm256_stream *s = runtime->private_data; | ||
727 | |||
728 | memcpy_toio(s->bufptr + pos, src, count); | ||
729 | return 0; | ||
730 | } | ||
731 | |||
726 | /* | 732 | /* |
727 | * copy to user | 733 | * copy to user |
728 | */ | 734 | */ |
729 | static int | 735 | static int |
730 | snd_nm256_capture_copy(struct snd_pcm_substream *substream, | 736 | snd_nm256_capture_copy(struct snd_pcm_substream *substream, |
731 | int channel, /* not used (interleaved data) */ | 737 | int channel, unsigned long pos, |
732 | snd_pcm_uframes_t pos, | 738 | void __user *dst, unsigned long count) |
733 | void __user *dst, | ||
734 | snd_pcm_uframes_t count) | ||
735 | { | 739 | { |
736 | struct snd_pcm_runtime *runtime = substream->runtime; | 740 | struct snd_pcm_runtime *runtime = substream->runtime; |
737 | struct nm256_stream *s = runtime->private_data; | 741 | struct nm256_stream *s = runtime->private_data; |
738 | count = frames_to_bytes(runtime, count); | 742 | |
739 | pos = frames_to_bytes(runtime, pos); | ||
740 | if (copy_to_user_fromio(dst, s->bufptr + pos, count)) | 743 | if (copy_to_user_fromio(dst, s->bufptr + pos, count)) |
741 | return -EFAULT; | 744 | return -EFAULT; |
742 | return 0; | 745 | return 0; |
743 | } | 746 | } |
744 | 747 | ||
748 | static int | ||
749 | snd_nm256_capture_copy_kernel(struct snd_pcm_substream *substream, | ||
750 | int channel, unsigned long pos, | ||
751 | void *dst, unsigned long count) | ||
752 | { | ||
753 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
754 | struct nm256_stream *s = runtime->private_data; | ||
755 | |||
756 | memcpy_fromio(dst, s->bufptr + pos, count); | ||
757 | return 0; | ||
758 | } | ||
759 | |||
745 | #endif /* !__i386__ */ | 760 | #endif /* !__i386__ */ |
746 | 761 | ||
747 | 762 | ||
@@ -911,8 +926,9 @@ static const struct snd_pcm_ops snd_nm256_playback_ops = { | |||
911 | .trigger = snd_nm256_playback_trigger, | 926 | .trigger = snd_nm256_playback_trigger, |
912 | .pointer = snd_nm256_playback_pointer, | 927 | .pointer = snd_nm256_playback_pointer, |
913 | #ifndef __i386__ | 928 | #ifndef __i386__ |
914 | .copy = snd_nm256_playback_copy, | 929 | .copy_user = snd_nm256_playback_copy, |
915 | .silence = snd_nm256_playback_silence, | 930 | .copy_kernel = snd_nm256_playback_copy_kernel, |
931 | .fill_silence = snd_nm256_playback_silence, | ||
916 | #endif | 932 | #endif |
917 | .mmap = snd_pcm_lib_mmap_iomem, | 933 | .mmap = snd_pcm_lib_mmap_iomem, |
918 | }; | 934 | }; |
@@ -926,7 +942,8 @@ static const struct snd_pcm_ops snd_nm256_capture_ops = { | |||
926 | .trigger = snd_nm256_capture_trigger, | 942 | .trigger = snd_nm256_capture_trigger, |
927 | .pointer = snd_nm256_capture_pointer, | 943 | .pointer = snd_nm256_capture_pointer, |
928 | #ifndef __i386__ | 944 | #ifndef __i386__ |
929 | .copy = snd_nm256_capture_copy, | 945 | .copy_user = snd_nm256_capture_copy, |
946 | .copy_kernel = snd_nm256_capture_copy_kernel, | ||
930 | #endif | 947 | #endif |
931 | .mmap = snd_pcm_lib_mmap_iomem, | 948 | .mmap = snd_pcm_lib_mmap_iomem, |
932 | }; | 949 | }; |
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 96d15db65dfd..e4cdef94e4a2 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c | |||
@@ -254,39 +254,46 @@ static inline unsigned int snd_rme32_pcm_byteptr(struct rme32 * rme32) | |||
254 | } | 254 | } |
255 | 255 | ||
256 | /* silence callback for halfduplex mode */ | 256 | /* silence callback for halfduplex mode */ |
257 | static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */ | 257 | static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, |
258 | snd_pcm_uframes_t pos, | 258 | int channel, unsigned long pos, |
259 | snd_pcm_uframes_t count) | 259 | unsigned long count) |
260 | { | 260 | { |
261 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); | 261 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); |
262 | count <<= rme32->playback_frlog; | 262 | |
263 | pos <<= rme32->playback_frlog; | ||
264 | memset_io(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 0, count); | 263 | memset_io(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 0, count); |
265 | return 0; | 264 | return 0; |
266 | } | 265 | } |
267 | 266 | ||
268 | /* copy callback for halfduplex mode */ | 267 | /* copy callback for halfduplex mode */ |
269 | static int snd_rme32_playback_copy(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */ | 268 | static int snd_rme32_playback_copy(struct snd_pcm_substream *substream, |
270 | snd_pcm_uframes_t pos, | 269 | int channel, unsigned long pos, |
271 | void __user *src, snd_pcm_uframes_t count) | 270 | void __user *src, unsigned long count) |
272 | { | 271 | { |
273 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); | 272 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); |
274 | count <<= rme32->playback_frlog; | 273 | |
275 | pos <<= rme32->playback_frlog; | ||
276 | if (copy_from_user_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos, | 274 | if (copy_from_user_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos, |
277 | src, count)) | 275 | src, count)) |
278 | return -EFAULT; | 276 | return -EFAULT; |
279 | return 0; | 277 | return 0; |
280 | } | 278 | } |
281 | 279 | ||
280 | static int snd_rme32_playback_copy_kernel(struct snd_pcm_substream *substream, | ||
281 | int channel, unsigned long pos, | ||
282 | void *src, unsigned long count) | ||
283 | { | ||
284 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); | ||
285 | |||
286 | memcpy_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos, src, count); | ||
287 | return 0; | ||
288 | } | ||
289 | |||
282 | /* copy callback for halfduplex mode */ | 290 | /* copy callback for halfduplex mode */ |
283 | static int snd_rme32_capture_copy(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */ | 291 | static int snd_rme32_capture_copy(struct snd_pcm_substream *substream, |
284 | snd_pcm_uframes_t pos, | 292 | int channel, unsigned long pos, |
285 | void __user *dst, snd_pcm_uframes_t count) | 293 | void __user *dst, unsigned long count) |
286 | { | 294 | { |
287 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); | 295 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); |
288 | count <<= rme32->capture_frlog; | 296 | |
289 | pos <<= rme32->capture_frlog; | ||
290 | if (copy_to_user_fromio(dst, | 297 | if (copy_to_user_fromio(dst, |
291 | rme32->iobase + RME32_IO_DATA_BUFFER + pos, | 298 | rme32->iobase + RME32_IO_DATA_BUFFER + pos, |
292 | count)) | 299 | count)) |
@@ -294,6 +301,16 @@ static int snd_rme32_capture_copy(struct snd_pcm_substream *substream, int chann | |||
294 | return 0; | 301 | return 0; |
295 | } | 302 | } |
296 | 303 | ||
304 | static int snd_rme32_capture_copy_kernel(struct snd_pcm_substream *substream, | ||
305 | int channel, unsigned long pos, | ||
306 | void *dst, unsigned long count) | ||
307 | { | ||
308 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); | ||
309 | |||
310 | memcpy_fromio(dst, rme32->iobase + RME32_IO_DATA_BUFFER + pos, count); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
297 | /* | 314 | /* |
298 | * SPDIF I/O capabilities (half-duplex mode) | 315 | * SPDIF I/O capabilities (half-duplex mode) |
299 | */ | 316 | */ |
@@ -819,10 +836,9 @@ static irqreturn_t snd_rme32_interrupt(int irq, void *dev_id) | |||
819 | return IRQ_HANDLED; | 836 | return IRQ_HANDLED; |
820 | } | 837 | } |
821 | 838 | ||
822 | static unsigned int period_bytes[] = { RME32_BLOCK_SIZE }; | 839 | static const unsigned int period_bytes[] = { RME32_BLOCK_SIZE }; |
823 | |||
824 | 840 | ||
825 | static struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = { | 841 | static const struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = { |
826 | .count = ARRAY_SIZE(period_bytes), | 842 | .count = ARRAY_SIZE(period_bytes), |
827 | .list = period_bytes, | 843 | .list = period_bytes, |
828 | .mask = 0 | 844 | .mask = 0 |
@@ -1157,9 +1173,8 @@ static int snd_rme32_playback_fd_ack(struct snd_pcm_substream *substream) | |||
1157 | if (rme32->running & (1 << SNDRV_PCM_STREAM_CAPTURE)) | 1173 | if (rme32->running & (1 << SNDRV_PCM_STREAM_CAPTURE)) |
1158 | rec->hw_queue_size -= cprec->hw_ready; | 1174 | rec->hw_queue_size -= cprec->hw_ready; |
1159 | spin_unlock(&rme32->lock); | 1175 | spin_unlock(&rme32->lock); |
1160 | snd_pcm_indirect_playback_transfer(substream, rec, | 1176 | return snd_pcm_indirect_playback_transfer(substream, rec, |
1161 | snd_rme32_pb_trans_copy); | 1177 | snd_rme32_pb_trans_copy); |
1162 | return 0; | ||
1163 | } | 1178 | } |
1164 | 1179 | ||
1165 | static void snd_rme32_cp_trans_copy(struct snd_pcm_substream *substream, | 1180 | static void snd_rme32_cp_trans_copy(struct snd_pcm_substream *substream, |
@@ -1174,9 +1189,8 @@ static void snd_rme32_cp_trans_copy(struct snd_pcm_substream *substream, | |||
1174 | static int snd_rme32_capture_fd_ack(struct snd_pcm_substream *substream) | 1189 | static int snd_rme32_capture_fd_ack(struct snd_pcm_substream *substream) |
1175 | { | 1190 | { |
1176 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); | 1191 | struct rme32 *rme32 = snd_pcm_substream_chip(substream); |
1177 | snd_pcm_indirect_capture_transfer(substream, &rme32->capture_pcm, | 1192 | return snd_pcm_indirect_capture_transfer(substream, &rme32->capture_pcm, |
1178 | snd_rme32_cp_trans_copy); | 1193 | snd_rme32_cp_trans_copy); |
1179 | return 0; | ||
1180 | } | 1194 | } |
1181 | 1195 | ||
1182 | static snd_pcm_uframes_t | 1196 | static snd_pcm_uframes_t |
@@ -1205,8 +1219,9 @@ static const struct snd_pcm_ops snd_rme32_playback_spdif_ops = { | |||
1205 | .prepare = snd_rme32_playback_prepare, | 1219 | .prepare = snd_rme32_playback_prepare, |
1206 | .trigger = snd_rme32_pcm_trigger, | 1220 | .trigger = snd_rme32_pcm_trigger, |
1207 | .pointer = snd_rme32_playback_pointer, | 1221 | .pointer = snd_rme32_playback_pointer, |
1208 | .copy = snd_rme32_playback_copy, | 1222 | .copy_user = snd_rme32_playback_copy, |
1209 | .silence = snd_rme32_playback_silence, | 1223 | .copy_kernel = snd_rme32_playback_copy_kernel, |
1224 | .fill_silence = snd_rme32_playback_silence, | ||
1210 | .mmap = snd_pcm_lib_mmap_iomem, | 1225 | .mmap = snd_pcm_lib_mmap_iomem, |
1211 | }; | 1226 | }; |
1212 | 1227 | ||
@@ -1219,7 +1234,8 @@ static const struct snd_pcm_ops snd_rme32_capture_spdif_ops = { | |||
1219 | .prepare = snd_rme32_capture_prepare, | 1234 | .prepare = snd_rme32_capture_prepare, |
1220 | .trigger = snd_rme32_pcm_trigger, | 1235 | .trigger = snd_rme32_pcm_trigger, |
1221 | .pointer = snd_rme32_capture_pointer, | 1236 | .pointer = snd_rme32_capture_pointer, |
1222 | .copy = snd_rme32_capture_copy, | 1237 | .copy_user = snd_rme32_capture_copy, |
1238 | .copy_kernel = snd_rme32_capture_copy_kernel, | ||
1223 | .mmap = snd_pcm_lib_mmap_iomem, | 1239 | .mmap = snd_pcm_lib_mmap_iomem, |
1224 | }; | 1240 | }; |
1225 | 1241 | ||
@@ -1231,8 +1247,9 @@ static const struct snd_pcm_ops snd_rme32_playback_adat_ops = { | |||
1231 | .prepare = snd_rme32_playback_prepare, | 1247 | .prepare = snd_rme32_playback_prepare, |
1232 | .trigger = snd_rme32_pcm_trigger, | 1248 | .trigger = snd_rme32_pcm_trigger, |
1233 | .pointer = snd_rme32_playback_pointer, | 1249 | .pointer = snd_rme32_playback_pointer, |
1234 | .copy = snd_rme32_playback_copy, | 1250 | .copy_user = snd_rme32_playback_copy, |
1235 | .silence = snd_rme32_playback_silence, | 1251 | .copy_kernel = snd_rme32_playback_copy_kernel, |
1252 | .fill_silence = snd_rme32_playback_silence, | ||
1236 | .mmap = snd_pcm_lib_mmap_iomem, | 1253 | .mmap = snd_pcm_lib_mmap_iomem, |
1237 | }; | 1254 | }; |
1238 | 1255 | ||
@@ -1244,7 +1261,8 @@ static const struct snd_pcm_ops snd_rme32_capture_adat_ops = { | |||
1244 | .prepare = snd_rme32_capture_prepare, | 1261 | .prepare = snd_rme32_capture_prepare, |
1245 | .trigger = snd_rme32_pcm_trigger, | 1262 | .trigger = snd_rme32_pcm_trigger, |
1246 | .pointer = snd_rme32_capture_pointer, | 1263 | .pointer = snd_rme32_capture_pointer, |
1247 | .copy = snd_rme32_capture_copy, | 1264 | .copy_user = snd_rme32_capture_copy, |
1265 | .copy_kernel = snd_rme32_capture_copy_kernel, | ||
1248 | .mmap = snd_pcm_lib_mmap_iomem, | 1266 | .mmap = snd_pcm_lib_mmap_iomem, |
1249 | }; | 1267 | }; |
1250 | 1268 | ||
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 05b9da30990d..2e19ba55e754 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c | |||
@@ -327,13 +327,10 @@ snd_rme96_capture_ptr(struct rme96 *rme96) | |||
327 | 327 | ||
328 | static int | 328 | static int |
329 | snd_rme96_playback_silence(struct snd_pcm_substream *substream, | 329 | snd_rme96_playback_silence(struct snd_pcm_substream *substream, |
330 | int channel, /* not used (interleaved data) */ | 330 | int channel, unsigned long pos, unsigned long count) |
331 | snd_pcm_uframes_t pos, | ||
332 | snd_pcm_uframes_t count) | ||
333 | { | 331 | { |
334 | struct rme96 *rme96 = snd_pcm_substream_chip(substream); | 332 | struct rme96 *rme96 = snd_pcm_substream_chip(substream); |
335 | count <<= rme96->playback_frlog; | 333 | |
336 | pos <<= rme96->playback_frlog; | ||
337 | memset_io(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, | 334 | memset_io(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, |
338 | 0, count); | 335 | 0, count); |
339 | return 0; | 336 | return 0; |
@@ -341,32 +338,49 @@ snd_rme96_playback_silence(struct snd_pcm_substream *substream, | |||
341 | 338 | ||
342 | static int | 339 | static int |
343 | snd_rme96_playback_copy(struct snd_pcm_substream *substream, | 340 | snd_rme96_playback_copy(struct snd_pcm_substream *substream, |
344 | int channel, /* not used (interleaved data) */ | 341 | int channel, unsigned long pos, |
345 | snd_pcm_uframes_t pos, | 342 | void __user *src, unsigned long count) |
346 | void __user *src, | ||
347 | snd_pcm_uframes_t count) | ||
348 | { | 343 | { |
349 | struct rme96 *rme96 = snd_pcm_substream_chip(substream); | 344 | struct rme96 *rme96 = snd_pcm_substream_chip(substream); |
350 | count <<= rme96->playback_frlog; | 345 | |
351 | pos <<= rme96->playback_frlog; | 346 | return copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, |
352 | return copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, src, | 347 | src, count); |
353 | count); | 348 | } |
349 | |||
350 | static int | ||
351 | snd_rme96_playback_copy_kernel(struct snd_pcm_substream *substream, | ||
352 | int channel, unsigned long pos, | ||
353 | void *src, unsigned long count) | ||
354 | { | ||
355 | struct rme96 *rme96 = snd_pcm_substream_chip(substream); | ||
356 | |||
357 | memcpy_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, src, count); | ||
358 | return 0; | ||
354 | } | 359 | } |
355 | 360 | ||
356 | static int | 361 | static int |
357 | snd_rme96_capture_copy(struct snd_pcm_substream *substream, | 362 | snd_rme96_capture_copy(struct snd_pcm_substream *substream, |
358 | int channel, /* not used (interleaved data) */ | 363 | int channel, unsigned long pos, |
359 | snd_pcm_uframes_t pos, | 364 | void __user *dst, unsigned long count) |
360 | void __user *dst, | ||
361 | snd_pcm_uframes_t count) | ||
362 | { | 365 | { |
363 | struct rme96 *rme96 = snd_pcm_substream_chip(substream); | 366 | struct rme96 *rme96 = snd_pcm_substream_chip(substream); |
364 | count <<= rme96->capture_frlog; | 367 | |
365 | pos <<= rme96->capture_frlog; | 368 | return copy_to_user_fromio(dst, |
366 | return copy_to_user_fromio(dst, rme96->iobase + RME96_IO_REC_BUFFER + pos, | 369 | rme96->iobase + RME96_IO_REC_BUFFER + pos, |
367 | count); | 370 | count); |
368 | } | 371 | } |
369 | 372 | ||
373 | static int | ||
374 | snd_rme96_capture_copy_kernel(struct snd_pcm_substream *substream, | ||
375 | int channel, unsigned long pos, | ||
376 | void *dst, unsigned long count) | ||
377 | { | ||
378 | struct rme96 *rme96 = snd_pcm_substream_chip(substream); | ||
379 | |||
380 | memcpy_fromio(dst, rme96->iobase + RME96_IO_REC_BUFFER + pos, count); | ||
381 | return 0; | ||
382 | } | ||
383 | |||
370 | /* | 384 | /* |
371 | * Digital output capabilities (S/PDIF) | 385 | * Digital output capabilities (S/PDIF) |
372 | */ | 386 | */ |
@@ -1149,9 +1163,9 @@ snd_rme96_interrupt(int irq, | |||
1149 | return IRQ_HANDLED; | 1163 | return IRQ_HANDLED; |
1150 | } | 1164 | } |
1151 | 1165 | ||
1152 | static unsigned int period_bytes[] = { RME96_SMALL_BLOCK_SIZE, RME96_LARGE_BLOCK_SIZE }; | 1166 | static const unsigned int period_bytes[] = { RME96_SMALL_BLOCK_SIZE, RME96_LARGE_BLOCK_SIZE }; |
1153 | 1167 | ||
1154 | static struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = { | 1168 | static const struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = { |
1155 | .count = ARRAY_SIZE(period_bytes), | 1169 | .count = ARRAY_SIZE(period_bytes), |
1156 | .list = period_bytes, | 1170 | .list = period_bytes, |
1157 | .mask = 0 | 1171 | .mask = 0 |
@@ -1513,8 +1527,9 @@ static const struct snd_pcm_ops snd_rme96_playback_spdif_ops = { | |||
1513 | .prepare = snd_rme96_playback_prepare, | 1527 | .prepare = snd_rme96_playback_prepare, |
1514 | .trigger = snd_rme96_playback_trigger, | 1528 | .trigger = snd_rme96_playback_trigger, |
1515 | .pointer = snd_rme96_playback_pointer, | 1529 | .pointer = snd_rme96_playback_pointer, |
1516 | .copy = snd_rme96_playback_copy, | 1530 | .copy_user = snd_rme96_playback_copy, |
1517 | .silence = snd_rme96_playback_silence, | 1531 | .copy_kernel = snd_rme96_playback_copy_kernel, |
1532 | .fill_silence = snd_rme96_playback_silence, | ||
1518 | .mmap = snd_pcm_lib_mmap_iomem, | 1533 | .mmap = snd_pcm_lib_mmap_iomem, |
1519 | }; | 1534 | }; |
1520 | 1535 | ||
@@ -1526,7 +1541,8 @@ static const struct snd_pcm_ops snd_rme96_capture_spdif_ops = { | |||
1526 | .prepare = snd_rme96_capture_prepare, | 1541 | .prepare = snd_rme96_capture_prepare, |
1527 | .trigger = snd_rme96_capture_trigger, | 1542 | .trigger = snd_rme96_capture_trigger, |
1528 | .pointer = snd_rme96_capture_pointer, | 1543 | .pointer = snd_rme96_capture_pointer, |
1529 | .copy = snd_rme96_capture_copy, | 1544 | .copy_user = snd_rme96_capture_copy, |
1545 | .copy_kernel = snd_rme96_capture_copy_kernel, | ||
1530 | .mmap = snd_pcm_lib_mmap_iomem, | 1546 | .mmap = snd_pcm_lib_mmap_iomem, |
1531 | }; | 1547 | }; |
1532 | 1548 | ||
@@ -1538,8 +1554,9 @@ static const struct snd_pcm_ops snd_rme96_playback_adat_ops = { | |||
1538 | .prepare = snd_rme96_playback_prepare, | 1554 | .prepare = snd_rme96_playback_prepare, |
1539 | .trigger = snd_rme96_playback_trigger, | 1555 | .trigger = snd_rme96_playback_trigger, |
1540 | .pointer = snd_rme96_playback_pointer, | 1556 | .pointer = snd_rme96_playback_pointer, |
1541 | .copy = snd_rme96_playback_copy, | 1557 | .copy_user = snd_rme96_playback_copy, |
1542 | .silence = snd_rme96_playback_silence, | 1558 | .copy_kernel = snd_rme96_playback_copy_kernel, |
1559 | .fill_silence = snd_rme96_playback_silence, | ||
1543 | .mmap = snd_pcm_lib_mmap_iomem, | 1560 | .mmap = snd_pcm_lib_mmap_iomem, |
1544 | }; | 1561 | }; |
1545 | 1562 | ||
@@ -1551,7 +1568,8 @@ static const struct snd_pcm_ops snd_rme96_capture_adat_ops = { | |||
1551 | .prepare = snd_rme96_capture_prepare, | 1568 | .prepare = snd_rme96_capture_prepare, |
1552 | .trigger = snd_rme96_capture_trigger, | 1569 | .trigger = snd_rme96_capture_trigger, |
1553 | .pointer = snd_rme96_capture_pointer, | 1570 | .pointer = snd_rme96_capture_pointer, |
1554 | .copy = snd_rme96_capture_copy, | 1571 | .copy_user = snd_rme96_capture_copy, |
1572 | .copy_kernel = snd_rme96_capture_copy_kernel, | ||
1555 | .mmap = snd_pcm_lib_mmap_iomem, | 1573 | .mmap = snd_pcm_lib_mmap_iomem, |
1556 | }; | 1574 | }; |
1557 | 1575 | ||
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index fc0face6cdc6..fe36d44d16c6 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -3913,42 +3913,73 @@ static char *hdsp_channel_buffer_location(struct hdsp *hdsp, | |||
3913 | return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES); | 3913 | return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES); |
3914 | } | 3914 | } |
3915 | 3915 | ||
3916 | static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, int channel, | 3916 | static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, |
3917 | snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count) | 3917 | int channel, unsigned long pos, |
3918 | void __user *src, unsigned long count) | ||
3918 | { | 3919 | { |
3919 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); | 3920 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); |
3920 | char *channel_buf; | 3921 | char *channel_buf; |
3921 | 3922 | ||
3922 | if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4)) | 3923 | if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) |
3923 | return -EINVAL; | 3924 | return -EINVAL; |
3924 | 3925 | ||
3925 | channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); | 3926 | channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); |
3926 | if (snd_BUG_ON(!channel_buf)) | 3927 | if (snd_BUG_ON(!channel_buf)) |
3927 | return -EIO; | 3928 | return -EIO; |
3928 | if (copy_from_user(channel_buf + pos * 4, src, count * 4)) | 3929 | if (copy_from_user(channel_buf + pos, src, count)) |
3929 | return -EFAULT; | 3930 | return -EFAULT; |
3930 | return count; | 3931 | return 0; |
3931 | } | 3932 | } |
3932 | 3933 | ||
3933 | static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, int channel, | 3934 | static int snd_hdsp_playback_copy_kernel(struct snd_pcm_substream *substream, |
3934 | snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count) | 3935 | int channel, unsigned long pos, |
3936 | void *src, unsigned long count) | ||
3935 | { | 3937 | { |
3936 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); | 3938 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); |
3937 | char *channel_buf; | 3939 | char *channel_buf; |
3938 | 3940 | ||
3939 | if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4)) | 3941 | channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); |
3942 | if (snd_BUG_ON(!channel_buf)) | ||
3943 | return -EIO; | ||
3944 | memcpy(channel_buf + pos, src, count); | ||
3945 | return 0; | ||
3946 | } | ||
3947 | |||
3948 | static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, | ||
3949 | int channel, unsigned long pos, | ||
3950 | void __user *dst, unsigned long count) | ||
3951 | { | ||
3952 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); | ||
3953 | char *channel_buf; | ||
3954 | |||
3955 | if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) | ||
3940 | return -EINVAL; | 3956 | return -EINVAL; |
3941 | 3957 | ||
3942 | channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); | 3958 | channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); |
3943 | if (snd_BUG_ON(!channel_buf)) | 3959 | if (snd_BUG_ON(!channel_buf)) |
3944 | return -EIO; | 3960 | return -EIO; |
3945 | if (copy_to_user(dst, channel_buf + pos * 4, count * 4)) | 3961 | if (copy_to_user(dst, channel_buf + pos, count)) |
3946 | return -EFAULT; | 3962 | return -EFAULT; |
3947 | return count; | 3963 | return 0; |
3948 | } | 3964 | } |
3949 | 3965 | ||
3950 | static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream, int channel, | 3966 | static int snd_hdsp_capture_copy_kernel(struct snd_pcm_substream *substream, |
3951 | snd_pcm_uframes_t pos, snd_pcm_uframes_t count) | 3967 | int channel, unsigned long pos, |
3968 | void *dst, unsigned long count) | ||
3969 | { | ||
3970 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); | ||
3971 | char *channel_buf; | ||
3972 | |||
3973 | channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); | ||
3974 | if (snd_BUG_ON(!channel_buf)) | ||
3975 | return -EIO; | ||
3976 | memcpy(dst, channel_buf + pos, count); | ||
3977 | return 0; | ||
3978 | } | ||
3979 | |||
3980 | static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream, | ||
3981 | int channel, unsigned long pos, | ||
3982 | unsigned long count) | ||
3952 | { | 3983 | { |
3953 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); | 3984 | struct hdsp *hdsp = snd_pcm_substream_chip(substream); |
3954 | char *channel_buf; | 3985 | char *channel_buf; |
@@ -3956,8 +3987,8 @@ static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream, int channel, | |||
3956 | channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); | 3987 | channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); |
3957 | if (snd_BUG_ON(!channel_buf)) | 3988 | if (snd_BUG_ON(!channel_buf)) |
3958 | return -EIO; | 3989 | return -EIO; |
3959 | memset(channel_buf + pos * 4, 0, count * 4); | 3990 | memset(channel_buf + pos, 0, count); |
3960 | return count; | 3991 | return 0; |
3961 | } | 3992 | } |
3962 | 3993 | ||
3963 | static int snd_hdsp_reset(struct snd_pcm_substream *substream) | 3994 | static int snd_hdsp_reset(struct snd_pcm_substream *substream) |
@@ -4239,17 +4270,17 @@ static struct snd_pcm_hardware snd_hdsp_capture_subinfo = | |||
4239 | .fifo_size = 0 | 4270 | .fifo_size = 0 |
4240 | }; | 4271 | }; |
4241 | 4272 | ||
4242 | static unsigned int hdsp_period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; | 4273 | static const unsigned int hdsp_period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; |
4243 | 4274 | ||
4244 | static struct snd_pcm_hw_constraint_list hdsp_hw_constraints_period_sizes = { | 4275 | static const struct snd_pcm_hw_constraint_list hdsp_hw_constraints_period_sizes = { |
4245 | .count = ARRAY_SIZE(hdsp_period_sizes), | 4276 | .count = ARRAY_SIZE(hdsp_period_sizes), |
4246 | .list = hdsp_period_sizes, | 4277 | .list = hdsp_period_sizes, |
4247 | .mask = 0 | 4278 | .mask = 0 |
4248 | }; | 4279 | }; |
4249 | 4280 | ||
4250 | static unsigned int hdsp_9632_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }; | 4281 | static const unsigned int hdsp_9632_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }; |
4251 | 4282 | ||
4252 | static struct snd_pcm_hw_constraint_list hdsp_hw_constraints_9632_sample_rates = { | 4283 | static const struct snd_pcm_hw_constraint_list hdsp_hw_constraints_9632_sample_rates = { |
4253 | .count = ARRAY_SIZE(hdsp_9632_sample_rates), | 4284 | .count = ARRAY_SIZE(hdsp_9632_sample_rates), |
4254 | .list = hdsp_9632_sample_rates, | 4285 | .list = hdsp_9632_sample_rates, |
4255 | .mask = 0 | 4286 | .mask = 0 |
@@ -4869,8 +4900,9 @@ static const struct snd_pcm_ops snd_hdsp_playback_ops = { | |||
4869 | .prepare = snd_hdsp_prepare, | 4900 | .prepare = snd_hdsp_prepare, |
4870 | .trigger = snd_hdsp_trigger, | 4901 | .trigger = snd_hdsp_trigger, |
4871 | .pointer = snd_hdsp_hw_pointer, | 4902 | .pointer = snd_hdsp_hw_pointer, |
4872 | .copy = snd_hdsp_playback_copy, | 4903 | .copy_user = snd_hdsp_playback_copy, |
4873 | .silence = snd_hdsp_hw_silence, | 4904 | .copy_kernel = snd_hdsp_playback_copy_kernel, |
4905 | .fill_silence = snd_hdsp_hw_silence, | ||
4874 | }; | 4906 | }; |
4875 | 4907 | ||
4876 | static const struct snd_pcm_ops snd_hdsp_capture_ops = { | 4908 | static const struct snd_pcm_ops snd_hdsp_capture_ops = { |
@@ -4881,7 +4913,8 @@ static const struct snd_pcm_ops snd_hdsp_capture_ops = { | |||
4881 | .prepare = snd_hdsp_prepare, | 4913 | .prepare = snd_hdsp_prepare, |
4882 | .trigger = snd_hdsp_trigger, | 4914 | .trigger = snd_hdsp_trigger, |
4883 | .pointer = snd_hdsp_hw_pointer, | 4915 | .pointer = snd_hdsp_hw_pointer, |
4884 | .copy = snd_hdsp_capture_copy, | 4916 | .copy_user = snd_hdsp_capture_copy, |
4917 | .copy_kernel = snd_hdsp_capture_copy_kernel, | ||
4885 | }; | 4918 | }; |
4886 | 4919 | ||
4887 | static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp) | 4920 | static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp) |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index c48acdb0e186..254c3d040118 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -6040,11 +6040,11 @@ static int snd_hdspm_hw_rule_out_channels(struct snd_pcm_hw_params *params, | |||
6040 | } | 6040 | } |
6041 | 6041 | ||
6042 | 6042 | ||
6043 | static unsigned int hdspm_aes32_sample_rates[] = { | 6043 | static const unsigned int hdspm_aes32_sample_rates[] = { |
6044 | 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 | 6044 | 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 |
6045 | }; | 6045 | }; |
6046 | 6046 | ||
6047 | static struct snd_pcm_hw_constraint_list | 6047 | static const struct snd_pcm_hw_constraint_list |
6048 | hdspm_hw_constraints_aes32_sample_rates = { | 6048 | hdspm_hw_constraints_aes32_sample_rates = { |
6049 | .count = ARRAY_SIZE(hdspm_aes32_sample_rates), | 6049 | .count = ARRAY_SIZE(hdspm_aes32_sample_rates), |
6050 | .list = hdspm_aes32_sample_rates, | 6050 | .list = hdspm_aes32_sample_rates, |
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 55172c689991..150d08898db8 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
@@ -1883,13 +1883,14 @@ static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652, | |||
1883 | } | 1883 | } |
1884 | } | 1884 | } |
1885 | 1885 | ||
1886 | static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, int channel, | 1886 | static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, |
1887 | snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count) | 1887 | int channel, unsigned long pos, |
1888 | void __user *src, unsigned long count) | ||
1888 | { | 1889 | { |
1889 | struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); | 1890 | struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); |
1890 | char *channel_buf; | 1891 | char *channel_buf; |
1891 | 1892 | ||
1892 | if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4)) | 1893 | if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES)) |
1893 | return -EINVAL; | 1894 | return -EINVAL; |
1894 | 1895 | ||
1895 | channel_buf = rme9652_channel_buffer_location (rme9652, | 1896 | channel_buf = rme9652_channel_buffer_location (rme9652, |
@@ -1897,18 +1898,35 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, int ch | |||
1897 | channel); | 1898 | channel); |
1898 | if (snd_BUG_ON(!channel_buf)) | 1899 | if (snd_BUG_ON(!channel_buf)) |
1899 | return -EIO; | 1900 | return -EIO; |
1900 | if (copy_from_user(channel_buf + pos * 4, src, count * 4)) | 1901 | if (copy_from_user(channel_buf + pos, src, count)) |
1901 | return -EFAULT; | 1902 | return -EFAULT; |
1902 | return count; | 1903 | return 0; |
1903 | } | 1904 | } |
1904 | 1905 | ||
1905 | static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, int channel, | 1906 | static int snd_rme9652_playback_copy_kernel(struct snd_pcm_substream *substream, |
1906 | snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count) | 1907 | int channel, unsigned long pos, |
1908 | void *src, unsigned long count) | ||
1907 | { | 1909 | { |
1908 | struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); | 1910 | struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); |
1909 | char *channel_buf; | 1911 | char *channel_buf; |
1910 | 1912 | ||
1911 | if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4)) | 1913 | channel_buf = rme9652_channel_buffer_location(rme9652, |
1914 | substream->pstr->stream, | ||
1915 | channel); | ||
1916 | if (snd_BUG_ON(!channel_buf)) | ||
1917 | return -EIO; | ||
1918 | memcpy(channel_buf + pos, src, count); | ||
1919 | return 0; | ||
1920 | } | ||
1921 | |||
1922 | static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, | ||
1923 | int channel, unsigned long pos, | ||
1924 | void __user *dst, unsigned long count) | ||
1925 | { | ||
1926 | struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); | ||
1927 | char *channel_buf; | ||
1928 | |||
1929 | if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES)) | ||
1912 | return -EINVAL; | 1930 | return -EINVAL; |
1913 | 1931 | ||
1914 | channel_buf = rme9652_channel_buffer_location (rme9652, | 1932 | channel_buf = rme9652_channel_buffer_location (rme9652, |
@@ -1916,13 +1934,30 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, int cha | |||
1916 | channel); | 1934 | channel); |
1917 | if (snd_BUG_ON(!channel_buf)) | 1935 | if (snd_BUG_ON(!channel_buf)) |
1918 | return -EIO; | 1936 | return -EIO; |
1919 | if (copy_to_user(dst, channel_buf + pos * 4, count * 4)) | 1937 | if (copy_to_user(dst, channel_buf + pos, count)) |
1920 | return -EFAULT; | 1938 | return -EFAULT; |
1921 | return count; | 1939 | return 0; |
1922 | } | 1940 | } |
1923 | 1941 | ||
1924 | static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream, int channel, | 1942 | static int snd_rme9652_capture_copy_kernel(struct snd_pcm_substream *substream, |
1925 | snd_pcm_uframes_t pos, snd_pcm_uframes_t count) | 1943 | int channel, unsigned long pos, |
1944 | void *dst, unsigned long count) | ||
1945 | { | ||
1946 | struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); | ||
1947 | char *channel_buf; | ||
1948 | |||
1949 | channel_buf = rme9652_channel_buffer_location(rme9652, | ||
1950 | substream->pstr->stream, | ||
1951 | channel); | ||
1952 | if (snd_BUG_ON(!channel_buf)) | ||
1953 | return -EIO; | ||
1954 | memcpy(dst, channel_buf + pos, count); | ||
1955 | return 0; | ||
1956 | } | ||
1957 | |||
1958 | static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream, | ||
1959 | int channel, unsigned long pos, | ||
1960 | unsigned long count) | ||
1926 | { | 1961 | { |
1927 | struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); | 1962 | struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); |
1928 | char *channel_buf; | 1963 | char *channel_buf; |
@@ -1932,8 +1967,8 @@ static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream, int chann | |||
1932 | channel); | 1967 | channel); |
1933 | if (snd_BUG_ON(!channel_buf)) | 1968 | if (snd_BUG_ON(!channel_buf)) |
1934 | return -EIO; | 1969 | return -EIO; |
1935 | memset(channel_buf + pos * 4, 0, count * 4); | 1970 | memset(channel_buf + pos, 0, count); |
1936 | return count; | 1971 | return 0; |
1937 | } | 1972 | } |
1938 | 1973 | ||
1939 | static int snd_rme9652_reset(struct snd_pcm_substream *substream) | 1974 | static int snd_rme9652_reset(struct snd_pcm_substream *substream) |
@@ -2193,9 +2228,9 @@ static struct snd_pcm_hardware snd_rme9652_capture_subinfo = | |||
2193 | .fifo_size = 0, | 2228 | .fifo_size = 0, |
2194 | }; | 2229 | }; |
2195 | 2230 | ||
2196 | static unsigned int period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; | 2231 | static const unsigned int period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; |
2197 | 2232 | ||
2198 | static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = { | 2233 | static const struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = { |
2199 | .count = ARRAY_SIZE(period_sizes), | 2234 | .count = ARRAY_SIZE(period_sizes), |
2200 | .list = period_sizes, | 2235 | .list = period_sizes, |
2201 | .mask = 0 | 2236 | .mask = 0 |
@@ -2376,8 +2411,9 @@ static const struct snd_pcm_ops snd_rme9652_playback_ops = { | |||
2376 | .prepare = snd_rme9652_prepare, | 2411 | .prepare = snd_rme9652_prepare, |
2377 | .trigger = snd_rme9652_trigger, | 2412 | .trigger = snd_rme9652_trigger, |
2378 | .pointer = snd_rme9652_hw_pointer, | 2413 | .pointer = snd_rme9652_hw_pointer, |
2379 | .copy = snd_rme9652_playback_copy, | 2414 | .copy_user = snd_rme9652_playback_copy, |
2380 | .silence = snd_rme9652_hw_silence, | 2415 | .copy_kernel = snd_rme9652_playback_copy_kernel, |
2416 | .fill_silence = snd_rme9652_hw_silence, | ||
2381 | }; | 2417 | }; |
2382 | 2418 | ||
2383 | static const struct snd_pcm_ops snd_rme9652_capture_ops = { | 2419 | static const struct snd_pcm_ops snd_rme9652_capture_ops = { |
@@ -2388,7 +2424,8 @@ static const struct snd_pcm_ops snd_rme9652_capture_ops = { | |||
2388 | .prepare = snd_rme9652_prepare, | 2424 | .prepare = snd_rme9652_prepare, |
2389 | .trigger = snd_rme9652_trigger, | 2425 | .trigger = snd_rme9652_trigger, |
2390 | .pointer = snd_rme9652_hw_pointer, | 2426 | .pointer = snd_rme9652_hw_pointer, |
2391 | .copy = snd_rme9652_capture_copy, | 2427 | .copy_user = snd_rme9652_capture_copy, |
2428 | .copy_kernel = snd_rme9652_capture_copy_kernel, | ||
2392 | }; | 2429 | }; |
2393 | 2430 | ||
2394 | static int snd_rme9652_create_pcm(struct snd_card *card, | 2431 | static int snd_rme9652_create_pcm(struct snd_card *card, |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 8e3d4ec39c35..784d762f18a7 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -248,13 +248,13 @@ static const struct pci_device_id snd_sonic_ids[] = { | |||
248 | 248 | ||
249 | MODULE_DEVICE_TABLE(pci, snd_sonic_ids); | 249 | MODULE_DEVICE_TABLE(pci, snd_sonic_ids); |
250 | 250 | ||
251 | static struct snd_ratden sonicvibes_adc_clock = { | 251 | static const struct snd_ratden sonicvibes_adc_clock = { |
252 | .num_min = 4000 * 65536, | 252 | .num_min = 4000 * 65536, |
253 | .num_max = 48000UL * 65536, | 253 | .num_max = 48000UL * 65536, |
254 | .num_step = 1, | 254 | .num_step = 1, |
255 | .den = 65536, | 255 | .den = 65536, |
256 | }; | 256 | }; |
257 | static struct snd_pcm_hw_constraint_ratdens snd_sonicvibes_hw_constraints_adc_clock = { | 257 | static const struct snd_pcm_hw_constraint_ratdens snd_sonicvibes_hw_constraints_adc_clock = { |
258 | .nrats = 1, | 258 | .nrats = 1, |
259 | .rats = &sonicvibes_adc_clock, | 259 | .rats = &sonicvibes_adc_clock, |
260 | }; | 260 | }; |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index b6c84d15b10b..c767b8664359 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -1286,10 +1286,10 @@ static int snd_via8233_multi_open(struct snd_pcm_substream *substream) | |||
1286 | /* channels constraint for VIA8233A | 1286 | /* channels constraint for VIA8233A |
1287 | * 3 and 5 channels are not supported | 1287 | * 3 and 5 channels are not supported |
1288 | */ | 1288 | */ |
1289 | static unsigned int channels[] = { | 1289 | static const unsigned int channels[] = { |
1290 | 1, 2, 4, 6 | 1290 | 1, 2, 4, 6 |
1291 | }; | 1291 | }; |
1292 | static struct snd_pcm_hw_constraint_list hw_constraints_channels = { | 1292 | static const struct snd_pcm_hw_constraint_list hw_constraints_channels = { |
1293 | .count = ARRAY_SIZE(channels), | 1293 | .count = ARRAY_SIZE(channels), |
1294 | .list = channels, | 1294 | .list = channels, |
1295 | .mask = 0, | 1295 | .mask = 0, |
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 2f6d40f10618..55f79b2599e7 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c | |||
@@ -744,8 +744,8 @@ static int snd_via82xx_modem_pcm_open(struct via82xx_modem *chip, struct viadev | |||
744 | { | 744 | { |
745 | struct snd_pcm_runtime *runtime = substream->runtime; | 745 | struct snd_pcm_runtime *runtime = substream->runtime; |
746 | int err; | 746 | int err; |
747 | static unsigned int rates[] = { 8000, 9600, 12000, 16000 }; | 747 | static const unsigned int rates[] = { 8000, 9600, 12000, 16000 }; |
748 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 748 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
749 | .count = ARRAY_SIZE(rates), | 749 | .count = ARRAY_SIZE(rates), |
750 | .list = rates, | 750 | .list = rates, |
751 | .mask = 0, | 751 | .mask = 0, |
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c index ecbaf473fc1e..55861849d7df 100644 --- a/sound/pci/vx222/vx222.c +++ b/sound/pci/vx222/vx222.c | |||
@@ -116,7 +116,7 @@ static struct snd_vx_hardware vx222_mic_hw = { | |||
116 | */ | 116 | */ |
117 | static int snd_vx222_free(struct vx_core *chip) | 117 | static int snd_vx222_free(struct vx_core *chip) |
118 | { | 118 | { |
119 | struct snd_vx222 *vx = (struct snd_vx222 *)chip; | 119 | struct snd_vx222 *vx = to_vx222(chip); |
120 | 120 | ||
121 | if (chip->irq >= 0) | 121 | if (chip->irq >= 0) |
122 | free_irq(chip->irq, (void*)chip); | 122 | free_irq(chip->irq, (void*)chip); |
@@ -158,7 +158,7 @@ static int snd_vx222_create(struct snd_card *card, struct pci_dev *pci, | |||
158 | pci_disable_device(pci); | 158 | pci_disable_device(pci); |
159 | return -ENOMEM; | 159 | return -ENOMEM; |
160 | } | 160 | } |
161 | vx = (struct snd_vx222 *)chip; | 161 | vx = to_vx222(chip); |
162 | vx->pci = pci; | 162 | vx->pci = pci; |
163 | 163 | ||
164 | if ((err = pci_request_regions(pci, CARD_NAME)) < 0) { | 164 | if ((err = pci_request_regions(pci, CARD_NAME)) < 0) { |
diff --git a/sound/pci/vx222/vx222.h b/sound/pci/vx222/vx222.h index 2f0d78f609a6..cae355c8ed28 100644 --- a/sound/pci/vx222/vx222.h +++ b/sound/pci/vx222/vx222.h | |||
@@ -39,6 +39,8 @@ struct snd_vx222 { | |||
39 | int mic_level; /* mic level for vx222 mic */ | 39 | int mic_level; /* mic level for vx222 mic */ |
40 | }; | 40 | }; |
41 | 41 | ||
42 | #define to_vx222(x) container_of(x, struct snd_vx222, core) | ||
43 | |||
42 | /* we use a lookup table with 148 values, see vx_mixer.c */ | 44 | /* we use a lookup table with 148 values, see vx_mixer.c */ |
43 | #define VX2_AKM_LEVEL_MAX 0x93 | 45 | #define VX2_AKM_LEVEL_MAX 0x93 |
44 | 46 | ||
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index 7df1663ea510..d4298af6d3ee 100644 --- a/sound/pci/vx222/vx222_ops.c +++ b/sound/pci/vx222/vx222_ops.c | |||
@@ -86,7 +86,7 @@ static int vx2_reg_index[VX_REG_MAX] = { | |||
86 | 86 | ||
87 | static inline unsigned long vx2_reg_addr(struct vx_core *_chip, int reg) | 87 | static inline unsigned long vx2_reg_addr(struct vx_core *_chip, int reg) |
88 | { | 88 | { |
89 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 89 | struct snd_vx222 *chip = to_vx222(_chip); |
90 | return chip->port[vx2_reg_index[reg]] + vx2_reg_offset[reg]; | 90 | return chip->port[vx2_reg_index[reg]] + vx2_reg_offset[reg]; |
91 | } | 91 | } |
92 | 92 | ||
@@ -159,7 +159,7 @@ static void vx2_outl(struct vx_core *chip, int offset, unsigned int val) | |||
159 | 159 | ||
160 | static void vx2_reset_dsp(struct vx_core *_chip) | 160 | static void vx2_reset_dsp(struct vx_core *_chip) |
161 | { | 161 | { |
162 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 162 | struct snd_vx222 *chip = to_vx222(_chip); |
163 | 163 | ||
164 | /* set the reset dsp bit to 0 */ | 164 | /* set the reset dsp bit to 0 */ |
165 | vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_DSP_RESET_MASK); | 165 | vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_DSP_RESET_MASK); |
@@ -174,7 +174,7 @@ static void vx2_reset_dsp(struct vx_core *_chip) | |||
174 | 174 | ||
175 | static int vx2_test_xilinx(struct vx_core *_chip) | 175 | static int vx2_test_xilinx(struct vx_core *_chip) |
176 | { | 176 | { |
177 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 177 | struct snd_vx222 *chip = to_vx222(_chip); |
178 | unsigned int data; | 178 | unsigned int data; |
179 | 179 | ||
180 | dev_dbg(_chip->card->dev, "testing xilinx...\n"); | 180 | dev_dbg(_chip->card->dev, "testing xilinx...\n"); |
@@ -479,7 +479,7 @@ static int vx2_test_and_ack(struct vx_core *chip) | |||
479 | */ | 479 | */ |
480 | static void vx2_validate_irq(struct vx_core *_chip, int enable) | 480 | static void vx2_validate_irq(struct vx_core *_chip, int enable) |
481 | { | 481 | { |
482 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 482 | struct snd_vx222 *chip = to_vx222(_chip); |
483 | 483 | ||
484 | /* Set the interrupt enable bit to 1 in CDSP register */ | 484 | /* Set the interrupt enable bit to 1 in CDSP register */ |
485 | if (enable) { | 485 | if (enable) { |
@@ -730,7 +730,7 @@ static void vx2_old_write_codec_bit(struct vx_core *chip, int codec, unsigned in | |||
730 | */ | 730 | */ |
731 | static void vx2_reset_codec(struct vx_core *_chip) | 731 | static void vx2_reset_codec(struct vx_core *_chip) |
732 | { | 732 | { |
733 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 733 | struct snd_vx222 *chip = to_vx222(_chip); |
734 | 734 | ||
735 | /* Set the reset CODEC bit to 0. */ | 735 | /* Set the reset CODEC bit to 0. */ |
736 | vx_outl(chip, CDSP, chip->regCDSP &~ VX_CDSP_CODEC_RESET_MASK); | 736 | vx_outl(chip, CDSP, chip->regCDSP &~ VX_CDSP_CODEC_RESET_MASK); |
@@ -772,7 +772,7 @@ static void vx2_reset_codec(struct vx_core *_chip) | |||
772 | */ | 772 | */ |
773 | static void vx2_change_audio_source(struct vx_core *_chip, int src) | 773 | static void vx2_change_audio_source(struct vx_core *_chip, int src) |
774 | { | 774 | { |
775 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 775 | struct snd_vx222 *chip = to_vx222(_chip); |
776 | 776 | ||
777 | switch (src) { | 777 | switch (src) { |
778 | case VX_AUDIO_SRC_DIGITAL: | 778 | case VX_AUDIO_SRC_DIGITAL: |
@@ -791,7 +791,7 @@ static void vx2_change_audio_source(struct vx_core *_chip, int src) | |||
791 | */ | 791 | */ |
792 | static void vx2_set_clock_source(struct vx_core *_chip, int source) | 792 | static void vx2_set_clock_source(struct vx_core *_chip, int source) |
793 | { | 793 | { |
794 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 794 | struct snd_vx222 *chip = to_vx222(_chip); |
795 | 795 | ||
796 | if (source == INTERNAL_QUARTZ) | 796 | if (source == INTERNAL_QUARTZ) |
797 | chip->regCFG &= ~VX_CFG_CLOCKIN_SEL_MASK; | 797 | chip->regCFG &= ~VX_CFG_CLOCKIN_SEL_MASK; |
@@ -805,7 +805,7 @@ static void vx2_set_clock_source(struct vx_core *_chip, int source) | |||
805 | */ | 805 | */ |
806 | static void vx2_reset_board(struct vx_core *_chip, int cold_reset) | 806 | static void vx2_reset_board(struct vx_core *_chip, int cold_reset) |
807 | { | 807 | { |
808 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 808 | struct snd_vx222 *chip = to_vx222(_chip); |
809 | 809 | ||
810 | /* initialize the register values */ | 810 | /* initialize the register values */ |
811 | chip->regCDSP = VX_CDSP_CODEC_RESET_MASK | VX_CDSP_DSP_RESET_MASK ; | 811 | chip->regCDSP = VX_CDSP_CODEC_RESET_MASK | VX_CDSP_DSP_RESET_MASK ; |
@@ -878,7 +878,7 @@ static int vx_input_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
878 | static int vx_input_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 878 | static int vx_input_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
879 | { | 879 | { |
880 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 880 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
881 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 881 | struct snd_vx222 *chip = to_vx222(_chip); |
882 | mutex_lock(&_chip->mixer_mutex); | 882 | mutex_lock(&_chip->mixer_mutex); |
883 | ucontrol->value.integer.value[0] = chip->input_level[0]; | 883 | ucontrol->value.integer.value[0] = chip->input_level[0]; |
884 | ucontrol->value.integer.value[1] = chip->input_level[1]; | 884 | ucontrol->value.integer.value[1] = chip->input_level[1]; |
@@ -889,7 +889,7 @@ static int vx_input_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
889 | static int vx_input_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 889 | static int vx_input_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
890 | { | 890 | { |
891 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 891 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
892 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 892 | struct snd_vx222 *chip = to_vx222(_chip); |
893 | if (ucontrol->value.integer.value[0] < 0 || | 893 | if (ucontrol->value.integer.value[0] < 0 || |
894 | ucontrol->value.integer.value[0] > MIC_LEVEL_MAX) | 894 | ucontrol->value.integer.value[0] > MIC_LEVEL_MAX) |
895 | return -EINVAL; | 895 | return -EINVAL; |
@@ -922,7 +922,7 @@ static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
922 | static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 922 | static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
923 | { | 923 | { |
924 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 924 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
925 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 925 | struct snd_vx222 *chip = to_vx222(_chip); |
926 | ucontrol->value.integer.value[0] = chip->mic_level; | 926 | ucontrol->value.integer.value[0] = chip->mic_level; |
927 | return 0; | 927 | return 0; |
928 | } | 928 | } |
@@ -930,7 +930,7 @@ static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
930 | static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 930 | static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
931 | { | 931 | { |
932 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 932 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
933 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 933 | struct snd_vx222 *chip = to_vx222(_chip); |
934 | if (ucontrol->value.integer.value[0] < 0 || | 934 | if (ucontrol->value.integer.value[0] < 0 || |
935 | ucontrol->value.integer.value[0] > MIC_LEVEL_MAX) | 935 | ucontrol->value.integer.value[0] > MIC_LEVEL_MAX) |
936 | return -EINVAL; | 936 | return -EINVAL; |
@@ -973,7 +973,7 @@ static const struct snd_kcontrol_new vx_control_mic_level = { | |||
973 | 973 | ||
974 | static int vx2_add_mic_controls(struct vx_core *_chip) | 974 | static int vx2_add_mic_controls(struct vx_core *_chip) |
975 | { | 975 | { |
976 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 976 | struct snd_vx222 *chip = to_vx222(_chip); |
977 | int err; | 977 | int err; |
978 | 978 | ||
979 | if (_chip->type != VX_TYPE_MIC) | 979 | if (_chip->type != VX_TYPE_MIC) |
diff --git a/sound/pcmcia/vx/vxp_mixer.c b/sound/pcmcia/vx/vxp_mixer.c index a4a664259f0d..304b153005a5 100644 --- a/sound/pcmcia/vx/vxp_mixer.c +++ b/sound/pcmcia/vx/vxp_mixer.c | |||
@@ -43,7 +43,7 @@ static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
43 | static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 43 | static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
44 | { | 44 | { |
45 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 45 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
46 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 46 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
47 | ucontrol->value.integer.value[0] = chip->mic_level; | 47 | ucontrol->value.integer.value[0] = chip->mic_level; |
48 | return 0; | 48 | return 0; |
49 | } | 49 | } |
@@ -51,7 +51,7 @@ static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
51 | static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 51 | static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
52 | { | 52 | { |
53 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 53 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
54 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 54 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
55 | unsigned int val = ucontrol->value.integer.value[0]; | 55 | unsigned int val = ucontrol->value.integer.value[0]; |
56 | 56 | ||
57 | if (val > MIC_LEVEL_MAX) | 57 | if (val > MIC_LEVEL_MAX) |
@@ -69,7 +69,7 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
69 | 69 | ||
70 | static const DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0); | 70 | static const DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0); |
71 | 71 | ||
72 | static struct snd_kcontrol_new vx_control_mic_level = { | 72 | static const struct snd_kcontrol_new vx_control_mic_level = { |
73 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 73 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
74 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | 74 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | |
75 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), | 75 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), |
@@ -88,7 +88,7 @@ static struct snd_kcontrol_new vx_control_mic_level = { | |||
88 | static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 88 | static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
89 | { | 89 | { |
90 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 90 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
91 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 91 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
92 | ucontrol->value.integer.value[0] = chip->mic_level; | 92 | ucontrol->value.integer.value[0] = chip->mic_level; |
93 | return 0; | 93 | return 0; |
94 | } | 94 | } |
@@ -96,7 +96,7 @@ static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
96 | static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 96 | static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
97 | { | 97 | { |
98 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 98 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
99 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 99 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
100 | int val = !!ucontrol->value.integer.value[0]; | 100 | int val = !!ucontrol->value.integer.value[0]; |
101 | mutex_lock(&_chip->mixer_mutex); | 101 | mutex_lock(&_chip->mixer_mutex); |
102 | if (chip->mic_level != val) { | 102 | if (chip->mic_level != val) { |
@@ -109,7 +109,7 @@ static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | static struct snd_kcontrol_new vx_control_mic_boost = { | 112 | static const struct snd_kcontrol_new vx_control_mic_boost = { |
113 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 113 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
114 | .name = "Mic Boost", | 114 | .name = "Mic Boost", |
115 | .info = vx_mic_boost_info, | 115 | .info = vx_mic_boost_info, |
@@ -120,7 +120,7 @@ static struct snd_kcontrol_new vx_control_mic_boost = { | |||
120 | 120 | ||
121 | int vxp_add_mic_controls(struct vx_core *_chip) | 121 | int vxp_add_mic_controls(struct vx_core *_chip) |
122 | { | 122 | { |
123 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 123 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
124 | int err; | 124 | int err; |
125 | 125 | ||
126 | /* mute input levels */ | 126 | /* mute input levels */ |
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c index 5f97791f00d7..8cde40226355 100644 --- a/sound/pcmcia/vx/vxp_ops.c +++ b/sound/pcmcia/vx/vxp_ops.c | |||
@@ -50,7 +50,7 @@ static int vxp_reg_offset[VX_REG_MAX] = { | |||
50 | 50 | ||
51 | static inline unsigned long vxp_reg_addr(struct vx_core *_chip, int reg) | 51 | static inline unsigned long vxp_reg_addr(struct vx_core *_chip, int reg) |
52 | { | 52 | { |
53 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 53 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
54 | return chip->port + vxp_reg_offset[reg]; | 54 | return chip->port + vxp_reg_offset[reg]; |
55 | } | 55 | } |
56 | 56 | ||
@@ -110,7 +110,7 @@ static int vx_check_magic(struct vx_core *chip) | |||
110 | 110 | ||
111 | static void vxp_reset_dsp(struct vx_core *_chip) | 111 | static void vxp_reset_dsp(struct vx_core *_chip) |
112 | { | 112 | { |
113 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 113 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
114 | 114 | ||
115 | /* set the reset dsp bit to 1 */ | 115 | /* set the reset dsp bit to 1 */ |
116 | vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_DSP_RESET_MASK); | 116 | vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_DSP_RESET_MASK); |
@@ -128,7 +128,7 @@ static void vxp_reset_dsp(struct vx_core *_chip) | |||
128 | */ | 128 | */ |
129 | static void vxp_reset_codec(struct vx_core *_chip) | 129 | static void vxp_reset_codec(struct vx_core *_chip) |
130 | { | 130 | { |
131 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 131 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
132 | 132 | ||
133 | /* Set the reset CODEC bit to 1. */ | 133 | /* Set the reset CODEC bit to 1. */ |
134 | vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_CODEC_RESET_MASK); | 134 | vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_CODEC_RESET_MASK); |
@@ -147,7 +147,7 @@ static void vxp_reset_codec(struct vx_core *_chip) | |||
147 | */ | 147 | */ |
148 | static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware *fw) | 148 | static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware *fw) |
149 | { | 149 | { |
150 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 150 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
151 | unsigned int i; | 151 | unsigned int i; |
152 | int c; | 152 | int c; |
153 | int regCSUER, regRUER; | 153 | int regCSUER, regRUER; |
@@ -280,7 +280,7 @@ static int vxp_load_dsp(struct vx_core *vx, int index, const struct firmware *fw | |||
280 | */ | 280 | */ |
281 | static int vxp_test_and_ack(struct vx_core *_chip) | 281 | static int vxp_test_and_ack(struct vx_core *_chip) |
282 | { | 282 | { |
283 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 283 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
284 | 284 | ||
285 | /* not booted yet? */ | 285 | /* not booted yet? */ |
286 | if (! (_chip->chip_status & VX_STAT_XILINX_LOADED)) | 286 | if (! (_chip->chip_status & VX_STAT_XILINX_LOADED)) |
@@ -307,7 +307,7 @@ static int vxp_test_and_ack(struct vx_core *_chip) | |||
307 | */ | 307 | */ |
308 | static void vxp_validate_irq(struct vx_core *_chip, int enable) | 308 | static void vxp_validate_irq(struct vx_core *_chip, int enable) |
309 | { | 309 | { |
310 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 310 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
311 | 311 | ||
312 | /* Set the interrupt enable bit to 1 in CDSP register */ | 312 | /* Set the interrupt enable bit to 1 in CDSP register */ |
313 | if (enable) | 313 | if (enable) |
@@ -323,7 +323,7 @@ static void vxp_validate_irq(struct vx_core *_chip, int enable) | |||
323 | */ | 323 | */ |
324 | static void vx_setup_pseudo_dma(struct vx_core *_chip, int do_write) | 324 | static void vx_setup_pseudo_dma(struct vx_core *_chip, int do_write) |
325 | { | 325 | { |
326 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 326 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
327 | 327 | ||
328 | /* Interrupt mode and HREQ pin enabled for host transmit / receive data transfers */ | 328 | /* Interrupt mode and HREQ pin enabled for host transmit / receive data transfers */ |
329 | vx_outb(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ); | 329 | vx_outb(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ); |
@@ -343,7 +343,7 @@ static void vx_setup_pseudo_dma(struct vx_core *_chip, int do_write) | |||
343 | */ | 343 | */ |
344 | static void vx_release_pseudo_dma(struct vx_core *_chip) | 344 | static void vx_release_pseudo_dma(struct vx_core *_chip) |
345 | { | 345 | { |
346 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 346 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
347 | 347 | ||
348 | /* Disable DMA and 16-bit accesses */ | 348 | /* Disable DMA and 16-bit accesses */ |
349 | chip->regDIALOG &= ~(VXP_DLG_DMAWRITE_SEL_MASK| | 349 | chip->regDIALOG &= ~(VXP_DLG_DMAWRITE_SEL_MASK| |
@@ -403,7 +403,7 @@ static void vxp_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime, | |||
403 | static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime, | 403 | static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime, |
404 | struct vx_pipe *pipe, int count) | 404 | struct vx_pipe *pipe, int count) |
405 | { | 405 | { |
406 | struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip; | 406 | struct snd_vxpocket *pchip = to_vxpocket(chip); |
407 | long port = vxp_reg_addr(chip, VX_DMA); | 407 | long port = vxp_reg_addr(chip, VX_DMA); |
408 | int offset = pipe->hw_ptr; | 408 | int offset = pipe->hw_ptr; |
409 | unsigned short *addr = (unsigned short *)(runtime->dma_area + offset); | 409 | unsigned short *addr = (unsigned short *)(runtime->dma_area + offset); |
@@ -467,7 +467,7 @@ static void vxp_write_codec_reg(struct vx_core *chip, int codec, unsigned int da | |||
467 | */ | 467 | */ |
468 | void vx_set_mic_boost(struct vx_core *chip, int boost) | 468 | void vx_set_mic_boost(struct vx_core *chip, int boost) |
469 | { | 469 | { |
470 | struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip; | 470 | struct snd_vxpocket *pchip = to_vxpocket(chip); |
471 | 471 | ||
472 | if (chip->chip_status & VX_STAT_IS_STALE) | 472 | if (chip->chip_status & VX_STAT_IS_STALE) |
473 | return; | 473 | return; |
@@ -509,7 +509,7 @@ static int vx_compute_mic_level(int level) | |||
509 | */ | 509 | */ |
510 | void vx_set_mic_level(struct vx_core *chip, int level) | 510 | void vx_set_mic_level(struct vx_core *chip, int level) |
511 | { | 511 | { |
512 | struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip; | 512 | struct snd_vxpocket *pchip = to_vxpocket(chip); |
513 | 513 | ||
514 | if (chip->chip_status & VX_STAT_IS_STALE) | 514 | if (chip->chip_status & VX_STAT_IS_STALE) |
515 | return; | 515 | return; |
@@ -528,7 +528,7 @@ void vx_set_mic_level(struct vx_core *chip, int level) | |||
528 | */ | 528 | */ |
529 | static void vxp_change_audio_source(struct vx_core *_chip, int src) | 529 | static void vxp_change_audio_source(struct vx_core *_chip, int src) |
530 | { | 530 | { |
531 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 531 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
532 | 532 | ||
533 | switch (src) { | 533 | switch (src) { |
534 | case VX_AUDIO_SRC_DIGITAL: | 534 | case VX_AUDIO_SRC_DIGITAL: |
@@ -568,7 +568,7 @@ static void vxp_change_audio_source(struct vx_core *_chip, int src) | |||
568 | */ | 568 | */ |
569 | static void vxp_set_clock_source(struct vx_core *_chip, int source) | 569 | static void vxp_set_clock_source(struct vx_core *_chip, int source) |
570 | { | 570 | { |
571 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 571 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
572 | 572 | ||
573 | if (source == INTERNAL_QUARTZ) | 573 | if (source == INTERNAL_QUARTZ) |
574 | chip->regCDSP &= ~VXP_CDSP_CLOCKIN_SEL_MASK; | 574 | chip->regCDSP &= ~VXP_CDSP_CLOCKIN_SEL_MASK; |
@@ -583,7 +583,7 @@ static void vxp_set_clock_source(struct vx_core *_chip, int source) | |||
583 | */ | 583 | */ |
584 | static void vxp_reset_board(struct vx_core *_chip, int cold_reset) | 584 | static void vxp_reset_board(struct vx_core *_chip, int cold_reset) |
585 | { | 585 | { |
586 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 586 | struct snd_vxpocket *chip = to_vxpocket(_chip); |
587 | 587 | ||
588 | chip->regCDSP = 0; | 588 | chip->regCDSP = 0; |
589 | chip->regDIALOG = 0; | 589 | chip->regDIALOG = 0; |
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index b16f42deed67..ca0d19e723fd 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -155,7 +155,7 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl, | |||
155 | } | 155 | } |
156 | chip->ibl.size = ibl; | 156 | chip->ibl.size = ibl; |
157 | 157 | ||
158 | vxp = (struct snd_vxpocket *)chip; | 158 | vxp = to_vxpocket(chip); |
159 | 159 | ||
160 | vxp->p_dev = link; | 160 | vxp->p_dev = link; |
161 | link->priv = chip; | 161 | link->priv = chip; |
@@ -187,7 +187,7 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq | |||
187 | { | 187 | { |
188 | int err; | 188 | int err; |
189 | struct snd_card *card = chip->card; | 189 | struct snd_card *card = chip->card; |
190 | struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | 190 | struct snd_vxpocket *vxp = to_vxpocket(chip); |
191 | 191 | ||
192 | snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq); | 192 | snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq); |
193 | vxp->port = port; | 193 | vxp->port = port; |
diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h index 13d658c1a216..26f4255e132e 100644 --- a/sound/pcmcia/vx/vxpocket.h +++ b/sound/pcmcia/vx/vxpocket.h | |||
@@ -43,6 +43,8 @@ struct snd_vxpocket { | |||
43 | struct pcmcia_device *p_dev; | 43 | struct pcmcia_device *p_dev; |
44 | }; | 44 | }; |
45 | 45 | ||
46 | #define to_vxpocket(x) container_of(x, struct snd_vxpocket, core) | ||
47 | |||
46 | extern struct snd_vx_ops snd_vxpocket_ops; | 48 | extern struct snd_vx_ops snd_vxpocket_ops; |
47 | 49 | ||
48 | void vx_set_mic_boost(struct vx_core *chip, int boost); | 50 | void vx_set_mic_boost(struct vx_core *chip, int boost); |
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c index 1468e4b7bf93..d1e4ef1c5c30 100644 --- a/sound/ppc/awacs.c +++ b/sound/ppc/awacs.c | |||
@@ -514,7 +514,7 @@ static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] = { | |||
514 | }, | 514 | }, |
515 | }; | 515 | }; |
516 | 516 | ||
517 | static struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw = { | 517 | static const struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw = { |
518 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 518 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
519 | .name = "Headphone Playback Switch", | 519 | .name = "Headphone Playback Switch", |
520 | .info = snd_pmac_boolean_stereo_info, | 520 | .info = snd_pmac_boolean_stereo_info, |
@@ -523,7 +523,7 @@ static struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw = { | |||
523 | .private_value = AMP_CH_HD, | 523 | .private_value = AMP_CH_HD, |
524 | }; | 524 | }; |
525 | 525 | ||
526 | static struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw = { | 526 | static const struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw = { |
527 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 527 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
528 | .name = "Speaker Playback Switch", | 528 | .name = "Speaker Playback Switch", |
529 | .info = snd_pmac_boolean_stereo_info, | 529 | .info = snd_pmac_boolean_stereo_info, |
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c index d3524f9fa05d..f19eb3e39937 100644 --- a/sound/ppc/beep.c +++ b/sound/ppc/beep.c | |||
@@ -206,7 +206,7 @@ static int snd_pmac_put_beep(struct snd_kcontrol *kcontrol, | |||
206 | return oval != chip->beep->volume; | 206 | return oval != chip->beep->volume; |
207 | } | 207 | } |
208 | 208 | ||
209 | static struct snd_kcontrol_new snd_pmac_beep_mixer = { | 209 | static const struct snd_kcontrol_new snd_pmac_beep_mixer = { |
210 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 210 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
211 | .name = "Beep Playback Volume", | 211 | .name = "Beep Playback Volume", |
212 | .info = snd_pmac_info_beep, | 212 | .info = snd_pmac_info_beep, |
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 58ee8089bbf9..0779a2912237 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c | |||
@@ -897,7 +897,7 @@ static struct snd_kcontrol_new snapper_mixers[] = { | |||
897 | }, | 897 | }, |
898 | }; | 898 | }; |
899 | 899 | ||
900 | static struct snd_kcontrol_new tumbler_hp_sw = { | 900 | static const struct snd_kcontrol_new tumbler_hp_sw = { |
901 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 901 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
902 | .name = "Headphone Playback Switch", | 902 | .name = "Headphone Playback Switch", |
903 | .info = snd_pmac_boolean_mono_info, | 903 | .info = snd_pmac_boolean_mono_info, |
@@ -905,7 +905,7 @@ static struct snd_kcontrol_new tumbler_hp_sw = { | |||
905 | .put = tumbler_put_mute_switch, | 905 | .put = tumbler_put_mute_switch, |
906 | .private_value = TUMBLER_MUTE_HP, | 906 | .private_value = TUMBLER_MUTE_HP, |
907 | }; | 907 | }; |
908 | static struct snd_kcontrol_new tumbler_speaker_sw = { | 908 | static const struct snd_kcontrol_new tumbler_speaker_sw = { |
909 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 909 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
910 | .name = "Speaker Playback Switch", | 910 | .name = "Speaker Playback Switch", |
911 | .info = snd_pmac_boolean_mono_info, | 911 | .info = snd_pmac_boolean_mono_info, |
@@ -913,7 +913,7 @@ static struct snd_kcontrol_new tumbler_speaker_sw = { | |||
913 | .put = tumbler_put_mute_switch, | 913 | .put = tumbler_put_mute_switch, |
914 | .private_value = TUMBLER_MUTE_AMP, | 914 | .private_value = TUMBLER_MUTE_AMP, |
915 | }; | 915 | }; |
916 | static struct snd_kcontrol_new tumbler_lineout_sw = { | 916 | static const struct snd_kcontrol_new tumbler_lineout_sw = { |
917 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 917 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
918 | .name = "Line Out Playback Switch", | 918 | .name = "Line Out Playback Switch", |
919 | .info = snd_pmac_boolean_mono_info, | 919 | .info = snd_pmac_boolean_mono_info, |
@@ -921,7 +921,7 @@ static struct snd_kcontrol_new tumbler_lineout_sw = { | |||
921 | .put = tumbler_put_mute_switch, | 921 | .put = tumbler_put_mute_switch, |
922 | .private_value = TUMBLER_MUTE_LINE, | 922 | .private_value = TUMBLER_MUTE_LINE, |
923 | }; | 923 | }; |
924 | static struct snd_kcontrol_new tumbler_drc_sw = { | 924 | static const struct snd_kcontrol_new tumbler_drc_sw = { |
925 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 925 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
926 | .name = "DRC Switch", | 926 | .name = "DRC Switch", |
927 | .info = snd_pmac_boolean_mono_info, | 927 | .info = snd_pmac_boolean_mono_info, |
diff --git a/sound/sh/aica.c b/sound/sh/aica.c index fbbc25279559..ab4802df62e1 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c | |||
@@ -535,7 +535,7 @@ static int aica_pcmvolume_put(struct snd_kcontrol *kcontrol, | |||
535 | return 1; | 535 | return 1; |
536 | } | 536 | } |
537 | 537 | ||
538 | static struct snd_kcontrol_new snd_aica_pcmswitch_control = { | 538 | static const struct snd_kcontrol_new snd_aica_pcmswitch_control = { |
539 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 539 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
540 | .name = "PCM Playback Switch", | 540 | .name = "PCM Playback Switch", |
541 | .index = 0, | 541 | .index = 0, |
@@ -544,7 +544,7 @@ static struct snd_kcontrol_new snd_aica_pcmswitch_control = { | |||
544 | .put = aica_pcmswitch_put | 544 | .put = aica_pcmswitch_put |
545 | }; | 545 | }; |
546 | 546 | ||
547 | static struct snd_kcontrol_new snd_aica_pcmvolume_control = { | 547 | static const struct snd_kcontrol_new snd_aica_pcmvolume_control = { |
548 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 548 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
549 | .name = "PCM Playback Volume", | 549 | .name = "PCM Playback Volume", |
550 | .index = 0, | 550 | .index = 0, |
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c index 461b310c7872..c1e00ed715ee 100644 --- a/sound/sh/sh_dac_audio.c +++ b/sound/sh/sh_dac_audio.c | |||
@@ -184,23 +184,36 @@ static int snd_sh_dac_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
186 | 186 | ||
187 | static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, int channel, | 187 | static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, |
188 | snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count) | 188 | int channel, unsigned long pos, |
189 | void __user *src, unsigned long count) | ||
189 | { | 190 | { |
190 | /* channel is not used (interleaved data) */ | 191 | /* channel is not used (interleaved data) */ |
191 | struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); | 192 | struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); |
192 | struct snd_pcm_runtime *runtime = substream->runtime; | 193 | struct snd_pcm_runtime *runtime = substream->runtime; |
193 | ssize_t b_count = frames_to_bytes(runtime , count); | ||
194 | ssize_t b_pos = frames_to_bytes(runtime , pos); | ||
195 | 194 | ||
196 | if (count < 0) | 195 | if (copy_from_user_toio(chip->data_buffer + pos, src, count)) |
197 | return -EINVAL; | 196 | return -EFAULT; |
197 | chip->buffer_end = chip->data_buffer + pos + count; | ||
198 | 198 | ||
199 | if (!count) | 199 | if (chip->empty) { |
200 | return 0; | 200 | chip->empty = 0; |
201 | dac_audio_start_timer(chip); | ||
202 | } | ||
203 | |||
204 | return 0; | ||
205 | } | ||
201 | 206 | ||
202 | memcpy_toio(chip->data_buffer + b_pos, src, b_count); | 207 | static int snd_sh_dac_pcm_copy_kernel(struct snd_pcm_substream *substream, |
203 | chip->buffer_end = chip->data_buffer + b_pos + b_count; | 208 | int channel, unsigned long pos, |
209 | void *src, unsigned long count) | ||
210 | { | ||
211 | /* channel is not used (interleaved data) */ | ||
212 | struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); | ||
213 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
214 | |||
215 | memcpy_toio(chip->data_buffer + pos, src, count); | ||
216 | chip->buffer_end = chip->data_buffer + pos + count; | ||
204 | 217 | ||
205 | if (chip->empty) { | 218 | if (chip->empty) { |
206 | chip->empty = 0; | 219 | chip->empty = 0; |
@@ -211,23 +224,15 @@ static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, int channel, | |||
211 | } | 224 | } |
212 | 225 | ||
213 | static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream, | 226 | static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream, |
214 | int channel, snd_pcm_uframes_t pos, | 227 | int channel, unsigned long pos, |
215 | snd_pcm_uframes_t count) | 228 | unsigned long count) |
216 | { | 229 | { |
217 | /* channel is not used (interleaved data) */ | 230 | /* channel is not used (interleaved data) */ |
218 | struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); | 231 | struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); |
219 | struct snd_pcm_runtime *runtime = substream->runtime; | 232 | struct snd_pcm_runtime *runtime = substream->runtime; |
220 | ssize_t b_count = frames_to_bytes(runtime , count); | ||
221 | ssize_t b_pos = frames_to_bytes(runtime , pos); | ||
222 | |||
223 | if (count < 0) | ||
224 | return -EINVAL; | ||
225 | |||
226 | if (!count) | ||
227 | return 0; | ||
228 | 233 | ||
229 | memset_io(chip->data_buffer + b_pos, 0, b_count); | 234 | memset_io(chip->data_buffer + pos, 0, count); |
230 | chip->buffer_end = chip->data_buffer + b_pos + b_count; | 235 | chip->buffer_end = chip->data_buffer + pos + count; |
231 | 236 | ||
232 | if (chip->empty) { | 237 | if (chip->empty) { |
233 | chip->empty = 0; | 238 | chip->empty = 0; |
@@ -256,8 +261,9 @@ static struct snd_pcm_ops snd_sh_dac_pcm_ops = { | |||
256 | .prepare = snd_sh_dac_pcm_prepare, | 261 | .prepare = snd_sh_dac_pcm_prepare, |
257 | .trigger = snd_sh_dac_pcm_trigger, | 262 | .trigger = snd_sh_dac_pcm_trigger, |
258 | .pointer = snd_sh_dac_pcm_pointer, | 263 | .pointer = snd_sh_dac_pcm_pointer, |
259 | .copy = snd_sh_dac_pcm_copy, | 264 | .copy_user = snd_sh_dac_pcm_copy, |
260 | .silence = snd_sh_dac_pcm_silence, | 265 | .copy_kernel = snd_sh_dac_pcm_copy_kernel, |
266 | .fill_silence = snd_sh_dac_pcm_silence, | ||
261 | .mmap = snd_pcm_lib_mmap_iomem, | 267 | .mmap = snd_pcm_lib_mmap_iomem, |
262 | }; | 268 | }; |
263 | 269 | ||
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index 02ad2606fa19..913e29275f4e 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c | |||
@@ -279,23 +279,33 @@ static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream, | |||
279 | return 0 ; | 279 | return 0 ; |
280 | } | 280 | } |
281 | #else | 281 | #else |
282 | static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, | 282 | static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, |
283 | snd_pcm_uframes_t pos, | 283 | int channel, unsigned long pos, |
284 | void __user *buf, snd_pcm_uframes_t count) | 284 | void *buf, unsigned long count) |
285 | { | 285 | { |
286 | struct snd_pcm_runtime *runtime = substream->runtime; | 286 | struct snd_pcm_runtime *runtime = substream->runtime; |
287 | unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1]; | 287 | unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1]; |
288 | struct ac97_frame *dst; | ||
289 | |||
288 | pr_debug("%s copy pos:0x%lx count:0x%lx\n", | 290 | pr_debug("%s copy pos:0x%lx count:0x%lx\n", |
289 | substream->stream ? "Capture" : "Playback", pos, count); | 291 | substream->stream ? "Capture" : "Playback", pos, count); |
292 | dst = (struct ac97_frame *)runtime->dma_area + | ||
293 | bytes_to_frames(runtime, pos); | ||
294 | count = bytes_to_frames(runtime, count); | ||
290 | 295 | ||
291 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 296 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
292 | bf5xx_pcm_to_ac97((struct ac97_frame *)runtime->dma_area + pos, | 297 | bf5xx_pcm_to_ac97(dst, buf, count, chan_mask); |
293 | (__u16 *)buf, count, chan_mask); | ||
294 | else | 298 | else |
295 | bf5xx_ac97_to_pcm((struct ac97_frame *)runtime->dma_area + pos, | 299 | bf5xx_ac97_to_pcm(dst, buf, count); |
296 | (__u16 *)buf, count); | ||
297 | return 0; | 300 | return 0; |
298 | } | 301 | } |
302 | |||
303 | static int bf5xx_pcm_copy_user(struct snd_pcm_substream *substream, | ||
304 | int channel, unsigned long pos, | ||
305 | void __user *buf, unsigned long count) | ||
306 | { | ||
307 | return bf5xx_pcm_copy(substream, channel, pos, (void *)buf, count); | ||
308 | } | ||
299 | #endif | 309 | #endif |
300 | 310 | ||
301 | static struct snd_pcm_ops bf5xx_pcm_ac97_ops = { | 311 | static struct snd_pcm_ops bf5xx_pcm_ac97_ops = { |
@@ -309,7 +319,8 @@ static struct snd_pcm_ops bf5xx_pcm_ac97_ops = { | |||
309 | #if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT) | 319 | #if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT) |
310 | .mmap = bf5xx_pcm_mmap, | 320 | .mmap = bf5xx_pcm_mmap, |
311 | #else | 321 | #else |
312 | .copy = bf5xx_pcm_copy, | 322 | .copy_user = bf5xx_pcm_copy_user, |
323 | .copy_kernel = bf5xx_pcm_copy, | ||
313 | #endif | 324 | #endif |
314 | }; | 325 | }; |
315 | 326 | ||
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 6cba211da32e..470d99abf6f6 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c | |||
@@ -225,8 +225,9 @@ static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream, | |||
225 | return 0 ; | 225 | return 0 ; |
226 | } | 226 | } |
227 | 227 | ||
228 | static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, | 228 | static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, |
229 | snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count) | 229 | int channel, unsigned long pos, |
230 | void *buf, unsigned long count) | ||
230 | { | 231 | { |
231 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 232 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
232 | struct snd_pcm_runtime *runtime = substream->runtime; | 233 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -238,6 +239,8 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, | |||
238 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | 239 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
239 | 240 | ||
240 | if (dma_data->tdm_mode) { | 241 | if (dma_data->tdm_mode) { |
242 | pos = bytes_to_frames(runtime, pos); | ||
243 | count = bytes_to_frames(runtime, count); | ||
241 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 244 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
242 | src = buf; | 245 | src = buf; |
243 | dst = runtime->dma_area; | 246 | dst = runtime->dma_area; |
@@ -269,21 +272,29 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, | |||
269 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 272 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
270 | src = buf; | 273 | src = buf; |
271 | dst = runtime->dma_area; | 274 | dst = runtime->dma_area; |
272 | dst += frames_to_bytes(runtime, pos); | 275 | dst += pos; |
273 | } else { | 276 | } else { |
274 | src = runtime->dma_area; | 277 | src = runtime->dma_area; |
275 | src += frames_to_bytes(runtime, pos); | 278 | src += pos; |
276 | dst = buf; | 279 | dst = buf; |
277 | } | 280 | } |
278 | 281 | ||
279 | memcpy(dst, src, frames_to_bytes(runtime, count)); | 282 | memcpy(dst, src, count); |
280 | } | 283 | } |
281 | 284 | ||
282 | return 0; | 285 | return 0; |
283 | } | 286 | } |
284 | 287 | ||
288 | static int bf5xx_pcm_copy_user(struct snd_pcm_substream *substream, | ||
289 | int channel, unsigned long pos, | ||
290 | void __user *buf, unsigned long count) | ||
291 | { | ||
292 | return bf5xx_pcm_copy(substream, channel, pos, (void *)buf, count); | ||
293 | } | ||
294 | |||
285 | static int bf5xx_pcm_silence(struct snd_pcm_substream *substream, | 295 | static int bf5xx_pcm_silence(struct snd_pcm_substream *substream, |
286 | int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count) | 296 | int channel, unsigned long pos, |
297 | unsigned long count) | ||
287 | { | 298 | { |
288 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 299 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
289 | struct snd_pcm_runtime *runtime = substream->runtime; | 300 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -295,11 +306,11 @@ static int bf5xx_pcm_silence(struct snd_pcm_substream *substream, | |||
295 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | 306 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
296 | 307 | ||
297 | if (dma_data->tdm_mode) { | 308 | if (dma_data->tdm_mode) { |
298 | offset = pos * 8 * sample_size; | 309 | offset = bytes_to_frames(runtime, pos) * 8 * sample_size; |
299 | samples = count * 8; | 310 | samples = bytes_to_frames(runtime, count) * 8; |
300 | } else { | 311 | } else { |
301 | offset = frames_to_bytes(runtime, pos); | 312 | offset = pos; |
302 | samples = count * runtime->channels; | 313 | samples = bytes_to_samples(runtime, count); |
303 | } | 314 | } |
304 | 315 | ||
305 | snd_pcm_format_set_silence(runtime->format, buf + offset, samples); | 316 | snd_pcm_format_set_silence(runtime->format, buf + offset, samples); |
@@ -316,8 +327,9 @@ static struct snd_pcm_ops bf5xx_pcm_i2s_ops = { | |||
316 | .trigger = bf5xx_pcm_trigger, | 327 | .trigger = bf5xx_pcm_trigger, |
317 | .pointer = bf5xx_pcm_pointer, | 328 | .pointer = bf5xx_pcm_pointer, |
318 | .mmap = bf5xx_pcm_mmap, | 329 | .mmap = bf5xx_pcm_mmap, |
319 | .copy = bf5xx_pcm_copy, | 330 | .copy_user = bf5xx_pcm_copy_user, |
320 | .silence = bf5xx_pcm_silence, | 331 | .copy_kernel = bf5xx_pcm_copy, |
332 | .fill_silence = bf5xx_pcm_silence, | ||
321 | }; | 333 | }; |
322 | 334 | ||
323 | static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd) | 335 | static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd) |
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index 76b2ab8c2b4a..4a22aadac294 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c | |||
@@ -441,7 +441,7 @@ static int siu_dai_put_volume(struct snd_kcontrol *kctrl, | |||
441 | return 0; | 441 | return 0; |
442 | } | 442 | } |
443 | 443 | ||
444 | static struct snd_kcontrol_new playback_controls = { | 444 | static const struct snd_kcontrol_new playback_controls = { |
445 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 445 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
446 | .name = "PCM Playback Volume", | 446 | .name = "PCM Playback Volume", |
447 | .index = 0, | 447 | .index = 0, |
@@ -451,7 +451,7 @@ static struct snd_kcontrol_new playback_controls = { | |||
451 | .private_value = VOLUME_PLAYBACK, | 451 | .private_value = VOLUME_PLAYBACK, |
452 | }; | 452 | }; |
453 | 453 | ||
454 | static struct snd_kcontrol_new capture_controls = { | 454 | static const struct snd_kcontrol_new capture_controls = { |
455 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 455 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
456 | .name = "PCM Capture Volume", | 456 | .name = "PCM Capture Volume", |
457 | .index = 0, | 457 | .index = 0, |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index efc5831f205d..dcc5ece08668 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -2743,8 +2743,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) | |||
2743 | 2743 | ||
2744 | if (platform->driver->ops) { | 2744 | if (platform->driver->ops) { |
2745 | rtd->ops.ack = platform->driver->ops->ack; | 2745 | rtd->ops.ack = platform->driver->ops->ack; |
2746 | rtd->ops.copy = platform->driver->ops->copy; | 2746 | rtd->ops.copy_user = platform->driver->ops->copy_user; |
2747 | rtd->ops.silence = platform->driver->ops->silence; | 2747 | rtd->ops.copy_kernel = platform->driver->ops->copy_kernel; |
2748 | rtd->ops.fill_silence = platform->driver->ops->fill_silence; | ||
2748 | rtd->ops.page = platform->driver->ops->page; | 2749 | rtd->ops.page = platform->driver->ops->page; |
2749 | rtd->ops.mmap = platform->driver->ops->mmap; | 2750 | rtd->ops.mmap = platform->driver->ops->mmap; |
2750 | } | 2751 | } |
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 30bdc971883b..3d7d425fbd24 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -200,12 +200,12 @@ static unsigned char freq_bits[14] = { | |||
200 | /* 48000 */ 0x0C | CS4231_XTAL1 | 200 | /* 48000 */ 0x0C | CS4231_XTAL1 |
201 | }; | 201 | }; |
202 | 202 | ||
203 | static unsigned int rates[14] = { | 203 | static const unsigned int rates[14] = { |
204 | 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050, | 204 | 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050, |
205 | 27042, 32000, 33075, 37800, 44100, 48000 | 205 | 27042, 32000, 33075, 37800, 44100, 48000 |
206 | }; | 206 | }; |
207 | 207 | ||
208 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 208 | static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
209 | .count = ARRAY_SIZE(rates), | 209 | .count = ARRAY_SIZE(rates), |
210 | .list = rates, | 210 | .list = rates, |
211 | }; | 211 | }; |
diff --git a/sound/synth/Kconfig b/sound/synth/Kconfig new file mode 100644 index 000000000000..dfe8950e0556 --- /dev/null +++ b/sound/synth/Kconfig | |||
@@ -0,0 +1,2 @@ | |||
1 | config SND_SYNTH_EMUX | ||
2 | tristate | ||
diff --git a/sound/synth/emux/Makefile b/sound/synth/emux/Makefile index fb761c2c2b50..4599108452fd 100644 --- a/sound/synth/emux/Makefile +++ b/sound/synth/emux/Makefile | |||
@@ -8,6 +8,4 @@ snd-emux-synth-objs := emux.o emux_synth.o emux_seq.o emux_nrpn.o \ | |||
8 | snd-emux-synth-$(CONFIG_SND_PROC_FS) += emux_proc.o | 8 | snd-emux-synth-$(CONFIG_SND_PROC_FS) += emux_proc.o |
9 | snd-emux-synth-$(CONFIG_SND_SEQUENCER_OSS) += emux_oss.o | 9 | snd-emux-synth-$(CONFIG_SND_SEQUENCER_OSS) += emux_oss.o |
10 | 10 | ||
11 | # Toplevel Module Dependencies | 11 | obj-$(CONFIG_SND_SYNTH_EMUX) += snd-emux-synth.o |
12 | obj-$(CONFIG_SND_SBAWE_SEQ) += snd-emux-synth.o | ||
13 | obj-$(CONFIG_SND_EMU10K1_SEQ) += snd-emux-synth.o | ||
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c index 9312cd8a6fdd..b9981e8c0027 100644 --- a/sound/synth/emux/emux.c +++ b/sound/synth/emux/emux.c | |||
@@ -47,7 +47,7 @@ int snd_emux_new(struct snd_emux **remu) | |||
47 | mutex_init(&emu->register_mutex); | 47 | mutex_init(&emu->register_mutex); |
48 | 48 | ||
49 | emu->client = -1; | 49 | emu->client = -1; |
50 | #ifdef CONFIG_SND_SEQUENCER_OSS | 50 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
51 | emu->oss_synth = NULL; | 51 | emu->oss_synth = NULL; |
52 | #endif | 52 | #endif |
53 | emu->max_voices = 0; | 53 | emu->max_voices = 0; |
@@ -123,7 +123,7 @@ int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, ch | |||
123 | snd_emux_init_voices(emu); | 123 | snd_emux_init_voices(emu); |
124 | 124 | ||
125 | snd_emux_init_seq(emu, card, index); | 125 | snd_emux_init_seq(emu, card, index); |
126 | #ifdef CONFIG_SND_SEQUENCER_OSS | 126 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
127 | snd_emux_init_seq_oss(emu); | 127 | snd_emux_init_seq_oss(emu); |
128 | #endif | 128 | #endif |
129 | snd_emux_init_virmidi(emu, card); | 129 | snd_emux_init_virmidi(emu, card); |
@@ -150,7 +150,7 @@ int snd_emux_free(struct snd_emux *emu) | |||
150 | 150 | ||
151 | snd_emux_proc_free(emu); | 151 | snd_emux_proc_free(emu); |
152 | snd_emux_delete_virmidi(emu); | 152 | snd_emux_delete_virmidi(emu); |
153 | #ifdef CONFIG_SND_SEQUENCER_OSS | 153 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
154 | snd_emux_detach_seq_oss(emu); | 154 | snd_emux_detach_seq_oss(emu); |
155 | #endif | 155 | #endif |
156 | snd_emux_detach_seq(emu); | 156 | snd_emux_detach_seq(emu); |
diff --git a/sound/synth/emux/emux_effect.c b/sound/synth/emux/emux_effect.c index a447218b6160..9ac0bf531b4b 100644 --- a/sound/synth/emux/emux_effect.c +++ b/sound/synth/emux/emux_effect.c | |||
@@ -150,7 +150,7 @@ effect_get_offset(struct snd_midi_channel *chan, int lo, int hi, int mode) | |||
150 | return addr; | 150 | return addr; |
151 | } | 151 | } |
152 | 152 | ||
153 | #ifdef CONFIG_SND_SEQUENCER_OSS | 153 | #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS) |
154 | /* change effects - for OSS sequencer compatibility */ | 154 | /* change effects - for OSS sequencer compatibility */ |
155 | void | 155 | void |
156 | snd_emux_send_effect_oss(struct snd_emux_port *port, | 156 | snd_emux_send_effect_oss(struct snd_emux_port *port, |
diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c index 850fab4a8f3b..de19e108974a 100644 --- a/sound/synth/emux/emux_oss.c +++ b/sound/synth/emux/emux_oss.c | |||
@@ -23,8 +23,6 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | 25 | ||
26 | #ifdef CONFIG_SND_SEQUENCER_OSS | ||
27 | |||
28 | #include <linux/export.h> | 26 | #include <linux/export.h> |
29 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
30 | #include <sound/core.h> | 28 | #include <sound/core.h> |
@@ -505,5 +503,3 @@ fake_event(struct snd_emux *emu, struct snd_emux_port *port, int ch, int param, | |||
505 | ev.data.control.value = val; | 503 | ev.data.control.value = val; |
506 | snd_emux_event_input(&ev, 0, port, atomic, hop); | 504 | snd_emux_event_input(&ev, 0, port, atomic, hop); |
507 | } | 505 | } |
508 | |||
509 | #endif /* CONFIG_SND_SEQUENCER_OSS */ | ||
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index a452ad7cec40..f61b5662bb89 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -91,7 +91,7 @@ config SND_USB_CAIAQ_INPUT | |||
91 | 91 | ||
92 | config SND_USB_US122L | 92 | config SND_USB_US122L |
93 | tristate "Tascam US-122L USB driver" | 93 | tristate "Tascam US-122L USB driver" |
94 | depends on X86 | 94 | depends on X86 || COMPILE_TEST |
95 | select SND_HWDEP | 95 | select SND_HWDEP |
96 | select SND_RAWMIDI | 96 | select SND_RAWMIDI |
97 | help | 97 | help |
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index a5c2e9ae5f17..dc97895547be 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h | |||
@@ -117,6 +117,8 @@ enum { | |||
117 | LINE6_CAP_IN_NEEDS_OUT = 1 << 3, | 117 | LINE6_CAP_IN_NEEDS_OUT = 1 << 3, |
118 | /* device uses raw MIDI via USB (data endpoints) */ | 118 | /* device uses raw MIDI via USB (data endpoints) */ |
119 | LINE6_CAP_CONTROL_MIDI = 1 << 4, | 119 | LINE6_CAP_CONTROL_MIDI = 1 << 4, |
120 | /* device provides low-level information */ | ||
121 | LINE6_CAP_CONTROL_INFO = 1 << 5, | ||
120 | }; | 122 | }; |
121 | 123 | ||
122 | /* | 124 | /* |
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 6ab23e5aee71..956f847a96e4 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com> | 4 | * Copyright (C) 2011 Stefan Hajnoczi <stefanha@gmail.com> |
5 | * Copyright (C) 2015 Andrej Krutak <dev@andree.sk> | 5 | * Copyright (C) 2015 Andrej Krutak <dev@andree.sk> |
6 | * Copyright (C) 2017 Hans P. Moller <hmoller@uc.cl> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License as | 9 | * modify it under the terms of the GNU General Public License as |
@@ -37,7 +38,8 @@ enum { | |||
37 | LINE6_PODHD500_0, | 38 | LINE6_PODHD500_0, |
38 | LINE6_PODHD500_1, | 39 | LINE6_PODHD500_1, |
39 | LINE6_PODX3, | 40 | LINE6_PODX3, |
40 | LINE6_PODX3LIVE | 41 | LINE6_PODX3LIVE, |
42 | LINE6_PODHD500X | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | struct usb_line6_podhd { | 45 | struct usb_line6_podhd { |
@@ -291,7 +293,7 @@ static void podhd_disconnect(struct usb_line6 *line6) | |||
291 | { | 293 | { |
292 | struct usb_line6_podhd *pod = (struct usb_line6_podhd *)line6; | 294 | struct usb_line6_podhd *pod = (struct usb_line6_podhd *)line6; |
293 | 295 | ||
294 | if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { | 296 | if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) { |
295 | struct usb_interface *intf; | 297 | struct usb_interface *intf; |
296 | 298 | ||
297 | del_timer_sync(&pod->startup_timer); | 299 | del_timer_sync(&pod->startup_timer); |
@@ -331,7 +333,9 @@ static int podhd_init(struct usb_line6 *line6, | |||
331 | pod->line6.properties->ctrl_if, err); | 333 | pod->line6.properties->ctrl_if, err); |
332 | return err; | 334 | return err; |
333 | } | 335 | } |
336 | } | ||
334 | 337 | ||
338 | if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO) { | ||
335 | /* create sysfs entries: */ | 339 | /* create sysfs entries: */ |
336 | err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group); | 340 | err = snd_card_add_dev_attr(line6->card, &podhd_dev_attr_group); |
337 | if (err < 0) | 341 | if (err < 0) |
@@ -348,7 +352,7 @@ static int podhd_init(struct usb_line6 *line6, | |||
348 | return err; | 352 | return err; |
349 | } | 353 | } |
350 | 354 | ||
351 | if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL)) { | 355 | if (!(pod->line6.properties->capabilities & LINE6_CAP_CONTROL_INFO)) { |
352 | /* register USB audio system directly */ | 356 | /* register USB audio system directly */ |
353 | return podhd_startup_finalize(pod); | 357 | return podhd_startup_finalize(pod); |
354 | } | 358 | } |
@@ -372,6 +376,7 @@ static const struct usb_device_id podhd_id_table[] = { | |||
372 | { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, | 376 | { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, |
373 | { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 }, | 377 | { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 }, |
374 | { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE }, | 378 | { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE }, |
379 | { LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X }, | ||
375 | {} | 380 | {} |
376 | }; | 381 | }; |
377 | 382 | ||
@@ -425,7 +430,7 @@ static const struct line6_properties podhd_properties_table[] = { | |||
425 | [LINE6_PODX3] = { | 430 | [LINE6_PODX3] = { |
426 | .id = "PODX3", | 431 | .id = "PODX3", |
427 | .name = "POD X3", | 432 | .name = "POD X3", |
428 | .capabilities = LINE6_CAP_CONTROL | 433 | .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO |
429 | | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, | 434 | | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, |
430 | .altsetting = 1, | 435 | .altsetting = 1, |
431 | .ep_ctrl_r = 0x81, | 436 | .ep_ctrl_r = 0x81, |
@@ -437,7 +442,7 @@ static const struct line6_properties podhd_properties_table[] = { | |||
437 | [LINE6_PODX3LIVE] = { | 442 | [LINE6_PODX3LIVE] = { |
438 | .id = "PODX3LIVE", | 443 | .id = "PODX3LIVE", |
439 | .name = "POD X3 LIVE", | 444 | .name = "POD X3 LIVE", |
440 | .capabilities = LINE6_CAP_CONTROL | 445 | .capabilities = LINE6_CAP_CONTROL | LINE6_CAP_CONTROL_INFO |
441 | | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, | 446 | | LINE6_CAP_PCM | LINE6_CAP_HWMON | LINE6_CAP_IN_NEEDS_OUT, |
442 | .altsetting = 1, | 447 | .altsetting = 1, |
443 | .ep_ctrl_r = 0x81, | 448 | .ep_ctrl_r = 0x81, |
@@ -446,6 +451,18 @@ static const struct line6_properties podhd_properties_table[] = { | |||
446 | .ep_audio_r = 0x86, | 451 | .ep_audio_r = 0x86, |
447 | .ep_audio_w = 0x02, | 452 | .ep_audio_w = 0x02, |
448 | }, | 453 | }, |
454 | [LINE6_PODHD500X] = { | ||
455 | .id = "PODHD500X", | ||
456 | .name = "POD HD500X", | ||
457 | .capabilities = LINE6_CAP_CONTROL | ||
458 | | LINE6_CAP_PCM | LINE6_CAP_HWMON, | ||
459 | .altsetting = 1, | ||
460 | .ep_ctrl_r = 0x81, | ||
461 | .ep_ctrl_w = 0x01, | ||
462 | .ctrl_if = 1, | ||
463 | .ep_audio_r = 0x86, | ||
464 | .ep_audio_w = 0x02, | ||
465 | }, | ||
449 | }; | 466 | }; |
450 | 467 | ||
451 | /* | 468 | /* |
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 4fa0053a40af..e3d1dec48ee4 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -362,7 +362,7 @@ static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list) | |||
362 | } | 362 | } |
363 | 363 | ||
364 | /* name and private_value are set dynamically */ | 364 | /* name and private_value are set dynamically */ |
365 | static struct snd_kcontrol_new snd_audigy2nx_control = { | 365 | static const struct snd_kcontrol_new snd_audigy2nx_control = { |
366 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 366 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
367 | .info = snd_audigy2nx_led_info, | 367 | .info = snd_audigy2nx_led_info, |
368 | .get = snd_audigy2nx_led_get, | 368 | .get = snd_audigy2nx_led_get, |
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index e118bdca983d..a33e31b2fc2f 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c | |||
@@ -46,8 +46,10 @@ MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS"."); | |||
46 | module_param_array(enable, bool, NULL, 0444); | 46 | module_param_array(enable, bool, NULL, 0444); |
47 | MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS"."); | 47 | MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS"."); |
48 | 48 | ||
49 | static int snd_us122l_card_used[SNDRV_CARDS]; | 49 | /* driver_info flags */ |
50 | #define US122L_FLAG_US144 BIT(0) | ||
50 | 51 | ||
52 | static int snd_us122l_card_used[SNDRV_CARDS]; | ||
51 | 53 | ||
52 | static int us122l_create_usbmidi(struct snd_card *card) | 54 | static int us122l_create_usbmidi(struct snd_card *card) |
53 | { | 55 | { |
@@ -198,8 +200,7 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file) | |||
198 | if (!us122l->first) | 200 | if (!us122l->first) |
199 | us122l->first = file; | 201 | us122l->first = file; |
200 | 202 | ||
201 | if (us122l->dev->descriptor.idProduct == USB_ID_US144 || | 203 | if (us122l->is_us144) { |
202 | us122l->dev->descriptor.idProduct == USB_ID_US144MKII) { | ||
203 | iface = usb_ifnum_to_if(us122l->dev, 0); | 204 | iface = usb_ifnum_to_if(us122l->dev, 0); |
204 | usb_autopm_get_interface(iface); | 205 | usb_autopm_get_interface(iface); |
205 | } | 206 | } |
@@ -214,8 +215,7 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file) | |||
214 | struct usb_interface *iface; | 215 | struct usb_interface *iface; |
215 | snd_printdd(KERN_DEBUG "%p %p\n", hw, file); | 216 | snd_printdd(KERN_DEBUG "%p %p\n", hw, file); |
216 | 217 | ||
217 | if (us122l->dev->descriptor.idProduct == USB_ID_US144 || | 218 | if (us122l->is_us144) { |
218 | us122l->dev->descriptor.idProduct == USB_ID_US144MKII) { | ||
219 | iface = usb_ifnum_to_if(us122l->dev, 0); | 219 | iface = usb_ifnum_to_if(us122l->dev, 0); |
220 | usb_autopm_put_interface(iface); | 220 | usb_autopm_put_interface(iface); |
221 | } | 221 | } |
@@ -483,8 +483,7 @@ static bool us122l_create_card(struct snd_card *card) | |||
483 | int err; | 483 | int err; |
484 | struct us122l *us122l = US122L(card); | 484 | struct us122l *us122l = US122L(card); |
485 | 485 | ||
486 | if (us122l->dev->descriptor.idProduct == USB_ID_US144 || | 486 | if (us122l->is_us144) { |
487 | us122l->dev->descriptor.idProduct == USB_ID_US144MKII) { | ||
488 | err = usb_set_interface(us122l->dev, 0, 1); | 487 | err = usb_set_interface(us122l->dev, 0, 1); |
489 | if (err) { | 488 | if (err) { |
490 | snd_printk(KERN_ERR "usb_set_interface error \n"); | 489 | snd_printk(KERN_ERR "usb_set_interface error \n"); |
@@ -503,8 +502,7 @@ static bool us122l_create_card(struct snd_card *card) | |||
503 | if (!us122l_start(us122l, 44100, 256)) | 502 | if (!us122l_start(us122l, 44100, 256)) |
504 | return false; | 503 | return false; |
505 | 504 | ||
506 | if (us122l->dev->descriptor.idProduct == USB_ID_US144 || | 505 | if (us122l->is_us144) |
507 | us122l->dev->descriptor.idProduct == USB_ID_US144MKII) | ||
508 | err = us144_create_usbmidi(card); | 506 | err = us144_create_usbmidi(card); |
509 | else | 507 | else |
510 | err = us122l_create_usbmidi(card); | 508 | err = us122l_create_usbmidi(card); |
@@ -536,7 +534,8 @@ static void snd_us122l_free(struct snd_card *card) | |||
536 | 534 | ||
537 | static int usx2y_create_card(struct usb_device *device, | 535 | static int usx2y_create_card(struct usb_device *device, |
538 | struct usb_interface *intf, | 536 | struct usb_interface *intf, |
539 | struct snd_card **cardp) | 537 | struct snd_card **cardp, |
538 | unsigned long flags) | ||
540 | { | 539 | { |
541 | int dev; | 540 | int dev; |
542 | struct snd_card *card; | 541 | struct snd_card *card; |
@@ -556,6 +555,7 @@ static int usx2y_create_card(struct usb_device *device, | |||
556 | US122L(card)->dev = device; | 555 | US122L(card)->dev = device; |
557 | mutex_init(&US122L(card)->mutex); | 556 | mutex_init(&US122L(card)->mutex); |
558 | init_waitqueue_head(&US122L(card)->sk.sleep); | 557 | init_waitqueue_head(&US122L(card)->sk.sleep); |
558 | US122L(card)->is_us144 = flags & US122L_FLAG_US144; | ||
559 | INIT_LIST_HEAD(&US122L(card)->midi_list); | 559 | INIT_LIST_HEAD(&US122L(card)->midi_list); |
560 | strcpy(card->driver, "USB "NAME_ALLCAPS""); | 560 | strcpy(card->driver, "USB "NAME_ALLCAPS""); |
561 | sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); | 561 | sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); |
@@ -579,7 +579,7 @@ static int us122l_usb_probe(struct usb_interface *intf, | |||
579 | struct snd_card *card; | 579 | struct snd_card *card; |
580 | int err; | 580 | int err; |
581 | 581 | ||
582 | err = usx2y_create_card(device, intf, &card); | 582 | err = usx2y_create_card(device, intf, &card, device_id->driver_info); |
583 | if (err < 0) | 583 | if (err < 0) |
584 | return err; | 584 | return err; |
585 | 585 | ||
@@ -607,9 +607,8 @@ static int snd_us122l_probe(struct usb_interface *intf, | |||
607 | struct snd_card *card; | 607 | struct snd_card *card; |
608 | int err; | 608 | int err; |
609 | 609 | ||
610 | if ((device->descriptor.idProduct == USB_ID_US144 || | 610 | if (id->driver_info & US122L_FLAG_US144 && |
611 | device->descriptor.idProduct == USB_ID_US144MKII) | 611 | device->speed == USB_SPEED_HIGH) { |
612 | && device->speed == USB_SPEED_HIGH) { | ||
613 | snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n"); | 612 | snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n"); |
614 | return -ENODEV; | 613 | return -ENODEV; |
615 | } | 614 | } |
@@ -703,8 +702,7 @@ static int snd_us122l_resume(struct usb_interface *intf) | |||
703 | 702 | ||
704 | mutex_lock(&us122l->mutex); | 703 | mutex_lock(&us122l->mutex); |
705 | /* needed, doesn't restart without: */ | 704 | /* needed, doesn't restart without: */ |
706 | if (us122l->dev->descriptor.idProduct == USB_ID_US144 || | 705 | if (us122l->is_us144) { |
707 | us122l->dev->descriptor.idProduct == USB_ID_US144MKII) { | ||
708 | err = usb_set_interface(us122l->dev, 0, 1); | 706 | err = usb_set_interface(us122l->dev, 0, 1); |
709 | if (err) { | 707 | if (err) { |
710 | snd_printk(KERN_ERR "usb_set_interface error \n"); | 708 | snd_printk(KERN_ERR "usb_set_interface error \n"); |
@@ -747,7 +745,8 @@ static struct usb_device_id snd_us122l_usb_id_table[] = { | |||
747 | { /* US-144 only works at USB1.1! Disable module ehci-hcd. */ | 745 | { /* US-144 only works at USB1.1! Disable module ehci-hcd. */ |
748 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 746 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
749 | .idVendor = 0x0644, | 747 | .idVendor = 0x0644, |
750 | .idProduct = USB_ID_US144 | 748 | .idProduct = USB_ID_US144, |
749 | .driver_info = US122L_FLAG_US144 | ||
751 | }, | 750 | }, |
752 | { | 751 | { |
753 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 752 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
@@ -757,7 +756,8 @@ static struct usb_device_id snd_us122l_usb_id_table[] = { | |||
757 | { | 756 | { |
758 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 757 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
759 | .idVendor = 0x0644, | 758 | .idVendor = 0x0644, |
760 | .idProduct = USB_ID_US144MKII | 759 | .idProduct = USB_ID_US144MKII, |
760 | .driver_info = US122L_FLAG_US144 | ||
761 | }, | 761 | }, |
762 | { /* terminator */ } | 762 | { /* terminator */ } |
763 | }; | 763 | }; |
diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h index f263b3f96c86..3e2a2d0041ee 100644 --- a/sound/usb/usx2y/us122l.h +++ b/sound/usb/usx2y/us122l.h | |||
@@ -16,6 +16,8 @@ struct us122l { | |||
16 | struct list_head midi_list; | 16 | struct list_head midi_list; |
17 | 17 | ||
18 | atomic_t mmap_count; | 18 | atomic_t mmap_count; |
19 | |||
20 | bool is_us144; | ||
19 | }; | 21 | }; |
20 | 22 | ||
21 | 23 | ||