📄 pmac_feature.c
字号:
pmac_mb.model_id == PMAC_TYPE_YIKES) return 0; macio = macio_find(node, 0); if (!macio) return -ENODEV; if (value) { LOCK(flags); MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); UNLOCK(flags); (void)MACIO_IN32(HEATHROW_FCR); } else { LOCK(flags); MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N); MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); UNLOCK(flags); } return 0;}static u32 save_fcr[5] __pmacdata;static u32 save_mbcr __pmacdata;static u32 save_gpio_levels[2] __pmacdata;static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata;static u8 save_gpio_normal[KEYLARGO_GPIO_CNT] __pmacdata;static u32 save_unin_clock_ctl __pmacdata;static struct dbdma_regs save_dbdma[13] __pmacdata;static struct dbdma_regs save_alt_dbdma[13] __pmacdata;static void __pmacdbdma_save(struct macio_chip* macio, struct dbdma_regs* save){ int i; /* Save state & config of DBDMA channels */ for (i=0; i<13; i++) { volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*) (macio->base + ((0x8000+i*0x100)>>2)); save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi); save[i].cmdptr = in_le32(&chan->cmdptr); save[i].intr_sel = in_le32(&chan->intr_sel); save[i].br_sel = in_le32(&chan->br_sel); save[i].wait_sel = in_le32(&chan->wait_sel); }}static void __pmacdbdma_restore(struct macio_chip* macio, struct dbdma_regs* save){ int i; /* Save state & config of DBDMA channels */ for (i=0; i<13; i++) { volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*) (macio->base + ((0x8000+i*0x100)>>2)); out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16); while (in_le32(&chan->status) & ACTIVE) mb(); out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi); out_le32(&chan->cmdptr, save[i].cmdptr); out_le32(&chan->intr_sel, save[i].intr_sel); out_le32(&chan->br_sel, save[i].br_sel); out_le32(&chan->wait_sel, save[i].wait_sel); }}static void __pmacheathrow_sleep(struct macio_chip* macio, int secondary){ if (secondary) { dbdma_save(macio, save_alt_dbdma); save_fcr[2] = MACIO_IN32(0x38); save_fcr[3] = MACIO_IN32(0x3c); } else { dbdma_save(macio, save_dbdma); save_fcr[0] = MACIO_IN32(0x38); save_fcr[1] = MACIO_IN32(0x3c); save_mbcr = MACIO_IN32(0x34); /* Make sure sound is shut down */ MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N); MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); /* This seems to be necessary as well or the fan * keeps coming up and battery drains fast */ MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE); } /* Make sure modem is shut down */ MACIO_OUT8(HRW_GPIO_MODEM_RESET, MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1); MACIO_BIS(HEATHROW_FCR, PADD_MODEM_POWER_N); MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE); /* Let things settle */ (void)MACIO_IN32(HEATHROW_FCR); mdelay(1);}static void __pmacheathrow_wakeup(struct macio_chip* macio, int secondary){ if (secondary) { MACIO_OUT32(0x38, save_fcr[2]); (void)MACIO_IN32(0x38); mdelay(1); MACIO_OUT32(0x3c, save_fcr[3]); (void)MACIO_IN32(0x38); mdelay(10); dbdma_restore(macio, save_alt_dbdma); } else { MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE); (void)MACIO_IN32(0x38); mdelay(1); MACIO_OUT32(0x3c, save_fcr[1]); (void)MACIO_IN32(0x38); mdelay(1); MACIO_OUT32(0x34, save_mbcr); (void)MACIO_IN32(0x38); mdelay(10); dbdma_restore(macio, save_dbdma); }}static int __pmacheathrow_sleep_state(struct device_node* node, int param, int value){ if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) return -EPERM; if (value == 1) { if (macio_chips[1].type == macio_gatwick) heathrow_sleep(&macio_chips[0], 1); heathrow_sleep(&macio_chips[0], 0); } else if (value == 0) { heathrow_wakeup(&macio_chips[0], 0); if (macio_chips[1].type == macio_gatwick) heathrow_wakeup(&macio_chips[0], 1); } return 0;}static int __pmaccore99_scc_enable(struct device_node* node, int param, int value){ struct macio_chip* macio; unsigned long flags; unsigned long chan_mask; u32 fcr; macio = macio_find(node, 0); if (!macio) return -ENODEV; if (!strcmp(node->name, "ch-a")) chan_mask = MACIO_FLAG_SCCA_ON; else if (!strcmp(node->name, "ch-b")) chan_mask = MACIO_FLAG_SCCB_ON; else return -ENODEV; if (value) { int need_reset_scc = 0; int need_reset_irda = 0; LOCK(flags); fcr = MACIO_IN32(KEYLARGO_FCR0); /* Check if scc cell need enabling */ if (!(fcr & KL0_SCC_CELL_ENABLE)) { fcr |= KL0_SCC_CELL_ENABLE; need_reset_scc = 1; } if (chan_mask & MACIO_FLAG_SCCA_ON) { fcr |= KL0_SCCA_ENABLE; /* Don't enable line drivers for I2S modem */ if ((param & 0xfff) == PMAC_SCC_I2S1) fcr &= ~KL0_SCC_A_INTF_ENABLE; else fcr |= KL0_SCC_A_INTF_ENABLE; } if (chan_mask & MACIO_FLAG_SCCB_ON) { fcr |= KL0_SCCB_ENABLE; /* Perform irda specific inits */ if ((param & 0xfff) == PMAC_SCC_IRDA) { fcr &= ~KL0_SCC_B_INTF_ENABLE; fcr |= KL0_IRDA_ENABLE; fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE; fcr |= KL0_IRDA_SOURCE1_SEL; fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0); fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND); need_reset_irda = 1; } else fcr |= KL0_SCC_B_INTF_ENABLE; } MACIO_OUT32(KEYLARGO_FCR0, fcr); macio->flags |= chan_mask; if (need_reset_scc) { MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET); (void)MACIO_IN32(KEYLARGO_FCR0); UNLOCK(flags); mdelay(15); LOCK(flags); MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET); } if (need_reset_irda) { MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET); (void)MACIO_IN32(KEYLARGO_FCR0); UNLOCK(flags); mdelay(15); LOCK(flags); MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET); } UNLOCK(flags); if (param & PMAC_SCC_FLAG_XMON) macio->flags |= MACIO_FLAG_SCC_LOCKED; } else { if (macio->flags & MACIO_FLAG_SCC_LOCKED) return -EPERM; LOCK(flags); fcr = MACIO_IN32(KEYLARGO_FCR0); if (chan_mask & MACIO_FLAG_SCCA_ON) fcr &= ~KL0_SCCA_ENABLE; if (chan_mask & MACIO_FLAG_SCCB_ON) { fcr &= ~KL0_SCCB_ENABLE; /* Perform irda specific clears */ if ((param & 0xfff) == PMAC_SCC_IRDA) { fcr &= ~KL0_IRDA_ENABLE; fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE); fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0); fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND); } } MACIO_OUT32(KEYLARGO_FCR0, fcr); if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) { fcr &= ~KL0_SCC_CELL_ENABLE; MACIO_OUT32(KEYLARGO_FCR0, fcr); } macio->flags &= ~(chan_mask); UNLOCK(flags); mdelay(10); } return 0;}static int __pmaccore99_modem_enable(struct device_node* node, int param, int value){ struct macio_chip* macio; u8 gpio; unsigned long flags; macio = macio_find(node, 0); if (!macio) return -ENODEV; gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; if (!value) { LOCK(flags); MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); UNLOCK(flags); (void)MACIO_IN8(KL_GPIO_MODEM_RESET); mdelay(250); } LOCK(flags); if (value) { MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); UNLOCK(flags); (void)MACIO_IN32(KEYLARGO_FCR2); mdelay(250); } else { MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); UNLOCK(flags); } if (value) { LOCK(flags); MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); (void)MACIO_IN8(KL_GPIO_MODEM_RESET); UNLOCK(flags); mdelay(250); LOCK(flags); MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); (void)MACIO_IN8(KL_GPIO_MODEM_RESET); UNLOCK(flags); mdelay(250); LOCK(flags); MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); (void)MACIO_IN8(KL_GPIO_MODEM_RESET); UNLOCK(flags); mdelay(250); LOCK(flags); } return 0;}static int __pmaccore99_ide_enable(struct device_node* node, int param, int value){ switch(param) { case 0: return simple_feature_tweak(node, macio_unknown, KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value); case 1: return simple_feature_tweak(node, macio_unknown, KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value); case 2: return simple_feature_tweak(node, macio_unknown, KEYLARGO_FCR1, KL1_UIDE_ENABLE, value); default: return -ENODEV; }}static int __pmaccore99_ide_reset(struct device_node* node, int param, int value){ switch(param) { case 0: return simple_feature_tweak(node, macio_unknown, KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value); case 1: return simple_feature_tweak(node, macio_unknown, KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value); case 2: return simple_feature_tweak(node, macio_unknown, KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value); default: return -ENODEV; }}static int __pmaccore99_gmac_enable(struct device_node* node, int param, int value){ unsigned long flags; LOCK(flags); if (value) UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); else UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); (void)UN_IN(UNI_N_CLOCK_CNTL); UNLOCK(flags); udelay(20); return 0;}static int __pmaccore99_gmac_phy_reset(struct device_node* node, int param, int value){ unsigned long flags; struct macio_chip* macio; macio = &macio_chips[0]; if (macio->type != macio_keylargo && macio->type != macio_pangea) return -ENODEV; LOCK(flags); MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE); (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET); UNLOCK(flags); mdelay(10); LOCK(flags); MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); UNLOCK(flags); mdelay(10); return 0;}static int __pmaccore99_sound_chip_enable(struct device_node* node, int param, int value){ struct macio_chip* macio; unsigned long flags; macio = macio_find(node, 0); if (!macio) return -ENODEV; /* Do a better probe code, screamer G4 desktops & * iMacs can do that too, add a recalibrate in * the driver as well */ if (pmac_mb.model_id == PMAC_TYPE_PISMO || pmac_mb.model_id == PMAC_TYPE_TITANIUM) { LOCK(flags); if (value) MACIO_OUT8(KL_GPIO_SOUND_POWER, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); else MACIO_OUT8(KL_GPIO_SOUND_POWER, KEYLARGO_GPIO_OUTPUT_ENABLE); (void)MACIO_IN8(KL_GPIO_SOUND_POWER); UNLOCK(flags); } return 0;}static int __pmaccore99_airport_enable(struct device_node* node, int param, int value){ struct macio_chip* macio; unsigned long flags; int state; macio = macio_find(node, 0); if (!macio) return -ENODEV; /* Hint: we allow passing of macio itself for the sake of the * sleep code */ if (node != macio->of_node && (!node->parent || node->parent != macio->of_node)) return -ENODEV; state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0; if (value == state) return 0; if (value) { /* This code is a reproduction of OF enable-cardslot * and init-wireless methods, slightly hacked until * I got it working. */ LOCK(flags); MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5); (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf); UNLOCK(flags); mdelay(10); LOCK(flags); MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4); (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf); UNLOCK(flags); mdelay(10); LOCK(flags); MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16); (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10); MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0); (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb); udelay(10); MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28); (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa); udelay(10); MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28); (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd); udelay(10); MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28); (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd); udelay(10); MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28); (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe); UNLOCK(flags); udelay(10); MACIO_OUT32(0x1c000, 0); mdelay(1); MACIO_OUT8(0x1a3e0, 0x41); (void)MACIO_IN8(0x1a3e0); udelay(10); LOCK(flags); MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16); (void)MACIO_IN32(KEYLARGO_FCR2); UNLOCK(flags); mdelay(100); macio->flags |= MACIO_FLAG_AIRPORT_ON; } else { LOCK(flags); MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16); (void)MACIO_IN32(KEYLARGO_FCR2); MACIO_OUT8(KL_GPIO_AIRPORT_0, 0); MACIO_OUT8(KL_GPIO_AIRPORT_1, 0); MACIO_OUT8(KL_GPIO_AIRPORT_2, 0); MACIO_OUT8(KL_GPIO_AIRPORT_3, 0); MACIO_OUT8(KL_GPIO_AIRPORT_4, 0); (void)MACIO_IN8(KL_GPIO_AIRPORT_4); UNLOCK(flags); macio->flags &= ~MACIO_FLAG_AIRPORT_ON; } return 0;}#ifdef CONFIG_SMPstatic int __pmaccore99_reset_cpu(struct device_node* node, int param, int value){ const int reset_lines[] = { KL_GPIO_RESET_CPU0, KL_GPIO_RESET_CPU1, KL_GPIO_RESET_CPU2, KL_GPIO_RESET_CPU3 }; int reset_io; unsigned long flags; struct macio_chip* macio; macio = &macio_chips[0]; if (macio->type != macio_keylargo && macio->type != macio_pangea) return -ENODEV; if (param > 3 || param < 0) return -ENODEV; reset_io = reset_lines[param]; LOCK(flags); MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); (void)MACIO_IN8(reset_io); udelay(1); MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); (void)MACIO_IN8(reset_io); UNLOCK(flags); return 0;}#endif /* CONFIG_SMP */static int __pmaccore99_usb_enable(struct device_node* node, int param, int value){ struct macio_chip* macio; unsigned long flags; char* prop; int number; u32 reg; macio = &macio_chips[0]; if (macio->type != macio_keylargo && macio->type != macio_pangea) return -ENODEV; prop = (char *)get_property(node, "AAPL,clock-id", NULL); if (!prop) return -ENODEV; if (strncmp(prop, "usb0u048", strlen("usb0u048")) == 0) number = 0; else if (strncmp(prop, "usb1u148", strlen("usb1u148")) == 0) number = 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -