18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/drivers/pcmcia/sa1100_badge4.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * BadgePAD 4 PCMCIA specific routines 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Christopher Hoover <ch@hpl.hp.com> 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Copyright (C) 2002 Hewlett-Packard Company 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/device.h> 148c2ecf20Sopenharmony_ci#include <linux/errno.h> 158c2ecf20Sopenharmony_ci#include <linux/init.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <mach/hardware.h> 188c2ecf20Sopenharmony_ci#include <asm/mach-types.h> 198c2ecf20Sopenharmony_ci#include <mach/badge4.h> 208c2ecf20Sopenharmony_ci#include <asm/hardware/sa1111.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include "sa1111_generic.h" 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* 258c2ecf20Sopenharmony_ci * BadgePAD 4 Details 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * PCM Vcc: 288c2ecf20Sopenharmony_ci * 298c2ecf20Sopenharmony_ci * PCM Vcc on BadgePAD 4 can be jumpered for 3v3 (short pins 1 and 3 308c2ecf20Sopenharmony_ci * on JP6) or 5v0 (short pins 3 and 5 on JP6). 318c2ecf20Sopenharmony_ci * 328c2ecf20Sopenharmony_ci * PCM Vpp: 338c2ecf20Sopenharmony_ci * 348c2ecf20Sopenharmony_ci * PCM Vpp on BadgePAD 4 can be jumpered for 12v0 (short pins 4 and 6 358c2ecf20Sopenharmony_ci * on JP6) or tied to PCM Vcc (short pins 2 and 4 on JP6). N.B., 368c2ecf20Sopenharmony_ci * 12v0 operation requires that the power supply actually supply 12v0 378c2ecf20Sopenharmony_ci * via pin 7 of JP7. 388c2ecf20Sopenharmony_ci * 398c2ecf20Sopenharmony_ci * CF Vcc: 408c2ecf20Sopenharmony_ci * 418c2ecf20Sopenharmony_ci * CF Vcc on BadgePAD 4 can be jumpered either for 3v3 (short pins 1 428c2ecf20Sopenharmony_ci * and 2 on JP10) or 5v0 (short pins 2 and 3 on JP10). 438c2ecf20Sopenharmony_ci * 448c2ecf20Sopenharmony_ci * Unfortunately there's no way programmatically to determine how a 458c2ecf20Sopenharmony_ci * given board is jumpered. This code assumes a default jumpering 468c2ecf20Sopenharmony_ci * as described below. 478c2ecf20Sopenharmony_ci * 488c2ecf20Sopenharmony_ci * If the defaults aren't correct, you may override them with a pcmv 498c2ecf20Sopenharmony_ci * setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf vcc>. The units are 508c2ecf20Sopenharmony_ci * tenths of volts; e.g. pcmv=33,120,50 indicates 3v3 PCM Vcc, 12v0 518c2ecf20Sopenharmony_ci * PCM Vpp, and 5v0 CF Vcc. 528c2ecf20Sopenharmony_ci * 538c2ecf20Sopenharmony_ci */ 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic int badge4_pcmvcc = 50; /* pins 3 and 5 jumpered on JP6 */ 568c2ecf20Sopenharmony_cistatic int badge4_pcmvpp = 50; /* pins 2 and 4 jumpered on JP6 */ 578c2ecf20Sopenharmony_cistatic int badge4_cfvcc = 33; /* pins 1 and 2 jumpered on JP10 */ 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic void complain_about_jumpering(const char *whom, 608c2ecf20Sopenharmony_ci const char *supply, 618c2ecf20Sopenharmony_ci int given, int wanted) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci printk(KERN_ERR 648c2ecf20Sopenharmony_ci "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation" 658c2ecf20Sopenharmony_ci "; re-jumper the board and/or use pcmv=xx,xx,xx\n", 668c2ecf20Sopenharmony_ci whom, supply, 678c2ecf20Sopenharmony_ci wanted / 10, wanted % 10, 688c2ecf20Sopenharmony_ci supply, 698c2ecf20Sopenharmony_ci given / 10, given % 10); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic int 738c2ecf20Sopenharmony_cibadge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci int ret; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci switch (skt->nr) { 788c2ecf20Sopenharmony_ci case 0: 798c2ecf20Sopenharmony_ci if ((state->Vcc != 0) && 808c2ecf20Sopenharmony_ci (state->Vcc != badge4_pcmvcc)) { 818c2ecf20Sopenharmony_ci complain_about_jumpering(__func__, "pcmvcc", 828c2ecf20Sopenharmony_ci badge4_pcmvcc, state->Vcc); 838c2ecf20Sopenharmony_ci // Apply power regardless of the jumpering. 848c2ecf20Sopenharmony_ci // return -1; 858c2ecf20Sopenharmony_ci } 868c2ecf20Sopenharmony_ci if ((state->Vpp != 0) && 878c2ecf20Sopenharmony_ci (state->Vpp != badge4_pcmvpp)) { 888c2ecf20Sopenharmony_ci complain_about_jumpering(__func__, "pcmvpp", 898c2ecf20Sopenharmony_ci badge4_pcmvpp, state->Vpp); 908c2ecf20Sopenharmony_ci return -1; 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci break; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci case 1: 958c2ecf20Sopenharmony_ci if ((state->Vcc != 0) && 968c2ecf20Sopenharmony_ci (state->Vcc != badge4_cfvcc)) { 978c2ecf20Sopenharmony_ci complain_about_jumpering(__func__, "cfvcc", 988c2ecf20Sopenharmony_ci badge4_cfvcc, state->Vcc); 998c2ecf20Sopenharmony_ci return -1; 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci break; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci default: 1048c2ecf20Sopenharmony_ci return -1; 1058c2ecf20Sopenharmony_ci } 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci ret = sa1111_pcmcia_configure_socket(skt, state); 1088c2ecf20Sopenharmony_ci if (ret == 0) { 1098c2ecf20Sopenharmony_ci unsigned long flags; 1108c2ecf20Sopenharmony_ci int need5V; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci local_irq_save(flags); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci need5V = ((state->Vcc == 50) || (state->Vpp == 50)); 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(skt->nr), need5V); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci local_irq_restore(flags); 1198c2ecf20Sopenharmony_ci } 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci return ret; 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic struct pcmcia_low_level badge4_pcmcia_ops = { 1258c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 1268c2ecf20Sopenharmony_ci .configure_socket = badge4_pcmcia_configure_socket, 1278c2ecf20Sopenharmony_ci .first = 0, 1288c2ecf20Sopenharmony_ci .nr = 2, 1298c2ecf20Sopenharmony_ci}; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ciint pcmcia_badge4_init(struct sa1111_dev *dev) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci printk(KERN_INFO 1348c2ecf20Sopenharmony_ci "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n", 1358c2ecf20Sopenharmony_ci __func__, 1368c2ecf20Sopenharmony_ci badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); 1398c2ecf20Sopenharmony_ci return sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, 1408c2ecf20Sopenharmony_ci sa11xx_drv_pcmcia_add_one); 1418c2ecf20Sopenharmony_ci} 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci#ifndef MODULE 1448c2ecf20Sopenharmony_cistatic int __init pcmv_setup(char *s) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci int v[4]; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci s = get_options(s, ARRAY_SIZE(v), v); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci if (v[0] >= 1) badge4_pcmvcc = v[1]; 1518c2ecf20Sopenharmony_ci if (v[0] >= 2) badge4_pcmvpp = v[2]; 1528c2ecf20Sopenharmony_ci if (v[0] >= 3) badge4_cfvcc = v[3]; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci return 1; 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci__setup("pcmv=", pcmv_setup); 1588c2ecf20Sopenharmony_ci#endif 159