|
@@ -285,3 +285,109 @@ static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot,
|
|
|
break;
|
|
|
default:
|
|
|
BUG();
|
|
|
+ }
|
|
|
+ return menelaus_set_vmmc(mV);
|
|
|
+ } else {
|
|
|
+ if (!power_on)
|
|
|
+ return menelaus_set_vdcdc(3, 0);
|
|
|
+ switch (1 << vdd) {
|
|
|
+ case MMC_VDD_33_34:
|
|
|
+ case MMC_VDD_32_33:
|
|
|
+ mV = 3300;
|
|
|
+ break;
|
|
|
+ case MMC_VDD_30_31:
|
|
|
+ case MMC_VDD_29_30:
|
|
|
+ mV = 3000;
|
|
|
+ break;
|
|
|
+ case MMC_VDD_28_29:
|
|
|
+ case MMC_VDD_27_28:
|
|
|
+ mV = 2800;
|
|
|
+ break;
|
|
|
+ case MMC_VDD_24_25:
|
|
|
+ case MMC_VDD_23_24:
|
|
|
+ mV = 2400;
|
|
|
+ break;
|
|
|
+ case MMC_VDD_22_23:
|
|
|
+ case MMC_VDD_21_22:
|
|
|
+ mV = 2200;
|
|
|
+ break;
|
|
|
+ case MMC_VDD_20_21:
|
|
|
+ mV = 2000;
|
|
|
+ break;
|
|
|
+ case MMC_VDD_165_195:
|
|
|
+ mV = 1800;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ BUG();
|
|
|
+ }
|
|
|
+ return menelaus_set_vdcdc(3, mV);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void n810_set_power_emmc(struct device *dev,
|
|
|
+ int power_on)
|
|
|
+{
|
|
|
+ dev_dbg(dev, "Set EMMC power %s\n", power_on ? "on" : "off");
|
|
|
+
|
|
|
+ if (power_on) {
|
|
|
+ gpio_set_value(N810_EMMC_VSD_GPIO, 1);
|
|
|
+ msleep(1);
|
|
|
+ gpio_set_value(N810_EMMC_VIO_GPIO, 1);
|
|
|
+ msleep(1);
|
|
|
+ } else {
|
|
|
+ gpio_set_value(N810_EMMC_VIO_GPIO, 0);
|
|
|
+ msleep(50);
|
|
|
+ gpio_set_value(N810_EMMC_VSD_GPIO, 0);
|
|
|
+ msleep(50);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static int n8x0_mmc_set_power(struct device *dev, int slot, int power_on,
|
|
|
+ int vdd)
|
|
|
+{
|
|
|
+ if (machine_is_nokia_n800() || slot == 0)
|
|
|
+ return n8x0_mmc_set_power_menelaus(dev, slot, power_on, vdd);
|
|
|
+
|
|
|
+ n810_set_power_emmc(dev, power_on);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int n8x0_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
|
|
|
+{
|
|
|
+ int r;
|
|
|
+
|
|
|
+ dev_dbg(dev, "Set slot %d bus mode %s\n", slot + 1,
|
|
|
+ bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
|
|
|
+ BUG_ON(slot != 0 && slot != 1);
|
|
|
+ slot++;
|
|
|
+ switch (bus_mode) {
|
|
|
+ case MMC_BUSMODE_OPENDRAIN:
|
|
|
+ r = menelaus_set_mmc_opendrain(slot, 1);
|
|
|
+ break;
|
|
|
+ case MMC_BUSMODE_PUSHPULL:
|
|
|
+ r = menelaus_set_mmc_opendrain(slot, 0);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ BUG();
|
|
|
+ }
|
|
|
+ if (r != 0 && printk_ratelimit())
|
|
|
+ dev_err(dev, "MMC: unable to set bus mode for slot %d\n",
|
|
|
+ slot);
|
|
|
+ return r;
|
|
|
+}
|
|
|
+
|
|
|
+static int n8x0_mmc_get_cover_state(struct device *dev, int slot)
|
|
|
+{
|
|
|
+ slot++;
|
|
|
+ BUG_ON(slot != 1 && slot != 2);
|
|
|
+ if (slot == 1)
|
|
|
+ return slot1_cover_open;
|
|
|
+ else
|
|
|
+ return slot2_cover_open;
|
|
|
+}
|
|
|
+
|
|
|
+static void n8x0_mmc_callback(void *data, u8 card_mask)
|
|
|
+{
|
|
|
+ int bit, *openp, index;
|