linux/arch/sh/boards/mach-microdev/fdc37c93xapm.c
<<
>>
Prefs
   1/*
   2 *
   3 * Setup for the SMSC FDC37C93xAPM
   4 *
   5 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
   6 * Copyright (C) 2003, 2004 SuperH, Inc.
   7 * Copyright (C) 2004, 2005 Paul Mundt
   8 *
   9 * SuperH SH4-202 MicroDev board support.
  10 *
  11 * May be copied or modified under the terms of the GNU General Public
  12 * License.  See linux/COPYING for more information.
  13 */
  14#include <linux/init.h>
  15#include <linux/ioport.h>
  16#include <linux/io.h>
  17#include <linux/err.h>
  18#include <mach/microdev.h>
  19
  20#define SMSC_CONFIG_PORT_ADDR    (0x3F0)
  21#define SMSC_INDEX_PORT_ADDR     SMSC_CONFIG_PORT_ADDR
  22#define SMSC_DATA_PORT_ADDR      (SMSC_INDEX_PORT_ADDR + 1)
  23
  24#define SMSC_ENTER_CONFIG_KEY    0x55
  25#define SMSC_EXIT_CONFIG_KEY     0xaa
  26
  27#define SMCS_LOGICAL_DEV_INDEX   0x07   /* Logical Device Number */
  28#define SMSC_DEVICE_ID_INDEX     0x20   /* Device ID */
  29#define SMSC_DEVICE_REV_INDEX    0x21   /* Device Revision */
  30#define SMSC_ACTIVATE_INDEX      0x30   /* Activate */
  31#define SMSC_PRIMARY_BASE_INDEX  0x60   /* Primary Base Address */
  32#define SMSC_SECONDARY_BASE_INDEX 0x62  /* Secondary Base Address */
  33#define SMSC_PRIMARY_INT_INDEX   0x70   /* Primary Interrupt Select */
  34#define SMSC_SECONDARY_INT_INDEX 0x72   /* Secondary Interrupt Select */
  35#define SMSC_HDCS0_INDEX         0xf0   /* HDCS0 Address Decoder */
  36#define SMSC_HDCS1_INDEX         0xf1   /* HDCS1 Address Decoder */
  37
  38#define SMSC_IDE1_DEVICE        1       /* IDE #1 logical device */
  39#define SMSC_IDE2_DEVICE        2       /* IDE #2 logical device */
  40#define SMSC_PARALLEL_DEVICE    3       /* Parallel Port logical device */
  41#define SMSC_SERIAL1_DEVICE     4       /* Serial #1 logical device */
  42#define SMSC_SERIAL2_DEVICE     5       /* Serial #2 logical device */
  43#define SMSC_KEYBOARD_DEVICE    7       /* Keyboard logical device */
  44#define SMSC_CONFIG_REGISTERS   8       /* Configuration Registers (Aux I/O) */
  45
  46#define SMSC_READ_INDEXED(index) ({ \
  47        outb((index), SMSC_INDEX_PORT_ADDR); \
  48        inb(SMSC_DATA_PORT_ADDR); })
  49#define SMSC_WRITE_INDEXED(val, index) ({ \
  50        outb((index), SMSC_INDEX_PORT_ADDR); \
  51        outb((val),   SMSC_DATA_PORT_ADDR); })
  52
  53#define IDE1_PRIMARY_BASE       0x01f0  /* Task File Registe base for IDE #1 */
  54#define IDE1_SECONDARY_BASE     0x03f6  /* Miscellaneous AT registers for IDE #1 */
  55#define IDE2_PRIMARY_BASE       0x0170  /* Task File Registe base for IDE #2 */
  56#define IDE2_SECONDARY_BASE     0x0376  /* Miscellaneous AT registers for IDE #2 */
  57
  58#define SERIAL1_PRIMARY_BASE    0x03f8
  59#define SERIAL2_PRIMARY_BASE    0x02f8
  60
  61#define MSB(x)          ( (x) >> 8 )
  62#define LSB(x)          ( (x) & 0xff )
  63
  64        /* General-Purpose base address on CPU-board FPGA */
  65#define MICRODEV_FPGA_GP_BASE           0xa6100000ul
  66
  67static int __init smsc_superio_setup(void)
  68{
  69
  70        unsigned char devid, devrev;
  71
  72                /* Initially the chip is in run state */
  73                /* Put it into configuration state */
  74        outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
  75
  76                /* Read device ID info */
  77        devid  = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
  78        devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
  79
  80        if ((devid == 0x30) && (devrev == 0x01))
  81                printk("SMSC FDC37C93xAPM SuperIO device detected\n");
  82        else
  83                return -ENODEV;
  84
  85                /* Select the keyboard device */
  86        SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
  87                /* enable it */
  88        SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
  89                /* enable the interrupts */
  90        SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
  91        SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
  92
  93                /* Select the Serial #1 device */
  94        SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
  95                /* enable it */
  96        SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
  97                /* program with port addresses */
  98        SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
  99        SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
 100        SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
 101                /* enable the interrupts */
 102        SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
 103
 104                /* Select the Serial #2 device */
 105        SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
 106                /* enable it */
 107        SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
 108                /* program with port addresses */
 109        SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
 110        SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
 111        SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
 112                /* enable the interrupts */
 113        SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
 114
 115                /* Select the IDE#1 device */
 116        SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
 117                /* enable it */
 118        SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
 119                /* program with port addresses */
 120        SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
 121        SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
 122        SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
 123        SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
 124        SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
 125        SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
 126                /* select the interrupt */
 127        SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
 128
 129                /* Select the IDE#2 device */
 130        SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
 131                /* enable it */
 132        SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
 133                /* program with port addresses */
 134        SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
 135        SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
 136        SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
 137        SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
 138                /* select the interrupt */
 139        SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
 140
 141                /* Select the configuration registers */
 142        SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
 143                /* enable the appropriate GPIO pins for IDE functionality:
 144                 * bit[0]   In/Out              1==input;  0==output
 145                 * bit[1]   Polarity            1==invert; 0==no invert
 146                 * bit[2]   Int Enb #1          1==Enable Combined IRQ #1; 0==disable
 147                 * bit[3:4] Function Select     00==original; 01==Alternate Function #1
 148                 */
 149        SMSC_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */
 150        SMSC_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
 151        SMSC_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
 152        SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
 153        SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */
 154
 155                /* Exit the configuration state */
 156        outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
 157
 158        return 0;
 159}
 160device_initcall(smsc_superio_setup);
 161