aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ctxfi
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-06-02 09:55:22 -0400
committerTakashi Iwai <tiwai@suse.de>2009-06-02 09:55:22 -0400
commitbd05dbd3b22612455283610b4e006ee3e421b13d (patch)
tree06868be09771d6908acd657b1a9f66b0fb209bce /sound/pci/ctxfi
parent67fbf880631bb4493ad8d23f25562abdf09dc01d (diff)
parentc76157d9286ed598c241c212aa5a3c6e5107bd82 (diff)
Merge branch 'topic/ctxfi-fix' into topic/ctxfi
Diffstat (limited to 'sound/pci/ctxfi')
-rw-r--r--sound/pci/ctxfi/ctatc.c35
-rw-r--r--sound/pci/ctxfi/ctatc.h5
-rw-r--r--sound/pci/ctxfi/cthw20k1.c16
-rw-r--r--sound/pci/ctxfi/cthw20k2.c17
-rw-r--r--sound/pci/ctxfi/ctmixer.c8
-rw-r--r--sound/pci/ctxfi/ctpcm.c25
-rw-r--r--sound/pci/ctxfi/ctvmem.c77
-rw-r--r--sound/pci/ctxfi/ctvmem.h16
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
120static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) 120static 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
142static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm) 139static 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
30enum CTALSADEVS { /* Types of alsa devices */ 30enum 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. */
112static struct ct_vm_block * 126static struct ct_vm_block *
113ct_vm_map(struct ct_vm *vm, void *host_addr, int size) 127ct_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
158static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block) 154static 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
26struct ct_vm_block { 34struct 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
40struct snd_pcm_substream;
41
32/* Virtual memory management object for card device */ 42/* Virtual memory management object for card device */
33struct ct_vm { 43struct 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);