uboot/drivers/misc/ali512x.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/*
  25 * Based on sc520cdp.c from rolo 1.6:
  26 *----------------------------------------------------------------------
  27 * (C) Copyright 2000
  28 * Sysgo Real-Time Solutions GmbH
  29 * Klein-Winternheim, Germany
  30 *----------------------------------------------------------------------
  31 */
  32
  33#include <config.h>
  34
  35#include <common.h>
  36#include <asm/io.h>
  37#include <ali512x.h>
  38
  39
  40/* ALI M5123 Logical device numbers:
  41 * 0 FDC
  42 * 1 unused?
  43 * 2 unused?
  44 * 3 lpt
  45 * 4 UART1
  46 * 5 UART2
  47 * 6 RTC
  48 * 7 mouse/kbd
  49 * 8 CIO
  50 */
  51
  52/*
  53 ************************************************************
  54 *  Some access primitives for the ALi chip:                *
  55 ************************************************************
  56 */
  57
  58static void ali_write(u8 index, u8 value)
  59{
  60        /* write an arbirary register */
  61        outb(index, ALI_INDEX);
  62        outb(value, ALI_DATA);
  63}
  64
  65#if 0
  66static int ali_read(u8 index)
  67{
  68        outb(index, ALI_INDEX);
  69        return inb(ALI_DATA);
  70}
  71#endif
  72
  73#define ALI_OPEN() \
  74        outb(0x51, ALI_INDEX); \
  75        outb(0x23, ALI_INDEX)
  76
  77
  78#define ALI_CLOSE() \
  79        outb(0xbb, ALI_INDEX)
  80
  81/* Select a logical device */
  82#define ALI_SELDEV(dev) \
  83        ali_write(0x07, dev)
  84
  85
  86void ali512x_init(void)
  87{
  88        ALI_OPEN();
  89
  90        ali_write(0x02, 0x01);  /* soft reset */
  91        ali_write(0x03, 0x03);  /* disable access to CIOs */
  92        ali_write(0x22, 0x00);  /* disable direct powerdown */
  93        ali_write(0x23, 0x00);  /* disable auto powerdown */
  94        ali_write(0x24, 0x00);  /* IR 8 is active hi, pin26 is PDIR */
  95
  96        ALI_CLOSE();
  97}
  98
  99void ali512x_set_fdc(int enabled, u16 io, u8 irq, u8 dma_channel)
 100{
 101        ALI_OPEN();
 102        ALI_SELDEV(0);
 103
 104        ali_write(0x30, enabled?1:0);
 105        if (enabled) {
 106                ali_write(0x60, io >> 8);
 107                ali_write(0x61, io & 0xff);
 108                ali_write(0x70, irq);
 109                ali_write(0x74, dma_channel);
 110
 111                /* AT mode, no drive swap */
 112                ali_write(0xf0, 0x08);
 113                ali_write(0xf1, 0x00);
 114                ali_write(0xf2, 0xff);
 115                ali_write(0xf4, 0x00);
 116        }
 117        ALI_CLOSE();
 118}
 119
 120
 121void ali512x_set_pp(int enabled, u16 io, u8 irq, u8 dma_channel)
 122{
 123        ALI_OPEN();
 124        ALI_SELDEV(3);
 125
 126        ali_write(0x30, enabled?1:0);
 127        if (enabled) {
 128                ali_write(0x60, io >> 8);
 129                ali_write(0x61, io & 0xff);
 130                ali_write(0x70, irq);
 131                ali_write(0x74, dma_channel);
 132
 133                /* mode: EPP 1.9, ECP FIFO threshold = 7, IRQ active low */
 134                ali_write(0xf0, 0xbc);
 135                /* 12 MHz, Burst DMA in ECP */
 136                ali_write(0xf1, 0x05);
 137        }
 138        ALI_CLOSE();
 139
 140}
 141
 142void ali512x_set_uart(int enabled, int index, u16 io, u8 irq)
 143{
 144        ALI_OPEN();
 145        ALI_SELDEV(index?5:4);
 146
 147        ali_write(0x30, enabled?1:0);
 148        if (enabled) {
 149                ali_write(0x60, io >> 8);
 150                ali_write(0x61, io & 0xff);
 151                ali_write(0x70, irq);
 152
 153                ali_write(0xf0, 0x00);
 154                ali_write(0xf1, 0x00);
 155
 156                /* huh? write 0xf2 twice - a typo in rolo
 157                 * or some secret ali errata? Who knows?
 158                 */
 159                if (index) {
 160                        ali_write(0xf2, 0x00);
 161                }
 162                ali_write(0xf2, 0x0c);
 163        }
 164        ALI_CLOSE();
 165
 166}
 167
 168void ali512x_set_uart2_irda(int enabled)
 169{
 170        ALI_OPEN();
 171        ALI_SELDEV(5);
 172
 173        ali_write(0xf1, enabled?0x48:0x00); /* fullduplex IrDa */
 174        ALI_CLOSE();
 175
 176}
 177
 178void ali512x_set_rtc(int enabled, u16 io, u8 irq)
 179{
 180        ALI_OPEN();
 181        ALI_SELDEV(6);
 182
 183        ali_write(0x30, enabled?1:0);
 184        if (enabled) {
 185                ali_write(0x60, io >> 8);
 186                ali_write(0x61, io & 0xff);
 187                ali_write(0x70, irq);
 188
 189                ali_write(0xf0, 0x00);
 190        }
 191        ALI_CLOSE();
 192}
 193
 194void ali512x_set_kbc(int enabled, u8 kbc_irq, u8 mouse_irq)
 195{
 196        ALI_OPEN();
 197        ALI_SELDEV(7);
 198
 199        ali_write(0x30, enabled?1:0);
 200        if (enabled) {
 201                ali_write(0x70, kbc_irq);
 202                ali_write(0x72, mouse_irq);
 203
 204                ali_write(0xf0, 0x00);
 205        }
 206        ALI_CLOSE();
 207}
 208
 209
 210/* Common I/O
 211 *
 212 * (This descripotsion is base on several incompete sources
 213 *  since I have not been able to obtain any datasheet for the device
 214 *  there may be some mis-understandings burried in here.
 215 *  -- Daniel daniel@omicron.se)
 216 *
 217 * There are 22 CIO pins numbered
 218 * 10-17
 219 * 20-25
 220 * 30-37
 221 *
 222 * 20-24 are dedicated CIO pins, the other 17 are muliplexed with
 223 * other functions.
 224 *
 225 *           Secondary
 226 * CIO Pin   Function    Decription
 227 * =======================================================
 228 * CIO10     IRQIN1      Interrupt input 1?
 229 * CIO11     IRQIN2      Interrupt input 2?
 230 * CIO12     IRRX        IrDa Receive
 231 * CIO13     IRTX        IrDa Transmit
 232 * CIO14     P21         KBC P21 fucntion
 233 * CIO15     P20         KBC P21 fucntion
 234 * CIO16     I2C_CLK     I2C Clock
 235 * CIO17     I2C_DAT     I2C Data
 236 *
 237 * CIO20     -
 238 * CIO21     -
 239 * CIO22     -
 240 * CIO23     -
 241 * CIO24     -
 242 * CIO25     LOCK        Keylock
 243 *
 244 * CIO30     KBC_CLK     Keybaord Clock
 245 * CIO31     CS0J        General Chip Select decoder CS0J
 246 * CIO32     CS1J        General Chip Select decoder CS1J
 247 * CIO33     ALT_KCLK    Alternative Keyboard Clock
 248 * CIO34     ALT_KDAT    Alternative Keyboard Data
 249 * CIO35     ALT_MCLK    Alternative Mouse Clock
 250 * CIO36     ALT_MDAT    Alternative Mouse Data
 251 * CIO37     ALT_KBC     Alternative KBC select
 252 *
 253 * The CIO use an indirect address scheme.
 254 *
 255 * Reigster 3 in the SIO is used to select the index and data
 256 * port addresses where the CIO I/O registers show up.
 257 * The function selection registers are accessible under
 258 * function SIO 8.
 259 *
 260 * SIO reigster 3 (CIO Address Selection) bit definitions:
 261 * bit 7   CIO index and data registers enabled
 262 * bit 1-0 CIO indirect registers port address select
 263 *       0  index = 0xE0 data = 0xE1
 264 *       1  index = 0xE2 data = 0xE3
 265 *       2  index = 0xE4 data = 0xE5
 266 *       3  index = 0xEA data = 0xEB
 267 *
 268 * There are three CIO I/O register accessed via CIO index port and CIO data port
 269 * 0x01     CIO 10-17 data
 270 * 0x02     CIO 20-25 data (bits 7-6 unused)
 271 * 0x03     CIO 30-37 data
 272 *
 273 *
 274 * The pin function is accessed through normal
 275 * SIO registers, each register have the same format:
 276 *
 277 * Bit   Function                     Value
 278 * 0     Input/output                 1=input
 279 * 1     Polarity of signal           1=inverted
 280 * 2     Unused                       ??
 281 * 3     Function (normal or special) 1=special
 282 * 7-4   Unused
 283 *
 284 * SIO REG
 285 * 0xe0     CIO 10 Config
 286 * 0xe1     CIO 11 Config
 287 * 0xe2     CIO 12 Config
 288 * 0xe3     CIO 13 Config
 289 * 0xe4     CIO 14 Config
 290 * 0xe5     CIO 15 Config
 291 * 0xe6     CIO 16 Config
 292 * 0xe7     CIO 16 Config
 293 *
 294 * 0xe8     CIO 20 Config
 295 * 0xe9     CIO 21 Config
 296 * 0xea     CIO 22 Config
 297 * 0xeb     CIO 23 Config
 298 * 0xec     CIO 24 Config
 299 * 0xed     CIO 25 Config
 300 *
 301 * 0xf5     CIO 30 Config
 302 * 0xf6     CIO 31 Config
 303 * 0xf7     CIO 32 Config
 304 * 0xf8     CIO 33 Config
 305 * 0xf9     CIO 34 Config
 306 * 0xfa     CIO 35 Config
 307 * 0xfb     CIO 36 Config
 308 * 0xfc     CIO 37 Config
 309 *
 310 */
 311
 312#define ALI_CIO_PORT_SEL 0x83
 313#define ALI_CIO_INDEX    0xea
 314#define ALI_CIO_DATA     0xeb
 315
 316void ali512x_set_cio(int enabled)
 317{
 318        int i;
 319
 320        ALI_OPEN();
 321
 322        if (enabled) {
 323                ali_write(0x3, ALI_CIO_PORT_SEL);    /* Enable CIO data register */
 324        } else {
 325                ali_write(0x3, ALI_CIO_PORT_SEL & ~0x80);
 326        }
 327
 328        ALI_SELDEV(8);
 329
 330        ali_write(0x30, enabled?1:0);
 331
 332        /* set all pins to input to start with */
 333        for (i=0xe0;i<0xee;i++) {
 334                ali_write(i, 1);
 335        }
 336
 337        for (i=0xf5;i<0xfe;i++) {
 338                ali_write(i, 1);
 339        }
 340
 341        ALI_CLOSE();
 342}
 343
 344
 345void ali512x_cio_function(int pin, int special, int inv, int input)
 346{
 347        u8 data;
 348        u8 addr;
 349
 350        /* valid pins are 10-17, 20-25 and 30-37 */
 351        if (pin >= 10 && pin <= 17) {
 352                addr = 0xe0+(pin&7);
 353        } else if (pin >= 20 && pin <= 25) {
 354                addr = 0xe8+(pin&7);
 355        } else if (pin >= 30 && pin <= 37) {
 356                addr = 0xf5+(pin&7);
 357        } else {
 358                return;
 359        }
 360
 361        ALI_OPEN();
 362
 363        ALI_SELDEV(8);
 364
 365
 366        data=0xf4;
 367        if (special) {
 368                data |= 0x08;
 369        } else {
 370                if (inv) {
 371                        data |= 0x02;
 372                }
 373                if (input) {
 374                        data |= 0x01;
 375                }
 376        }
 377
 378        ali_write(addr, data);
 379
 380        ALI_CLOSE();
 381}
 382
 383void ali512x_cio_out(int pin, int value)
 384{
 385        u8 reg;
 386        u8 data;
 387        u8 bit;
 388
 389        reg = pin/10;
 390        bit = 1 << (pin%10);
 391
 392
 393        outb(reg, ALI_CIO_INDEX);     /* select I/O register */
 394        data = inb(ALI_CIO_DATA);
 395        if (value) {
 396                data |= bit;
 397        } else {
 398                data &= ~bit;
 399        }
 400        outb(data, ALI_CIO_DATA);
 401}
 402
 403int ali512x_cio_in(int pin)
 404{
 405        u8 reg;
 406        u8 data;
 407        u8 bit;
 408
 409        /* valid pins are 10-17, 20-25 and 30-37 */
 410        reg = pin/10;
 411        bit = 1 << (pin%10);
 412
 413
 414        outb(reg, ALI_CIO_INDEX);     /* select I/O register */
 415        data = inb(ALI_CIO_DATA);
 416
 417        return data & bit;
 418}
 419