⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmac_feature.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    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 + -