diff -urN linux-2.4.0-test8-rmk1-np1/Makefile linux-2.4.0-test8-rmk1-np1-jd1-ck1/Makefile --- linux-2.4.0-test8-rmk1-np1/Makefile Sat Sep 23 23:52:40 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/Makefile Sat Sep 23 21:53:48 2000 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -test8-rmk1-np1 +EXTRAVERSION = -test8-rmk1-np1-ck1 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -urN linux-2.4.0-test8-rmk1-np1/arch/arm/defconfig linux-2.4.0-test8-rmk1-np1-jd1-ck1/arch/arm/defconfig --- linux-2.4.0-test8-rmk1-np1/arch/arm/defconfig Sat Sep 23 23:51:55 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/arch/arm/defconfig Sat Sep 23 21:34:37 2000 @@ -31,6 +31,14 @@ CONFIG_ARCH_SA1100=y # +# Archimedes/A5000 Implementations +# + +# +# Footbridge Implementations +# + +# # SA11x0 Implementations # CONFIG_SA1100_ASSABET=y @@ -45,7 +53,7 @@ # CONFIG_SA1100_VICTOR is not set # CONFIG_SA1100_XP860 is not set CONFIG_ANGELBOOT=y -# CONFIG_SA1100_FREQUENCY_SCALE is not set +CONFIG_SA1100_FREQUENCY_SCALE=y # CONFIG_SA1100_VOLTAGE_SCALE is not set # CONFIG_ARCH_ACORN is not set # CONFIG_FOOTBRIDGE is not set @@ -53,17 +61,21 @@ # CONFIG_FOOTBRIDGE_ADDIN is not set CONFIG_CPU_32=y # CONFIG_CPU_26 is not set + +# +# Processor Type +# CONFIG_CPU_32v4=y CONFIG_CPU_SA1100=y CONFIG_DISCONTIGMEM=y -# CONFIG_PCI is not set -# CONFIG_ISA is not set -# CONFIG_ISA_DMA is not set -CONFIG_PC_KEYMAP=y # # General setup # +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +CONFIG_PC_KEYMAP=y CONFIG_HOTPLUG=y # @@ -140,10 +152,8 @@ # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -182,6 +192,7 @@ # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # CONFIG_NET_SB1000 is not set # @@ -321,13 +332,11 @@ # CONFIG_VT=y # CONFIG_VT_CONSOLE is not set -CONFIG_SERIAL_SA1100=y -CONFIG_SERIAL_SA1100_CONSOLE=y -CONFIG_TOUCHSCREEN_UCB1200=y -# CONFIG_TOUCHSCREEN_BITSY is not set # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=32 @@ -346,6 +355,10 @@ # Joysticks # # CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# # CONFIG_QIC02_TAPE is not set # @@ -355,11 +368,6 @@ # CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set - -# -# Video For Linux -# -# CONFIG_VIDEO_DEV is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -528,6 +536,7 @@ CONFIG_SOUND_UDA1341=y # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set # CONFIG_SOUND_ES1370 is not set # CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ESSSOLO1 is not set diff -urN linux-2.4.0-test8-rmk1-np1/arch/arm/mach-sa1100/dma-sa1100.c linux-2.4.0-test8-rmk1-np1-jd1-ck1/arch/arm/mach-sa1100/dma-sa1100.c --- linux-2.4.0-test8-rmk1-np1/arch/arm/mach-sa1100/dma-sa1100.c Sat Sep 23 23:51:55 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/arch/arm/mach-sa1100/dma-sa1100.c Sat Sep 23 10:44:51 2000 @@ -5,10 +5,14 @@ * * Support functions for the SA11x0 internal DMA channels. * (see also Documentation/arm/SA1100/DMA) + * + * Added SA-1111 Serial Audio Controller support. + * John Dorsey, 4 September, 2000 */ #include #include +#include #include #include #include @@ -51,6 +55,17 @@ } dma_regs_t; +#ifdef CONFIG_SA1111 +typedef struct { + volatile u_long SAD_CS; + volatile u_long SAD_SA; + volatile u_long SAD_CA; + volatile u_long SAD_SB; + volatile u_long SAD_CB; +} sa1111_sac_dma_regs_t; +#endif + + /* * DMA buffer structure */ @@ -76,6 +91,10 @@ int ready; /* 1 if DMA can occur */ int active; /* 1 if DMA is actually processing data */ dma_regs_t *regs; /* points to appropriate DMA registers */ +#ifdef CONFIG_SA1111 + sa1111_sac_dma_regs_t *sac_regs; /* points to SA-1111 SAC DMA regs */ + int dma_a, dma_b, last_dma; +#endif dma_callback_t callback; /* ... to call when buffers are done */ int spin_size; /* > 0 when DMA should spin when no more buffers */ dma_addr_t spin_addr; /* DMA address to spin onto */ @@ -89,7 +108,7 @@ * DMA processing... */ -static inline int start_dma(dma_t * dma, dma_addr_t dma_ptr, int size) +static inline int sa1100_start_dma(dma_t * dma, dma_addr_t dma_ptr, int size) { dma_regs_t *regs = dma->regs; int status; @@ -123,6 +142,68 @@ } +#ifdef CONFIG_SA1111 +static inline int sa1111_sac_start_dma(dma_t * dma, dma_addr_t dma_ptr, + size_t size) +{ + sa1111_sac_dma_regs_t *sac_regs = dma->sac_regs; + unsigned int status = sac_regs->SAD_CS; + + DPRINTK(" SAC DMA %cCS %02x at %08x (%d)", + (sac_regs==&SADTCS)?'T':'R', status, dma_ptr, size); + + if( size < SA1111_SAC_DMA_MIN_XFER ) + size = SA1111_SAC_DMA_MIN_XFER; + + if(dma->dma_a && dma->dma_b) + return -1; + + if( dma->dma_a == 0 ){ + sac_regs->SAD_SA = SA1111_DMA_ADDR((u_int)dma_ptr); + sac_regs->SAD_CA = size; + sac_regs->SAD_CS = SAD_CS_DSTA | SAD_CS_DEN; + ++dma->dma_a; + DPRINTK(" with A [%02lx %08lx %04lx]\n", sac_regs->SAD_CS, + sac_regs->SAD_SA, sac_regs->SAD_CA); + } else { + sac_regs->SAD_SB = SA1111_DMA_ADDR((u_int)dma_ptr); + sac_regs->SAD_CB = size; + sac_regs->SAD_CS = SAD_CS_DSTB | SAD_CS_DEN; + ++dma->dma_b; + mdelay(1); + DPRINTK(" with B [%02lx %08lx %04lx]\n", sac_regs->SAD_CS, + sac_regs->SAD_SB, sac_regs->SAD_CB); + } + + return 0; +} +#else +static inline int sa1111_sac_start_dma(dma_t * dma, dma_addr_t *dma_ptr, + size_t size) +{ + printk(KERN_ERR "%s(): SA-1111 support not compiled into kernel\n", + __FUNCTION__); + return -1; +} +#endif /* CONFIG_SA1111 */ + + +static inline int start_dma(dma_t * dma, dma_addr_t dma_ptr, int size) +{ + unsigned int channel = dma - dma_chan; /* Horrible, horrible... -jd */ + + if (channel_is_sa1100(channel)) + return sa1100_start_dma(dma, dma_ptr, size); + else if (channel_is_sa1111_sac(channel)) + return sa1111_sac_start_dma(dma, dma_ptr, size); + + printk(KERN_ERR "%s(): invalid DMA channel %u\n", __FUNCTION__, + channel); + + return -1; +} + + /* This must be called with IRQ disabled */ static void process_dma(dma_t * dma) { @@ -184,14 +265,79 @@ static void dma_irq(int irq, void *dev_id, struct pt_regs *regs) { dma_t *dma = (dma_t *) dev_id; - int status = dma->regs->RdDCSR; + int status; dma_buf_t *buf = dma->curr; DPRINTK("IRQ: b=%#x st=%#x\n", (int) buf->id, status); - dma->regs->ClrDCSR = DCSR_ERROR | DCSR_DONEA | DCSR_DONEB; - if (!(status & (DCSR_DONEA | DCSR_DONEB))) - return; + if (machine_is_assabet() && machine_has_neponset()) { + +#ifdef CONFIG_SA1111 + status = dma->sac_regs->SAD_CS; + + /* Occasionally, one of the DMA engines (A or B) will + * lock up. We try to deal with this by quietly kicking + * the control register for the afflicted transfer + * direction. + */ + + if(irq==AUDXMTDMADONEA || irq==AUDRCVDMADONEA){ + + if(dma->last_dma == 0){ + DPRINTK("DMA B has locked up!\n"); + dma->sac_regs->SAD_CS = 0; + mdelay(1); + dma->sac_regs->SAD_CS = SAD_CS_DEN | SAD_CS_DIE; + dma->dma_a = dma->dma_b = 0; + } else { + if(dma->dma_a == 0) + DPRINTK("spurious SAC IRQ %d\n", irq); + else + --dma->dma_a; + } + + dma->last_dma = 0; + + } else { + + if(dma->last_dma == 1){ + DPRINTK("DMA A has locked up!\n"); + dma->sac_regs->SAD_CS = 0; + mdelay(1); + dma->sac_regs->SAD_CS = SAD_CS_DEN | SAD_CS_DIE; + dma->dma_a = dma->dma_b = 0; + } else { + if(dma->dma_b == 0) + DPRINTK("spurious SAC IRQ %d\n", irq); + else + --dma->dma_b; + } + + dma->last_dma = 1; + + } + + /* Servicing the SAC DMA engines too quickly after they + * issue a DONE interrupt causes them to lock up. + */ + if(irq==AUDRCVDMADONEA || irq==AUDRCVDMADONEB) + mdelay(1); +#endif + +#if defined (CONFIG_ASSABET_NEPONSET) && defined (CHROME) + if(irq==AUDXMTDMADONEA || irq==AUDXMTDMADONEB){ + L3_read( (UDA1341_L3Addr<<2)|UDA1341_DATA1, + (char*)&DATA1, 1 ); + LEDS = (1 << (DATA1.peak >> 1)) - 1; + } +#endif + } else { + status = dma->regs->RdDCSR; + dma->regs->ClrDCSR = DCSR_ERROR | DCSR_DONEA | DCSR_DONEB; + if (!(status & (DCSR_DONEA | DCSR_DONEB))) + return; + } + if (dma->spin_ref > 0) { dma->spin_ref--; @@ -288,6 +434,72 @@ } +#ifdef CONFIG_SA1111 +int sa1111_sac_request_dma(dmach_t * channel, const char *device_id, + unsigned int direction) +{ + dma_t *dma = NULL; + int ch, irq, err; + + *channel = -1; /* to be sure we catch the freeing of a misregistered channel */ + + ch = SA1111_SAC_DMA_BASE + direction; + + if (!channel_is_sa1111_sac(ch)) { + printk(KERN_ERR "%s: invalid SA-1111 SAC DMA channel (%d)\n", + device_id, ch); + return -1; + } + + dma = &dma_chan[ch]; + + if (xchg(&dma->lock, 1) == 1) { + printk(KERN_ERR "%s: SA-1111 SAC DMA channel %d in use\n", + device_id, ch); + return -EBUSY; + } + + irq = AUDXMTDMADONEA + direction; + err = request_irq(irq, dma_irq, SA_INTERRUPT, + device_id, (void *) dma); + if (err) { + printk(KERN_ERR + "%s: unable to request IRQ %d for DMA channel %d (A)\n", + device_id, irq, ch); + dma->lock = 0; + return err; + } + + irq = AUDXMTDMADONEB + direction; + err = request_irq(irq, dma_irq, SA_INTERRUPT, + device_id, (void *) dma); + if (err) { + printk(KERN_ERR + "%s: unable to request IRQ %d for DMA channel %d (B)\n", + device_id, irq, ch); + dma->lock = 0; + return err; + } + + *channel = ch; + dma->device_id = device_id; + dma->callback = NULL; + dma->spin_size = 0; + + DPRINTK("requested\n"); + return 0; +} +#else +int sa1111_sac_request_dma(dmach_t * channel, const char *device_id, + unsigned int direction) +{ + printk(KERN_ERR "%s(): SA-1111 support not compiled into kernel\n", + __FUNCTION__); + return -1; +} +#endif /* CONFIG_SA1111 */ + + int sa1100_dma_set_callback(dmach_t channel, dma_callback_t cb) { dma_t *dma = &dma_chan[channel]; @@ -301,14 +513,19 @@ int sa1100_dma_set_device(dmach_t channel, dma_device_t device) { dma_t *dma = &dma_chan[channel]; - dma_regs_t *regs = dma->regs; if (dma->ready) return -EINVAL; - regs->ClrDCSR = DCSR_STRTA | DCSR_STRTB | DCSR_IE | DCSR_RUN; - regs->DDAR = device; - DPRINTK("DDAR = %#x\n", device); + if (channel_is_sa1100(channel)) { + dma_regs_t *regs = dma->regs; + + regs->ClrDCSR = DCSR_STRTA | DCSR_STRTB | DCSR_IE | DCSR_RUN; + regs->DDAR = device; + + DPRINTK("DDAR = %#x\n", device); + } + dma->ready = 1; return 0; } @@ -407,9 +624,13 @@ int sa1100_dma_stop(dmach_t channel) { dma_t *dma = &dma_chan[channel]; - dma_regs_t *regs = dma->regs; - regs->ClrDCSR = DCSR_RUN; + if (channel_is_sa1100(channel)) { + dma_regs_t *regs = dma->regs; + + regs->ClrDCSR = DCSR_RUN; + } + return 0; } @@ -417,9 +638,13 @@ int sa1100_dma_resume(dmach_t channel) { dma_t *dma = &dma_chan[channel]; - dma_regs_t *regs = dma->regs; - regs->SetDCSR = DCSR_RUN; + if (channel_is_sa1100(channel)) { + dma_regs_t *regs = dma->regs; + + regs->SetDCSR = DCSR_RUN; + } + return 0; } @@ -432,11 +657,18 @@ dma = &dma_chan[channel]; save_flags_cli(flags); - dma->regs->ClrDCSR = DCSR_STRTA | DCSR_STRTB | DCSR_IE | DCSR_RUN; + + if (channel_is_sa1100(channel)) + dma->regs->ClrDCSR = DCSR_STRTA | DCSR_STRTB | DCSR_IE | DCSR_RUN; + buf = dma->curr; if (!buf) buf = dma->tail; dma->head = dma->tail = dma->curr = NULL; +#ifdef CONFIG_SA1111 + dma->dma_a = dma->dma_b = 0; + dma->last_dma = 1; +#endif dma->active = 0; dma->spin_ref = 0; if (dma->spin_size) @@ -468,13 +700,25 @@ sa1100_dma_set_spin(channel, 0, 0); sa1100_dma_flush_all(channel); - free_irq(IRQ_DMA0 + channel, dma->device_id); + + if (channel_is_sa1100(channel)) + free_irq(IRQ_DMA0 + channel, dma->device_id); + else if (channel_is_sa1111_sac(channel)) { +#ifdef CONFIG_SA1111 + free_irq(AUDXMTDMADONEA + (channel - SA1111_SAC_DMA_BASE), + dma->device_id); + free_irq(AUDXMTDMADONEB + (channel - SA1111_SAC_DMA_BASE), + dma->device_id); +#endif + } + dma->lock = 0; DPRINTK("freed\n"); } EXPORT_SYMBOL(sa1100_request_dma); +EXPORT_SYMBOL(sa1111_sac_request_dma); EXPORT_SYMBOL(sa1100_dma_set_callback); EXPORT_SYMBOL(sa1100_dma_set_device); EXPORT_SYMBOL(sa1100_dma_set_spin); @@ -489,10 +733,14 @@ int __init init_dma(void) { int channel; - for (channel = 0; channel < MAX_DMA_CHANNELS; channel++) { + for (channel = 0; channel < SA1100_DMA_CHANNELS; channel++) { dma_chan[channel].regs = (dma_regs_t *) io_p2v(_DDAR(channel)); } +#ifdef CONFIG_SA1111 + dma_chan[channel++].sac_regs = (sa1111_sac_dma_regs_t *) &SADTCS; + dma_chan[channel++].sac_regs = (sa1111_sac_dma_regs_t *) &SADRCS; +#endif return 0; } diff -urN linux-2.4.0-test8-rmk1-np1/arch/arm/mach-sa1100/hw.c linux-2.4.0-test8-rmk1-np1-jd1-ck1/arch/arm/mach-sa1100/hw.c --- linux-2.4.0-test8-rmk1-np1/arch/arm/mach-sa1100/hw.c Sat Sep 23 23:51:44 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/arch/arm/mach-sa1100/hw.c Sat Sep 23 10:44:51 2000 @@ -119,8 +119,8 @@ /* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: * (SA-1110 Developer's Manual, section 9.1.2.1) */ - GAFR |= GPIO_GPIO27; - GPDR |= GPIO_GPIO27; + GAFR |= GPIO_32_768kHz; + GPDR |= GPIO_32_768kHz; TUCR = TUCR_3_6864MHz; /* Now, set up the PLL and RCLK in the SA-1111: */ @@ -133,32 +133,32 @@ * using the SKPCR. */ - { - /* - * SA1111 DMA bus master setup + /* If the system is going to use the SA-1111 DMA engines, set up + * the memory bus request/grant pins. Also configure the shared + * memory controller on the SA-1111 (SA-1111 Developer's Manual, + * section 3.2.3) and power up the DMA bus clock: */ - int cas; + if(machine_is_assabet()){ - /* SA1111 side */ - switch ( (MDCNFG>>12) & 0x03 ) { - case 0x02: - cas = 0; break; - case 0x03: - cas = 1; break; - default: - cas = 1; break; - } - SMCR = 1 /* 1: memory is SDRAM */ - | ( 1 << 1 ) /* 1:MBGNT is enable */ - | ( ((MDCNFG >> 4) & 0x07) << 2 ) /* row address lines */ - | ( cas << 5 ); /* CAS latency */ - - /* SA1110 side */ - GPDR |= 1<<21; - GPDR &= ~(1<<22); - GAFR |= ( (1<<21) | (1<<22) ); + GAFR |= (GPIO_MBGNT | GPIO_MBREQ); + GPDR |= GPIO_MBGNT; + GPDR &= ~GPIO_MBREQ; + TUCR |= TUCR_MR; + + /* Assabet is populated by default with two Samsung KM416S8030T-G8 + * 128Mb SDRAMs, which are organized as 12-bit (row addr) x 9-bit + * (column addr), according to the data sheet. Apparently, the + * bank selects factor into the row address, as Angel sets up the + * SA-1110 to use 14x9 addresses. The SDRAM datasheet specifies + * that when running at 100-125MHz, the CAS latency for -8 parts + * is 3 cycles, which is consistent with Angel. + */ + + SMCR = (SMCR_DTIM | SMCR_MBGE | + FInsrt(FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), SMCR_DRAC) | + ((FExtr(MDCNFG, MDCNFG_SA1110_TDL0)==3) ? SMCR_CLAT : 0)); - TUCR |= (1<<10); + SKPCR |= SKPCR_DCLKEN; } } diff -urN linux-2.4.0-test8-rmk1-np1/drivers/block/flash_mem.c linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/block/flash_mem.c --- linux-2.4.0-test8-rmk1-np1/drivers/block/flash_mem.c Sat Sep 23 23:51:56 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/block/flash_mem.c Sat Sep 23 14:04:28 2000 @@ -73,7 +73,7 @@ /* features*/ #define USE_WRITE_BUFFER #define WRITE_VERIFY -#if 1 +#if 0 #define FLASH_DEBUG_CFI #if 0 #define FLASH_VERBOSE diff -urN linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/cs.c linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/cs.c --- linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/cs.c Sat Sep 23 23:51:56 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/cs.c Sat Sep 23 10:44:51 2000 @@ -1623,7 +1623,7 @@ bus_free_irq(s->cap.bus, req->AssignedIRQ, req->Instance); } -#if defined(CONFIG_ISA) || defined(CONFIG_ARCH_SA1100) +#ifdef CONFIG_ISA if (req->AssignedIRQ != s->cap.pci_irq) undo_irq(req->Attributes, req->AssignedIRQ); #endif @@ -1885,16 +1885,14 @@ return CS_IN_USE; /* Short cut: if there are no ISA interrupts, then it is PCI */ -// NP : hacked out for now -// if (!s->cap.irq_mask) - if (0) + if (!s->cap.irq_mask) irq = s->cap.pci_irq; -#if defined(CONFIG_ISA) || defined(CONFIG_ARCH_SA1100) +#ifdef CONFIG_ISA else if (s->irq.AssignedIRQ != 0) { /* If the interrupt is already assigned, it must match */ irq = s->irq.AssignedIRQ; if (req->IRQInfo1 & IRQ_INFO2_VALID) { - mask = IRQ_MASK_LOW(&s->cap.irq_mask, req->IRQInfo2); + mask = req->IRQInfo2 & s->cap.irq_mask; ret = ((mask >> irq) & 1) ? 0 : CS_BAD_ARGS; } else ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS; @@ -1907,11 +1905,6 @@ if ((mask >> irq) & 1) { ret = try_irq(req->Attributes, irq, try); if (ret == 0) break; - } - for (; irq < NR_IRQS; irq++) - if (IRQ_ISSET(&s->cap.irq_mask, irq)) { - ret = try_irq(req->Attributes, irq, try); - if (ret == 0) break; } if (ret == 0) break; } diff -urN linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/rsrc_mgr.c linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/rsrc_mgr.c --- linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/rsrc_mgr.c Sat Sep 23 23:51:56 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/rsrc_mgr.c Sat Sep 23 10:44:51 2000 @@ -84,7 +84,7 @@ /* IO port resource database */ static resource_map_t io_db = { 0, 0, &io_db }; -#if defined(CONFIG_ISA) || defined(CONFIG_ARCH_SA1100) +#ifdef CONFIG_ISA typedef struct irq_info_t { u_int Attributes; @@ -421,7 +421,7 @@ ======================================================================*/ -#if defined(CONFIG_ISA) || defined(CONFIG_ARCH_SA1100) +#ifdef CONFIG_ISA static void fake_irq(int i, void *d, struct pt_regs *r) { } static inline int check_irq(int irq) @@ -488,7 +488,7 @@ /*====================================================================*/ -#if defined(CONFIG_ISA) || defined(CONFIG_ARCH_SA1100) +#ifdef CONFIG_ISA void undo_irq(u_int Attributes, int irq) { diff -urN linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/sa1100.h linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/sa1100.h --- linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/sa1100.h Sat Sep 23 23:51:56 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/sa1100.h Sat Sep 23 21:37:35 2000 @@ -209,7 +209,8 @@ void *handler_info; pccard_io_map io_map[SA1100_PCMCIA_IO_MAP_COUNT]; pccard_mem_map mem_map[SA1100_PCMCIA_MEM_MAP_COUNT]; - ioaddr_t phys_io, phys_attr, phys_mem; + ioaddr_t virt_io, phys_attr, phys_mem; + unsigned short speed_io, speed_attr, speed_mem; struct bus_operations bus_ops; }; diff -urN linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/sa1100_generic.c linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/sa1100_generic.c --- linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/sa1100_generic.c Sat Sep 23 23:51:56 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/sa1100_generic.c Sat Sep 23 10:44:51 2000 @@ -434,7 +434,7 @@ sa1100_pcmcia_socket[i].bus_ops.b_request_irq=sa1100_bus_request_irq; sa1100_pcmcia_socket[i].bus_ops.b_free_irq=sa1100_bus_free_irq; - sa1100_pcmcia_socket[i].phys_io=_PCMCIAIO(i); + sa1100_pcmcia_socket[i].virt_io=(i==0)?PCMCIA_IO_0_BASE:PCMCIA_IO_1_BASE; sa1100_pcmcia_socket[i].phys_attr=_PCMCIAAttr(i); sa1100_pcmcia_socket[i].phys_mem=_PCMCIAMem(i); @@ -698,10 +698,9 @@ return -1; } - if(irq_info.irq!=-1) - IRQ_SET(&cap->irq_mask, irq_info.irq); + cap->irq_mask=0; cap->map_size=PAGE_SIZE; - cap->pci_irq=0; + cap->pci_irq=irq_info.irq; cap->bus=&(sa1100_pcmcia_socket[sock].bus_ops); return 0; @@ -926,6 +925,8 @@ MECR_BSIO_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock)); + sa1100_pcmcia_socket[sock].speed_io=speed; + DEBUG(4, "%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx\n", __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock, MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock), @@ -935,35 +936,18 @@ } else { - /* This is extremely sketchy. What's going on here is that we're - * causing Card Services to change its mind about where it thinks - * the I/O base should be. This is necessary because many client - * drivers issue their RequestIO before RequestConfiguration, and - * use the results of RequestIO as the final word on I/O bases. - * To deal with this, we generate the virtual mapping here if one - * is not already in place. I like set_mem_map() better. + /* Although we map on demand for the common and attribute memory + * spaces, we just use the in-place maps for I/O. (These are + * kept static for machines with hardwired IDE interfaces, &c.) + * Using the static map helps us avoid unreliable map/unmap logic, + * while still allowing us to set up a new set of base I/O addresses + * within Card Services in time for client drivers to use them. */ - if(sa1100_pcmcia_socket[sock].io_map[map->map].start==NULL){ - - start=map->start; - - if((map->start=ioremap_nocache(sa1100_pcmcia_socket[sock].phys_io, - (map->stop-start)+1))==NULL){ - printk(KERN_ERR "%s(): unable to map socket %d map %d at %08lx\n", - __FUNCTION__, sock, map->map, start); - return -1; - } - - map->stop=map->start+(map->stop-start); - - } else { + start=map->start; - iounmap(sa1100_pcmcia_socket[sock].io_map[map->map].start); - - sa1100_pcmcia_socket[sock].io_map[map->map].start=NULL; - - } + map->start=sa1100_pcmcia_socket[sock].virt_io; + map->stop=map->start+(map->stop-start); } @@ -1037,44 +1021,33 @@ if(map->flags&MAP_ACTIVE){ - /* Some client drivers (e.g., pcnet_cs) go on a whirlwind tour of - * attribute memory without properly releasing their maps. Try - * to catch this here: - */ - if(sa1100_pcmcia_socket[sock].mem_map[map->map].sys_start!=NULL){ - - iounmap(sa1100_pcmcia_socket[sock].mem_map[map->map].sys_start); - - sa1100_pcmcia_socket[sock].mem_map[map->map].sys_start=NULL; - - } - - /* Card Services is unreliable about passing sane stopping addresses, - * so we always try to allocate at least a page: - */ - if(map->sys_start==0 && (map->sys_stop-map->sys_start==0)) - map->sys_stop+=PAGE_SIZE; - - start=map->sys_start; - - if((map->sys_start=ioremap_nocache((map->flags & MAP_ATTRIB)?\ - sa1100_pcmcia_socket[sock].phys_attr:\ - sa1100_pcmcia_socket[sock].phys_mem, - (map->sys_stop-start)+1))==NULL){ - printk(KERN_ERR "%s(): unable to map socket %d map %d at %08lx\n", - __FUNCTION__, sock, map->map, start); - return -1; - } + if(sa1100_pcmcia_socket[sock].mem_map[map->map].sys_start==NULL){ - map->sys_stop=map->sys_start+(map->sys_stop-start); + /* Card Services is unreliable about passing sane stopping addresses, + * so we always try to allocate at least a page: + */ + if(map->sys_start==0 && map->sys_stop==0) + map->sys_stop=PAGE_SIZE-1; - sa1100_pcmcia_socket[sock].mem_map[map->map]=*map; + start=map->sys_start; + + if((map->sys_start=ioremap_nocache((map->flags & MAP_ATTRIB)?\ + sa1100_pcmcia_socket[sock].phys_attr:\ + sa1100_pcmcia_socket[sock].phys_mem, + (map->sys_stop-start)+1))==NULL){ + printk(KERN_ERR "%s(): unable to map socket %d map %d at %08lx\n", + __FUNCTION__, sock, map->map, start); + return -1; + } + + map->sys_stop=map->sys_start+(map->sys_stop-start); + } /* When clients issue RequestMap, the access speed is not always * properly configured: */ - speed=(map->speed>0)?map->speed:SA1100_PCMCIA_IO_ACCESS; + speed=(map->speed>0)?map->speed:SA1100_PCMCIA_MEM_ACCESS; if((clock=SA1100_PCMCIA_CCF())==0){ printk(KERN_ERR "sa1100: invalid CCF code (0x%02x)\n", @@ -1088,11 +1061,18 @@ * behalf of the IO space as well: */ MECR_FAST_SET(mecr, sock, 0); - - if(map->flags&MAP_ATTRIB) - MECR_BSA_SET(mecr, sock, sa1100_pcmcia_mecr_bs(map->speed, clock)); - else - MECR_BSM_SET(mecr, sock, sa1100_pcmcia_mecr_bs(map->speed, clock)); + + if(map->flags&MAP_ATTRIB){ + + MECR_BSA_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock)); + sa1100_pcmcia_socket[sock].speed_attr=speed; + + } else { + + MECR_BSM_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock)); + sa1100_pcmcia_socket[sock].speed_mem=speed; + + } DEBUG(4, "%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx\n", __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock, @@ -1100,19 +1080,21 @@ sock, MECR_BSIO_GET(mecr, sock)); MECR=mecr; - + } else { if(sa1100_pcmcia_socket[sock].mem_map[map->map].sys_start!=NULL){ iounmap(sa1100_pcmcia_socket[sock].mem_map[map->map].sys_start); - sa1100_pcmcia_socket[sock].mem_map[map->map].sys_start=NULL; + map->sys_start=NULL; } } - + + sa1100_pcmcia_socket[sock].mem_map[map->map]=*map; + return 0; } /* sa1100_pcmcia_set_mem_map() */ @@ -1205,6 +1187,12 @@ p+=sprintf(p, "Vpp : %d\n", sa1100_pcmcia_socket[sock].cs_state.Vpp); p+=sprintf(p, "irq : %d\n", sa1100_pcmcia_socket[sock].cs_state.io_irq); + + p+=sprintf(p, "I/O : %u\n", sa1100_pcmcia_socket[sock].speed_io); + + p+=sprintf(p, "attribute: %u\n", sa1100_pcmcia_socket[sock].speed_attr); + + p+=sprintf(p, "common : %u\n", sa1100_pcmcia_socket[sock].speed_mem); return p-buf; } diff -urN linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/sa1100_neponset.c linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/sa1100_neponset.c --- linux-2.4.0-test8-rmk1-np1/drivers/pcmcia/sa1100_neponset.c Sat Sep 23 23:51:56 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/pcmcia/sa1100_neponset.c Sat Sep 23 10:44:51 2000 @@ -5,9 +5,9 @@ * */ #include +#include #include -#include #include #include #include @@ -151,17 +151,16 @@ switch(configure->vcc){ case 0: - pccr=(pccr & ~PCCR_S0_FLT); gpio&=~(GPIO_GPIO0 | GPIO_GPIO1); break; case 33: - pccr=(pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT; + pccr=(pccr & ~PCCR_S0_PSE); gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO1; break; case 50: - pccr=(pccr | PCCR_S0_PSE | PCCR_S0_FLT); + pccr=(pccr | PCCR_S0_PSE); gpio=(gpio & ~(GPIO_GPIO0 | GPIO_GPIO1)) | GPIO_GPIO0; break; @@ -191,23 +190,23 @@ } pccr=(configure->reset)?(pccr | PCCR_S0_RST):(pccr & ~PCCR_S0_RST); + pccr=(configure->output)?(pccr | PCCR_S0_FLT):(pccr & ~PCCR_S0_FLT); break; case 1: switch(configure->vcc){ case 0: - pccr=(pccr & ~PCCR_S1_FLT); gpio&=~(GPIO_GPIO2 | GPIO_GPIO3); break; case 33: - pccr=(pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT; + pccr=(pccr & ~PCCR_S1_PSE); gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO2; break; case 50: - pccr=(pccr | PCCR_S1_PSE | PCCR_S1_FLT); + pccr=(pccr | PCCR_S1_PSE); gpio=(gpio & ~(GPIO_GPIO2 | GPIO_GPIO3)) | GPIO_GPIO3; break; @@ -224,6 +223,7 @@ } pccr=(configure->reset)?(pccr | PCCR_S1_RST):(pccr & ~PCCR_S1_RST); + pccr=(configure->output)?(pccr | PCCR_S1_FLT):(pccr & ~PCCR_S1_FLT); break; diff -urN linux-2.4.0-test8-rmk1-np1/drivers/sound/sa1100-uda1341.c linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/sound/sa1100-uda1341.c --- linux-2.4.0-test8-rmk1-np1/drivers/sound/sa1100-uda1341.c Sat Sep 23 23:51:56 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/drivers/sound/sa1100-uda1341.c Sat Sep 23 22:17:19 2000 @@ -21,6 +21,8 @@ * * 2000-08-22 Nicolas Pitre Removed all DMA stuff. Now using the * generic SA1100 DMA interface. + * + * 2000-09-04 John Dorsey SA-1111 Serial Audio Controller support. */ #include @@ -45,6 +47,7 @@ #undef DEBUG +//#define DEBUG 1 #ifdef DEBUG #define DPRINTK( x... ) printk( ##x ) #else @@ -58,12 +61,13 @@ #define AUDIO_NAME "UDA1341" #define AUDIO_NAME_VERBOSE "UDA1341 audio driver" -#define AUDIO_VERSION_STRING "version 0.5" +#define AUDIO_VERSION_STRING "version 0.6" #define AUDIO_FMT_MASK (AFMT_S16_LE) #define AUDIO_FMT_DEFAULT (AFMT_S16_LE) #define AUDIO_CHANNELS_DEFAULT 2 #define AUDIO_RATE_DEFAULT 44100 +#define AUDIO_RATE_DEFAULT_SAC 22050 #define AUDIO_NBFRAGS_DEFAULT 8 #define AUDIO_FRAGSIZE_DEFAULT 8192 @@ -102,6 +106,13 @@ #define L3_ClockPin GPIO_BITSY_L3_CLOCK #define L3_ModePin GPIO_BITSY_L3_MODE #endif +#if 0 +#ifdef CONFIG_SA1111 +#define L3_DataPin GPIO_GPIO_B5 +#define L3_ClockPin GPIO_GPIO_B4 +#define L3_ModePin GPIO_GPIO_B1 +#endif +#endif /* @@ -138,10 +149,12 @@ */ static void __init L3_init(void) { - GAFR &= ~(L3_DataPin | L3_ClockPin | L3_ModePin); - GPSR = L3_ModePin; - GPDR |= L3_ModePin; - L3_releasepins(); + if(!machine_has_neponset()){ + GAFR &= ~(L3_DataPin | L3_ClockPin | L3_ModePin); + GPSR = L3_ModePin; + GPDR |= L3_ModePin; + L3_releasepins(); + } } /* @@ -267,12 +280,38 @@ */ static int L3_write(char addr, char *data, int len) { - int mode = 0; int bytes = len; - L3_sendbyte(addr, mode++); - while (len--) - L3_sendbyte(*data++, mode++); + DPRINTK("%s(0x%x, %d)\n", __FUNCTION__, addr, len); + + if(machine_has_neponset()){ /* SA-1111 L3 Control Bus */ +#ifdef CONFIG_SA1111 + if( len > 1 ){ + //Hack,disable record function + SACR1 |= (SACR1_L3MB | SACR1_L3EN | SACR1_DREC); + while( (len--) > 1 ){ + L3_CAR = addr; + L3_CDR = *data++; + while((SASR0 & SASR0_L3WD) == 0) + mdelay(1); + SASCR = SASCR_DTS; + } + } + SACR1 &= ~SACR1_L3MB; + L3_CAR = addr; + L3_CDR = *data; + while((SASR0 & SASR0_L3WD) == 0) + mdelay(1); + SASCR = SASCR_DTS; +#endif + } else { + + int mode = 0; + + L3_sendbyte(addr, mode++); + while(len--) + L3_sendbyte(*data++, mode++); + } return bytes; } @@ -285,12 +324,38 @@ */ static int L3_read(char addr, char *data, int len) { - int mode = 0; int bytes = len; - L3_sendbyte(addr, mode++); - while (len--) - *data++ = L3_getbyte(mode++); + DPRINTK("%s(0x%x, %d)\n", __FUNCTION__, addr, len); + + if(machine_has_neponset()){ /* SA-1111 L3 Control Bus */ +#ifdef CONFIG_SA1111 + if( len > 1 ){ + //Hack,disable record function + SACR1 |= (SACR1_L3MB | SACR1_L3EN | SACR1_DREC); + while( (len--) > 1 ){ + L3_CAR = addr; + while((SASR0 & SASR0_L3RD) == 0) + mdelay(1); + *data++ = L3_CDR; + SASCR = SASCR_RDD; + } + } + SACR1 &= ~SACR1_L3MB; + L3_CAR = addr; + while((SASR0 & SASR0_L3RD) == 0) + mdelay(1); + *data = L3_CDR; + SASCR = SASCR_RDD; +#endif + } else { + + int mode = 0; + + L3_sendbyte(addr, mode++); + while(len--) + *data++ = L3_getbyte(mode++); + } return bytes; } @@ -424,6 +489,10 @@ } DATA0_ext6 = { 6, 24, 0, 0, 7}; +static struct { + u_int peak:6; /* peak level value */ +} DATA1 = { 0 }; + /* * Buffer Management @@ -532,7 +601,7 @@ if (!dmasize) { dmasize = (s->nbfrags - frag) * s->fragsize; do { - dmabuf = consistent_alloc(GFP_KERNEL, + dmabuf = consistent_alloc(GFP_DMA, dmasize, &dmaphys); if (!dmabuf) @@ -577,6 +646,17 @@ * Current buffer is sent: wake up any process waiting for it. */ up(&b->sem); + +#define CHROME 1 /* What else are you going to do with 32 LEDs? */ +#ifdef CHROME + if (machine_is_assabet() && machine_has_neponset()) { +#ifdef CONFIG_ASSABET_NEPONSET + L3_read( (UDA1341_L3Addr<<2)|UDA1341_DATA1, + (char*)&DATA1, 1 ); + LEDS = (1 << (DATA1.peak >> 1)) - 1; +#endif + } +#endif } static void audio_dmain_done_callback(void *buf_id, int size) @@ -698,8 +778,9 @@ * So if there is no playback data to send, the output DMA will * spin with all zeroes. */ - sa1100_dma_set_spin(output_stream.dma_ch, - (dma_addr_t) FLUSH_BASE_PHYS, 2048); + if (!machine_is_assabet() || !machine_has_neponset()) + sa1100_dma_set_spin(output_stream.dma_ch, + (dma_addr_t) FLUSH_BASE_PHYS, 2048); /* * Since we just allocated all buffers, we must send them to @@ -1087,10 +1168,37 @@ get_user(val, (long *) arg); if (machine_is_assabet()) { - /* FIXME: we need to modify the clock rate for DRAM bank 2 - * (our clock source) accordingly. - */ - val = 44100; + if (machine_has_neponset()) { +#ifdef CONFIG_SA1111 + if (val > 0 && val < 9512) { + val = 8000; /* 8kHz */ + SKAUD = 69; + } else if (val >= 9512 && val < 13512) { + val = 11025; /* 11.025kHz */ + SKAUD = 50; + } else if (val >=13512 && val < 19025) { + val = 16000; /* 16kHz */ + SKAUD = 34; + } else if (val >= 19025 && val < 24012) { + val = 22050; /* 22.05kHz */ + SKAUD = 24; + } else { + val = 44100; + SKAUD = 11; + } + + STATUS_0.system_clk = UDA_STATUS0_SC_256FS; + L3_write((UDA1341_L3Addr << 2) | + UDA1341_STATUS, + (char *) &STATUS_0, 1); +#endif + } else { + /* FIXME: we need to modify the clock rate for DRAM bank 2 + * (our clock source) accordingly. + */ + val = 44100; + } + } else if (machine_is_bitsy()) { #ifdef CONFIG_SA1100_BITSY /* set the external clock generator */ @@ -1276,7 +1384,16 @@ DPRINTK("audio_open\n"); if (audio_refcount == 0) { - audio_rate = AUDIO_RATE_DEFAULT; + + if (machine_is_assabet() && machine_has_neponset()) { +#ifdef CONFIG_SA1111 + //audio_rate = AUDIO_RATE_DEFAULT_SAC; + audio_rate = AUDIO_RATE_DEFAULT; + SACR0 |= SACR0_ENB; +#endif + } else + audio_rate = AUDIO_RATE_DEFAULT; + audio_fragsize = AUDIO_FRAGSIZE_DEFAULT; audio_nbfrags = AUDIO_NBFRAGS_DEFAULT; audio_clear_buf(&output_stream); @@ -1303,9 +1420,21 @@ audio_refcount--; if (audio_refcount == 0) { audio_sync(file); - sa1100_dma_set_spin(output_stream.dma_ch, 0, 0); + + if (!machine_is_assabet() || !machine_has_neponset()) + sa1100_dma_set_spin(output_stream.dma_ch, 0, 0); + audio_clear_buf(&output_stream); audio_clear_buf(&input_stream); + + if (machine_is_assabet() && machine_has_neponset()) { +#ifdef CONFIG_SA1111 + SACR0 &= ~SACR0_ENB; +#endif +#if defined (CONFIG_ASSABET_NEPONSET) && defined (CHROME) + LEDS = 0; +#endif + } } MOD_DEC_USE_COUNT; @@ -1345,33 +1474,64 @@ static inline void audio_assabet_init(void) { #ifdef CONFIG_SA1100_ASSABET - /* Setup the uarts */ - GAFR |= (GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK | - GPIO_SSP_SFRM | GPIO_SSP_CLK); - GPDR |= (GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM); - GPDR &= ~(GPIO_SSP_RXD | GPIO_SSP_CLK); - PPAR |= PPAR_SPR; - Ser4SSCR0 = SSCR0_SSE + SSCR0_DataSize(16) + SSCR0_TI; - Ser4SSCR1 = SSCR1_SClkIactL + SSCR1_SClk1P + SSCR1_ExtClk; + if (machine_has_neponset()) { - /* Enable the audio power */ - BCR_clear(BCR_STEREO_LB | BCR_QMUTE | BCR_SPK_OFF); - BCR_set(BCR_CODEC_RST | BCR_AUDIO_ON); +#ifdef CONFIG_SA1111 + /* Select I2S audio (instead of AC-Link) */ + AUD_CTL = AUD_SEL_1341; + SKCR &= ~SKCR_SELAC; + + /* Enable the I2S clock and L3 bus clock: */ + SKPCR |= (SKPCR_I2SCLKEN | SKPCR_L3CLKEN); + + /* Activate and reset the Serial Audio Controller */ + SACR0 |= (SACR0_ENB | SACR0_RST); + mdelay(5); + SACR0 &= ~SACR0_RST; + + /* For I2S, BIT_CLK is supplied internally. The "SA-1111 + * Specification Update" mentions that the BCKD bit should + * be interpreted as "0 = output". Default clock divider + * is 22.05kHz. + * + * Select I2S, L3 bus. "Recording" and "Replaying" + * (receive and transmit) are enabled. + */ + SACR1 = SACR1_L3EN; + mdelay(100); +#endif - /* - * The assabet board uses the SDRAM clock as the source clock for - * audio. This is supplied to the SA11x0 from the CPLD on pin 19. - * At 206Mhz we need to run the audio clock (SDRAM bank 2) - * at half speed. This clock will scale with core frequency so - * the audio sample rate will also scale. The CPLD on Assabet - * will need to be programmed to match the core frequency. - */ - MDREFR |= (MDREFR_K2DB2 | MDREFR_K2RUN); - /* Make sure EAPD and KAPD are clear to run the clocks at all times. */ - MDREFR &= ~(MDREFR_EAPD | MDREFR_KAPD); + } else { - /* Wait for the UDA1341 to wake up */ - mdelay(100); + /* Setup the uarts */ + GAFR |= (GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK | + GPIO_SSP_SFRM | GPIO_SSP_CLK); + GPDR |= (GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM); + GPDR &= ~(GPIO_SSP_RXD | GPIO_SSP_CLK); + PPAR |= PPAR_SPR; + Ser4SSCR0 = SSCR0_SSE + SSCR0_DataSize(16) + SSCR0_TI; + Ser4SSCR1 = SSCR1_SClkIactL + SSCR1_SClk1P + SSCR1_ExtClk; + + /* Enable the audio power */ + BCR_clear(BCR_STEREO_LB | BCR_QMUTE | BCR_SPK_OFF); + BCR_set(BCR_CODEC_RST | BCR_AUDIO_ON); + + /* + * The assabet board uses the SDRAM clock as the source clock for + * audio. This is supplied to the SA11x0 from the CPLD on pin 19. + * At 206Mhz we need to run the audio clock (SDRAM bank 2) + * at half speed. This clock will scale with core frequency so + * the audio sample rate will also scale. The CPLD on Assabet + * will need to be programmed to match the core frequency. + */ + MDREFR |= (MDREFR_K2DB2 | MDREFR_K2RUN); + /* Make sure EAPD and KAPD are clear to run the clocks at all times. */ + MDREFR &= ~(MDREFR_EAPD | MDREFR_KAPD); + + /* Wait for the UDA1341 to wake up */ + mdelay(100); + + } #endif } @@ -1408,7 +1568,13 @@ { int err; - err = sa1100_request_dma(&s->dma_ch, desc); + if(machine_is_assabet() && machine_has_neponset()) + err = sa1111_sac_request_dma(&s->dma_ch, desc, + (s == &output_stream)?\ + SA1111_SAC_XMT_CHANNEL:\ + SA1111_SAC_RCV_CHANNEL); + else + err = sa1100_request_dma(&s->dma_ch, desc); if (err) return err; if (s == &output_stream) { @@ -1445,6 +1611,11 @@ #endif } + if (machine_has_neponset()) { + STATUS_0.input_fmt = UDA_STATUS0_IF_I2S; + STATUS_0.system_clk = UDA_STATUS0_SC_256FS; + } + STATUS_0.reset = 0; L3_write((UDA1341_L3Addr << 2) | UDA1341_STATUS, (char *) &STATUS_0, 1); @@ -1479,7 +1650,11 @@ STATUS_1.ADC_gain = 1; L3_write((UDA1341_L3Addr << 2) | UDA1341_STATUS, (char *) &STATUS_1, 1); +#ifdef CONFIG_SA1111 + DATA0_0.volume = 30; +#else DATA0_0.volume = 15; +#endif L3_write((UDA1341_L3Addr << 2) | UDA1341_DATA0, (char *) &DATA0_0, 1); DATA0_2.mode = 3; @@ -1492,7 +1667,11 @@ DATA0_ext4.AGC_ctrl = 1; L3_write((UDA1341_L3Addr << 2) | UDA1341_DATA0, (char *) &DATA0_ext4, 2); +#ifdef CONFIG_SA1111 + DATA0_ext6.AGC_level = 2; +#else DATA0_ext6.AGC_level = 3; +#endif L3_write((UDA1341_L3Addr << 2) | UDA1341_DATA0, (char *) &DATA0_ext6, 2); @@ -1500,7 +1679,8 @@ audio_dev_dsp = register_sound_dsp(&UDA1341_dsp_fops, -1); audio_dev_mixer = register_sound_mixer(&UDA1341_mixer_fops, -1); - printk(AUDIO_NAME_VERBOSE " initialized\n"); + printk(AUDIO_NAME_VERBOSE "%s initialized\n", + machine_has_neponset() ? " (SA-1111 L3 Control Bus)" : "" ); return 0; } diff -urN linux-2.4.0-test8-rmk1-np1/include/asm-arm/arch-sa1100/SA-1111.h linux-2.4.0-test8-rmk1-np1-jd1-ck1/include/asm-arm/arch-sa1100/SA-1111.h --- linux-2.4.0-test8-rmk1-np1/include/asm-arm/arch-sa1100/SA-1111.h Thu Aug 17 22:35:15 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/include/asm-arm/arch-sa1100/SA-1111.h Sat Sep 23 20:49:50 2000 @@ -11,6 +11,8 @@ #ifndef _ASM_ARCH_SA1111 #define _ASM_ARCH_SA1111 +#include + /* * Macro that calculates real address for registers in the SA-1111 */ @@ -18,7 +20,21 @@ #define _SA1111( x ) ((x) + SA1111_BASE) /* - * System Bus Interface (SBI) + * 26 bits of the SA-1110 address bus are available to the SA-1111. + * Use these when feeding target addresses to the DMA engines. + */ + +#define SA1111_ADDR_WIDTH (26) +#define SA1111_ADDR_MASK ((1<=SA1111_SAC_DMA_BASE && + (c)<(SA1111_SAC_DMA_BASE+SA1111_SAC_DMA_CHANNELS)); +#endif + return 0; +} /* @@ -56,6 +91,8 @@ int sa1100_request_dma( dmach_t *channel, const char *device_id ); +int sa1111_sac_request_dma( dmach_t * channel, const char *device_id, + unsigned int direction ); int sa1100_dma_set_callback( dmach_t channel, dma_callback_t cb ); int sa1100_dma_set_device( dmach_t channel, dma_device_t device ); int sa1100_dma_set_spin( dmach_t channel, dma_addr_t addr, int size ); diff -urN linux-2.4.0-test8-rmk1-np1/include/pcmcia/ss.h linux-2.4.0-test8-rmk1-np1-jd1-ck1/include/pcmcia/ss.h --- linux-2.4.0-test8-rmk1-np1/include/pcmcia/ss.h Sat Sep 23 23:51:56 2000 +++ linux-2.4.0-test8-rmk1-np1-jd1-ck1/include/pcmcia/ss.h Sat Sep 23 10:44:51 2000 @@ -30,38 +30,6 @@ #ifndef _LINUX_SS_H #define _LINUX_SS_H - -#define IRQ_MASK_SIZE (256) - -typedef unsigned long irq_bitfield; - -#define IRQ_BITS (sizeof(irq_bitfield)*8) -#define IRQ_NUM_FIELDS (IRQ_MASK_SIZE/IRQ_BITS) -#define IRQ_FIELD_SELECT(i) ((i)/IRQ_BITS) -#define IRQ_FIELD_MASK(i) ((irq_bitfield)(1 << (i)%IRQ_BITS)) - -typedef struct irq_mask_t { - irq_bitfield fields[IRQ_NUM_FIELDS]; -} irq_mask_t; - -#define IRQ_ZERO(m) \ -do { \ - unsigned int iz_i; \ - for(iz_i=0; iz_ifields[iz_i]=0; \ -} while(0) - -#define IRQ_SET(m, i) \ -((m)->fields[IRQ_FIELD_SELECT((i))] |= IRQ_FIELD_MASK((i))) - -#define IRQ_CLEAR(m, i) \ -((m)->fields[IRQ_FIELD_SELECT((i))] &= ~IRQ_FIELD_MASK((i))) - -#define IRQ_ISSET(m, i) \ -((m)->fields[IRQ_FIELD_SELECT((i))] & IRQ_FIELD_MASK((i))) - -#define IRQ_MASK_LOW(m, k) ((m)->fields[0] & (k)) - - /* Definitions for card status flags for GetStatus */ #define SS_WRPROT 0x0001 #define SS_CARDLOCK 0x0002 @@ -82,7 +50,7 @@ /* for InquireSocket */ typedef struct socket_cap_t { u_int features; - irq_mask_t irq_mask; + u_int irq_mask; u_int map_size; u_char pci_irq; struct pci_dev *cb_dev;