pmac_feature.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,405 行 · 第 1/5 页

C
2,405
字号
		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 long __pmaccore99_airport_enable(struct device_node* node, long param, long 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 long __pmaccore99_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;	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;	np = find_path_device("/cpus");	if (np == NULL)		return -ENODEV;	for (np = np->child; np != NULL; np = np->sibling) {		u32* num = (u32 *)get_property(np, "reg", NULL);		u32* rst = (u32 *)get_property(np, "soft-reset", NULL);		if (num == NULL || rst == NULL)			continue;		if (param == *num) {			reset_io = *rst;			break;		}	}	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 long __pmaccore99_usb_enable(struct device_node* node, long param, long 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 &&	    macio->type != macio_intrepid)		return -ENODEV;	prop = (char *)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);		}	} 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) {			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) {			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) {			MACIO_BIC(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);			(void)MACIO_IN32(KEYLARGO_FCR1);			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 long __pmaccore99_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 long __pmaccore99_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 long __pmacintrepid_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 long __pmaccore99_read_gpio(struct device_node* node, long param, long value){	struct macio_chip* macio = &macio_chips[0];	return MACIO_IN8(param);}static long __pmaccore99_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 __pmacg5_gmac_enable(struct device_node* node, long param, long value){	struct macio_chip* macio = &macio_chips[0];	unsigned long flags;	struct pci_dev *pdev;	u8 pbus, pid;	/* XXX FIXME: We should fix pci_device_from_OF_node here, and	 * get to a real pci_dev or we'll get into trouble with PCI	 * domains the day we get overlapping numbers (like if we ever	 * decide to show the HT root	 */	if (pci_device_from_OF_node(node, &pbus, &pid) == 0)		pdev = pci_find_slot(pbus, pid);	LOCK(flags);	if (value) {		MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);		mb();		k2_skiplist[0] = NULL;	} else {		k2_skiplist[0] = pdev;		mb();		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);	}		UNLOCK(flags);	mdelay(1);	return 0;}static long __pmacg5_fw_enable(struct device_node* node, long param, long value){	struct macio_chip* macio = &macio_chips[0];	unsigned long flags;	struct pci_dev *pdev;	u8 pbus, pid;	/* XXX FIXME: We should fix pci_device_from_OF_node here, and	 * get to a real pci_dev or we'll get into trouble with PCI	 * domains the day we get overlapping numbers (like if we ever	 * decide to show the HT root	 */	if (pci_device_from_OF_node(node, &pbus, &pid) == 0)		pdev = pci_find_slot(pbus, pid);	LOCK(flags);	if (value) {		MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);		mb();		k2_skiplist[1] = NULL;	} else {		k2_skiplist[1] = pdev;		mb();		MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);	}		UNLOCK(flags);	mdelay(1);	return 0;}static long __pmacg5_mpic_enable(struct device_node* node, long param, long value){	unsigned long flags;	if (node->parent == NULL || strcmp(node->parent->name, "u3"))		return 0;	LOCK(flags);	UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);	UNLOCK(flags);	return 0;}#ifdef CONFIG_SMPstatic long __pmacg5_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;	macio = &macio_chips[0];	if (macio->type != macio_keylargo2)		return -ENODEV;	np = find_path_device("/cpus");	if (np == NULL)		return -ENODEV;	for (np = np->child; np != NULL; np = np->sibling) {		u32* num = (u32 *)get_property(np, "reg", NULL);		u32* rst = (u32 *)get_property(np, "soft-reset", NULL);		if (num == NULL || rst == NULL)			continue;		if (param == *num) {			reset_io = *rst;			break;		}	}	if (np == NULL || reset_io == 0)		return -ENODEV;	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);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?