diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-06-02 09:55:22 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-06-02 09:55:22 -0400 |
commit | bd05dbd3b22612455283610b4e006ee3e421b13d (patch) | |
tree | 06868be09771d6908acd657b1a9f66b0fb209bce /sound/pci/ctxfi | |
parent | 67fbf880631bb4493ad8d23f25562abdf09dc01d (diff) | |
parent | c76157d9286ed598c241c212aa5a3c6e5107bd82 (diff) |
Merge branch 'topic/ctxfi-fix' into topic/ctxfi
Diffstat (limited to 'sound/pci/ctxfi')
-rw-r--r-- | sound/pci/ctxfi/ctatc.c | 35 | ||||
-rw-r--r-- | sound/pci/ctxfi/ctatc.h | 5 | ||||
-rw-r--r-- | sound/pci/ctxfi/cthw20k1.c | 16 | ||||
-rw-r--r-- | sound/pci/ctxfi/cthw20k2.c | 17 | ||||
-rw-r--r-- | sound/pci/ctxfi/ctmixer.c | 8 | ||||
-rw-r--r-- | sound/pci/ctxfi/ctpcm.c | 25 | ||||
-rw-r--r-- | sound/pci/ctxfi/ctvmem.c | 77 | ||||
-rw-r--r-- | sound/pci/ctxfi/ctvmem.h | 16 |
8 files changed, 92 insertions, 107 deletions
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index ead104ea1e35..684947546d81 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c | |||
@@ -72,15 +72,15 @@ static struct { | |||
72 | [FRONT] = { .create = ct_alsa_pcm_create, | 72 | [FRONT] = { .create = ct_alsa_pcm_create, |
73 | .destroy = NULL, | 73 | .destroy = NULL, |
74 | .public_name = "Front/WaveIn"}, | 74 | .public_name = "Front/WaveIn"}, |
75 | [REAR] = { .create = ct_alsa_pcm_create, | 75 | [SURROUND] = { .create = ct_alsa_pcm_create, |
76 | .destroy = NULL, | 76 | .destroy = NULL, |
77 | .public_name = "Rear"}, | 77 | .public_name = "Surround"}, |
78 | [CLFE] = { .create = ct_alsa_pcm_create, | 78 | [CLFE] = { .create = ct_alsa_pcm_create, |
79 | .destroy = NULL, | 79 | .destroy = NULL, |
80 | .public_name = "Center/LFE"}, | 80 | .public_name = "Center/LFE"}, |
81 | [SURROUND] = { .create = ct_alsa_pcm_create, | 81 | [SIDE] = { .create = ct_alsa_pcm_create, |
82 | .destroy = NULL, | 82 | .destroy = NULL, |
83 | .public_name = "Surround"}, | 83 | .public_name = "Side"}, |
84 | [IEC958] = { .create = ct_alsa_pcm_create, | 84 | [IEC958] = { .create = ct_alsa_pcm_create, |
85 | .destroy = NULL, | 85 | .destroy = NULL, |
86 | .public_name = "IEC958 Non-audio"}, | 86 | .public_name = "IEC958 Non-audio"}, |
@@ -119,7 +119,6 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm); | |||
119 | 119 | ||
120 | static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) | 120 | static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) |
121 | { | 121 | { |
122 | unsigned long flags; | ||
123 | struct snd_pcm_runtime *runtime; | 122 | struct snd_pcm_runtime *runtime; |
124 | struct ct_vm *vm; | 123 | struct ct_vm *vm; |
125 | 124 | ||
@@ -129,9 +128,7 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
129 | runtime = apcm->substream->runtime; | 128 | runtime = apcm->substream->runtime; |
130 | vm = atc->vm; | 129 | vm = atc->vm; |
131 | 130 | ||
132 | spin_lock_irqsave(&atc->vm_lock, flags); | 131 | apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes); |
133 | apcm->vm_block = vm->map(vm, runtime->dma_area, runtime->dma_bytes); | ||
134 | spin_unlock_irqrestore(&atc->vm_lock, flags); | ||
135 | 132 | ||
136 | if (NULL == apcm->vm_block) | 133 | if (NULL == apcm->vm_block) |
137 | return -ENOENT; | 134 | return -ENOENT; |
@@ -141,7 +138,6 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
141 | 138 | ||
142 | static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) | 139 | static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) |
143 | { | 140 | { |
144 | unsigned long flags; | ||
145 | struct ct_vm *vm; | 141 | struct ct_vm *vm; |
146 | 142 | ||
147 | if (NULL == apcm->vm_block) | 143 | if (NULL == apcm->vm_block) |
@@ -149,9 +145,7 @@ static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
149 | 145 | ||
150 | vm = atc->vm; | 146 | vm = atc->vm; |
151 | 147 | ||
152 | spin_lock_irqsave(&atc->vm_lock, flags); | ||
153 | vm->unmap(vm, apcm->vm_block); | 148 | vm->unmap(vm, apcm->vm_block); |
154 | spin_unlock_irqrestore(&atc->vm_lock, flags); | ||
155 | 149 | ||
156 | apcm->vm_block = NULL; | 150 | apcm->vm_block = NULL; |
157 | } | 151 | } |
@@ -161,9 +155,7 @@ static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index) | |||
161 | struct ct_vm *vm; | 155 | struct ct_vm *vm; |
162 | void *kvirt_addr; | 156 | void *kvirt_addr; |
163 | unsigned long phys_addr; | 157 | unsigned long phys_addr; |
164 | unsigned long flags; | ||
165 | 158 | ||
166 | spin_lock_irqsave(&atc->vm_lock, flags); | ||
167 | vm = atc->vm; | 159 | vm = atc->vm; |
168 | kvirt_addr = vm->get_ptp_virt(vm, index); | 160 | kvirt_addr = vm->get_ptp_virt(vm, index); |
169 | if (kvirt_addr == NULL) | 161 | if (kvirt_addr == NULL) |
@@ -171,8 +163,6 @@ static unsigned long atc_get_ptp_phys(struct ct_atc *atc, int index) | |||
171 | else | 163 | else |
172 | phys_addr = virt_to_phys(kvirt_addr); | 164 | phys_addr = virt_to_phys(kvirt_addr); |
173 | 165 | ||
174 | spin_unlock_irqrestore(&atc->vm_lock, flags); | ||
175 | |||
176 | return phys_addr; | 166 | return phys_addr; |
177 | } | 167 | } |
178 | 168 | ||
@@ -180,16 +170,15 @@ static unsigned int convert_format(snd_pcm_format_t snd_format) | |||
180 | { | 170 | { |
181 | switch (snd_format) { | 171 | switch (snd_format) { |
182 | case SNDRV_PCM_FORMAT_U8: | 172 | case SNDRV_PCM_FORMAT_U8: |
183 | case SNDRV_PCM_FORMAT_S8: | ||
184 | return SRC_SF_U8; | 173 | return SRC_SF_U8; |
185 | case SNDRV_PCM_FORMAT_S16_LE: | 174 | case SNDRV_PCM_FORMAT_S16_LE: |
186 | case SNDRV_PCM_FORMAT_U16_LE: | ||
187 | return SRC_SF_S16; | 175 | return SRC_SF_S16; |
188 | case SNDRV_PCM_FORMAT_S24_3LE: | 176 | case SNDRV_PCM_FORMAT_S24_3LE: |
189 | return SRC_SF_S24; | 177 | return SRC_SF_S24; |
190 | case SNDRV_PCM_FORMAT_S24_LE: | ||
191 | case SNDRV_PCM_FORMAT_S32_LE: | 178 | case SNDRV_PCM_FORMAT_S32_LE: |
192 | return SRC_SF_S32; | 179 | return SRC_SF_S32; |
180 | case SNDRV_PCM_FORMAT_FLOAT_LE: | ||
181 | return SRC_SF_F32; | ||
193 | default: | 182 | default: |
194 | printk(KERN_ERR "ctxfi: not recognized snd format is %d \n", | 183 | printk(KERN_ERR "ctxfi: not recognized snd format is %d \n", |
195 | snd_format); | 184 | snd_format); |
@@ -264,6 +253,9 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
264 | return 0; | 253 | return 0; |
265 | } | 254 | } |
266 | 255 | ||
256 | /* first release old resources */ | ||
257 | atc->pcm_release_resources(atc, apcm); | ||
258 | |||
267 | /* Get SRC resource */ | 259 | /* Get SRC resource */ |
268 | desc.multi = apcm->substream->runtime->channels; | 260 | desc.multi = apcm->substream->runtime->channels; |
269 | desc.msr = atc->msr; | 261 | desc.msr = atc->msr; |
@@ -506,6 +498,9 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
506 | int n_srcimp = 0, n_amixer = 0, n_srcc = 0, n_sum = 0; | 498 | int n_srcimp = 0, n_amixer = 0, n_srcc = 0, n_sum = 0; |
507 | struct src_node_conf_t src_node_conf[2] = {{0} }; | 499 | struct src_node_conf_t src_node_conf[2] = {{0} }; |
508 | 500 | ||
501 | /* first release old resources */ | ||
502 | atc->pcm_release_resources(atc, apcm); | ||
503 | |||
509 | /* The numbers of converting SRCs and SRCIMPs should be determined | 504 | /* The numbers of converting SRCs and SRCIMPs should be determined |
510 | * by pitch value. */ | 505 | * by pitch value. */ |
511 | 506 | ||
@@ -777,6 +772,9 @@ static int spdif_passthru_playback_get_resources(struct ct_atc *atc, | |||
777 | int n_amixer = apcm->substream->runtime->channels, i = 0; | 772 | int n_amixer = apcm->substream->runtime->channels, i = 0; |
778 | unsigned int pitch = 0, rsr = atc->pll_rate; | 773 | unsigned int pitch = 0, rsr = atc->pll_rate; |
779 | 774 | ||
775 | /* first release old resources */ | ||
776 | atc->pcm_release_resources(atc, apcm); | ||
777 | |||
780 | /* Get SRC resource */ | 778 | /* Get SRC resource */ |
781 | desc.multi = apcm->substream->runtime->channels; | 779 | desc.multi = apcm->substream->runtime->channels; |
782 | desc.msr = 1; | 780 | desc.msr = 1; |
@@ -1562,7 +1560,6 @@ int ct_atc_create(struct snd_card *card, struct pci_dev *pci, | |||
1562 | atc_set_ops(atc); | 1560 | atc_set_ops(atc); |
1563 | 1561 | ||
1564 | spin_lock_init(&atc->atc_lock); | 1562 | spin_lock_init(&atc->atc_lock); |
1565 | spin_lock_init(&atc->vm_lock); | ||
1566 | 1563 | ||
1567 | /* Find card model */ | 1564 | /* Find card model */ |
1568 | err = atc_identify_card(atc); | 1565 | err = atc_identify_card(atc); |
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index 286c993d461a..b86d12cd4a19 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h | |||
@@ -29,9 +29,9 @@ | |||
29 | 29 | ||
30 | enum CTALSADEVS { /* Types of alsa devices */ | 30 | enum CTALSADEVS { /* Types of alsa devices */ |
31 | FRONT, | 31 | FRONT, |
32 | REAR, | ||
33 | CLFE, | ||
34 | SURROUND, | 32 | SURROUND, |
33 | CLFE, | ||
34 | SIDE, | ||
35 | IEC958, | 35 | IEC958, |
36 | MIXER, | 36 | MIXER, |
37 | NUM_CTALSADEVS /* This should always be the last */ | 37 | NUM_CTALSADEVS /* This should always be the last */ |
@@ -101,7 +101,6 @@ struct ct_atc { | |||
101 | unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index); | 101 | unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index); |
102 | 102 | ||
103 | spinlock_t atc_lock; | 103 | spinlock_t atc_lock; |
104 | spinlock_t vm_lock; | ||
105 | 104 | ||
106 | int (*pcm_playback_prepare)(struct ct_atc *atc, | 105 | int (*pcm_playback_prepare)(struct ct_atc *atc, |
107 | struct ct_atc_pcm *apcm); | 106 | struct ct_atc_pcm *apcm); |
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 44283bd7b2df..b7b8e6f41d0d 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c | |||
@@ -1249,19 +1249,15 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info) | |||
1249 | } | 1249 | } |
1250 | 1250 | ||
1251 | trnctl = 0x13; /* 32-bit, 4k-size page */ | 1251 | trnctl = 0x13; /* 32-bit, 4k-size page */ |
1252 | #if BITS_PER_LONG == 64 | 1252 | ptp_phys_low = (u32)info->vm_pgt_phys; |
1253 | ptp_phys_low = info->vm_pgt_phys & ((1UL<<32)-1); | 1253 | ptp_phys_high = upper_32_bits(info->vm_pgt_phys); |
1254 | ptp_phys_high = (info->vm_pgt_phys>>32) & ((1UL<<32)-1); | 1254 | if (sizeof(void *) == 8) /* 64bit address */ |
1255 | trnctl |= (1<<2); | 1255 | trnctl |= (1 << 2); |
1256 | #elif BITS_PER_LONG == 32 | 1256 | #if 0 /* Only 4k h/w pages for simplicitiy */ |
1257 | ptp_phys_low = info->vm_pgt_phys & (~0UL); | ||
1258 | ptp_phys_high = 0; | ||
1259 | #else | ||
1260 | # error "Unknown BITS_PER_LONG!" | ||
1261 | #endif | ||
1262 | #if PAGE_SIZE == 8192 | 1257 | #if PAGE_SIZE == 8192 |
1263 | trnctl |= (1<<5); | 1258 | trnctl |= (1<<5); |
1264 | #endif | 1259 | #endif |
1260 | #endif | ||
1265 | hw_write_20kx(hw, PTPALX, ptp_phys_low); | 1261 | hw_write_20kx(hw, PTPALX, ptp_phys_low); |
1266 | hw_write_20kx(hw, PTPAHX, ptp_phys_high); | 1262 | hw_write_20kx(hw, PTPAHX, ptp_phys_high); |
1267 | hw_write_20kx(hw, TRNCTL, trnctl); | 1263 | hw_write_20kx(hw, TRNCTL, trnctl); |
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 7c24c2ca96bd..349728765f2c 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c | |||
@@ -1203,19 +1203,10 @@ static int hw_trn_init(struct hw *hw, const struct trn_conf *info) | |||
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | vmctl = 0x80000C0F; /* 32-bit, 4k-size page */ | 1205 | vmctl = 0x80000C0F; /* 32-bit, 4k-size page */ |
1206 | #if BITS_PER_LONG == 64 | 1206 | ptp_phys_low = (u32)info->vm_pgt_phys; |
1207 | ptp_phys_low = info->vm_pgt_phys & ((1UL<<32)-1); | 1207 | ptp_phys_high = upper_32_bits(info->vm_pgt_phys); |
1208 | ptp_phys_high = (info->vm_pgt_phys>>32) & ((1UL<<32)-1); | 1208 | if (sizeof(void *) == 8) /* 64bit address */ |
1209 | vmctl |= (3<<8); | 1209 | vmctl |= (3 << 8); |
1210 | #elif BITS_PER_LONG == 32 | ||
1211 | ptp_phys_low = info->vm_pgt_phys & (~0UL); | ||
1212 | ptp_phys_high = 0; | ||
1213 | #else | ||
1214 | # error "Unknown BITS_PER_LONG!" | ||
1215 | #endif | ||
1216 | #if PAGE_SIZE == 8192 | ||
1217 | # error "Don't support 8k-page!" | ||
1218 | #endif | ||
1219 | /* Write page table physical address to all PTPAL registers */ | 1210 | /* Write page table physical address to all PTPAL registers */ |
1220 | for (i = 0; i < 64; i++) { | 1211 | for (i = 0; i < 64; i++) { |
1221 | hw_write_20kx(hw, VMEM_PTPAL+(16*i), ptp_phys_low); | 1212 | hw_write_20kx(hw, VMEM_PTPAL+(16*i), ptp_phys_low); |
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index b7950768c3f8..177c46e248db 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c | |||
@@ -168,7 +168,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = { | |||
168 | }, | 168 | }, |
169 | [MIXER_WAVES_P] = { | 169 | [MIXER_WAVES_P] = { |
170 | .ctl = 1, | 170 | .ctl = 1, |
171 | .name = "Surround Playback Volume", | 171 | .name = "Side Playback Volume", |
172 | }, | 172 | }, |
173 | [MIXER_WAVEC_P] = { | 173 | [MIXER_WAVEC_P] = { |
174 | .ctl = 1, | 174 | .ctl = 1, |
@@ -176,7 +176,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = { | |||
176 | }, | 176 | }, |
177 | [MIXER_WAVER_P] = { | 177 | [MIXER_WAVER_P] = { |
178 | .ctl = 1, | 178 | .ctl = 1, |
179 | .name = "Rear Playback Volume", | 179 | .name = "Surround Playback Volume", |
180 | }, | 180 | }, |
181 | 181 | ||
182 | [MIXER_PCM_C_S] = { | 182 | [MIXER_PCM_C_S] = { |
@@ -213,7 +213,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = { | |||
213 | }, | 213 | }, |
214 | [MIXER_WAVES_P_S] = { | 214 | [MIXER_WAVES_P_S] = { |
215 | .ctl = 1, | 215 | .ctl = 1, |
216 | .name = "Surround Playback Switch", | 216 | .name = "Side Playback Switch", |
217 | }, | 217 | }, |
218 | [MIXER_WAVEC_P_S] = { | 218 | [MIXER_WAVEC_P_S] = { |
219 | .ctl = 1, | 219 | .ctl = 1, |
@@ -221,7 +221,7 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = { | |||
221 | }, | 221 | }, |
222 | [MIXER_WAVER_P_S] = { | 222 | [MIXER_WAVER_P_S] = { |
223 | .ctl = 1, | 223 | .ctl = 1, |
224 | .name = "Rear Playback Switch", | 224 | .name = "Surround Playback Switch", |
225 | }, | 225 | }, |
226 | [MIXER_DIGITAL_IO_S] = { | 226 | [MIXER_DIGITAL_IO_S] = { |
227 | .ctl = 0, | 227 | .ctl = 0, |
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index a64cb0ed8759..52ddf19d83bb 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c | |||
@@ -26,12 +26,10 @@ static struct snd_pcm_hardware ct_pcm_playback_hw = { | |||
26 | SNDRV_PCM_INFO_MMAP_VALID | | 26 | SNDRV_PCM_INFO_MMAP_VALID | |
27 | SNDRV_PCM_INFO_PAUSE), | 27 | SNDRV_PCM_INFO_PAUSE), |
28 | .formats = (SNDRV_PCM_FMTBIT_U8 | | 28 | .formats = (SNDRV_PCM_FMTBIT_U8 | |
29 | SNDRV_PCM_FMTBIT_S8 | | ||
30 | SNDRV_PCM_FMTBIT_S16_LE | | 29 | SNDRV_PCM_FMTBIT_S16_LE | |
31 | SNDRV_PCM_FMTBIT_U16_LE | | ||
32 | SNDRV_PCM_FMTBIT_S24_3LE | | 30 | SNDRV_PCM_FMTBIT_S24_3LE | |
33 | SNDRV_PCM_FMTBIT_S24_LE | | 31 | SNDRV_PCM_FMTBIT_S32_LE | |
34 | SNDRV_PCM_FMTBIT_S32_LE), | 32 | SNDRV_PCM_FMTBIT_FLOAT_LE), |
35 | .rates = (SNDRV_PCM_RATE_CONTINUOUS | | 33 | .rates = (SNDRV_PCM_RATE_CONTINUOUS | |
36 | SNDRV_PCM_RATE_8000_192000), | 34 | SNDRV_PCM_RATE_8000_192000), |
37 | .rate_min = 8000, | 35 | .rate_min = 8000, |
@@ -52,8 +50,7 @@ static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = { | |||
52 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 50 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
53 | SNDRV_PCM_INFO_MMAP_VALID | | 51 | SNDRV_PCM_INFO_MMAP_VALID | |
54 | SNDRV_PCM_INFO_PAUSE), | 52 | SNDRV_PCM_INFO_PAUSE), |
55 | .formats = (SNDRV_PCM_FMTBIT_S16_LE | | 53 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
56 | SNDRV_PCM_FMTBIT_U16_LE), | ||
57 | .rates = (SNDRV_PCM_RATE_48000 | | 54 | .rates = (SNDRV_PCM_RATE_48000 | |
58 | SNDRV_PCM_RATE_44100 | | 55 | SNDRV_PCM_RATE_44100 | |
59 | SNDRV_PCM_RATE_32000), | 56 | SNDRV_PCM_RATE_32000), |
@@ -77,12 +74,10 @@ static struct snd_pcm_hardware ct_pcm_capture_hw = { | |||
77 | SNDRV_PCM_INFO_PAUSE | | 74 | SNDRV_PCM_INFO_PAUSE | |
78 | SNDRV_PCM_INFO_MMAP_VALID), | 75 | SNDRV_PCM_INFO_MMAP_VALID), |
79 | .formats = (SNDRV_PCM_FMTBIT_U8 | | 76 | .formats = (SNDRV_PCM_FMTBIT_U8 | |
80 | SNDRV_PCM_FMTBIT_S8 | | ||
81 | SNDRV_PCM_FMTBIT_S16_LE | | 77 | SNDRV_PCM_FMTBIT_S16_LE | |
82 | SNDRV_PCM_FMTBIT_U16_LE | | ||
83 | SNDRV_PCM_FMTBIT_S24_3LE | | 78 | SNDRV_PCM_FMTBIT_S24_3LE | |
84 | SNDRV_PCM_FMTBIT_S24_LE | | 79 | SNDRV_PCM_FMTBIT_S32_LE | |
85 | SNDRV_PCM_FMTBIT_S32_LE), | 80 | SNDRV_PCM_FMTBIT_FLOAT_LE), |
86 | .rates = (SNDRV_PCM_RATE_CONTINUOUS | | 81 | .rates = (SNDRV_PCM_RATE_CONTINUOUS | |
87 | SNDRV_PCM_RATE_8000_96000), | 82 | SNDRV_PCM_RATE_8000_96000), |
88 | .rate_min = 8000, | 83 | .rate_min = 8000, |
@@ -447,6 +442,7 @@ static struct snd_pcm_ops ct_pcm_playback_ops = { | |||
447 | .prepare = ct_pcm_playback_prepare, | 442 | .prepare = ct_pcm_playback_prepare, |
448 | .trigger = ct_pcm_playback_trigger, | 443 | .trigger = ct_pcm_playback_trigger, |
449 | .pointer = ct_pcm_playback_pointer, | 444 | .pointer = ct_pcm_playback_pointer, |
445 | .page = snd_pcm_sgbuf_ops_page, | ||
450 | }; | 446 | }; |
451 | 447 | ||
452 | /* PCM operators for capture */ | 448 | /* PCM operators for capture */ |
@@ -459,6 +455,7 @@ static struct snd_pcm_ops ct_pcm_capture_ops = { | |||
459 | .prepare = ct_pcm_capture_prepare, | 455 | .prepare = ct_pcm_capture_prepare, |
460 | .trigger = ct_pcm_capture_trigger, | 456 | .trigger = ct_pcm_capture_trigger, |
461 | .pointer = ct_pcm_capture_pointer, | 457 | .pointer = ct_pcm_capture_pointer, |
458 | .page = snd_pcm_sgbuf_ops_page, | ||
462 | }; | 459 | }; |
463 | 460 | ||
464 | /* Create ALSA pcm device */ | 461 | /* Create ALSA pcm device */ |
@@ -469,12 +466,10 @@ int ct_alsa_pcm_create(struct ct_atc *atc, | |||
469 | struct snd_pcm *pcm; | 466 | struct snd_pcm *pcm; |
470 | int err; | 467 | int err; |
471 | int playback_count, capture_count; | 468 | int playback_count, capture_count; |
472 | char name[128]; | ||
473 | 469 | ||
474 | strncpy(name, device_name, sizeof(name)); | ||
475 | playback_count = (IEC958 == device) ? 1 : 8; | 470 | playback_count = (IEC958 == device) ? 1 : 8; |
476 | capture_count = (FRONT == device) ? 1 : 0; | 471 | capture_count = (FRONT == device) ? 1 : 0; |
477 | err = snd_pcm_new(atc->card, name, device, | 472 | err = snd_pcm_new(atc->card, "ctxfi", device, |
478 | playback_count, capture_count, &pcm); | 473 | playback_count, capture_count, &pcm); |
479 | if (err < 0) { | 474 | if (err < 0) { |
480 | printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err); | 475 | printk(KERN_ERR "ctxfi: snd_pcm_new failed!! Err=%d\n", err); |
@@ -484,7 +479,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc, | |||
484 | pcm->private_data = atc; | 479 | pcm->private_data = atc; |
485 | pcm->info_flags = 0; | 480 | pcm->info_flags = 0; |
486 | pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; | 481 | pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; |
487 | strcpy(pcm->name, device_name); | 482 | strlcpy(pcm->name, device_name, sizeof(pcm->name)); |
488 | 483 | ||
489 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops); | 484 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops); |
490 | 485 | ||
@@ -492,7 +487,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc, | |||
492 | snd_pcm_set_ops(pcm, | 487 | snd_pcm_set_ops(pcm, |
493 | SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops); | 488 | SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops); |
494 | 489 | ||
495 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | 490 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, |
496 | snd_dma_pci_data(atc->pci), 128*1024, 128*1024); | 491 | snd_dma_pci_data(atc->pci), 128*1024, 128*1024); |
497 | 492 | ||
498 | return 0; | 493 | return 0; |
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c index cecf77e3ee86..b7f8e58ae07d 100644 --- a/sound/pci/ctxfi/ctvmem.c +++ b/sound/pci/ctxfi/ctvmem.c | |||
@@ -18,12 +18,11 @@ | |||
18 | #include "ctvmem.h" | 18 | #include "ctvmem.h" |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | #include <asm/page.h> /* for PAGE_SIZE macro definition */ | ||
22 | #include <linux/io.h> | 21 | #include <linux/io.h> |
23 | #include <asm/pgtable.h> | 22 | #include <sound/pcm.h> |
24 | 23 | ||
25 | #define CT_PTES_PER_PAGE (PAGE_SIZE / sizeof(void *)) | 24 | #define CT_PTES_PER_PAGE (CT_PAGE_SIZE / sizeof(void *)) |
26 | #define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE * PAGE_SIZE) | 25 | #define CT_ADDRS_PER_PAGE (CT_PTES_PER_PAGE * CT_PAGE_SIZE) |
27 | 26 | ||
28 | /* * | 27 | /* * |
29 | * Find or create vm block based on requested @size. | 28 | * Find or create vm block based on requested @size. |
@@ -35,25 +34,34 @@ get_vm_block(struct ct_vm *vm, unsigned int size) | |||
35 | struct ct_vm_block *block = NULL, *entry = NULL; | 34 | struct ct_vm_block *block = NULL, *entry = NULL; |
36 | struct list_head *pos = NULL; | 35 | struct list_head *pos = NULL; |
37 | 36 | ||
37 | size = CT_PAGE_ALIGN(size); | ||
38 | if (size > vm->size) { | ||
39 | printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural " | ||
40 | "memory space available!\n"); | ||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | mutex_lock(&vm->lock); | ||
38 | list_for_each(pos, &vm->unused) { | 45 | list_for_each(pos, &vm->unused) { |
39 | entry = list_entry(pos, struct ct_vm_block, list); | 46 | entry = list_entry(pos, struct ct_vm_block, list); |
40 | if (entry->size >= size) | 47 | if (entry->size >= size) |
41 | break; /* found a block that is big enough */ | 48 | break; /* found a block that is big enough */ |
42 | } | 49 | } |
43 | if (pos == &vm->unused) | 50 | if (pos == &vm->unused) |
44 | return NULL; | 51 | goto out; |
45 | 52 | ||
46 | if (entry->size == size) { | 53 | if (entry->size == size) { |
47 | /* Move the vm node from unused list to used list directly */ | 54 | /* Move the vm node from unused list to used list directly */ |
48 | list_del(&entry->list); | 55 | list_del(&entry->list); |
49 | list_add(&entry->list, &vm->used); | 56 | list_add(&entry->list, &vm->used); |
50 | vm->size -= size; | 57 | vm->size -= size; |
51 | return entry; | 58 | block = entry; |
59 | goto out; | ||
52 | } | 60 | } |
53 | 61 | ||
54 | block = kzalloc(sizeof(*block), GFP_KERNEL); | 62 | block = kzalloc(sizeof(*block), GFP_KERNEL); |
55 | if (NULL == block) | 63 | if (NULL == block) |
56 | return NULL; | 64 | goto out; |
57 | 65 | ||
58 | block->addr = entry->addr; | 66 | block->addr = entry->addr; |
59 | block->size = size; | 67 | block->size = size; |
@@ -62,6 +70,8 @@ get_vm_block(struct ct_vm *vm, unsigned int size) | |||
62 | entry->size -= size; | 70 | entry->size -= size; |
63 | vm->size -= size; | 71 | vm->size -= size; |
64 | 72 | ||
73 | out: | ||
74 | mutex_unlock(&vm->lock); | ||
65 | return block; | 75 | return block; |
66 | } | 76 | } |
67 | 77 | ||
@@ -70,6 +80,9 @@ static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block) | |||
70 | struct ct_vm_block *entry = NULL, *pre_ent = NULL; | 80 | struct ct_vm_block *entry = NULL, *pre_ent = NULL; |
71 | struct list_head *pos = NULL, *pre = NULL; | 81 | struct list_head *pos = NULL, *pre = NULL; |
72 | 82 | ||
83 | block->size = CT_PAGE_ALIGN(block->size); | ||
84 | |||
85 | mutex_lock(&vm->lock); | ||
73 | list_del(&block->list); | 86 | list_del(&block->list); |
74 | vm->size += block->size; | 87 | vm->size += block->size; |
75 | 88 | ||
@@ -106,61 +119,41 @@ static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block) | |||
106 | pos = pre; | 119 | pos = pre; |
107 | pre = pos->prev; | 120 | pre = pos->prev; |
108 | } | 121 | } |
122 | mutex_unlock(&vm->lock); | ||
109 | } | 123 | } |
110 | 124 | ||
111 | /* Map host addr (kmalloced/vmalloced) to device logical addr. */ | 125 | /* Map host addr (kmalloced/vmalloced) to device logical addr. */ |
112 | static struct ct_vm_block * | 126 | static struct ct_vm_block * |
113 | ct_vm_map(struct ct_vm *vm, void *host_addr, int size) | 127 | ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size) |
114 | { | 128 | { |
115 | struct ct_vm_block *block = NULL; | 129 | struct ct_vm_block *block; |
116 | unsigned long pte_start; | 130 | unsigned int pte_start; |
117 | unsigned long i; | 131 | unsigned i, pages; |
118 | unsigned long pages; | ||
119 | unsigned long start_phys; | ||
120 | unsigned long *ptp; | 132 | unsigned long *ptp; |
121 | 133 | ||
122 | /* do mapping */ | 134 | block = get_vm_block(vm, size); |
123 | if ((unsigned long)host_addr >= VMALLOC_START) { | ||
124 | printk(KERN_ERR "ctxfi: " | ||
125 | "Fail! Not support vmalloced addr now!\n"); | ||
126 | return NULL; | ||
127 | } | ||
128 | |||
129 | if (size > vm->size) { | ||
130 | printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural " | ||
131 | "memory space available!\n"); | ||
132 | return NULL; | ||
133 | } | ||
134 | |||
135 | start_phys = (virt_to_phys(host_addr) & PAGE_MASK); | ||
136 | pages = (PAGE_ALIGN(virt_to_phys(host_addr) + size) | ||
137 | - start_phys) >> PAGE_SHIFT; | ||
138 | |||
139 | ptp = vm->ptp[0]; | ||
140 | |||
141 | block = get_vm_block(vm, (pages << PAGE_SHIFT)); | ||
142 | if (block == NULL) { | 135 | if (block == NULL) { |
143 | printk(KERN_ERR "ctxfi: No virtual memory block that is big " | 136 | printk(KERN_ERR "ctxfi: No virtual memory block that is big " |
144 | "enough to allocate!\n"); | 137 | "enough to allocate!\n"); |
145 | return NULL; | 138 | return NULL; |
146 | } | 139 | } |
147 | 140 | ||
148 | pte_start = (block->addr >> PAGE_SHIFT); | 141 | ptp = vm->ptp[0]; |
149 | for (i = 0; i < pages; i++) | 142 | pte_start = (block->addr >> CT_PAGE_SHIFT); |
150 | ptp[pte_start+i] = start_phys + (i << PAGE_SHIFT); | 143 | pages = block->size >> CT_PAGE_SHIFT; |
144 | for (i = 0; i < pages; i++) { | ||
145 | unsigned long addr; | ||
146 | addr = snd_pcm_sgbuf_get_addr(substream, i << CT_PAGE_SHIFT); | ||
147 | ptp[pte_start + i] = addr; | ||
148 | } | ||
151 | 149 | ||
152 | block->addr += (virt_to_phys(host_addr) & (~PAGE_MASK)); | ||
153 | block->size = size; | 150 | block->size = size; |
154 | |||
155 | return block; | 151 | return block; |
156 | } | 152 | } |
157 | 153 | ||
158 | static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block) | 154 | static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block) |
159 | { | 155 | { |
160 | /* do unmapping */ | 156 | /* do unmapping */ |
161 | block->size = ((block->addr + block->size + PAGE_SIZE - 1) | ||
162 | & PAGE_MASK) - (block->addr & PAGE_MASK); | ||
163 | block->addr &= PAGE_MASK; | ||
164 | put_vm_block(vm, block); | 157 | put_vm_block(vm, block); |
165 | } | 158 | } |
166 | 159 | ||
@@ -191,6 +184,8 @@ int ct_vm_create(struct ct_vm **rvm) | |||
191 | if (NULL == vm) | 184 | if (NULL == vm) |
192 | return -ENOMEM; | 185 | return -ENOMEM; |
193 | 186 | ||
187 | mutex_init(&vm->lock); | ||
188 | |||
194 | /* Allocate page table pages */ | 189 | /* Allocate page table pages */ |
195 | for (i = 0; i < CT_PTP_NUM; i++) { | 190 | for (i = 0; i < CT_PTP_NUM; i++) { |
196 | vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL); | 191 | vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL); |
diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h index 4eb5bdd5cad4..01e4fd0386a3 100644 --- a/sound/pci/ctxfi/ctvmem.h +++ b/sound/pci/ctxfi/ctvmem.h | |||
@@ -20,24 +20,36 @@ | |||
20 | 20 | ||
21 | #define CT_PTP_NUM 1 /* num of device page table pages */ | 21 | #define CT_PTP_NUM 1 /* num of device page table pages */ |
22 | 22 | ||
23 | #include <linux/spinlock.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
25 | 25 | ||
26 | /* The chip can handle the page table of 4k pages | ||
27 | * (emu20k1 can handle even 8k pages, but we don't use it right now) | ||
28 | */ | ||
29 | #define CT_PAGE_SIZE 4096 | ||
30 | #define CT_PAGE_SHIFT 12 | ||
31 | #define CT_PAGE_MASK (~(PAGE_SIZE - 1)) | ||
32 | #define CT_PAGE_ALIGN(addr) ALIGN(addr, CT_PAGE_SIZE) | ||
33 | |||
26 | struct ct_vm_block { | 34 | struct ct_vm_block { |
27 | unsigned int addr; /* starting logical addr of this block */ | 35 | unsigned int addr; /* starting logical addr of this block */ |
28 | unsigned int size; /* size of this device virtual mem block */ | 36 | unsigned int size; /* size of this device virtual mem block */ |
29 | struct list_head list; | 37 | struct list_head list; |
30 | }; | 38 | }; |
31 | 39 | ||
40 | struct snd_pcm_substream; | ||
41 | |||
32 | /* Virtual memory management object for card device */ | 42 | /* Virtual memory management object for card device */ |
33 | struct ct_vm { | 43 | struct ct_vm { |
34 | void *ptp[CT_PTP_NUM]; /* Device page table pages */ | 44 | void *ptp[CT_PTP_NUM]; /* Device page table pages */ |
35 | unsigned int size; /* Available addr space in bytes */ | 45 | unsigned int size; /* Available addr space in bytes */ |
36 | struct list_head unused; /* List of unused blocks */ | 46 | struct list_head unused; /* List of unused blocks */ |
37 | struct list_head used; /* List of used blocks */ | 47 | struct list_head used; /* List of used blocks */ |
48 | struct mutex lock; | ||
38 | 49 | ||
39 | /* Map host addr (kmalloced/vmalloced) to device logical addr. */ | 50 | /* Map host addr (kmalloced/vmalloced) to device logical addr. */ |
40 | struct ct_vm_block *(*map)(struct ct_vm *, void *host_addr, int size); | 51 | struct ct_vm_block *(*map)(struct ct_vm *, struct snd_pcm_substream *, |
52 | int size); | ||
41 | /* Unmap device logical addr area. */ | 53 | /* Unmap device logical addr area. */ |
42 | void (*unmap)(struct ct_vm *, struct ct_vm_block *block); | 54 | void (*unmap)(struct ct_vm *, struct ct_vm_block *block); |
43 | void *(*get_ptp_virt)(struct ct_vm *vm, int index); | 55 | void *(*get_ptp_virt)(struct ct_vm *vm, int index); |