pxa2xx_mainstone.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * linux/drivers/pcmcia/pxa2xx_mainstone.c
  4. *
  5. * Mainstone PCMCIA specific routines.
  6. *
  7. * Created: May 12, 2004
  8. * Author: Nicolas Pitre
  9. * Copyright: MontaVista Software Inc.
  10. */
  11. #include <linux/gpio/consumer.h>
  12. #include <linux/module.h>
  13. #include <linux/init.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/kernel.h>
  16. #include <linux/errno.h>
  17. #include <linux/platform_device.h>
  18. #include <pcmcia/ss.h>
  19. #include <asm/mach-types.h>
  20. #include "soc_common.h"
  21. #include "max1600.h"
  22. static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  23. {
  24. struct device *dev = skt->socket.dev.parent;
  25. struct max1600 *m;
  26. int ret;
  27. skt->stat[SOC_STAT_CD].name = skt->nr ? "bdetect" : "adetect";
  28. skt->stat[SOC_STAT_BVD1].name = skt->nr ? "bbvd1" : "abvd1";
  29. skt->stat[SOC_STAT_BVD2].name = skt->nr ? "bbvd2" : "abvd2";
  30. skt->stat[SOC_STAT_RDY].name = skt->nr ? "bready" : "aready";
  31. skt->stat[SOC_STAT_VS1].name = skt->nr ? "bvs1" : "avs1";
  32. skt->stat[SOC_STAT_VS2].name = skt->nr ? "bvs2" : "avs2";
  33. skt->gpio_reset = devm_gpiod_get(dev, skt->nr ? "breset" : "areset",
  34. GPIOD_OUT_HIGH);
  35. if (IS_ERR(skt->gpio_reset))
  36. return PTR_ERR(skt->gpio_reset);
  37. ret = max1600_init(dev, &m, skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
  38. MAX1600_CODE_HIGH);
  39. if (ret)
  40. return ret;
  41. skt->driver_data = m;
  42. return soc_pcmcia_request_gpiods(skt);
  43. }
  44. static unsigned int mst_pcmcia_bvd1_status[2];
  45. static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
  46. struct pcmcia_state *state)
  47. {
  48. unsigned int flip = mst_pcmcia_bvd1_status[skt->nr] ^ state->bvd1;
  49. /*
  50. * Workaround for STSCHG which can't be deasserted:
  51. * We therefore disable/enable corresponding IRQs
  52. * as needed to avoid IRQ locks.
  53. */
  54. if (flip) {
  55. mst_pcmcia_bvd1_status[skt->nr] = state->bvd1;
  56. if (state->bvd1)
  57. enable_irq(skt->stat[SOC_STAT_BVD1].irq);
  58. else
  59. disable_irq(skt->stat[SOC_STAT_BVD2].irq);
  60. }
  61. }
  62. static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  63. const socket_state_t *state)
  64. {
  65. return max1600_configure(skt->driver_data, state->Vcc, state->Vpp);
  66. }
  67. static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
  68. .owner = THIS_MODULE,
  69. .hw_init = mst_pcmcia_hw_init,
  70. .socket_state = mst_pcmcia_socket_state,
  71. .configure_socket = mst_pcmcia_configure_socket,
  72. .nr = 2,
  73. };
  74. static struct platform_device *mst_pcmcia_device;
  75. static int __init mst_pcmcia_init(void)
  76. {
  77. int ret;
  78. if (!machine_is_mainstone())
  79. return -ENODEV;
  80. mst_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
  81. if (!mst_pcmcia_device)
  82. return -ENOMEM;
  83. ret = platform_device_add_data(mst_pcmcia_device, &mst_pcmcia_ops,
  84. sizeof(mst_pcmcia_ops));
  85. if (ret == 0)
  86. ret = platform_device_add(mst_pcmcia_device);
  87. if (ret)
  88. platform_device_put(mst_pcmcia_device);
  89. return ret;
  90. }
  91. static void __exit mst_pcmcia_exit(void)
  92. {
  93. platform_device_unregister(mst_pcmcia_device);
  94. }
  95. fs_initcall(mst_pcmcia_init);
  96. module_exit(mst_pcmcia_exit);
  97. MODULE_LICENSE("GPL");
  98. MODULE_ALIAS("platform:pxa2xx-pcmcia");