11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 24baa9922430662431231ac637adedddbb0cfb2d7Russell King * arch/arm/include/asm/floppy.h 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1996-2000 Russell King 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License version 2 as 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * published by the Free Software Foundation. 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __ASM_ARM_FLOPPY_H 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __ASM_ARM_FLOPPY_H 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 15a09e64fbc0094e3073dbb09c3b4bfe4ab669244bRussell King#include <mach/floppy.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_outb(val,port) \ 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { \ 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((port) == FD_DOR) \ 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fd_setdor((val)); \ 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else \ 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb((val),(port)); \ 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while(0) 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_inb(port) inb((port)) 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\ 2852e405eaa9806968e88b35d65e57acad954a5ab5Thomas Gleixner IRQF_DISABLED,"floppy",NULL) 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL) 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK) 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK) 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3321d1ca04532005c50ed57c2b2948e465b2e90720Russell Kingstatic inline int fd_dma_setup(void *data, unsigned int length, 3421d1ca04532005c50ed57c2b2948e465b2e90720Russell King unsigned int mode, unsigned long addr) 3521d1ca04532005c50ed57c2b2948e465b2e90720Russell King{ 3621d1ca04532005c50ed57c2b2948e465b2e90720Russell King set_dma_mode(DMA_FLOPPY, mode); 3721d1ca04532005c50ed57c2b2948e465b2e90720Russell King __set_dma_addr(DMA_FLOPPY, data); 3821d1ca04532005c50ed57c2b2948e465b2e90720Russell King set_dma_count(DMA_FLOPPY, length); 3921d1ca04532005c50ed57c2b2948e465b2e90720Russell King virtual_dma_port = addr; 4021d1ca04532005c50ed57c2b2948e465b2e90720Russell King enable_dma(DMA_FLOPPY); 4121d1ca04532005c50ed57c2b2948e465b2e90720Russell King return 0; 4221d1ca04532005c50ed57c2b2948e465b2e90720Russell King} 4321d1ca04532005c50ed57c2b2948e465b2e90720Russell King#define fd_dma_setup fd_dma_setup 4421d1ca04532005c50ed57c2b2948e465b2e90720Russell King 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_request_dma() request_dma(DMA_FLOPPY,"floppy") 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_free_dma() free_dma(DMA_FLOPPY) 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_disable_dma() disable_dma(DMA_FLOPPY) 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* need to clean up dma.h */ 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DMA_FLOPPYDISK DMA_FLOPPY 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Floppy_selects is the list of DOR's to select drive fd 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On initialisation, the floppy list is scanned, and the drives allocated 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in the order that they are found. This is done by seeking the drive 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to a non-zero track, and then restoring it to track 0. If an error occurs, 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * then there is no floppy drive present. [to be put back in again] 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned char floppy_selects[2][4] = 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0x10, 0x21, 0x23, 0x33 }, 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0x10, 0x21, 0x23, 0x33 } 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define fd_setdor(dor) \ 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdo { \ 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int new_dor = (dor); \ 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (new_dor & 0xf0) \ 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_dor = (new_dor & 0x0c) | floppy_selects[fdc][new_dor & 3]; \ 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else \ 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_dor &= 0x0c; \ 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(new_dor, FD_DOR); \ 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} while (0) 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Someday, we'll automatically detect which drives are present... 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void fd_scandrives (void) 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int floppy, drive_count; 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fd_disable_irq(); 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_cmd = &default_raw_cmd; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_SEEK; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_cmd->track = 0; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds raw_cmd->rate = ?; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive_count = 0; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (floppy = 0; floppy < 4; floppy ++) { 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds current_drive = drive_count; 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Turn on floppy motor 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (start_motor(redo_fd_request)) 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Set up FDC 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fdc_specify(); 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Tell FDC to recalibrate 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds output_byte(FD_RECALIBRATE); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds LAST_OUT(UNIT(floppy)); 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait for command to complete */ 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!successful) { 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = drive_count; i < 3; i--) 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy_selects[fdc][i] = floppy_selects[fdc][i + 1]; 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy_selects[fdc][3] = 0; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy -= 1; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive_count++; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy_selects[0][0] = 0x10; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy_selects[0][1] = 0x21; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy_selects[0][2] = 0x23; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy_selects[0][3] = 0x33; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FDC1 (0x3f0) 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FLOPPY0_TYPE 4 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FLOPPY1_TYPE 4 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define N_FDC 1 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define N_DRIVE 4 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CROSS_64KB(a,s) (0) 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This allows people to reverse the order of 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * fd0 and fd1, in case their hardware is 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * strangely connected (as some RiscPCs 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and A5000s seem to be). 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void driveswap(int *ints, int dummy, int dummy2) 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy_selects[0][0] ^= floppy_selects[0][1]; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy_selects[0][1] ^= floppy_selects[0][0]; 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds floppy_selects[0][0] ^= floppy_selects[0][1]; 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 } 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 149