sa1111_badge4.c (3838B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/drivers/pcmcia/sa1100_badge4.c 4 * 5 * BadgePAD 4 PCMCIA specific routines 6 * 7 * Christopher Hoover <ch@hpl.hp.com> 8 * 9 * Copyright (C) 2002 Hewlett-Packard Company 10 */ 11#include <linux/module.h> 12#include <linux/kernel.h> 13#include <linux/device.h> 14#include <linux/errno.h> 15#include <linux/init.h> 16 17#include <mach/hardware.h> 18#include <asm/mach-types.h> 19#include <mach/badge4.h> 20#include <asm/hardware/sa1111.h> 21 22#include "sa1111_generic.h" 23 24/* 25 * BadgePAD 4 Details 26 * 27 * PCM Vcc: 28 * 29 * PCM Vcc on BadgePAD 4 can be jumpered for 3v3 (short pins 1 and 3 30 * on JP6) or 5v0 (short pins 3 and 5 on JP6). 31 * 32 * PCM Vpp: 33 * 34 * PCM Vpp on BadgePAD 4 can be jumpered for 12v0 (short pins 4 and 6 35 * on JP6) or tied to PCM Vcc (short pins 2 and 4 on JP6). N.B., 36 * 12v0 operation requires that the power supply actually supply 12v0 37 * via pin 7 of JP7. 38 * 39 * CF Vcc: 40 * 41 * CF Vcc on BadgePAD 4 can be jumpered either for 3v3 (short pins 1 42 * and 2 on JP10) or 5v0 (short pins 2 and 3 on JP10). 43 * 44 * Unfortunately there's no way programmatically to determine how a 45 * given board is jumpered. This code assumes a default jumpering 46 * as described below. 47 * 48 * If the defaults aren't correct, you may override them with a pcmv 49 * setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf vcc>. The units are 50 * tenths of volts; e.g. pcmv=33,120,50 indicates 3v3 PCM Vcc, 12v0 51 * PCM Vpp, and 5v0 CF Vcc. 52 * 53 */ 54 55static int badge4_pcmvcc = 50; /* pins 3 and 5 jumpered on JP6 */ 56static int badge4_pcmvpp = 50; /* pins 2 and 4 jumpered on JP6 */ 57static int badge4_cfvcc = 33; /* pins 1 and 2 jumpered on JP10 */ 58 59static void complain_about_jumpering(const char *whom, 60 const char *supply, 61 int given, int wanted) 62{ 63 printk(KERN_ERR 64 "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation" 65 "; re-jumper the board and/or use pcmv=xx,xx,xx\n", 66 whom, supply, 67 wanted / 10, wanted % 10, 68 supply, 69 given / 10, given % 10); 70} 71 72static int 73badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) 74{ 75 int ret; 76 77 switch (skt->nr) { 78 case 0: 79 if ((state->Vcc != 0) && 80 (state->Vcc != badge4_pcmvcc)) { 81 complain_about_jumpering(__func__, "pcmvcc", 82 badge4_pcmvcc, state->Vcc); 83 // Apply power regardless of the jumpering. 84 // return -1; 85 } 86 if ((state->Vpp != 0) && 87 (state->Vpp != badge4_pcmvpp)) { 88 complain_about_jumpering(__func__, "pcmvpp", 89 badge4_pcmvpp, state->Vpp); 90 return -1; 91 } 92 break; 93 94 case 1: 95 if ((state->Vcc != 0) && 96 (state->Vcc != badge4_cfvcc)) { 97 complain_about_jumpering(__func__, "cfvcc", 98 badge4_cfvcc, state->Vcc); 99 return -1; 100 } 101 break; 102 103 default: 104 return -1; 105 } 106 107 ret = sa1111_pcmcia_configure_socket(skt, state); 108 if (ret == 0) { 109 unsigned long flags; 110 int need5V; 111 112 local_irq_save(flags); 113 114 need5V = ((state->Vcc == 50) || (state->Vpp == 50)); 115 116 badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(skt->nr), need5V); 117 118 local_irq_restore(flags); 119 } 120 121 return ret; 122} 123 124static struct pcmcia_low_level badge4_pcmcia_ops = { 125 .owner = THIS_MODULE, 126 .configure_socket = badge4_pcmcia_configure_socket, 127 .first = 0, 128 .nr = 2, 129}; 130 131int pcmcia_badge4_init(struct sa1111_dev *dev) 132{ 133 printk(KERN_INFO 134 "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n", 135 __func__, 136 badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); 137 138 sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); 139 return sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, 140 sa11xx_drv_pcmcia_add_one); 141} 142 143#ifndef MODULE 144static int __init pcmv_setup(char *s) 145{ 146 int v[4]; 147 148 s = get_options(s, ARRAY_SIZE(v), v); 149 150 if (v[0] >= 1) badge4_pcmvcc = v[1]; 151 if (v[0] >= 2) badge4_pcmvpp = v[2]; 152 if (v[0] >= 3) badge4_cfvcc = v[3]; 153 154 return 1; 155} 156 157__setup("pcmv=", pcmv_setup); 158#endif