📄 feature.c
字号:
(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 longcore99_reset_cpu(struct device_node *node, long param, long value){ unsigned int reset_io = 0; unsigned long flags; struct macio_chip *macio; struct device_node *np; struct device_node *cpus; const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0, KL_GPIO_RESET_CPU1, KL_GPIO_RESET_CPU2, KL_GPIO_RESET_CPU3 }; macio = &macio_chips[0]; if (macio->type != macio_keylargo) return -ENODEV; cpus = of_find_node_by_path("/cpus"); if (cpus == NULL) return -ENODEV; for (np = cpus->child; np != NULL; np = np->sibling) { const u32 *num = of_get_property(np, "reg", NULL); const u32 *rst = of_get_property(np, "soft-reset", NULL); if (num == NULL || rst == NULL) continue; if (param == *num) { reset_io = *rst; break; } } of_node_put(cpus); if (np == NULL || reset_io == 0) reset_io = dflt_reset_lines[param]; LOCK(flags); MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); (void)MACIO_IN8(reset_io); udelay(1); MACIO_OUT8(reset_io, 0); (void)MACIO_IN8(reset_io); UNLOCK(flags); return 0;}#endif /* CONFIG_SMP */static longcore99_usb_enable(struct device_node *node, long param, long value){ struct macio_chip *macio; unsigned long flags; const char *prop; int number; u32 reg; macio = &macio_chips[0]; if (macio->type != macio_keylargo && macio->type != macio_pangea && macio->type != macio_intrepid) return -ENODEV; prop = of_get_property(node, "AAPL,clock-id", NULL); if (!prop) return -ENODEV; if (strncmp(prop, "usb0u048", 8) == 0) number = 0; else if (strncmp(prop, "usb1u148", 8) == 0) number = 2; else if (strncmp(prop, "usb2u248", 8) == 0) number = 4; else return -ENODEV; /* Sorry for the brute-force locking, but this is only used during * sleep and the timing seem to be critical */ LOCK(flags); if (value) { /* Turn ON */ if (number == 0) { MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); (void)MACIO_IN32(KEYLARGO_FCR0); UNLOCK(flags); mdelay(1); LOCK(flags); MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); } else if (number == 2) { MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); UNLOCK(flags); (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); LOCK(flags); MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); } else if (number == 4) { MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1)); UNLOCK(flags); (void)MACIO_IN32(KEYLARGO_FCR1); mdelay(1); LOCK(flags); MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE); } if (number < 4) { reg = MACIO_IN32(KEYLARGO_FCR4); reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number)); reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1)); MACIO_OUT32(KEYLARGO_FCR4, reg); (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10); } else { reg = MACIO_IN32(KEYLARGO_FCR3); reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) | KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0)); reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) | KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1)); MACIO_OUT32(KEYLARGO_FCR3, reg); (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10); } if (macio->type == macio_intrepid) { /* wait for clock stopped bits to clear */ u32 test0 = 0, test1 = 0; u32 status0, status1; int timeout = 1000; UNLOCK(flags); switch (number) { case 0: test0 = UNI_N_CLOCK_STOPPED_USB0; test1 = UNI_N_CLOCK_STOPPED_USB0PCI; break; case 2: test0 = UNI_N_CLOCK_STOPPED_USB1; test1 = UNI_N_CLOCK_STOPPED_USB1PCI; break; case 4: test0 = UNI_N_CLOCK_STOPPED_USB2; test1 = UNI_N_CLOCK_STOPPED_USB2PCI; break; } do { if (--timeout <= 0) { printk(KERN_ERR "core99_usb_enable: " "Timeout waiting for clocks\n"); break; } mdelay(1); status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0); status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1); } while ((status0 & test0) | (status1 & test1)); LOCK(flags); } } else { /* Turn OFF */ if (number < 4) { reg = MACIO_IN32(KEYLARGO_FCR4); reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number); reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1); MACIO_OUT32(KEYLARGO_FCR4, reg); (void)MACIO_IN32(KEYLARGO_FCR4); udelay(1); } else { reg = MACIO_IN32(KEYLARGO_FCR3); reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) | KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0); reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) | KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1); MACIO_OUT32(KEYLARGO_FCR3, reg); (void)MACIO_IN32(KEYLARGO_FCR3); udelay(1); } if (number == 0) { if (macio->type != macio_intrepid) MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); (void)MACIO_IN32(KEYLARGO_FCR0); udelay(1); MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); (void)MACIO_IN32(KEYLARGO_FCR0); } else if (number == 2) { if (macio->type != macio_intrepid) MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); (void)MACIO_IN32(KEYLARGO_FCR0); udelay(1); MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); (void)MACIO_IN32(KEYLARGO_FCR0); } else if (number == 4) { udelay(1); MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1)); (void)MACIO_IN32(KEYLARGO_FCR1); } udelay(1); } UNLOCK(flags); return 0;}static longcore99_firewire_enable(struct device_node *node, long param, long value){ unsigned long flags; struct macio_chip *macio; macio = &macio_chips[0]; if (macio->type != macio_keylargo && macio->type != macio_pangea && macio->type != macio_intrepid) return -ENODEV; if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) return -ENODEV; LOCK(flags); if (value) { UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); (void)UN_IN(UNI_N_CLOCK_CNTL); } else { UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); (void)UN_IN(UNI_N_CLOCK_CNTL); } UNLOCK(flags); mdelay(1); return 0;}static longcore99_firewire_cable_power(struct device_node *node, long param, long value){ unsigned long flags; struct macio_chip *macio; /* Trick: we allow NULL node */ if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0) return -ENODEV; macio = &macio_chips[0]; if (macio->type != macio_keylargo && macio->type != macio_pangea && macio->type != macio_intrepid) return -ENODEV; if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) return -ENODEV; LOCK(flags); if (value) { MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0); MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10); } else { MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4); MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10); } UNLOCK(flags); mdelay(1); return 0;}static longintrepid_aack_delay_enable(struct device_node *node, long param, long value){ unsigned long flags; if (uninorth_rev < 0xd2) return -ENODEV; LOCK(flags); if (param) UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); else UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE); UNLOCK(flags); return 0;}#endif /* CONFIG_POWER4 */static longcore99_read_gpio(struct device_node *node, long param, long value){ struct macio_chip *macio = &macio_chips[0]; return MACIO_IN8(param);}static longcore99_write_gpio(struct device_node *node, long param, long value){ struct macio_chip *macio = &macio_chips[0]; MACIO_OUT8(param, (u8)(value & 0xff)); return 0;}#ifdef CONFIG_POWER4static long g5_gmac_enable(struct device_node *node, long param, long value){ struct macio_chip *macio = &macio_chips[0]; unsigned long flags; if (node == NULL) return -ENODEV; LOCK(flags); if (value) { MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); mb(); k2_skiplist[0] = NULL; } else { k2_skiplist[0] = node; mb(); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); } UNLOCK(flags); mdelay(1); return 0;}static long g5_fw_enable(struct device_node *node, long param, long value){ struct macio_chip *macio = &macio_chips[0]; unsigned long flags; if (node == NULL) return -ENODEV; LOCK(flags); if (value) { MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); mb(); k2_skiplist[1] = NULL; } else { k2_skiplist[1] = node; mb(); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); } UNLOCK(flags); mdelay(1); return 0;}static long g5_mpic_enable(struct device_node *node, long param, long value){ unsigned long flags; struct device_node *parent = of_get_parent(node); int is_u3; if (parent == NULL) return 0; is_u3 = strcmp(parent->name, "u3") == 0 || strcmp(parent->name, "u4") == 0; of_node_put(parent); if (!is_u3) return 0; LOCK(flags); UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE); UNLOCK(flags); return 0;}static long g5_eth_phy_reset(struct device_node *node, long param, long value){ struct macio_chip *macio = &macio_chips[0]; struct device_node *phy; int need_reset; /* * We must not reset the combo PHYs, only the BCM5221 found in * the iMac G5. */ phy = of_get_next_child(node, NULL); if (!phy) return -ENODEV; need_reset = of_device_is_compatible(phy, "B5221"); of_node_put(phy); if (!need_reset) return 0; /* PHY reset is GPIO 29, not in device-tree unfortunately */ MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); /* Thankfully, this is now always called at a time when we can * schedule by sungem. */ msleep(10); MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0); return 0;}static long g5_i2s_enable(struct device_node *node, long param, long value){ /* Very crude implementation for now */ struct macio_chip *macio = &macio_chips[0]; unsigned long flags; int cell; u32 fcrs[3][3] = { { 0, K2_FCR1_I2S0_CELL_ENABLE | K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE, KL3_I2S0_CLK18_ENABLE }, { KL0_SCC_A_INTF_ENABLE, K2_FCR1_I2S1_CELL_ENABLE | K2_FCR1_I2S1_CLK_ENABLE_BIT | K2_FCR1_I2S1_ENABLE, KL3_I2S1_CLK18_ENABLE }, { KL0_SCC_B_INTF_ENABLE, SH_FCR1_I2S2_CELL_ENABLE | SH_FCR1_I2S2_CLK_ENABLE_BIT | SH_FCR1_I2S2_ENABLE, SH_FCR3_I2S2_CLK18_ENABLE }, }; if (macio->type != macio_keylargo2 && macio->type != macio_shasta) return -ENODEV; if (strncmp(node->name, "i2s-", 4)) return -ENODEV; cell = node->name[4] - 'a'; switch(cell) { case 0: case 1: break; case 2: if (macio->type == macio_shasta) break; default: return -ENODEV; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -