linux/drivers/pcmcia/sa1111_lubbock.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * linux/drivers/pcmcia/pxa2xx_lubbock.c
   4 *
   5 * Author:      George Davis
   6 * Created:     Jan 10, 2002
   7 * Copyright:   MontaVista Software Inc.
   8 *
   9 * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c
  10 *
  11 * Lubbock PCMCIA specific routines.
  12 */
  13#include <linux/module.h>
  14#include <linux/kernel.h>
  15#include <linux/device.h>
  16#include <linux/errno.h>
  17#include <linux/init.h>
  18#include <linux/delay.h>
  19
  20#include <mach/hardware.h>
  21#include <asm/hardware/sa1111.h>
  22#include <asm/mach-types.h>
  23
  24#include "sa1111_generic.h"
  25#include "max1600.h"
  26
  27static int lubbock_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
  28{
  29        struct max1600 *m;
  30        int ret;
  31
  32        ret = max1600_init(skt->socket.dev.parent, &m,
  33                           skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
  34                           MAX1600_CODE_HIGH);
  35        if (ret == 0)
  36                skt->driver_data = m;
  37
  38        return ret;
  39}
  40
  41static int
  42lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  43                                const socket_state_t *state)
  44{
  45        struct max1600 *m = skt->driver_data;
  46        int ret = 0;
  47
  48        /* Lubbock uses the Maxim MAX1602, with the following connections:
  49         *
  50         * Socket 0 (PCMCIA):
  51         *      MAX1602 Lubbock         Register
  52         *      Pin     Signal
  53         *      -----   -------         ----------------------
  54         *      A0VPP   S0_PWR0         SA-1111 GPIO A<0>
  55         *      A1VPP   S0_PWR1         SA-1111 GPIO A<1>
  56         *      A0VCC   S0_PWR2         SA-1111 GPIO A<2>
  57         *      A1VCC   S0_PWR3         SA-1111 GPIO A<3>
  58         *      VX      VCC
  59         *      VY      +3.3V
  60         *      12IN    +12V
  61         *      CODE    +3.3V           Cirrus  Code, CODE = High (VY)
  62         *
  63         * Socket 1 (CF):
  64         *      MAX1602 Lubbock         Register
  65         *      Pin     Signal
  66         *      -----   -------         ----------------------
  67         *      A0VPP   GND             VPP is not connected
  68         *      A1VPP   GND             VPP is not connected
  69         *      A0VCC   S1_PWR0         MISC_WR<14>
  70         *      A1VCC   S1_PWR1         MISC_WR<15>
  71         *      VX      VCC
  72         *      VY      +3.3V
  73         *      12IN    GND             VPP is not connected
  74         *      CODE    +3.3V           Cirrus  Code, CODE = High (VY)
  75         *
  76         */
  77
  78 again:
  79        switch (skt->nr) {
  80        case 0:
  81        case 1:
  82                break;
  83
  84        default:
  85                ret = -1;
  86        }
  87
  88        if (ret == 0)
  89                ret = sa1111_pcmcia_configure_socket(skt, state);
  90        if (ret == 0)
  91                ret = max1600_configure(m, state->Vcc, state->Vpp);
  92
  93#if 1
  94        if (ret == 0 && state->Vcc == 33) {
  95                struct pcmcia_state new_state;
  96
  97                /*
  98                 * HACK ALERT:
  99                 * We can't sense the voltage properly on Lubbock before
 100                 * actually applying some power to the socket (catch 22).
 101                 * Resense the socket Voltage Sense pins after applying
 102                 * socket power.
 103                 *
 104                 * Note: It takes about 2.5ms for the MAX1602 VCC output
 105                 * to rise.
 106                 */
 107                mdelay(3);
 108
 109                sa1111_pcmcia_socket_state(skt, &new_state);
 110
 111                if (!new_state.vs_3v && !new_state.vs_Xv) {
 112                        /*
 113                         * Switch to 5V,  Configure socket with 5V voltage
 114                         */
 115                        max1600_configure(m, 0, 0);
 116
 117                        /*
 118                         * It takes about 100ms to turn off Vcc.
 119                         */
 120                        mdelay(100);
 121
 122                        /*
 123                         * We need to hack around the const qualifier as
 124                         * well to keep this ugly workaround localized and
 125                         * not force it to the rest of the code. Barf bags
 126                         * available in the seat pocket in front of you!
 127                         */
 128                        ((socket_state_t *)state)->Vcc = 50;
 129                        ((socket_state_t *)state)->Vpp = 50;
 130                        goto again;
 131                }
 132        }
 133#endif
 134
 135        return ret;
 136}
 137
 138static struct pcmcia_low_level lubbock_pcmcia_ops = {
 139        .owner                  = THIS_MODULE,
 140        .hw_init                = lubbock_pcmcia_hw_init,
 141        .configure_socket       = lubbock_pcmcia_configure_socket,
 142        .first                  = 0,
 143        .nr                     = 2,
 144};
 145
 146#include "pxa2xx_base.h"
 147
 148int pcmcia_lubbock_init(struct sa1111_dev *sadev)
 149{
 150        pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
 151        pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops);
 152        return sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
 153                                 pxa2xx_drv_pcmcia_add_one);
 154}
 155
 156MODULE_LICENSE("GPL");
 157