board-sx1-mmc.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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. #include <mach/hardware.h>
  15. #include <mach/mmc.h>
  16. #include <mach/gpio.h>
  17. #ifdef CONFIG_MMC_OMAP
  18. static int slot_cover_open;
  19. static struct device *mmc_device;
  20. static int sx1_mmc_set_power(struct device *dev, int slot, int power_on,
  21. int vdd)
  22. {
  23. int err;
  24. u8 dat = 0;
  25. #ifdef CONFIG_MMC_DEBUG
  26. dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
  27. power_on ? "on" : "off", vdd);
  28. #endif
  29. if (slot != 0) {
  30. dev_err(dev, "No such slot %d\n", slot + 1);
  31. return -ENODEV;
  32. }
  33. err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
  34. if (err < 0)
  35. return err;
  36. if (power_on)
  37. dat |= SOFIA_MMC_POWER;
  38. else
  39. dat &= ~SOFIA_MMC_POWER;
  40. return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
  41. }
  42. static int sx1_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
  43. {
  44. #ifdef CONFIG_MMC_DEBUG
  45. dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
  46. bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
  47. #endif
  48. if (slot != 0) {
  49. dev_err(dev, "No such slot %d\n", slot + 1);
  50. return -ENODEV;
  51. }
  52. return 0;
  53. }
  54. static int sx1_mmc_get_cover_state(struct device *dev, int slot)
  55. {
  56. BUG_ON(slot != 0);
  57. return slot_cover_open;
  58. }
  59. void sx1_mmc_slot_cover_handler(void *arg, int state)
  60. {
  61. if (mmc_device == NULL)
  62. return;
  63. slot_cover_open = state;
  64. omap_mmc_notify_cover_event(mmc_device, 0, state);
  65. }
  66. static int sx1_mmc_late_init(struct device *dev)
  67. {
  68. int ret = 0;
  69. mmc_device = dev;
  70. return ret;
  71. }
  72. static void sx1_mmc_cleanup(struct device *dev)
  73. {
  74. }
  75. static struct omap_mmc_platform_data sx1_mmc_data = {
  76. .nr_slots = 1,
  77. .switch_slot = NULL,
  78. .init = sx1_mmc_late_init,
  79. .cleanup = sx1_mmc_cleanup,
  80. .slots[0] = {
  81. .set_power = sx1_mmc_set_power,
  82. .set_bus_mode = sx1_mmc_set_bus_mode,
  83. .get_ro = NULL,
  84. .get_cover_state = sx1_mmc_get_cover_state,
  85. .ocr_mask = MMC_VDD_28_29 | MMC_VDD_30_31 |
  86. MMC_VDD_32_33 | MMC_VDD_33_34,
  87. .name = "mmcblk",
  88. },
  89. };
  90. void __init sx1_mmc_init(void)
  91. {
  92. omap_set_mmc_info(1, &sx1_mmc_data);
  93. }
  94. #else
  95. void __init sx1_mmc_init(void)
  96. {
  97. }
  98. void sx1_mmc_slot_cover_handler(void *arg, int state)
  99. {
  100. }
  101. #endif