| 
					
				 | 
			
			
				@@ -459,3 +459,158 @@ static int n8x0_mmc_late_init(struct device *dev) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	/* All slot pin bits seem to be inversed until first switch change */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if (r == 0xf || r == (0xf & ~bit)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		r = ~r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (r & bit) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*openp = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		*openp = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	r = menelaus_register_mmc_callback(n8x0_mmc_callback, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void n8x0_mmc_shutdown(struct device *dev) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int vs2sel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (machine_is_nokia_n800()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		vs2sel = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		vs2sel = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	menelaus_set_mmc_slot(1, 0, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	menelaus_set_mmc_slot(2, 0, vs2sel, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void n8x0_mmc_cleanup(struct device *dev) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	menelaus_unregister_mmc_callback(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	gpio_free(N8X0_SLOT_SWITCH_GPIO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (machine_is_nokia_n810()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gpio_free(N810_EMMC_VSD_GPIO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		gpio_free(N810_EMMC_VIO_GPIO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * MMC controller1 has two slots that are multiplexed via I2C. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * MMC controller2 is not in use. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static struct omap_mmc_platform_data mmc1_data = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.nr_slots			= 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.switch_slot			= n8x0_mmc_switch_slot, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.init				= n8x0_mmc_late_init, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.cleanup			= n8x0_mmc_cleanup, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.shutdown			= n8x0_mmc_shutdown, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.max_freq			= 24000000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.slots[0] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.wires			= 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.set_power		= n8x0_mmc_set_power, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.set_bus_mode		= n8x0_mmc_set_bus_mode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.get_cover_state	= n8x0_mmc_get_cover_state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.ocr_mask		= MMC_VDD_165_195 | MMC_VDD_30_31 | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						MMC_VDD_32_33   | MMC_VDD_33_34, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.name			= "internal", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.slots[1] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.set_power		= n8x0_mmc_set_power, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.set_bus_mode		= n8x0_mmc_set_bus_mode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.get_cover_state	= n8x0_mmc_get_cover_state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.ocr_mask		= MMC_VDD_165_195 | MMC_VDD_20_21 | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						MMC_VDD_21_22 | MMC_VDD_22_23 | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						MMC_VDD_23_24 | MMC_VDD_24_25 | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						MMC_VDD_27_28 | MMC_VDD_28_29 | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						MMC_VDD_29_30 | MMC_VDD_30_31 | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						MMC_VDD_32_33 | MMC_VDD_33_34, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		.name			= "external", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static struct gpio n810_emmc_gpios[] __initdata = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ N810_EMMC_VSD_GPIO, GPIOF_OUT_INIT_LOW,  "MMC slot 2 Vddf" }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ N810_EMMC_VIO_GPIO, GPIOF_OUT_INIT_LOW,  "MMC slot 2 Vdd"  }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void __init n8x0_mmc_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (machine_is_nokia_n810()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		mmc1_data.slots[0].name = "external"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * Some Samsung Movinand chips do not like open-ended 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * multi-block reads and fall to braind-dead state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * while doing so. Reducing the number of blocks in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 * the transfer or delays in clock disable do not help 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		mmc1_data.slots[1].name = "internal"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		mmc1_data.slots[1].ban_openended = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	err = gpio_request_one(N8X0_SLOT_SWITCH_GPIO, GPIOF_OUT_INIT_LOW, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			       "MMC slot switch"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (err) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (machine_is_nokia_n810()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		err = gpio_request_array(n810_emmc_gpios, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					 ARRAY_SIZE(n810_emmc_gpios)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			gpio_free(N8X0_SLOT_SWITCH_GPIO); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	mmc_data[0] = &mmc1_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	omap242x_init_mmc(mmc_data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void __init n8x0_mmc_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif	/* CONFIG_MMC_OMAP */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef CONFIG_MENELAUS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int n8x0_auto_sleep_regulators(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = EN_VPLL_SLEEP | EN_VMMC_SLEEP    \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		| EN_VAUX_SLEEP | EN_VIO_SLEEP \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		| EN_VMEM_SLEEP | EN_DC3_SLEEP \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		| EN_VC_SLEEP | EN_DC2_SLEEP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ret = menelaus_set_regulator_sleep(1, val); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		pr_err("Could not set regulators to sleep on menelaus: %u\n", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		       ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int n8x0_auto_voltage_scale(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ret = menelaus_set_vcore_hw(1400, 1050); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		pr_err("Could not set VCORE voltage on menelaus: %u\n", ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int n8x0_menelaus_late_init(struct device *dev) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int ret; 
			 |