sa1100_badge4.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/drivers/pcmcia/sa1100_badge4.c
  3.  *
  4.  * BadgePAD 4 PCMCIA specific routines
  5.  *
  6.  *   Christopher Hoover <ch@hpl.hp.com>
  7.  *
  8.  * Copyright (C) 2002 Hewlett-Packard Company
  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 <linux/kernel.h>
  16. #include <linux/sched.h>
  17. #include <linux/init.h>
  18. #include <asm/hardware.h>
  19. #include <asm/arch/badge4.h>
  20. #include <asm/hardware/sa1111.h>
  21. #include "sa1100_generic.h"
  22. #include "sa1111_generic.h"
  23. /*
  24.  * BadgePAD 4 Details
  25.  *
  26.  * PCM Vcc:
  27.  *
  28.  *  PCM Vcc on BadgePAD 4 can be jumpered for 3.3V (short pins 1 and 3
  29.  *  on JP6) or 5V (short pins 3 and 5 on JP6).  N.B., 5V supply rail
  30.  *  is enabled by the SA-1110's BADGE4_GPIO_PCMEN5V (GPIO 24).
  31.  *
  32.  * PCM Vpp:
  33.  *
  34.  *  PCM Vpp on BadgePAD 4 can be jumpered for 12V (short pins 2 and 4
  35.  *  on JP6) or tied to PCM Vcc (short pins 4 and 6 on JP6).  N.B., 12V
  36.  *  operation requires that the power supply actually supply 12V.
  37.  *
  38.  * CF Vcc:
  39.  *
  40.  *  CF Vcc on BadgePAD 4 can be jumpered either for 3.3V (short pins 1
  41.  *  and 2 on JP10) or 5V (short pins 2 and 3 on JP10).  The note above
  42.  *  about the 5V supply rail applies.
  43.  *
  44.  * There's no way programmatically to determine how a given board is
  45.  * jumpered.  This code assumes a default jumpering: 5V PCM Vcc (pins
  46.  * 3 and 5 shorted) and PCM Vpp = PCM Vcc (pins 4 and 6 shorted) and
  47.  * no jumpering for CF Vcc.  If this isn't correct, Override these
  48.  * defaults with a pcmv setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf
  49.  * vcc>.  E.g. pcmv=33,120,50 indicates 3.3V PCM Vcc, 12.0V PCM Vpp,
  50.  * and 5.0V CF Vcc.
  51.  *
  52.  */
  53. static int badge4_pcmvcc = 50;
  54. static int badge4_pcmvpp = 50;
  55. static int badge4_cfvcc = 0;
  56. static int badge4_pcmcia_init(struct pcmcia_init *init)
  57. {
  58. printk(KERN_INFO __FUNCTION__
  59.        ": badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%dn",
  60.        badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
  61. return sa1111_pcmcia_init(init);
  62. }
  63. static int badge4_pcmcia_shutdown(void)
  64. {
  65. int rc = sa1111_pcmcia_shutdown();
  66. /* be sure to disable 5V use */
  67. badge4_set_5V(BADGE4_5V_PCMCIA_SOCK0, 0);
  68. badge4_set_5V(BADGE4_5V_PCMCIA_SOCK1, 0);
  69. return rc;
  70. }
  71. static void complain_about_jumpering(const char *whom,
  72.      const char *supply,
  73.      int given, int wanted)
  74. {
  75. printk(KERN_ERR
  76.  "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation"
  77.  "; re-jumper the board and/or use pcmv=xx,xx,xxn",
  78.        whom, supply,
  79.        wanted / 10, wanted % 10,
  80.        supply,
  81.        given / 10, given % 10);
  82. }
  83. static unsigned badge4_need_5V_bitmap = 0;
  84. static int
  85. badge4_pcmcia_configure_socket(const struct pcmcia_configure *conf)
  86. {
  87. int ret;
  88. switch (conf->sock) {
  89. case 0:
  90. if ((conf->vcc != 0) &&
  91.     (conf->vcc != badge4_pcmvcc)) {
  92. complain_about_jumpering(__FUNCTION__, "pcmvcc",
  93.  badge4_pcmvcc, conf->vcc);
  94. return -1;
  95. }
  96. if ((conf->vpp != 0) &&
  97.     (conf->vpp != badge4_pcmvpp)) {
  98. complain_about_jumpering(__FUNCTION__, "pcmvpp",
  99.  badge4_pcmvpp, conf->vpp);
  100. return -1;
  101. }
  102. break;
  103. case 1:
  104. if ((conf->vcc != 0) &&
  105.     (conf->vcc != badge4_cfvcc)) {
  106. complain_about_jumpering(__FUNCTION__, "cfvcc",
  107.  badge4_cfvcc, conf->vcc);
  108. return -1;
  109. }
  110. break;
  111. default:
  112. return -1;
  113. }
  114. ret = sa1111_pcmcia_configure_socket(conf);
  115. if (ret == 0) {
  116. unsigned long flags;
  117. int need5V;
  118. local_irq_save(flags);
  119. need5V = ((conf->vcc == 50) || (conf->vpp == 50));
  120. badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(conf->sock), need5V);
  121. local_irq_restore(flags);
  122. }
  123. return 0;
  124. }
  125. struct pcmcia_low_level badge4_pcmcia_ops = {
  126. init: badge4_pcmcia_init,
  127. shutdown: badge4_pcmcia_shutdown,
  128. socket_state: sa1111_pcmcia_socket_state,
  129. get_irq_info: sa1111_pcmcia_get_irq_info,
  130. configure_socket: badge4_pcmcia_configure_socket,
  131. socket_init: sa1111_pcmcia_socket_init,
  132. socket_suspend: sa1111_pcmcia_socket_suspend,
  133. };
  134. static int __init pcmv_setup(char *s)
  135. {
  136. int v[4];
  137. s = get_options(s, ARRAY_SIZE(v), v);
  138. if (v[0] >= 1) badge4_pcmvcc = v[1];
  139. if (v[0] >= 2) badge4_pcmvpp = v[2];
  140. if (v[0] >= 3) badge4_cfvcc = v[3];
  141. return 1;
  142. }
  143. __setup("pcmv=", pcmv_setup);