0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/kernel.h>
0013 #include <linux/device.h>
0014 #include <linux/errno.h>
0015 #include <linux/init.h>
0016
0017 #include <mach/hardware.h>
0018 #include <asm/mach-types.h>
0019 #include <mach/badge4.h>
0020 #include <asm/hardware/sa1111.h>
0021
0022 #include "sa1111_generic.h"
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 static int badge4_pcmvcc = 50;
0056 static int badge4_pcmvpp = 50;
0057 static int badge4_cfvcc = 33;
0058
0059 static void complain_about_jumpering(const char *whom,
0060 const char *supply,
0061 int given, int wanted)
0062 {
0063 printk(KERN_ERR
0064 "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation"
0065 "; re-jumper the board and/or use pcmv=xx,xx,xx\n",
0066 whom, supply,
0067 wanted / 10, wanted % 10,
0068 supply,
0069 given / 10, given % 10);
0070 }
0071
0072 static int
0073 badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
0074 {
0075 int ret;
0076
0077 switch (skt->nr) {
0078 case 0:
0079 if ((state->Vcc != 0) &&
0080 (state->Vcc != badge4_pcmvcc)) {
0081 complain_about_jumpering(__func__, "pcmvcc",
0082 badge4_pcmvcc, state->Vcc);
0083
0084
0085 }
0086 if ((state->Vpp != 0) &&
0087 (state->Vpp != badge4_pcmvpp)) {
0088 complain_about_jumpering(__func__, "pcmvpp",
0089 badge4_pcmvpp, state->Vpp);
0090 return -1;
0091 }
0092 break;
0093
0094 case 1:
0095 if ((state->Vcc != 0) &&
0096 (state->Vcc != badge4_cfvcc)) {
0097 complain_about_jumpering(__func__, "cfvcc",
0098 badge4_cfvcc, state->Vcc);
0099 return -1;
0100 }
0101 break;
0102
0103 default:
0104 return -1;
0105 }
0106
0107 ret = sa1111_pcmcia_configure_socket(skt, state);
0108 if (ret == 0) {
0109 unsigned long flags;
0110 int need5V;
0111
0112 local_irq_save(flags);
0113
0114 need5V = ((state->Vcc == 50) || (state->Vpp == 50));
0115
0116 badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(skt->nr), need5V);
0117
0118 local_irq_restore(flags);
0119 }
0120
0121 return ret;
0122 }
0123
0124 static struct pcmcia_low_level badge4_pcmcia_ops = {
0125 .owner = THIS_MODULE,
0126 .configure_socket = badge4_pcmcia_configure_socket,
0127 .first = 0,
0128 .nr = 2,
0129 };
0130
0131 int pcmcia_badge4_init(struct sa1111_dev *dev)
0132 {
0133 printk(KERN_INFO
0134 "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n",
0135 __func__,
0136 badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
0137
0138 sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops);
0139 return sa1111_pcmcia_add(dev, &badge4_pcmcia_ops,
0140 sa11xx_drv_pcmcia_add_one);
0141 }
0142
0143 #ifndef MODULE
0144 static int __init pcmv_setup(char *s)
0145 {
0146 int v[4];
0147
0148 s = get_options(s, ARRAY_SIZE(v), v);
0149
0150 if (v[0] >= 1) badge4_pcmvcc = v[1];
0151 if (v[0] >= 2) badge4_pcmvpp = v[2];
0152 if (v[0] >= 3) badge4_cfvcc = v[3];
0153
0154 return 1;
0155 }
0156
0157 __setup("pcmv=", pcmv_setup);
0158 #endif