sa1100_assabet.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * drivers/pcmcia/sa1100_assabet.c
  3. *
  4. * PCMCIA implementation routines for Assabet
  5. *
  6. */
  7. #include <linux/module.h>
  8. #include <linux/kernel.h>
  9. #include <linux/errno.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/device.h>
  12. #include <linux/init.h>
  13. #include <linux/gpio.h>
  14. #include <asm/mach-types.h>
  15. #include <mach/assabet.h>
  16. #include "sa1100_generic.h"
  17. static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  18. {
  19. skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD;
  20. skt->stat[SOC_STAT_CD].name = "CF CD";
  21. skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1;
  22. skt->stat[SOC_STAT_BVD1].name = "CF BVD1";
  23. skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2;
  24. skt->stat[SOC_STAT_BVD2].name = "CF BVD2";
  25. skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ;
  26. skt->stat[SOC_STAT_RDY].name = "CF RDY";
  27. return 0;
  28. }
  29. static void
  30. assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
  31. {
  32. state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */
  33. state->vs_Xv = 0;
  34. }
  35. static int
  36. assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
  37. {
  38. unsigned int mask;
  39. switch (state->Vcc) {
  40. case 0:
  41. mask = 0;
  42. break;
  43. case 50:
  44. printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
  45. __func__);
  46. case 33: /* Can only apply 3.3V to the CF slot. */
  47. mask = ASSABET_BCR_CF_PWR;
  48. break;
  49. default:
  50. printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__,
  51. state->Vcc);
  52. return -1;
  53. }
  54. /* Silently ignore Vpp, speaker enable. */
  55. if (state->flags & SS_RESET)
  56. mask |= ASSABET_BCR_CF_RST;
  57. if (!(state->flags & SS_OUTPUT_ENA))
  58. mask |= ASSABET_BCR_CF_BUS_OFF;
  59. ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR |
  60. ASSABET_BCR_CF_BUS_OFF, mask);
  61. return 0;
  62. }
  63. /*
  64. * Disable card status IRQs on suspend.
  65. */
  66. static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
  67. {
  68. /*
  69. * Tristate the CF bus signals. Also assert CF
  70. * reset as per user guide page 4-11.
  71. */
  72. ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST);
  73. }
  74. static struct pcmcia_low_level assabet_pcmcia_ops = {
  75. .owner = THIS_MODULE,
  76. .hw_init = assabet_pcmcia_hw_init,
  77. .socket_state = assabet_pcmcia_socket_state,
  78. .configure_socket = assabet_pcmcia_configure_socket,
  79. .socket_suspend = assabet_pcmcia_socket_suspend,
  80. };
  81. int pcmcia_assabet_init(struct device *dev)
  82. {
  83. int ret = -ENODEV;
  84. if (machine_is_assabet() && !machine_has_neponset())
  85. ret = sa11xx_drv_pcmcia_probe(dev, &assabet_pcmcia_ops, 1, 1);
  86. return ret;
  87. }