diff options
Diffstat (limited to 'sound/sparc/cs4231.c')
-rw-r--r-- | sound/sparc/cs4231.c | 654 |
1 files changed, 371 insertions, 283 deletions
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index f4361c518e46..1f8d27a6152e 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -61,13 +61,37 @@ MODULE_DESCRIPTION("Sun CS4231"); | |||
61 | MODULE_LICENSE("GPL"); | 61 | MODULE_LICENSE("GPL"); |
62 | MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}"); | 62 | MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}"); |
63 | 63 | ||
64 | typedef struct snd_cs4231 { | 64 | #ifdef SBUS_SUPPORT |
65 | spinlock_t lock; | 65 | typedef struct sbus_dma_info { |
66 | void __iomem *port; | 66 | spinlock_t lock; |
67 | int dir; | ||
68 | void __iomem *regs; | ||
69 | } sbus_dma_info_t; | ||
70 | #endif | ||
71 | |||
72 | typedef struct snd_cs4231 cs4231_t; | ||
73 | |||
74 | typedef struct cs4231_dma_control { | ||
75 | void (*prepare)(struct cs4231_dma_control *dma_cont, int dir); | ||
76 | void (*enable)(struct cs4231_dma_control *dma_cont, int on); | ||
77 | int (*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len); | ||
78 | unsigned int (*address)(struct cs4231_dma_control *dma_cont); | ||
79 | void (*reset)(cs4231_t *chip); | ||
80 | void (*preallocate)(cs4231_t *chip, snd_pcm_t *pcm); | ||
67 | #ifdef EBUS_SUPPORT | 81 | #ifdef EBUS_SUPPORT |
68 | struct ebus_dma_info eb2c; | 82 | struct ebus_dma_info ebus_info; |
69 | struct ebus_dma_info eb2p; | 83 | #endif |
84 | #ifdef SBUS_SUPPORT | ||
85 | struct sbus_dma_info sbus_info; | ||
70 | #endif | 86 | #endif |
87 | } cs4231_dma_control_t; | ||
88 | |||
89 | struct snd_cs4231 { | ||
90 | spinlock_t lock; | ||
91 | void __iomem *port; | ||
92 | |||
93 | cs4231_dma_control_t p_dma; | ||
94 | cs4231_dma_control_t c_dma; | ||
71 | 95 | ||
72 | u32 flags; | 96 | u32 flags; |
73 | #define CS4231_FLAG_EBUS 0x00000001 | 97 | #define CS4231_FLAG_EBUS 0x00000001 |
@@ -106,7 +130,7 @@ typedef struct snd_cs4231 { | |||
106 | unsigned int irq[2]; | 130 | unsigned int irq[2]; |
107 | unsigned int regs_size; | 131 | unsigned int regs_size; |
108 | struct snd_cs4231 *next; | 132 | struct snd_cs4231 *next; |
109 | } cs4231_t; | 133 | }; |
110 | 134 | ||
111 | static cs4231_t *cs4231_list; | 135 | static cs4231_t *cs4231_list; |
112 | 136 | ||
@@ -251,6 +275,15 @@ static cs4231_t *cs4231_list; | |||
251 | #define APCPNVA 0x38UL /* APC Play DMA Next Address */ | 275 | #define APCPNVA 0x38UL /* APC Play DMA Next Address */ |
252 | #define APCPNC 0x3cUL /* APC Play Next Count */ | 276 | #define APCPNC 0x3cUL /* APC Play Next Count */ |
253 | 277 | ||
278 | /* Defines for SBUS DMA-routines */ | ||
279 | |||
280 | #define APCVA 0x0UL /* APC DMA Address */ | ||
281 | #define APCC 0x4UL /* APC Count */ | ||
282 | #define APCNVA 0x8UL /* APC DMA Next Address */ | ||
283 | #define APCNC 0xcUL /* APC Next Count */ | ||
284 | #define APC_PLAY 0x30UL /* Play registers start at 0x30 */ | ||
285 | #define APC_RECORD 0x20UL /* Record registers start at 0x20 */ | ||
286 | |||
254 | /* APCCSR bits */ | 287 | /* APCCSR bits */ |
255 | 288 | ||
256 | #define APC_INT_PENDING 0x800000 /* Interrupt Pending */ | 289 | #define APC_INT_PENDING 0x800000 /* Interrupt Pending */ |
@@ -569,8 +602,7 @@ static void snd_cs4231_mce_down(cs4231_t *chip) | |||
569 | spin_unlock_irqrestore(&chip->lock, flags); | 602 | spin_unlock_irqrestore(&chip->lock, flags); |
570 | } | 603 | } |
571 | 604 | ||
572 | #ifdef EBUS_SUPPORT | 605 | static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, snd_pcm_substream_t *substream, unsigned int *periods_sent) |
573 | static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent) | ||
574 | { | 606 | { |
575 | snd_pcm_runtime_t *runtime = substream->runtime; | 607 | snd_pcm_runtime_t *runtime = substream->runtime; |
576 | 608 | ||
@@ -581,129 +613,41 @@ static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substre | |||
581 | if (period_size >= (1 << 24)) | 613 | if (period_size >= (1 << 24)) |
582 | BUG(); | 614 | BUG(); |
583 | 615 | ||
584 | if (ebus_dma_request(p, runtime->dma_addr + offset, period_size)) | 616 | if (dma_cont->request(dma_cont, runtime->dma_addr + offset, period_size)) |
585 | return; | 617 | return; |
586 | (*periods_sent) = ((*periods_sent) + 1) % runtime->periods; | 618 | (*periods_sent) = ((*periods_sent) + 1) % runtime->periods; |
587 | } | 619 | } |
588 | } | 620 | } |
589 | #endif | ||
590 | |||
591 | #ifdef SBUS_SUPPORT | ||
592 | static void snd_cs4231_sbus_advance_dma(snd_pcm_substream_t *substream, unsigned int *periods_sent) | ||
593 | { | ||
594 | cs4231_t *chip = snd_pcm_substream_chip(substream); | ||
595 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
596 | |||
597 | unsigned int period_size = snd_pcm_lib_period_bytes(substream); | ||
598 | unsigned int offset = period_size * (*periods_sent % runtime->periods); | ||
599 | |||
600 | if (runtime->period_size > 0xffff + 1) | ||
601 | BUG(); | ||
602 | |||
603 | switch (substream->stream) { | ||
604 | case SNDRV_PCM_STREAM_PLAYBACK: | ||
605 | sbus_writel(runtime->dma_addr + offset, chip->port + APCPNVA); | ||
606 | sbus_writel(period_size, chip->port + APCPNC); | ||
607 | break; | ||
608 | case SNDRV_PCM_STREAM_CAPTURE: | ||
609 | sbus_writel(runtime->dma_addr + offset, chip->port + APCCNVA); | ||
610 | sbus_writel(period_size, chip->port + APCCNC); | ||
611 | break; | ||
612 | } | ||
613 | |||
614 | (*periods_sent) = (*periods_sent + 1) % runtime->periods; | ||
615 | } | ||
616 | #endif | ||
617 | 621 | ||
618 | static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on) | 622 | static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on) |
619 | { | 623 | { |
620 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 624 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
625 | cs4231_dma_control_t *dma_cont; | ||
621 | 626 | ||
622 | #ifdef EBUS_SUPPORT | 627 | if (what & CS4231_PLAYBACK_ENABLE) { |
623 | if (chip->flags & CS4231_FLAG_EBUS) { | 628 | dma_cont = &chip->p_dma; |
624 | if (what & CS4231_PLAYBACK_ENABLE) { | ||
625 | if (on) { | ||
626 | ebus_dma_prepare(&chip->eb2p, 0); | ||
627 | ebus_dma_enable(&chip->eb2p, 1); | ||
628 | snd_cs4231_ebus_advance_dma(&chip->eb2p, | ||
629 | chip->playback_substream, | ||
630 | &chip->p_periods_sent); | ||
631 | } else { | ||
632 | ebus_dma_enable(&chip->eb2p, 0); | ||
633 | } | ||
634 | } | ||
635 | if (what & CS4231_RECORD_ENABLE) { | ||
636 | if (on) { | ||
637 | ebus_dma_prepare(&chip->eb2c, 1); | ||
638 | ebus_dma_enable(&chip->eb2c, 1); | ||
639 | snd_cs4231_ebus_advance_dma(&chip->eb2c, | ||
640 | chip->capture_substream, | ||
641 | &chip->c_periods_sent); | ||
642 | } else { | ||
643 | ebus_dma_enable(&chip->eb2c, 0); | ||
644 | } | ||
645 | } | ||
646 | } else { | ||
647 | #endif | ||
648 | #ifdef SBUS_SUPPORT | ||
649 | u32 csr = sbus_readl(chip->port + APCCSR); | ||
650 | /* I don't know why, but on sbus the period counter must | ||
651 | * only start counting after the first period is sent. | ||
652 | * Therefore this dummy thing. | ||
653 | */ | ||
654 | unsigned int dummy = 0; | ||
655 | |||
656 | switch (what) { | ||
657 | case CS4231_PLAYBACK_ENABLE: | ||
658 | if (on) { | 629 | if (on) { |
659 | csr &= ~APC_XINT_PLAY; | 630 | dma_cont->prepare(dma_cont, 0); |
660 | sbus_writel(csr, chip->port + APCCSR); | 631 | dma_cont->enable(dma_cont, 1); |
661 | 632 | snd_cs4231_advance_dma(dma_cont, | |
662 | csr &= ~APC_PPAUSE; | 633 | chip->playback_substream, |
663 | sbus_writel(csr, chip->port + APCCSR); | 634 | &chip->p_periods_sent); |
664 | |||
665 | snd_cs4231_sbus_advance_dma(substream, &dummy); | ||
666 | |||
667 | csr |= APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA | | ||
668 | APC_XINT_PLAY | APC_XINT_EMPT | APC_XINT_GENL | | ||
669 | APC_XINT_PENA | APC_PDMA_READY; | ||
670 | sbus_writel(csr, chip->port + APCCSR); | ||
671 | } else { | 635 | } else { |
672 | csr |= APC_PPAUSE; | 636 | dma_cont->enable(dma_cont, 0); |
673 | sbus_writel(csr, chip->port + APCCSR); | ||
674 | |||
675 | csr &= ~APC_PDMA_READY; | ||
676 | sbus_writel(csr, chip->port + APCCSR); | ||
677 | } | 637 | } |
678 | break; | 638 | } |
679 | case CS4231_RECORD_ENABLE: | 639 | if (what & CS4231_RECORD_ENABLE) { |
640 | dma_cont = &chip->c_dma; | ||
680 | if (on) { | 641 | if (on) { |
681 | csr &= ~APC_XINT_CAPT; | 642 | dma_cont->prepare(dma_cont, 1); |
682 | sbus_writel(csr, chip->port + APCCSR); | 643 | dma_cont->enable(dma_cont, 1); |
683 | 644 | snd_cs4231_advance_dma(dma_cont, | |
684 | csr &= ~APC_CPAUSE; | 645 | chip->capture_substream, |
685 | sbus_writel(csr, chip->port + APCCSR); | 646 | &chip->c_periods_sent); |
686 | |||
687 | snd_cs4231_sbus_advance_dma(substream, &dummy); | ||
688 | |||
689 | csr |= APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA | | ||
690 | APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL | | ||
691 | APC_CDMA_READY; | ||
692 | |||
693 | sbus_writel(csr, chip->port + APCCSR); | ||
694 | } else { | 647 | } else { |
695 | csr |= APC_CPAUSE; | 648 | dma_cont->enable(dma_cont, 0); |
696 | sbus_writel(csr, chip->port + APCCSR); | ||
697 | |||
698 | csr &= ~APC_CDMA_READY; | ||
699 | sbus_writel(csr, chip->port + APCCSR); | ||
700 | } | 649 | } |
701 | break; | ||
702 | } | ||
703 | #endif | ||
704 | #ifdef EBUS_SUPPORT | ||
705 | } | 650 | } |
706 | #endif | ||
707 | } | 651 | } |
708 | 652 | ||
709 | static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd) | 653 | static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd) |
@@ -1136,10 +1080,7 @@ static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream) | |||
1136 | if (runtime->period_size > 0xffff + 1) | 1080 | if (runtime->period_size > 0xffff + 1) |
1137 | BUG(); | 1081 | BUG(); |
1138 | 1082 | ||
1139 | snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (runtime->period_size - 1) & 0x00ff); | ||
1140 | snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff); | ||
1141 | chip->p_periods_sent = 0; | 1083 | chip->p_periods_sent = 0; |
1142 | |||
1143 | spin_unlock_irqrestore(&chip->lock, flags); | 1084 | spin_unlock_irqrestore(&chip->lock, flags); |
1144 | 1085 | ||
1145 | return 0; | 1086 | return 0; |
@@ -1171,16 +1112,14 @@ static int snd_cs4231_capture_hw_free(snd_pcm_substream_t *substream) | |||
1171 | static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream) | 1112 | static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream) |
1172 | { | 1113 | { |
1173 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1114 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1174 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
1175 | unsigned long flags; | 1115 | unsigned long flags; |
1176 | 1116 | ||
1177 | spin_lock_irqsave(&chip->lock, flags); | 1117 | spin_lock_irqsave(&chip->lock, flags); |
1178 | chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | | 1118 | chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | |
1179 | CS4231_RECORD_PIO); | 1119 | CS4231_RECORD_PIO); |
1180 | 1120 | ||
1181 | snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) & 0x00ff); | ||
1182 | snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff); | ||
1183 | 1121 | ||
1122 | chip->c_periods_sent = 0; | ||
1184 | spin_unlock_irqrestore(&chip->lock, flags); | 1123 | spin_unlock_irqrestore(&chip->lock, flags); |
1185 | 1124 | ||
1186 | return 0; | 1125 | return 0; |
@@ -1199,134 +1138,55 @@ static void snd_cs4231_overrange(cs4231_t *chip) | |||
1199 | chip->capture_substream->runtime->overrange++; | 1138 | chip->capture_substream->runtime->overrange++; |
1200 | } | 1139 | } |
1201 | 1140 | ||
1202 | static irqreturn_t snd_cs4231_generic_interrupt(cs4231_t *chip) | 1141 | static void snd_cs4231_play_callback(cs4231_t *cookie) |
1203 | { | ||
1204 | unsigned long flags; | ||
1205 | unsigned char status; | ||
1206 | |||
1207 | /*This is IRQ is not raised by the cs4231*/ | ||
1208 | if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ)) | ||
1209 | return IRQ_NONE; | ||
1210 | |||
1211 | status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); | ||
1212 | |||
1213 | if (status & CS4231_TIMER_IRQ) { | ||
1214 | if (chip->timer) | ||
1215 | snd_timer_interrupt(chip->timer, chip->timer->sticks); | ||
1216 | } | ||
1217 | |||
1218 | if (status & CS4231_RECORD_IRQ) | ||
1219 | snd_cs4231_overrange(chip); | ||
1220 | |||
1221 | /* ACK the CS4231 interrupt. */ | ||
1222 | spin_lock_irqsave(&chip->lock, flags); | ||
1223 | snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); | ||
1224 | spin_unlock_irqrestore(&chip->lock, flags); | ||
1225 | |||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1229 | #ifdef SBUS_SUPPORT | ||
1230 | static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1231 | { | ||
1232 | cs4231_t *chip = dev_id; | ||
1233 | |||
1234 | /* ACK the APC interrupt. */ | ||
1235 | u32 csr = sbus_readl(chip->port + APCCSR); | ||
1236 | |||
1237 | sbus_writel(csr, chip->port + APCCSR); | ||
1238 | |||
1239 | if ((chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) && | ||
1240 | (csr & APC_PLAY_INT) && | ||
1241 | (csr & APC_XINT_PNVA) && | ||
1242 | !(csr & APC_XINT_EMPT)) { | ||
1243 | snd_cs4231_sbus_advance_dma(chip->playback_substream, | ||
1244 | &chip->p_periods_sent); | ||
1245 | snd_pcm_period_elapsed(chip->playback_substream); | ||
1246 | } | ||
1247 | |||
1248 | if ((chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) && | ||
1249 | (csr & APC_CAPT_INT) && | ||
1250 | (csr & APC_XINT_CNVA)) { | ||
1251 | snd_cs4231_sbus_advance_dma(chip->capture_substream, | ||
1252 | &chip->c_periods_sent); | ||
1253 | snd_pcm_period_elapsed(chip->capture_substream); | ||
1254 | } | ||
1255 | |||
1256 | return snd_cs4231_generic_interrupt(chip); | ||
1257 | } | ||
1258 | #endif | ||
1259 | |||
1260 | #ifdef EBUS_SUPPORT | ||
1261 | static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie) | ||
1262 | { | 1142 | { |
1263 | cs4231_t *chip = cookie; | 1143 | cs4231_t *chip = cookie; |
1264 | 1144 | ||
1265 | if (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) { | 1145 | if (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) { |
1266 | snd_pcm_period_elapsed(chip->playback_substream); | 1146 | snd_pcm_period_elapsed(chip->playback_substream); |
1267 | snd_cs4231_ebus_advance_dma(p, chip->playback_substream, | 1147 | snd_cs4231_advance_dma(&chip->p_dma, chip->playback_substream, |
1268 | &chip->p_periods_sent); | 1148 | &chip->p_periods_sent); |
1269 | } | 1149 | } |
1270 | } | 1150 | } |
1271 | 1151 | ||
1272 | static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie) | 1152 | static void snd_cs4231_capture_callback(cs4231_t *cookie) |
1273 | { | 1153 | { |
1274 | cs4231_t *chip = cookie; | 1154 | cs4231_t *chip = cookie; |
1275 | 1155 | ||
1276 | if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) { | 1156 | if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) { |
1277 | snd_pcm_period_elapsed(chip->capture_substream); | 1157 | snd_pcm_period_elapsed(chip->capture_substream); |
1278 | snd_cs4231_ebus_advance_dma(p, chip->capture_substream, | 1158 | snd_cs4231_advance_dma(&chip->c_dma, chip->capture_substream, |
1279 | &chip->c_periods_sent); | 1159 | &chip->c_periods_sent); |
1280 | } | 1160 | } |
1281 | } | 1161 | } |
1282 | #endif | ||
1283 | 1162 | ||
1284 | static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substream) | 1163 | static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substream) |
1285 | { | 1164 | { |
1286 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1165 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1287 | size_t ptr, residue, period_bytes; | 1166 | cs4231_dma_control_t *dma_cont = &chip->p_dma; |
1288 | 1167 | size_t ptr; | |
1168 | |||
1289 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) | 1169 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) |
1290 | return 0; | 1170 | return 0; |
1291 | period_bytes = snd_pcm_lib_period_bytes(substream); | 1171 | ptr = dma_cont->address(dma_cont); |
1292 | ptr = period_bytes * chip->p_periods_sent; | 1172 | if (ptr != 0) |
1293 | #ifdef EBUS_SUPPORT | 1173 | ptr -= substream->runtime->dma_addr; |
1294 | if (chip->flags & CS4231_FLAG_EBUS) { | 1174 | |
1295 | residue = ebus_dma_residue(&chip->eb2p); | ||
1296 | } else { | ||
1297 | #endif | ||
1298 | #ifdef SBUS_SUPPORT | ||
1299 | residue = sbus_readl(chip->port + APCPC); | ||
1300 | #endif | ||
1301 | #ifdef EBUS_SUPPORT | ||
1302 | } | ||
1303 | #endif | ||
1304 | ptr += period_bytes - residue; | ||
1305 | |||
1306 | return bytes_to_frames(substream->runtime, ptr); | 1175 | return bytes_to_frames(substream->runtime, ptr); |
1307 | } | 1176 | } |
1308 | 1177 | ||
1309 | static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream) | 1178 | static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream) |
1310 | { | 1179 | { |
1311 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1180 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1312 | size_t ptr, residue, period_bytes; | 1181 | cs4231_dma_control_t *dma_cont = &chip->c_dma; |
1182 | size_t ptr; | ||
1313 | 1183 | ||
1314 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) | 1184 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) |
1315 | return 0; | 1185 | return 0; |
1316 | period_bytes = snd_pcm_lib_period_bytes(substream); | 1186 | ptr = dma_cont->address(dma_cont); |
1317 | ptr = period_bytes * chip->c_periods_sent; | 1187 | if (ptr != 0) |
1318 | #ifdef EBUS_SUPPORT | 1188 | ptr -= substream->runtime->dma_addr; |
1319 | if (chip->flags & CS4231_FLAG_EBUS) { | 1189 | |
1320 | residue = ebus_dma_residue(&chip->eb2c); | ||
1321 | } else { | ||
1322 | #endif | ||
1323 | #ifdef SBUS_SUPPORT | ||
1324 | residue = sbus_readl(chip->port + APCCC); | ||
1325 | #endif | ||
1326 | #ifdef EBUS_SUPPORT | ||
1327 | } | ||
1328 | #endif | ||
1329 | ptr += period_bytes - residue; | ||
1330 | return bytes_to_frames(substream->runtime, ptr); | 1190 | return bytes_to_frames(substream->runtime, ptr); |
1331 | } | 1191 | } |
1332 | 1192 | ||
@@ -1362,30 +1222,8 @@ static int snd_cs4231_probe(cs4231_t *chip) | |||
1362 | spin_lock_irqsave(&chip->lock, flags); | 1222 | spin_lock_irqsave(&chip->lock, flags); |
1363 | 1223 | ||
1364 | 1224 | ||
1365 | /* Reset DMA engine. */ | 1225 | /* Reset DMA engine (sbus only). */ |
1366 | #ifdef EBUS_SUPPORT | 1226 | chip->p_dma.reset(chip); |
1367 | if (chip->flags & CS4231_FLAG_EBUS) { | ||
1368 | /* Done by ebus_dma_register */ | ||
1369 | } else { | ||
1370 | #endif | ||
1371 | #ifdef SBUS_SUPPORT | ||
1372 | sbus_writel(APC_CHIP_RESET, chip->port + APCCSR); | ||
1373 | sbus_writel(0x00, chip->port + APCCSR); | ||
1374 | sbus_writel(sbus_readl(chip->port + APCCSR) | APC_CDC_RESET, | ||
1375 | chip->port + APCCSR); | ||
1376 | |||
1377 | udelay(20); | ||
1378 | |||
1379 | sbus_writel(sbus_readl(chip->port + APCCSR) & ~APC_CDC_RESET, | ||
1380 | chip->port + APCCSR); | ||
1381 | sbus_writel(sbus_readl(chip->port + APCCSR) | (APC_XINT_ENA | | ||
1382 | APC_XINT_PENA | | ||
1383 | APC_XINT_CENA), | ||
1384 | chip->port + APCCSR); | ||
1385 | #endif | ||
1386 | #ifdef EBUS_SUPPORT | ||
1387 | } | ||
1388 | #endif | ||
1389 | 1227 | ||
1390 | __cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */ | 1228 | __cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */ |
1391 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); | 1229 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); |
@@ -1505,8 +1343,8 @@ static int snd_cs4231_playback_close(snd_pcm_substream_t *substream) | |||
1505 | { | 1343 | { |
1506 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1344 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1507 | 1345 | ||
1508 | chip->playback_substream = NULL; | ||
1509 | snd_cs4231_close(chip, CS4231_MODE_PLAY); | 1346 | snd_cs4231_close(chip, CS4231_MODE_PLAY); |
1347 | chip->playback_substream = NULL; | ||
1510 | 1348 | ||
1511 | return 0; | 1349 | return 0; |
1512 | } | 1350 | } |
@@ -1515,8 +1353,8 @@ static int snd_cs4231_capture_close(snd_pcm_substream_t *substream) | |||
1515 | { | 1353 | { |
1516 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1354 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1517 | 1355 | ||
1518 | chip->capture_substream = NULL; | ||
1519 | snd_cs4231_close(chip, CS4231_MODE_RECORD); | 1356 | snd_cs4231_close(chip, CS4231_MODE_RECORD); |
1357 | chip->capture_substream = NULL; | ||
1520 | 1358 | ||
1521 | return 0; | 1359 | return 0; |
1522 | } | 1360 | } |
@@ -1571,21 +1409,7 @@ int snd_cs4231_pcm(cs4231_t *chip) | |||
1571 | pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; | 1409 | pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; |
1572 | strcpy(pcm->name, "CS4231"); | 1410 | strcpy(pcm->name, "CS4231"); |
1573 | 1411 | ||
1574 | #ifdef EBUS_SUPPORT | 1412 | chip->p_dma.preallocate(chip, pcm); |
1575 | if (chip->flags & CS4231_FLAG_EBUS) { | ||
1576 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
1577 | snd_dma_pci_data(chip->dev_u.pdev), | ||
1578 | 64*1024, 128*1024); | ||
1579 | } else { | ||
1580 | #endif | ||
1581 | #ifdef SBUS_SUPPORT | ||
1582 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS, | ||
1583 | snd_dma_sbus_data(chip->dev_u.sdev), | ||
1584 | 64*1024, 128*1024); | ||
1585 | #endif | ||
1586 | #ifdef EBUS_SUPPORT | ||
1587 | } | ||
1588 | #endif | ||
1589 | 1413 | ||
1590 | chip->pcm = pcm; | 1414 | chip->pcm = pcm; |
1591 | 1415 | ||
@@ -1942,6 +1766,180 @@ out_err: | |||
1942 | } | 1766 | } |
1943 | 1767 | ||
1944 | #ifdef SBUS_SUPPORT | 1768 | #ifdef SBUS_SUPPORT |
1769 | |||
1770 | static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1771 | { | ||
1772 | unsigned long flags; | ||
1773 | unsigned char status; | ||
1774 | u32 csr; | ||
1775 | cs4231_t *chip = dev_id; | ||
1776 | |||
1777 | /*This is IRQ is not raised by the cs4231*/ | ||
1778 | if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ)) | ||
1779 | return IRQ_NONE; | ||
1780 | |||
1781 | /* ACK the APC interrupt. */ | ||
1782 | csr = sbus_readl(chip->port + APCCSR); | ||
1783 | |||
1784 | sbus_writel(csr, chip->port + APCCSR); | ||
1785 | |||
1786 | if ((csr & APC_PDMA_READY) && | ||
1787 | (csr & APC_PLAY_INT) && | ||
1788 | (csr & APC_XINT_PNVA) && | ||
1789 | !(csr & APC_XINT_EMPT)) | ||
1790 | snd_cs4231_play_callback(chip); | ||
1791 | |||
1792 | if ((csr & APC_CDMA_READY) && | ||
1793 | (csr & APC_CAPT_INT) && | ||
1794 | (csr & APC_XINT_CNVA) && | ||
1795 | !(csr & APC_XINT_EMPT)) | ||
1796 | snd_cs4231_capture_callback(chip); | ||
1797 | |||
1798 | status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); | ||
1799 | |||
1800 | if (status & CS4231_TIMER_IRQ) { | ||
1801 | if (chip->timer) | ||
1802 | snd_timer_interrupt(chip->timer, chip->timer->sticks); | ||
1803 | } | ||
1804 | |||
1805 | if ((status & CS4231_RECORD_IRQ) && (csr & APC_CDMA_READY)) | ||
1806 | snd_cs4231_overrange(chip); | ||
1807 | |||
1808 | /* ACK the CS4231 interrupt. */ | ||
1809 | spin_lock_irqsave(&chip->lock, flags); | ||
1810 | snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); | ||
1811 | spin_unlock_irqrestore(&chip->lock, flags); | ||
1812 | |||
1813 | return 0; | ||
1814 | } | ||
1815 | |||
1816 | /* | ||
1817 | * SBUS DMA routines | ||
1818 | */ | ||
1819 | |||
1820 | int sbus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len) | ||
1821 | { | ||
1822 | unsigned long flags; | ||
1823 | u32 test, csr; | ||
1824 | int err; | ||
1825 | sbus_dma_info_t *base = &dma_cont->sbus_info; | ||
1826 | |||
1827 | if (len >= (1 << 24)) | ||
1828 | return -EINVAL; | ||
1829 | spin_lock_irqsave(&base->lock, flags); | ||
1830 | csr = sbus_readl(base->regs + APCCSR); | ||
1831 | err = -EINVAL; | ||
1832 | test = APC_CDMA_READY; | ||
1833 | if ( base->dir == APC_PLAY ) | ||
1834 | test = APC_PDMA_READY; | ||
1835 | if (!(csr & test)) | ||
1836 | goto out; | ||
1837 | err = -EBUSY; | ||
1838 | csr = sbus_readl(base->regs + APCCSR); | ||
1839 | test = APC_XINT_CNVA; | ||
1840 | if ( base->dir == APC_PLAY ) | ||
1841 | test = APC_XINT_PNVA; | ||
1842 | if (!(csr & test)) | ||
1843 | goto out; | ||
1844 | err = 0; | ||
1845 | sbus_writel(bus_addr, base->regs + base->dir + APCNVA); | ||
1846 | sbus_writel(len, base->regs + base->dir + APCNC); | ||
1847 | out: | ||
1848 | spin_unlock_irqrestore(&base->lock, flags); | ||
1849 | return err; | ||
1850 | } | ||
1851 | |||
1852 | void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d) | ||
1853 | { | ||
1854 | unsigned long flags; | ||
1855 | u32 csr, test; | ||
1856 | sbus_dma_info_t *base = &dma_cont->sbus_info; | ||
1857 | |||
1858 | spin_lock_irqsave(&base->lock, flags); | ||
1859 | csr = sbus_readl(base->regs + APCCSR); | ||
1860 | test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA | | ||
1861 | APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL | | ||
1862 | APC_XINT_PENA; | ||
1863 | if ( base->dir == APC_RECORD ) | ||
1864 | test = APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA | | ||
1865 | APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL; | ||
1866 | csr |= test; | ||
1867 | sbus_writel(csr, base->regs + APCCSR); | ||
1868 | spin_unlock_irqrestore(&base->lock, flags); | ||
1869 | } | ||
1870 | |||
1871 | void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on) | ||
1872 | { | ||
1873 | unsigned long flags; | ||
1874 | u32 csr, shift; | ||
1875 | sbus_dma_info_t *base = &dma_cont->sbus_info; | ||
1876 | |||
1877 | spin_lock_irqsave(&base->lock, flags); | ||
1878 | if (!on) { | ||
1879 | if (base->dir == APC_PLAY) { | ||
1880 | sbus_writel(0, base->regs + base->dir + APCNVA); | ||
1881 | sbus_writel(1, base->regs + base->dir + APCC); | ||
1882 | } | ||
1883 | else | ||
1884 | { | ||
1885 | sbus_writel(0, base->regs + base->dir + APCNC); | ||
1886 | sbus_writel(0, base->regs + base->dir + APCVA); | ||
1887 | } | ||
1888 | } | ||
1889 | udelay(600); | ||
1890 | csr = sbus_readl(base->regs + APCCSR); | ||
1891 | shift = 0; | ||
1892 | if ( base->dir == APC_PLAY ) | ||
1893 | shift = 1; | ||
1894 | if (on) | ||
1895 | csr &= ~(APC_CPAUSE << shift); | ||
1896 | else | ||
1897 | csr |= (APC_CPAUSE << shift); | ||
1898 | sbus_writel(csr, base->regs + APCCSR); | ||
1899 | if (on) | ||
1900 | csr |= (APC_CDMA_READY << shift); | ||
1901 | else | ||
1902 | csr &= ~(APC_CDMA_READY << shift); | ||
1903 | sbus_writel(csr, base->regs + APCCSR); | ||
1904 | |||
1905 | spin_unlock_irqrestore(&base->lock, flags); | ||
1906 | } | ||
1907 | |||
1908 | unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont) | ||
1909 | { | ||
1910 | sbus_dma_info_t *base = &dma_cont->sbus_info; | ||
1911 | |||
1912 | return sbus_readl(base->regs + base->dir + APCVA); | ||
1913 | } | ||
1914 | |||
1915 | void sbus_dma_reset(cs4231_t *chip) | ||
1916 | { | ||
1917 | sbus_writel(APC_CHIP_RESET, chip->port + APCCSR); | ||
1918 | sbus_writel(0x00, chip->port + APCCSR); | ||
1919 | sbus_writel(sbus_readl(chip->port + APCCSR) | APC_CDC_RESET, | ||
1920 | chip->port + APCCSR); | ||
1921 | |||
1922 | udelay(20); | ||
1923 | |||
1924 | sbus_writel(sbus_readl(chip->port + APCCSR) & ~APC_CDC_RESET, | ||
1925 | chip->port + APCCSR); | ||
1926 | sbus_writel(sbus_readl(chip->port + APCCSR) | (APC_XINT_ENA | | ||
1927 | APC_XINT_PENA | | ||
1928 | APC_XINT_CENA), | ||
1929 | chip->port + APCCSR); | ||
1930 | } | ||
1931 | |||
1932 | void sbus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm) | ||
1933 | { | ||
1934 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS, | ||
1935 | snd_dma_sbus_data(chip->dev_u.sdev), | ||
1936 | 64*1024, 128*1024); | ||
1937 | } | ||
1938 | |||
1939 | /* | ||
1940 | * Init and exit routines | ||
1941 | */ | ||
1942 | |||
1945 | static int snd_cs4231_sbus_free(cs4231_t *chip) | 1943 | static int snd_cs4231_sbus_free(cs4231_t *chip) |
1946 | { | 1944 | { |
1947 | if (chip->irq[0]) | 1945 | if (chip->irq[0]) |
@@ -1983,6 +1981,8 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card, | |||
1983 | return -ENOMEM; | 1981 | return -ENOMEM; |
1984 | 1982 | ||
1985 | spin_lock_init(&chip->lock); | 1983 | spin_lock_init(&chip->lock); |
1984 | spin_lock_init(&chip->c_dma.sbus_info.lock); | ||
1985 | spin_lock_init(&chip->p_dma.sbus_info.lock); | ||
1986 | init_MUTEX(&chip->mce_mutex); | 1986 | init_MUTEX(&chip->mce_mutex); |
1987 | init_MUTEX(&chip->open_mutex); | 1987 | init_MUTEX(&chip->open_mutex); |
1988 | chip->card = card; | 1988 | chip->card = card; |
@@ -1998,6 +1998,25 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card, | |||
1998 | return -EIO; | 1998 | return -EIO; |
1999 | } | 1999 | } |
2000 | 2000 | ||
2001 | chip->c_dma.sbus_info.regs = chip->port; | ||
2002 | chip->p_dma.sbus_info.regs = chip->port; | ||
2003 | chip->c_dma.sbus_info.dir = APC_RECORD; | ||
2004 | chip->p_dma.sbus_info.dir = APC_PLAY; | ||
2005 | |||
2006 | chip->p_dma.prepare = sbus_dma_prepare; | ||
2007 | chip->p_dma.enable = sbus_dma_enable; | ||
2008 | chip->p_dma.request = sbus_dma_request; | ||
2009 | chip->p_dma.address = sbus_dma_addr; | ||
2010 | chip->p_dma.reset = sbus_dma_reset; | ||
2011 | chip->p_dma.preallocate = sbus_dma_preallocate; | ||
2012 | |||
2013 | chip->c_dma.prepare = sbus_dma_prepare; | ||
2014 | chip->c_dma.enable = sbus_dma_enable; | ||
2015 | chip->c_dma.request = sbus_dma_request; | ||
2016 | chip->c_dma.address = sbus_dma_addr; | ||
2017 | chip->c_dma.reset = sbus_dma_reset; | ||
2018 | chip->c_dma.preallocate = sbus_dma_preallocate; | ||
2019 | |||
2001 | if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, | 2020 | if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, |
2002 | SA_SHIRQ, "cs4231", chip)) { | 2021 | SA_SHIRQ, "cs4231", chip)) { |
2003 | snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n", | 2022 | snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n", |
@@ -2051,15 +2070,70 @@ static int cs4231_sbus_attach(struct sbus_dev *sdev) | |||
2051 | #endif | 2070 | #endif |
2052 | 2071 | ||
2053 | #ifdef EBUS_SUPPORT | 2072 | #ifdef EBUS_SUPPORT |
2073 | |||
2074 | static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie) | ||
2075 | { | ||
2076 | cs4231_t *chip = cookie; | ||
2077 | |||
2078 | snd_cs4231_play_callback(chip); | ||
2079 | } | ||
2080 | |||
2081 | static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie) | ||
2082 | { | ||
2083 | cs4231_t *chip = cookie; | ||
2084 | |||
2085 | snd_cs4231_capture_callback(chip); | ||
2086 | } | ||
2087 | |||
2088 | /* | ||
2089 | * EBUS DMA wrappers | ||
2090 | */ | ||
2091 | |||
2092 | int _ebus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len) | ||
2093 | { | ||
2094 | return ebus_dma_request(&dma_cont->ebus_info, bus_addr, len); | ||
2095 | } | ||
2096 | |||
2097 | void _ebus_dma_enable(struct cs4231_dma_control *dma_cont, int on) | ||
2098 | { | ||
2099 | ebus_dma_enable(&dma_cont->ebus_info, on); | ||
2100 | } | ||
2101 | |||
2102 | void _ebus_dma_prepare(struct cs4231_dma_control *dma_cont, int dir) | ||
2103 | { | ||
2104 | ebus_dma_prepare(&dma_cont->ebus_info, dir); | ||
2105 | } | ||
2106 | |||
2107 | unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont) | ||
2108 | { | ||
2109 | return ebus_dma_addr(&dma_cont->ebus_info); | ||
2110 | } | ||
2111 | |||
2112 | void _ebus_dma_reset(cs4231_t *chip) | ||
2113 | { | ||
2114 | return; | ||
2115 | } | ||
2116 | |||
2117 | void _ebus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm) | ||
2118 | { | ||
2119 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
2120 | snd_dma_pci_data(chip->dev_u.pdev), | ||
2121 | 64*1024, 128*1024); | ||
2122 | } | ||
2123 | |||
2124 | /* | ||
2125 | * Init and exit routines | ||
2126 | */ | ||
2127 | |||
2054 | static int snd_cs4231_ebus_free(cs4231_t *chip) | 2128 | static int snd_cs4231_ebus_free(cs4231_t *chip) |
2055 | { | 2129 | { |
2056 | if (chip->eb2c.regs) { | 2130 | if (chip->c_dma.ebus_info.regs) { |
2057 | ebus_dma_unregister(&chip->eb2c); | 2131 | ebus_dma_unregister(&chip->c_dma.ebus_info); |
2058 | iounmap(chip->eb2c.regs); | 2132 | iounmap(chip->c_dma.ebus_info.regs); |
2059 | } | 2133 | } |
2060 | if (chip->eb2p.regs) { | 2134 | if (chip->p_dma.ebus_info.regs) { |
2061 | ebus_dma_unregister(&chip->eb2p); | 2135 | ebus_dma_unregister(&chip->p_dma.ebus_info); |
2062 | iounmap(chip->eb2p.regs); | 2136 | iounmap(chip->p_dma.ebus_info.regs); |
2063 | } | 2137 | } |
2064 | 2138 | ||
2065 | if (chip->port) | 2139 | if (chip->port) |
@@ -2097,8 +2171,8 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card, | |||
2097 | return -ENOMEM; | 2171 | return -ENOMEM; |
2098 | 2172 | ||
2099 | spin_lock_init(&chip->lock); | 2173 | spin_lock_init(&chip->lock); |
2100 | spin_lock_init(&chip->eb2c.lock); | 2174 | spin_lock_init(&chip->c_dma.ebus_info.lock); |
2101 | spin_lock_init(&chip->eb2p.lock); | 2175 | spin_lock_init(&chip->p_dma.ebus_info.lock); |
2102 | init_MUTEX(&chip->mce_mutex); | 2176 | init_MUTEX(&chip->mce_mutex); |
2103 | init_MUTEX(&chip->open_mutex); | 2177 | init_MUTEX(&chip->open_mutex); |
2104 | chip->flags |= CS4231_FLAG_EBUS; | 2178 | chip->flags |= CS4231_FLAG_EBUS; |
@@ -2106,43 +2180,57 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card, | |||
2106 | chip->dev_u.pdev = edev->bus->self; | 2180 | chip->dev_u.pdev = edev->bus->self; |
2107 | memcpy(&chip->image, &snd_cs4231_original_image, | 2181 | memcpy(&chip->image, &snd_cs4231_original_image, |
2108 | sizeof(snd_cs4231_original_image)); | 2182 | sizeof(snd_cs4231_original_image)); |
2109 | strcpy(chip->eb2c.name, "cs4231(capture)"); | 2183 | strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)"); |
2110 | chip->eb2c.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; | 2184 | chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; |
2111 | chip->eb2c.callback = snd_cs4231_ebus_capture_callback; | 2185 | chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback; |
2112 | chip->eb2c.client_cookie = chip; | 2186 | chip->c_dma.ebus_info.client_cookie = chip; |
2113 | chip->eb2c.irq = edev->irqs[0]; | 2187 | chip->c_dma.ebus_info.irq = edev->irqs[0]; |
2114 | strcpy(chip->eb2p.name, "cs4231(play)"); | 2188 | strcpy(chip->p_dma.ebus_info.name, "cs4231(play)"); |
2115 | chip->eb2p.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; | 2189 | chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; |
2116 | chip->eb2p.callback = snd_cs4231_ebus_play_callback; | 2190 | chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback; |
2117 | chip->eb2p.client_cookie = chip; | 2191 | chip->p_dma.ebus_info.client_cookie = chip; |
2118 | chip->eb2p.irq = edev->irqs[1]; | 2192 | chip->p_dma.ebus_info.irq = edev->irqs[1]; |
2193 | |||
2194 | chip->p_dma.prepare = _ebus_dma_prepare; | ||
2195 | chip->p_dma.enable = _ebus_dma_enable; | ||
2196 | chip->p_dma.request = _ebus_dma_request; | ||
2197 | chip->p_dma.address = _ebus_dma_addr; | ||
2198 | chip->p_dma.reset = _ebus_dma_reset; | ||
2199 | chip->p_dma.preallocate = _ebus_dma_preallocate; | ||
2200 | |||
2201 | chip->c_dma.prepare = _ebus_dma_prepare; | ||
2202 | chip->c_dma.enable = _ebus_dma_enable; | ||
2203 | chip->c_dma.request = _ebus_dma_request; | ||
2204 | chip->c_dma.address = _ebus_dma_addr; | ||
2205 | chip->c_dma.reset = _ebus_dma_reset; | ||
2206 | chip->c_dma.preallocate = _ebus_dma_preallocate; | ||
2119 | 2207 | ||
2120 | chip->port = ioremap(edev->resource[0].start, 0x10); | 2208 | chip->port = ioremap(edev->resource[0].start, 0x10); |
2121 | chip->eb2p.regs = ioremap(edev->resource[1].start, 0x10); | 2209 | chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10); |
2122 | chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10); | 2210 | chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10); |
2123 | if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) { | 2211 | if (!chip->port || !chip->p_dma.ebus_info.regs || !chip->c_dma.ebus_info.regs) { |
2124 | snd_cs4231_ebus_free(chip); | 2212 | snd_cs4231_ebus_free(chip); |
2125 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); | 2213 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); |
2126 | return -EIO; | 2214 | return -EIO; |
2127 | } | 2215 | } |
2128 | 2216 | ||
2129 | if (ebus_dma_register(&chip->eb2c)) { | 2217 | if (ebus_dma_register(&chip->c_dma.ebus_info)) { |
2130 | snd_cs4231_ebus_free(chip); | 2218 | snd_cs4231_ebus_free(chip); |
2131 | snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev); | 2219 | snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev); |
2132 | return -EBUSY; | 2220 | return -EBUSY; |
2133 | } | 2221 | } |
2134 | if (ebus_dma_irq_enable(&chip->eb2c, 1)) { | 2222 | if (ebus_dma_irq_enable(&chip->c_dma.ebus_info, 1)) { |
2135 | snd_cs4231_ebus_free(chip); | 2223 | snd_cs4231_ebus_free(chip); |
2136 | snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev); | 2224 | snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev); |
2137 | return -EBUSY; | 2225 | return -EBUSY; |
2138 | } | 2226 | } |
2139 | 2227 | ||
2140 | if (ebus_dma_register(&chip->eb2p)) { | 2228 | if (ebus_dma_register(&chip->p_dma.ebus_info)) { |
2141 | snd_cs4231_ebus_free(chip); | 2229 | snd_cs4231_ebus_free(chip); |
2142 | snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev); | 2230 | snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev); |
2143 | return -EBUSY; | 2231 | return -EBUSY; |
2144 | } | 2232 | } |
2145 | if (ebus_dma_irq_enable(&chip->eb2p, 1)) { | 2233 | if (ebus_dma_irq_enable(&chip->p_dma.ebus_info, 1)) { |
2146 | snd_cs4231_ebus_free(chip); | 2234 | snd_cs4231_ebus_free(chip); |
2147 | snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev); | 2235 | snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev); |
2148 | return -EBUSY; | 2236 | return -EBUSY; |