1 /* 2 * linux/arch/arm/mach-omap1/board-sx1-mmc.c 3 * 4 * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT 5 * Author: Carlos Eduardo Aguiar <carlos.aguiar@indt.org.br> 6 * 7 * This code is based on linux/arch/arm/mach-omap1/board-h2-mmc.c, which is: 8 * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15 #include <mach/hardware.h> 16 #include <mach/mmc.h> 17 #include <mach/gpio.h> 18 19 #ifdef CONFIG_MMC_OMAP 20 static int slot_cover_open; 21 static struct device *mmc_device; 22 23 static int sx1_mmc_set_power(struct device *dev, int slot, int power_on, 24 int vdd) 25 { 26 int err; 27 u8 dat = 0; 28 29 #ifdef CONFIG_MMC_DEBUG 30 dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1, 31 power_on ? "on" : "off", vdd); 32 #endif 33 34 if (slot != 0) { 35 dev_err(dev, "No such slot %d\n", slot + 1); 36 return -ENODEV; 37 } 38 39 err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat); 40 if (err < 0) 41 return err; 42 43 if (power_on) 44 dat |= SOFIA_MMC_POWER; 45 else 46 dat &= ~SOFIA_MMC_POWER; 47 48 return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat); 49 } 50 51 static int sx1_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode) 52 { 53 #ifdef CONFIG_MMC_DEBUG 54 dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1, 55 bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull"); 56 #endif 57 if (slot != 0) { 58 dev_err(dev, "No such slot %d\n", slot + 1); 59 return -ENODEV; 60 } 61 62 return 0; 63 } 64 65 static int sx1_mmc_get_cover_state(struct device *dev, int slot) 66 { 67 BUG_ON(slot != 0); 68 69 return slot_cover_open; 70 } 71 72 void sx1_mmc_slot_cover_handler(void *arg, int state) 73 { 74 if (mmc_device == NULL) 75 return; 76 77 slot_cover_open = state; 78 omap_mmc_notify_cover_event(mmc_device, 0, state); 79 } 80 81 static int sx1_mmc_late_init(struct device *dev) 82 { 83 int ret = 0; 84 85 mmc_device = dev; 86 87 return ret; 88 } 89 90 static void sx1_mmc_cleanup(struct device *dev) 91 { 92 } 93 94 static struct omap_mmc_platform_data sx1_mmc_data = { 95 .nr_slots = 1, 96 .switch_slot = NULL, 97 .init = sx1_mmc_late_init, 98 .cleanup = sx1_mmc_cleanup, 99 .slots[0] = { 100 .set_power = sx1_mmc_set_power, 101 .set_bus_mode = sx1_mmc_set_bus_mode, 102 .get_ro = NULL, 103 .get_cover_state = sx1_mmc_get_cover_state, 104 .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 | 105 MMC_VDD_32_33 | MMC_VDD_33_34, 106 .name = "mmcblk", 107 }, 108 }; 109 110 void __init sx1_mmc_init(void) 111 { 112 omap_set_mmc_info(1, &sx1_mmc_data); 113 } 114 115 #else 116 117 void __init sx1_mmc_init(void) 118 { 119 } 120 121 void sx1_mmc_slot_cover_handler(void *arg, int state) 122 { 123 } 124 #endif 125