static int __init bus_init(void) { struct bit_data *bit = &bit_data; unsigned long flags; int ret; if (machine_is_assabet() || machine_is_pangolin()) { bit->sda = GPIO_GPIO15; bit->scl = GPIO_GPIO18; bit->l3_mode = GPIO_GPIO17; } if (machine_is_h3600() || machine_is_h3100()) { bit->sda = GPIO_GPIO14; bit->scl = GPIO_GPIO16; bit->l3_mode = GPIO_GPIO15; } if (machine_is_stork()) { bit->sda = GPIO_GPIO15; bit->scl = GPIO_GPIO18; bit->l3_mode = GPIO_GPIO17; } if (!bit->sda) return -ENODEV; /* * Default level for L3 mode is low. * We set SCL and SDA high (i2c idle state). */ local_irq_save(flags); GPDR &= ~(bit->scl | bit->sda); GPCR = bit->l3_mode | bit->scl | bit->sda; GPDR |= bit->l3_mode; local_irq_restore(flags); if (machine_is_assabet()) { /* * Release reset on UCB1300, ADI7171 and UDA1341. We * need to do this here so that we can communicate on * the I2C/L3 buses. */ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); mdelay(1); ASSABET_BCR_clear(ASSABET_BCR_CODEC_RST); mdelay(1); ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); } ret = i2c_init(bit); if (ret == 0 && bit->l3_mode) { ret = l3_init(bit); if (ret) i2c_exit(); } return ret; }
static int __init assabet_uda1341_init(void) { int ret; if (!machine_is_assabet()) return -ENODEV; ret = l3_attach_client(&uda1341, "l3-bit-sa1100-gpio", "uda1341"); if (ret) goto out; /* register devices */ audio_dev_id = register_sound_dsp(&assabet_audio_fops, -1); mixer_dev_id = register_sound_mixer(&assabet_mixer_fops, -1); #ifdef FIX_POWER_DRAIN { unsigned long flags; local_irq_save(flags); ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); GPSR = GPIO_SSP_SFRM; GPDR |= GPIO_SSP_SFRM; GPCR = GPIO_SSP_SFRM; local_irq_restore(flags); } #endif printk(KERN_INFO "Assabet UDA1341 audio driver initialized\n"); return 0; release_l3: l3_detach_client(&uda1341); out: return ret; }
static void assabet_lcd_backlight_power(int on) { if (on) ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON); else ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON); }
static void assabet_irda_set_speed(struct device *dev, unsigned int speed) { if (speed < 4000000) ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL); else ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL); }
static int mcp_sa11x0_probe(struct platform_device *pdev) { struct mcp_plat_data *data = pdev->dev.platform_data; struct mcp *mcp; int ret; if (!data) return -ENODEV; if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) return -EBUSY; mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0)); if (!mcp) { ret = -ENOMEM; goto release; } mcp->owner = THIS_MODULE; mcp->ops = &mcp_sa11x0; mcp->sclk_rate = data->sclk_rate; mcp->dma_audio_rd = DMA_Ser4MCP0Rd; mcp->dma_audio_wr = DMA_Ser4MCP0Wr; mcp->dma_telco_rd = DMA_Ser4MCP1Rd; mcp->dma_telco_wr = DMA_Ser4MCP1Wr; platform_set_drvdata(pdev, mcp); if (machine_is_assabet()) { ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); } PPDR &= ~PPC_RXD4; PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; PSDR |= PPC_RXD4; PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); Ser4MCSR = -1; Ser4MCCR1 = data->mccr1; Ser4MCCR0 = data->mccr0 | 0x7f7f; mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / mcp->sclk_rate; ret = mcp_host_register(mcp); if (ret == 0) goto out; release: release_mem_region(0x80060000, 0x60); platform_set_drvdata(pdev, NULL); out: return ret; }
/* * Turn on/off the backlight. When turning the backlight on, we wait * 500us after turning it on so we don't cause the supplies to droop * when we enable the LCD controller (and cause a hard reset.) */ static void assabet_lcd_power(int on) { if (on) { ASSABET_BCR_set(ASSABET_BCR_LCD_ON); udelay(500); } else ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); }
static void assabet_lcd_power(int on) { #ifndef ASSABET_PAL_VIDEO if (on) ASSABET_BCR_set(ASSABET_BCR_LCD_ON); else #endif ASSABET_BCR_clear(ASSABET_BCR_LCD_ON); }
static void assabet_backlight_power(int on) { #ifndef ASSABET_PAL_VIDEO if (on) ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON); else #endif ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON); }
static void assabet_lcd_set_visual(u32 visual) { u_int is_true_color = visual == FB_VISUAL_TRUECOLOR; if (machine_is_assabet()) { #if 1 // phase 4 or newer Assabet's if (is_true_color) ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); else ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); #else // older Assabet's if (is_true_color) ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB); else ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB); #endif } }
/* * Disable card status IRQs on suspend. */ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) { soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); /* * Tristate the CF bus signals. Also assert CF * reset as per user guide page 4-11. */ ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST); }
static void assabet_uart_pm(struct uart_port *port, u_int state, u_int oldstate) { if (port->mapbase == _Ser1UTCR0) { if (state) ASSABET_BCR_clear(ASSABET_BCR_RS232EN | ASSABET_BCR_COM_RTS | ASSABET_BCR_COM_DTR); else ASSABET_BCR_set(ASSABET_BCR_RS232EN | ASSABET_BCR_COM_RTS | ASSABET_BCR_COM_DTR); } }
static int assabet_irda_set_power(struct device *dev, unsigned int state) { static unsigned int bcr_state[4] = { ASSABET_BCR_IRDA_MD0, ASSABET_BCR_IRDA_MD1|ASSABET_BCR_IRDA_MD0, ASSABET_BCR_IRDA_MD1, 0 }; if (state < 4) { state = bcr_state[state]; ASSABET_BCR_clear(state ^ (ASSABET_BCR_IRDA_MD1| ASSABET_BCR_IRDA_MD0)); ASSABET_BCR_set(state); } return 0; }
/* * Shutdown the Assabet audio driver. * * We have to be careful about the SFRM line here for the same reasons * described in the initialisation comments above. This basically means * that we must hand the SSP pins back to the GPIO module before disabling * the SSP. * * In addition, to reduce power drain, we toggle the SFRM line once so * that the UDA_WS line is at logic 0. * * We can't clear ASSABET_BCR_CODEC_RST without knowing if the UCB1300 or * ADV7171 driver is still active. If it is, then we still need to play * games, so we might as well leave ASSABET_BCR_CODEC_RST set. */ static void assabet_audio_shutdown(void *dummy) { ASSABET_BCR_set(ASSABET_BCR_STEREO_LB | ASSABET_BCR_QMUTE | ASSABET_BCR_SPK_OFF); l3_close(&uda1341); GAFR &= ~(GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM); Ser4SSCR0 = 0; #ifdef FIX_POWER_DRAIN GPSR = GPIO_SSP_SFRM; GPCR = GPIO_SSP_SFRM; #endif /* disable the audio power */ ASSABET_BCR_clear(ASSABET_BCR_AUDIO_ON); }
/* * This sets the IRDA power level on the Assabet. */ static inline int sa1100_irda_set_power_assabet(struct sa1100_irda *si, unsigned int state) { static unsigned int bcr_state[4] = { ASSABET_BCR_IRDA_MD0, ASSABET_BCR_IRDA_MD1|ASSABET_BCR_IRDA_MD0, ASSABET_BCR_IRDA_MD1, 0 }; if (state < 4) { state = bcr_state[state]; ASSABET_BCR_clear(state ^ (ASSABET_BCR_IRDA_MD1| ASSABET_BCR_IRDA_MD0)); ASSABET_BCR_set(state); } return 0; }
/* * Assabet uses COM_RTS and COM_DTR for both UART1 (com port) * and UART3 (radio module). We only handle them for UART1 here. */ static void assabet_set_mctrl(struct uart_port *port, u_int mctrl) { if (port->mapbase == _Ser1UTCR0) { u_int set = 0, clear = 0; if (mctrl & TIOCM_RTS) clear |= ASSABET_BCR_COM_RTS; else set |= ASSABET_BCR_COM_RTS; if (mctrl & TIOCM_DTR) clear |= ASSABET_BCR_COM_DTR; else set |= ASSABET_BCR_COM_DTR; ASSABET_BCR_clear(clear); ASSABET_BCR_set(set); } }
static void assabet_codec_reset(unsigned mask, int set) { unsigned long flags; bool old; local_irq_save(flags); old = !codec_nreset; if (set) codec_nreset &= ~mask; else codec_nreset |= mask; if (old != !codec_nreset) { if (codec_nreset) { ASSABET_BCR_set(ASSABET_BCR_NCODEC_RST); adv7171_sleep(); } else { ASSABET_BCR_clear(ASSABET_BCR_NCODEC_RST); } } local_irq_restore(flags); }
static void assabet_ucb1x00_reset(enum ucb1x00_reset state) { if (state == UCB_RST_PROBE) ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); }
static int mcp_sa11x0_probe(struct platform_device *pdev) { struct mcp_plat_data *data = pdev->dev.platform_data; struct mcp *mcp; int ret; if (!data) return -ENODEV; if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) return -EBUSY; mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0)); if (!mcp) { ret = -ENOMEM; goto release; } mcp->owner = THIS_MODULE; mcp->ops = &mcp_sa11x0; mcp->sclk_rate = data->sclk_rate; mcp->dma_audio_rd = DMA_Ser4MCP0Rd; mcp->dma_audio_wr = DMA_Ser4MCP0Wr; mcp->dma_telco_rd = DMA_Ser4MCP1Rd; mcp->dma_telco_wr = DMA_Ser4MCP1Wr; mcp->gpio_base = data->gpio_base; platform_set_drvdata(pdev, mcp); if (machine_is_assabet()) { ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); } /* * Setup the PPC unit correctly. */ PPDR &= ~PPC_RXD4; PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; PSDR |= PPC_RXD4; PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); /* * Initialise device. Note that we initially * set the sampling rate to minimum. */ Ser4MCSR = -1; Ser4MCCR1 = data->mccr1; Ser4MCCR0 = data->mccr0 | 0x7f7f; /* * Calculate the read/write timeout (us) from the bit clock * rate. This is the period for 3 64-bit frames. Always * round this time up. */ mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / mcp->sclk_rate; ret = mcp_host_register(mcp); if (ret == 0) goto out; release: release_mem_region(0x80060000, 0x60); platform_set_drvdata(pdev, NULL); out: return ret; }
/* * Set the IrDA communications speed. */ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed) { unsigned long flags; int brd, ret = -EINVAL; switch (speed) { case 9600: case 19200: case 38400: case 57600: case 115200: brd = 3686400 / (16 * speed) - 1; /* * Stop the receive DMA. */ if (IS_FIR(si)) sa1100_stop_dma(si->rxdma); local_irq_save(flags); Ser2UTCR3 = 0; Ser2HSCR0 = HSCR0_UART; Ser2UTCR1 = brd >> 8; Ser2UTCR2 = brd; /* * Clear status register */ Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; if (machine_is_assabet()) ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL); if (machine_is_h3xxx()) clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL); if (machine_is_yopy()) PPSR &= ~GPIO_IRDA_FIR; si->speed = speed; local_irq_restore(flags); ret = 0; break; case 4000000: local_irq_save(flags); si->hscr0 = 0; Ser2HSSR0 = 0xff; Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; Ser2UTCR3 = 0; si->speed = speed; if (machine_is_assabet()) ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL); if (machine_is_h3xxx()) set_h3600_egpio(IPAQ_EGPIO_IR_FSEL); if (machine_is_yopy()) PPSR |= GPIO_IRDA_FIR; sa1100_irda_rx_alloc(si); sa1100_irda_rx_dma_start(si); local_irq_restore(flags); break; default: break; } return ret; }
/* * Initialise the Assabet audio driver. * * Note that we have to be careful with the order that we do things here; * there is a D-type flip flop which is clocked from the SFRM line which * indicates whether the same is for the left or right channel to the * UDA1341. * * When you disable the SSP (by clearing SSCR0_SSE) it appears that the * SFRM signal can float high. When you re-enable the SSP, you clock the * flip flop once, and end up swapping the left and right channels. * * The ASSABET_BCR_CODEC_RST line will force this flip flop into a known * state, but this line resets other devices as well! * * In addition to the above, it appears that powering down the UDA1341 on * early Assabets leaves the UDA_WS actively driving a logic '1' into the * chip, wasting power! (you can tell this by D11 being half-on). We * attempt to correct this by kicking the flip flop on init/open/close. * We should probably do this on PM resume as well. * * (Note the ordering of ASSABET_BCR_AUDIO_ON, SFRM and ASSABET_BCR_CODEC_RST * is important). */ static void assabet_audio_init(void *dummy) { unsigned long flags; unsigned int mdrefr; local_irq_save(flags); /* * Enable the power for the UDA1341 before driving any signals. * We leave the audio amp (LM4880) disabled for now. */ ASSABET_BCR_set(ASSABET_BCR_AUDIO_ON); #ifdef FIX_POWER_DRAIN GPSR = GPIO_SSP_SFRM; GPCR = GPIO_SSP_SFRM; #endif ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); ASSABET_BCR_clear(ASSABET_BCR_STEREO_LB); /* * Setup the SSP uart. */ PPAR |= PPAR_SPR; Ser4SSCR0 = SSCR0_DataSize(16) + SSCR0_TI + SSCR0_SerClkDiv(2); Ser4SSCR1 = SSCR1_SClkIactL + SSCR1_SClk1P + SSCR1_ExtClk; GAFR |= GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK | GPIO_SSP_CLK; GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; GPDR &= ~(GPIO_SSP_RXD | GPIO_SSP_CLK); Ser4SSCR0 |= SSCR0_SSE; /* * Only give SFRM to the SSP after it has been enabled. */ GAFR |= GPIO_SSP_SFRM; /* * 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; if ((mdrefr & (MDREFR_K2DB2 | MDREFR_K2RUN | MDREFR_EAPD | MDREFR_KAPD)) != (MDREFR_K2DB2 | MDREFR_K2RUN)) { mdrefr |= MDREFR_K2DB2 | MDREFR_K2RUN; mdrefr &= ~(MDREFR_EAPD | MDREFR_KAPD); MDREFR = mdrefr; (void) MDREFR; } local_irq_restore(flags); /* Wait for the UDA1341 to wake up */ mdelay(1); l3_open(&uda1341); assabet_set_samplerate(audio_samplerate); /* Enable the audio power */ ASSABET_BCR_clear(ASSABET_BCR_QMUTE | ASSABET_BCR_SPK_OFF); }
static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) { ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST); }