sa1100_assabet.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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 int
  30. assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
  31. {
  32. unsigned int mask;
  33. switch (state->Vcc) {
  34. case 0:
  35. mask = 0;
  36. break;
  37. case 50:
  38. printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
  39. __func__);
  40. case 33: /* Can only apply 3.3V to the CF slot. */
  41. mask = ASSABET_BCR_CF_PWR;
  42. break;
  43. default:
  44. printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__,
  45. state->Vcc);
  46. return -1;
  47. }
  48. /* Silently ignore Vpp, speaker enable. */
  49. if (state->flags & SS_RESET)
  50. mask |= ASSABET_BCR_CF_RST;
  51. if (!(state->flags & SS_OUTPUT_ENA))
  52. mask |= ASSABET_BCR_CF_BUS_OFF;
  53. ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR |
  54. ASSABET_BCR_CF_BUS_OFF, mask);
  55. return 0;
  56. }
  57. /*
  58. * Disable card status IRQs on suspend.
  59. */
  60. static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
  61. {
  62. /*
  63. * Tristate the CF bus signals. Also assert CF
  64. * reset as per user guide page 4-11.
  65. */
  66. ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST);
  67. }
  68. static struct pcmcia_low_level assabet_pcmcia_ops = {
  69. .owner = THIS_MODULE,
  70. .hw_init = assabet_pcmcia_hw_init,
  71. .socket_state = soc_common_cf_socket_state,
  72. .configure_socket = assabet_pcmcia_configure_socket,
  73. .socket_suspend = assabet_pcmcia_socket_suspend,
  74. };
  75. int pcmcia_assabet_init(struct device *dev)
  76. {
  77. int ret = -ENODEV;
  78. if (machine_is_assabet() && !machine_has_neponset())
  79. ret = sa11xx_drv_pcmcia_probe(dev, &assabet_pcmcia_ops, 1, 1);
  80. return ret;
  81. }