0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #undef HAVE_REALLY_SLOW_DMA_CONTROLLER
0013
0014 #include <linux/export.h>
0015 #include <linux/isa-dma.h>
0016 #include <sound/core.h>
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 void snd_dma_program(unsigned long dma,
0028 unsigned long addr, unsigned int size,
0029 unsigned short mode)
0030 {
0031 unsigned long flags;
0032
0033 flags = claim_dma_lock();
0034 disable_dma(dma);
0035 clear_dma_ff(dma);
0036 set_dma_mode(dma, mode);
0037 set_dma_addr(dma, addr);
0038 set_dma_count(dma, size);
0039 if (!(mode & DMA_MODE_NO_ENABLE))
0040 enable_dma(dma);
0041 release_dma_lock(flags);
0042 }
0043 EXPORT_SYMBOL(snd_dma_program);
0044
0045
0046
0047
0048
0049
0050
0051 void snd_dma_disable(unsigned long dma)
0052 {
0053 unsigned long flags;
0054
0055 flags = claim_dma_lock();
0056 clear_dma_ff(dma);
0057 disable_dma(dma);
0058 release_dma_lock(flags);
0059 }
0060 EXPORT_SYMBOL(snd_dma_disable);
0061
0062
0063
0064
0065
0066
0067
0068
0069 unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
0070 {
0071 unsigned long flags;
0072 unsigned int result, result1;
0073
0074 flags = claim_dma_lock();
0075 clear_dma_ff(dma);
0076 if (!isa_dma_bridge_buggy)
0077 disable_dma(dma);
0078 result = get_dma_residue(dma);
0079
0080
0081
0082
0083
0084 result1 = get_dma_residue(dma);
0085 if (!isa_dma_bridge_buggy)
0086 enable_dma(dma);
0087 release_dma_lock(flags);
0088 if (unlikely(result < result1))
0089 result = result1;
0090 #ifdef CONFIG_SND_DEBUG
0091 if (result > size)
0092 pr_err("ALSA: pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
0093 #endif
0094 if (result >= size || result == 0)
0095 return 0;
0096 else
0097 return size - result;
0098 }
0099 EXPORT_SYMBOL(snd_dma_pointer);
0100
0101 struct snd_dma_data {
0102 int dma;
0103 };
0104
0105 static void __snd_release_dma(struct device *dev, void *data)
0106 {
0107 struct snd_dma_data *p = data;
0108
0109 snd_dma_disable(p->dma);
0110 free_dma(p->dma);
0111 }
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 int snd_devm_request_dma(struct device *dev, int dma, const char *name)
0124 {
0125 struct snd_dma_data *p;
0126
0127 if (request_dma(dma, name))
0128 return -EBUSY;
0129 p = devres_alloc(__snd_release_dma, sizeof(*p), GFP_KERNEL);
0130 if (!p) {
0131 free_dma(dma);
0132 return -ENOMEM;
0133 }
0134 p->dma = dma;
0135 devres_add(dev, p);
0136 return 0;
0137 }
0138 EXPORT_SYMBOL_GPL(snd_devm_request_dma);