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

📄 board-omap3evm-hsmmc.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
字号:
/* * linux/arch/arm/mach-omap3/board-omap3evm-hsmmc.c * * Copyright (C) 2007 Texas Instruments * Author: Texas Instruments * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#include <linux/err.h>#include <linux/module.h>#include <linux/platform_device.h>#include <linux/interrupt.h>#include <asm/hardware.h>#include <asm/arch/twl4030.h>#include <asm/arch/board.h>#include <asm/arch/power_companion.h>#include <asm/io.h>#define mmc_slot1		1#define mmc_slot2		2#define T2_MMC1_CD		0#define T2_MMC2_CD		1#define VMMC1_DEV_GRP		0x27#define P1_DEV_GRP		0x20#define VMMC1_DEDICATED		0x2A#define VSEL_3V			0x02#define VSEL_18V		0x00#define PBIAS_3V		0x03#define PBIAS_18V		0x02#define PBIAS_CLR		0x00#define TWL_GPIO_PUPDCTR1	0x13#define TWL_GPIO_IMR1A		0x1C#define TWL_GPIO_ISR1A		0x19#define VMMC1_DEV_GRP		0x27#define VMMC1_DEDICATED		0x2A#define VMMC2_DEV_GRP		0x2B#define VMMC2_DEDICATED		0x2E#define VSEL_S2_18V		0x05#define LDO_CLR			0x00#define VSEL_S2_CLR		0x40#define GPIO_0_BIT_POS		1 << 0#define GPIO_1_BIT_POS		1 << 1#define VSIM_DEV_GRP		0x37#define VSIM_DEDICATED		0x3Aextern int twl4030_request_gpio(int gpio);extern int twl4030_set_gpio_edge_ctrl(int gpio, int edge);extern int twl4030_set_gpio_debounce(int gpio, int enable);extern int twl4030_get_gpio_datain(int gpio);/* * Enable power to MMC controller from T2. * slot - MMC1 or MMC2. */int enable_mmc_power(int slot){	int ret = 0;	u8 reg = 0;	if (slot == mmc_slot1) {		/* Enable SLOT1 and Power up */		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,				P1_DEV_GRP, VMMC1_DEV_GRP);		if (ret != 0) {			printk(KERN_ERR				"Configuring MMC1 device group failed\n");			return ret;		}		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,	      			VSEL_3V, VMMC1_DEDICATED);		if (ret != 0) {			printk(KERN_ERR				"Configuring MMC1 dedicated failed\n");			return ret;		}				/* Enable VSIM to support MMC 8-bit on ES2 */		if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {			ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECIEVER,				&reg, VSIM_DEV_GRP);			if (ret != 0) {				printk(KERN_ERR					"Reading VSIM DEV GRP failed\n");				return ret;			}			ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,				reg | (1<<5), VSIM_DEV_GRP);			if (ret != 0) {				printk(KERN_ERR					"Setting VSIM DEV GRP failed\n");				return ret;			}			reg = 0;			ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECIEVER,				&reg, VSIM_DEDICATED);			if (ret != 0) {				printk(KERN_ERR					"Reading VSIM DEDICATED failed\n");				return ret;			}			ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,				reg | 0x7, VSIM_DEDICATED);			if (ret != 0) {				printk(KERN_ERR					"Enabling VSIM LDO failed\n");				return ret;			}		}	} else if (slot == mmc_slot2) {		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER, P1_DEV_GRP,				VMMC2_DEV_GRP);		if (ret != 0) {			printk(KERN_ERR				"Configuring MMC2 device group  failed\n");			return ret;		}		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,VSEL_S2_18V,				VMMC2_DEDICATED);		if (ret != 0) {			printk(KERN_ERR "Configuring MMC2 dedicated  failed\n");			return ret;		}	}	return 0;}/* * Disable power to MMC controller from T2. * slot - MMC1 or MMC2. */int disable_mmc_power(int slot){	int ret = 0;	if (slot == mmc_slot1) {		/* Disable MMC SLOT1 and Power off */		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER, LDO_CLR,	       			VMMC1_DEV_GRP);		if (ret != 0) {			printk(KERN_ERR "Configuring MMC1 dev grp failed\n");			return ret;		}		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,VSEL_S2_CLR,				VMMC1_DEDICATED);		if (ret != 0) {			printk(KERN_ERR "Configuring MMC1 dedicated failed\n");			return ret;		}		if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {			ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,				LDO_CLR, VSIM_DEV_GRP);			if (ret != 0) {				printk(KERN_ERR "Clearing VSIM GRP failed\n");				return ret;			}			ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,				LDO_CLR, VSIM_DEDICATED);			if (ret != 0) {				printk(KERN_ERR "Clearing VSIM LDO failed\n");				return ret;			}		}	} else if (slot == mmc_slot2) {		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER, LDO_CLR,				VMMC2_DEV_GRP);		if (ret != 0) {			printk(KERN_ERR "Configuring MMC2 dev grp failed\n");			return ret;		}		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,VSEL_S2_CLR,				VMMC2_DEDICATED);		if (ret != 0) {			printk(KERN_ERR "Configuring MMC2 dedicated failed\n");			return ret;		}	}	return 0;}/* * Configure the GPIO parameters for the MMC hotplug irq */int setup_mmc_carddetect_irq(int irq){	int ret = 0;	/* configure T2 GPIO interrupts to detect card insertion/removal */	ret = twl4030_request_gpio(irq);	if (ret != 0) {		printk(KERN_ERR "failed in request gpio =%d\n", ret);		return ret;	}	ret =  twl4030_set_gpio_edge_ctrl(irq,TWL4030_GPIO_EDGE_RISING |					TWL4030_GPIO_EDGE_FALLING);	if (ret != 0) {		printk(KERN_ERR "failed in gpio ctrl edge =%d\n", ret);		return ret;	}	/* hack: the pullup configuration seems to be not behaving correctly */	ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x02,				  	TWL_GPIO_PUPDCTR1);	if (ret != 0) {		printk(KERN_ERR "failed in gpio pull =%d\n", ret);		return ret;	}	ret = twl4030_set_gpio_debounce(irq,TWL4030_GPIO_IS_ENABLE);	if (ret != 0) {		printk(KERN_ERR "failed in gpio ctrl edge =%d\n", ret);		return ret;	}	return 0;}/* * Sysfs entry function to show wether card is inserted or removed for MMC1 */ssize_t mmc_omap_show_cover_switch(struct device *dev, struct					   device_attribute *attr, char *buf){	struct omap_mmc_conf *minfo = dev->platform_data;	if (twl4030_get_gpio_datain(minfo->switch_pin))		return sprintf(buf, "%s\n", "open");	else		return sprintf(buf, "%s\n", "Closed");	return 0;}/* * sysfs function to enable/disable card detect feature for MMC1 */ssize_t set_mmc_carddetect(struct device *dev, struct device_attribute				   *attr, const char *buf, size_t count){	struct omap_mmc_conf *minfo = dev->platform_data;	char cmd[25];	int i = 0;	if (count < 6) {		printk(KERN_WARNING "Invalid string\n");		return count;	}	while (buf[i] != ' ' && buf[i] != '\n' && i < count) {		cmd[i] = buf[i];		i++;	}	cmd[i] = '\0';	i++;	if (!strcmp(cmd, "Enable")) {		enable_irq(TWL4030_GPIO_IRQ_NO(minfo->switch_pin));	} else if (!strcmp(cmd, "Disable")) {		disable_irq(TWL4030_GPIO_IRQ_NO(minfo->switch_pin));	} else {		dev_dbg(dev, "Unrecognized string\n");		dev_dbg(dev, "Usage:\n");		dev_dbg(dev, "echo Enable >"			"/sys/devices/platform/hsmmc-omap/"			"mmc_card_detect\n");		dev_dbg(dev, "echo Disable >"			"/sys/devices/platform/hsmmc-omap/mmc_card_detect\n");	}	return count;}int mask_carddetect_int(int slot){	u8 reg = 0, ret = 0;	int val;	if (slot == mmc_slot1)       		val = GPIO_0_BIT_POS;	else		val = GPIO_1_BIT_POS;	ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &reg,					TWL_GPIO_IMR1A);	if (ret) {		printk(KERN_ERR "Error reading T2 GPIO IMR1A\n");		return ret;	}	ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, (reg | val),					TWL_GPIO_IMR1A);	if (ret) {		printk(KERN_ERR "Error writing  T2 GPIO IMR1A\n");		return ret;	}	ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &reg,				  	TWL_GPIO_ISR1A);	if (ret) {		printk(KERN_ERR "Error reading T2 GPIO ISR1A\n");		return ret;	}	ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, (reg | val),				   	TWL_GPIO_ISR1A);	if (ret) {		printk(KERN_ERR "Error writing T2 GPIO ISR1A\n");		return ret;	}	return ret;}int unmask_carddetect_int(int slot){	u8 reg = 0, ret = 0;	int val;	if (slot == mmc_slot1)       		val = GPIO_0_BIT_POS;	else		val = GPIO_1_BIT_POS;	ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &reg,					TWL_GPIO_IMR1A);	if (ret) {		printk(KERN_ERR "Error reading T2 GPIO IMR1A\n");		return ret;	}	ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, (reg & ~val),				   	TWL_GPIO_IMR1A);	if (ret) {		printk(KERN_ERR "Error writing T2 GPIO IMR1A\n");		return ret;	}	ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &reg,				  	TWL_GPIO_ISR1A);	if (ret) {		printk(KERN_ERR "Error reading T2 GPIO ISR1A\n");		return ret;	}	ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, (reg & ~val),				   	TWL_GPIO_ISR1A);	if (ret) {		printk(KERN_ERR "Error writing T2 GPIO ISR1A\n");		return ret;	}	return ret;}int switch_power_mode(int power_mode){	int ret = 0;	ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER, P1_DEV_GRP,						VMMC1_DEV_GRP);	if (ret != 0) {		printk(KERN_ERR			       "Configuring MMC1 device group failed\n");		return -1;	}	if (power_mode == 0) {		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER, VSEL_18V,					 	VMMC1_DEDICATED);		if (ret != 0) {			printk(KERN_ERR			       "Configuring MMC1 dedicated failed %x\n", ret);			return -1;		}	} else {		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER, VSEL_3V,					 	VMMC1_DEDICATED);		if (ret != 0) {			printk(KERN_ERR			       "Configuring MMC1 dedicated failed %x\n", ret);			return -1;		}	}	return 0;}EXPORT_SYMBOL(enable_mmc_power);EXPORT_SYMBOL(disable_mmc_power);EXPORT_SYMBOL(setup_mmc_carddetect_irq);EXPORT_SYMBOL(mmc_omap_show_cover_switch);EXPORT_SYMBOL(set_mmc_carddetect);EXPORT_SYMBOL(switch_power_mode);EXPORT_SYMBOL(mask_carddetect_int);EXPORT_SYMBOL(unmask_carddetect_int);

⌨️ 快捷键说明

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