summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-02-21 13:30:36 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-02-21 13:30:36 +0000
commit49a3beac398bd3e89dc4c8a5caff106cbd1e0cff (patch)
tree4f9a8bfdbe571a81ca63b73ae45c0b466661fb35 /drivers
parentb8d3cc7ceb61a07b865b420139477b91a4be202f (diff)
ITE 8172 patches from Pete Popov slightly hacked by me.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/Makefile8
-rw-r--r--drivers/char/qtronix.c597
-rw-r--r--drivers/char/qtronixmap.map287
-rw-r--r--drivers/ide/Config.in5
-rw-r--r--drivers/ide/Makefile1
-rw-r--r--drivers/ide/ide-pci.c16
-rw-r--r--drivers/ide/it8172.c283
7 files changed, 1197 insertions, 0 deletions
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 568c3fb8a..e0fd5b5f5 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -91,6 +91,10 @@ ifneq ($(CONFIG_SUN_SERIAL),)
SERIAL =
endif
+ifeq ($(CONFIG_QTRONIX_KEYBOARD),y)
+ KEYBD = qtronix.o
+ KEYMAP = qtronixmap.o
+endif
obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
obj-$(CONFIG_SERIAL) += $(SERIAL)
@@ -208,3 +212,7 @@ consolemap_deftbl.o: consolemap_deftbl.c $(TOPDIR)/include/linux/types.h
defkeymap.c: defkeymap.map
loadkeys --mktable defkeymap.map > defkeymap.c
+ifeq ($(CONFIG_QTRONIX_KEYBOARD),y)
+qtronixmap.c: qtronixmap.map
+ loadkeys --mktable qtronixmap.map > qtronixmap.c
+endif
diff --git a/drivers/char/qtronix.c b/drivers/char/qtronix.c
new file mode 100644
index 000000000..c74aabf2b
--- /dev/null
+++ b/drivers/char/qtronix.c
@@ -0,0 +1,597 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Qtronix 990P infrared keyboard driver.
+ *
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ *
+ * The bottom portion of this driver was take from
+ * pc_keyb.c Please see that file for copyrights.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+
+/*
+ * NOTE:
+ *
+ * This driver has only been tested with the Consumer IR
+ * port of the ITE 8172 system controller.
+ *
+ * You do not need this driver if you are using the ps/2 or
+ * USB adapter that the keyboard ships with. You only need
+ * this driver if your board has a IR port and the keyboard
+ * data is being sent directly to the IR. In that case,
+ * you also need some low-level IR support. See it8172_cir.c.
+ *
+ */
+
+#ifdef CONFIG_QTRONIX_KEYBOARD
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_int.h>
+#include <asm/it8172/it8172_cir.h>
+
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/init.h>
+#include <linux/kbd_ll.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+#include <linux/malloc.h>
+#include <linux/kbd_kern.h>
+#include <linux/smp_lock.h>
+#include <asm/io.h>
+#include <linux/pc_keyb.h>
+
+#include <asm/keyboard.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#define leading1 0
+#define leading2 0xF
+
+#define KBD_CIR_PORT 0
+#define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */
+
+static int data_index;
+struct cir_port *cir;
+static unsigned char kbdbytes[5];
+static unsigned char cir_data[32]; /* we only need 16 chars */
+
+static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs);
+static int handle_data(unsigned char *p_data);
+static inline void handle_mouse_event(unsigned char scancode);
+static inline void handle_keyboard_event(unsigned char scancode, int down);
+static int __init psaux_init(void);
+
+static struct aux_queue *queue; /* Mouse data buffer. */
+static int aux_count = 0;
+
+/*
+ * Keys accessed through the 'Fn' key
+ * The Fn key does not produce a key-up sequence. So, the first
+ * time the user presses it, it will be key-down event. The key
+ * stays down until the user presses it again.
+ */
+#define NUM_FN_KEYS 56
+static unsigned char fn_keys[NUM_FN_KEYS] = {
+ 0,0,0,0,0,0,0,0, /* 0 7 */
+ 8,9,10,93,0,0,0,0, /* 8 15 */
+ 0,0,0,0,0,0,0,5, /* 16 23 */
+ 6,7,91,0,0,0,0,0, /* 24 31 */
+ 0,0,0,0,0,2,3,4, /* 32 39 */
+ 92,0,0,0,0,0,0,0, /* 40 47 */
+ 0,0,0,0,11,0,94,95 /* 48 55 */
+
+};
+
+void init_qtronix_990P_kbd(void)
+{
+ int retval;
+
+ cir = (struct cir_port *)kmalloc(sizeof(struct cir_port), GFP_KERNEL);
+ if (!cir) {
+ printk("Unable to initialize Qtronix keyboard\n");
+ return;
+ }
+
+ /*
+ * revisit
+ * this should be programmable, somehow by the, by the user.
+ */
+ cir->port = KBD_CIR_PORT;
+ cir->baud_rate = 0x1d;
+ cir->rdwos = 0;
+ cir->rxdcr = 0x3;
+ cir->hcfs = 0;
+ cir->fifo_tl = 0;
+ cir->cfq = 0x1d;
+ cir_port_init(cir);
+
+ retval = request_irq(IT8172_CIR0_IRQ, kbd_int_handler,
+ (unsigned long )(SA_INTERRUPT|SA_SHIRQ),
+ (const char *)"Qtronix IR Keyboard", (void *)cir);
+
+ if (retval) {
+ printk("unable to allocate cir %d irq %d\n",
+ cir->port, IT8172_CIR0_IRQ);
+ }
+#ifdef CONFIG_PSMOUSE
+ psaux_init();
+#endif
+}
+
+static inline unsigned char BitReverse(unsigned short key)
+{
+ unsigned char rkey = 0;
+ rkey |= (key & 0x1) << 7;
+ rkey |= (key & 0x2) << 5;
+ rkey |= (key & 0x4) << 3;
+ rkey |= (key & 0x8) << 1;
+ rkey |= (key & 0x10) >> 1;
+ rkey |= (key & 0x20) >> 3;
+ rkey |= (key & 0x40) >> 5;
+ rkey |= (key & 0x80) >> 7;
+ return rkey;
+
+}
+
+
+static inline u_int8_t UpperByte(u_int8_t data)
+{
+ return (data >> 4);
+}
+
+
+static inline u_int8_t LowerByte(u_int8_t data)
+{
+ return (data & 0xF);
+}
+
+
+int CheckSumOk(u_int8_t byte1, u_int8_t byte2,
+ u_int8_t byte3, u_int8_t byte4, u_int8_t byte5)
+{
+ u_int8_t CheckSum;
+
+ CheckSum = (byte1 & 0x0F) + byte2 + byte3 + byte4 + byte5;
+ if ( LowerByte(UpperByte(CheckSum) + LowerByte(CheckSum)) != UpperByte(byte1) )
+ return 0;
+ else
+ return 1;
+}
+
+
+static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct cir_port *cir;
+ int j;
+ unsigned char int_status;
+
+ cir = (struct cir_port *)dev_id;
+ int_status = get_int_status(cir);;
+ if (int_status & 0x4) {
+ clear_fifo(cir);
+ return;
+ }
+
+ while (cir_get_rx_count(cir)) {
+
+ cir_data[data_index] = cir_read_data(cir);
+
+ if (data_index == 0) {/* expecting first byte */
+ if (cir_data[data_index] != leading1) {
+ //printk("!leading byte %x\n", cir_data[data_index]);
+ set_rx_active(cir);
+ clear_fifo(cir);
+ continue;
+ }
+ }
+ if (data_index == 1) {
+ if ((cir_data[data_index] & 0xf) != leading2) {
+ set_rx_active(cir);
+ data_index = 0; /* start over */
+ clear_fifo(cir);
+ continue;
+ }
+ }
+
+ if ( (cir_data[data_index] == 0xff)) { /* last byte */
+ //printk("data_index %d\n", data_index);
+ set_rx_active(cir);
+#if 0
+ for (j=0; j<=data_index; j++) {
+ printk("rx_data %d: %x\n", j, cir_data[j]);
+ }
+#endif
+ data_index = 0;
+ handle_data(cir_data);
+ return;
+ }
+ else if (data_index>16) {
+ set_rx_active(cir);
+#if 0
+ printk("warning: data_index %d\n", data_index);
+ for (j=0; j<=data_index; j++) {
+ printk("rx_data %d: %x\n", j, cir_data[j]);
+ }
+#endif
+ data_index = 0;
+ clear_fifo(cir);
+ return;
+ }
+ data_index++;
+ }
+}
+
+
+#define NUM_KBD_BYTES 5
+static int handle_data(unsigned char *p_data)
+{
+ u_int32_t bit_bucket;
+ u_int32_t i, j;
+ u_int32_t got_bits, next_byte;
+ int down = 0;
+
+ /* Reorganize the bit stream */
+ for (i=0; i<16; i++)
+ p_data[i] = BitReverse(~p_data[i]);
+
+ /*
+ * We've already previously checked that p_data[0]
+ * is equal to leading1 and that (p_data[1] & 0xf)
+ * is equal to leading2. These twelve bits are the
+ * leader code. We can now throw them away (the 12
+ * bits) and continue parsing the stream.
+ */
+ bit_bucket = p_data[1] << 12;
+ got_bits = 4;
+ next_byte = 2;
+
+ /*
+ * Process four bits at a time
+ */
+ for (i=0; i<NUM_KBD_BYTES; i++) {
+
+ kbdbytes[i]=0;
+
+ for (j=0; j<8; j++) /* 8 bits per byte */
+ {
+ if (got_bits < 4) {
+ bit_bucket |= (p_data[next_byte++] << (8 - got_bits));
+ got_bits += 8;
+ }
+
+ if ((bit_bucket & 0xF000) == 0x8000) {
+ /* Convert 1000b to 1 */
+ kbdbytes[i] = 0x80 | (kbdbytes[i] >> 1);
+ got_bits -= 4;
+ bit_bucket = bit_bucket << 4;
+ }
+ else if ((bit_bucket & 0xC000) == 0x8000) {
+ /* Convert 10b to 0 */
+ kbdbytes[i] = kbdbytes[i] >> 1;
+ got_bits -= 2;
+ bit_bucket = bit_bucket << 2;
+ }
+ else {
+ /* bad serial stream */
+ return 1;
+ }
+
+ if (next_byte > 16) {
+ //printk("error: too many bytes\n");
+ return 1;
+ }
+ }
+ }
+
+
+ if (!CheckSumOk(kbdbytes[0], kbdbytes[1],
+ kbdbytes[2], kbdbytes[3], kbdbytes[4])) {
+ //printk("checksum failed\n");
+ return 1;
+ }
+
+ if (kbdbytes[1] & 0x08) {
+ //printk("m: %x %x %x\n", kbdbytes[1], kbdbytes[2], kbdbytes[3]);
+ handle_mouse_event(kbdbytes[1]);
+ handle_mouse_event(kbdbytes[2]);
+ handle_mouse_event(kbdbytes[3]);
+ }
+ else {
+ if (kbdbytes[2] == 0) down = 1;
+#if 0
+ if (down)
+ printk("down %d\n", kbdbytes[3]);
+ else
+ printk("up %d\n", kbdbytes[3]);
+#endif
+ handle_keyboard_event(kbdbytes[3], down);
+ }
+ return 0;
+}
+
+
+spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
+static unsigned char handle_kbd_event(void);
+
+
+int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+ printk("pckbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
+ return 0;
+}
+
+int pckbd_getkeycode(unsigned int scancode)
+{
+ return scancode;
+}
+
+
+int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode)
+{
+ static int prev_scancode = 0;
+
+ if (scancode == 0x00 || scancode == 0xff) {
+ prev_scancode = 0;
+ return 0;
+ }
+
+ /* todo */
+ if (!prev_scancode && scancode == 160) { /* Fn key down */
+ //printk("Fn key down\n");
+ prev_scancode = 160;
+ return 0;
+ }
+ else if (prev_scancode && scancode == 160) { /* Fn key up */
+ //printk("Fn key up\n");
+ prev_scancode = 0;
+ return 0;
+ }
+
+ /* todo */
+ if (prev_scancode == 160) {
+ if (scancode <= NUM_FN_KEYS) {
+ *keycode = fn_keys[scancode];
+ //printk("fn keycode %d\n", *keycode);
+ }
+ else
+ return 0;
+ }
+ else if (scancode <= 127) {
+ *keycode = scancode;
+ }
+ else
+ return 0;
+
+
+ return 1;
+}
+
+char pckbd_unexpected_up(unsigned char keycode)
+{
+ //printk("pckbd_unexpected_up\n");
+ return 0;
+}
+
+static unsigned char kbd_exists = 1;
+
+static inline void handle_keyboard_event(unsigned char scancode, int down)
+{
+ kbd_exists = 1;
+ handle_scancode(scancode, down);
+ tasklet_schedule(&keyboard_tasklet);
+}
+
+
+void pckbd_leds(unsigned char leds)
+{
+}
+
+/* dummy */
+void pckbd_init_hw(void)
+{
+}
+
+
+
+static inline void handle_mouse_event(unsigned char scancode)
+{
+ if(scancode == AUX_RECONNECT){
+ queue->head = queue->tail = 0; /* Flush input queue */
+ // __aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */
+ return;
+ }
+
+ add_mouse_randomness(scancode);
+ if (aux_count) {
+ int head = queue->head;
+
+ queue->buf[head] = scancode;
+ head = (head + 1) & (AUX_BUF_SIZE-1);
+ if (head != queue->tail) {
+ queue->head = head;
+ kill_fasync(&queue->fasync, SIGIO, POLL_IN);
+ wake_up_interruptible(&queue->proc_list);
+ }
+ }
+}
+
+static unsigned char get_from_queue(void)
+{
+ unsigned char result;
+ unsigned long flags;
+
+ spin_lock_irqsave(&kbd_controller_lock, flags);
+ result = queue->buf[queue->tail];
+ queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
+ return result;
+}
+
+
+static inline int queue_empty(void)
+{
+ return queue->head == queue->tail;
+}
+
+static int fasync_aux(int fd, struct file *filp, int on)
+{
+ int retval;
+
+ //printk("fasync_aux\n");
+ retval = fasync_helper(fd, filp, on, &queue->fasync);
+ if (retval < 0)
+ return retval;
+ return 0;
+}
+
+
+/*
+ * Random magic cookie for the aux device
+ */
+#define AUX_DEV ((void *)queue)
+
+static int release_aux(struct inode * inode, struct file * file)
+{
+ lock_kernel();
+ fasync_aux(-1, file, 0);
+ aux_count--;
+ unlock_kernel();
+ return 0;
+}
+
+static int open_aux(struct inode * inode, struct file * file)
+{
+ if (aux_count++) {
+ return 0;
+ }
+ queue->head = queue->tail = 0; /* Flush input queue */
+ return 0;
+}
+
+/*
+ * Put bytes from input queue to buffer.
+ */
+
+static ssize_t read_aux(struct file * file, char * buffer,
+ size_t count, loff_t *ppos)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ ssize_t i = count;
+ unsigned char c;
+
+ if (queue_empty()) {
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ add_wait_queue(&queue->proc_list, &wait);
+repeat:
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (queue_empty() && !signal_pending(current)) {
+ schedule();
+ goto repeat;
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&queue->proc_list, &wait);
+ }
+ while (i > 0 && !queue_empty()) {
+ c = get_from_queue();
+ put_user(c, buffer++);
+ i--;
+ }
+ if (count-i) {
+ file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+ return count-i;
+ }
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ return 0;
+}
+
+/*
+ * Write to the aux device.
+ */
+
+static ssize_t write_aux(struct file * file, const char * buffer,
+ size_t count, loff_t *ppos)
+{
+ /*
+ * The ITE boards this was tested on did not have the
+ * transmit wires connected.
+ */
+ return count;
+}
+
+static unsigned int aux_poll(struct file *file, poll_table * wait)
+{
+ poll_wait(file, &queue->proc_list, wait);
+ if (!queue_empty())
+ return POLLIN | POLLRDNORM;
+ return 0;
+}
+
+struct file_operations psaux_fops = {
+ read: read_aux,
+ write: write_aux,
+ poll: aux_poll,
+ open: open_aux,
+ release: release_aux,
+ fasync: fasync_aux,
+};
+
+/*
+ * Initialize driver.
+ */
+static struct miscdevice psaux_mouse = {
+ PSMOUSE_MINOR, "psaux", &psaux_fops
+};
+
+static int __init psaux_init(void)
+{
+ misc_register(&psaux_mouse);
+ queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
+ memset(queue, 0, sizeof(*queue));
+ queue->head = queue->tail = 0;
+ init_waitqueue_head(&queue->proc_list);
+
+ return 0;
+}
+#endif
diff --git a/drivers/char/qtronixmap.map b/drivers/char/qtronixmap.map
new file mode 100644
index 000000000..8d1ff5c1e
--- /dev/null
+++ b/drivers/char/qtronixmap.map
@@ -0,0 +1,287 @@
+# Default kernel keymap. This uses 7 modifier combinations.
+keymaps 0-2,4-5,8,12
+# Change the above line into
+# keymaps 0-2,4-6,8,12
+# in case you want the entries
+# altgr control keycode 83 = Boot
+# altgr control keycode 111 = Boot
+# below.
+#
+# In fact AltGr is used very little, and one more keymap can
+# be saved by mapping AltGr to Alt (and adapting a few entries):
+# keycode 100 = Alt
+#
+keycode 1 = grave asciitilde
+ alt keycode 1 = Meta_Escape
+keycode 2 = one exclam
+ alt keycode 2 = Meta_one
+keycode 3 = two at at
+ control keycode 3 = nul
+ shift control keycode 3 = nul
+ alt keycode 3 = Meta_two
+keycode 4 = three numbersign
+ control keycode 4 = Escape
+ alt keycode 4 = Meta_three
+keycode 5 = four dollar dollar
+ control keycode 5 = Control_backslash
+ alt keycode 5 = Meta_four
+keycode 6 = five percent
+ control keycode 6 = Control_bracketright
+ alt keycode 6 = Meta_five
+keycode 7 = six asciicircum
+ control keycode 7 = Control_asciicircum
+ alt keycode 7 = Meta_six
+keycode 8 = seven ampersand braceleft
+ control keycode 8 = Control_underscore
+ alt keycode 8 = Meta_seven
+keycode 9 = eight asterisk bracketleft
+ control keycode 9 = Delete
+ alt keycode 9 = Meta_eight
+keycode 10 = nine parenleft bracketright
+ alt keycode 10 = Meta_nine
+keycode 11 = zero parenright braceright
+ alt keycode 11 = Meta_zero
+keycode 12 = minus underscore backslash
+ control keycode 12 = Control_underscore
+ shift control keycode 12 = Control_underscore
+ alt keycode 12 = Meta_minus
+keycode 13 = equal plus
+ alt keycode 13 = Meta_equal
+keycode 15 = Delete Delete
+ control keycode 15 = BackSpace
+ alt keycode 15 = Meta_Delete
+keycode 16 = Tab Tab
+ alt keycode 16 = Meta_Tab
+keycode 17 = q
+keycode 18 = w
+keycode 19 = e
+keycode 20 = r
+keycode 21 = t
+keycode 22 = y
+keycode 23 = u
+keycode 24 = i
+keycode 25 = o
+keycode 26 = p
+keycode 27 = bracketleft braceleft
+ control keycode 27 = Escape
+ alt keycode 27 = Meta_bracketleft
+keycode 28 = bracketright braceright
+ control keycode 28 = Control_bracketright
+ alt keycode 28 = Meta_bracketright
+keycode 29 = backslash bar
+ control keycode 29 = Control_backslash
+ alt keycode 29 = Meta_backslash
+keycode 30 = Caps_Lock
+keycode 31 = a
+keycode 32 = s
+keycode 33 = d
+keycode 34 = f
+keycode 35 = g
+keycode 36 = h
+keycode 37 = j
+keycode 38 = k
+keycode 39 = l
+keycode 40 = semicolon colon
+ alt keycode 39 = Meta_semicolon
+keycode 41 = apostrophe quotedbl
+ control keycode 40 = Control_g
+ alt keycode 40 = Meta_apostrophe
+keycode 42 = grave asciitilde
+ control keycode 41 = nul
+ alt keycode 41 = Meta_grave
+keycode 43 = Return
+ alt keycode 43 = Meta_Control_m
+keycode 44 = Shift
+keycode 46 = z
+keycode 47 = x
+keycode 48 = c
+keycode 49 = v
+keycode 50 = b
+keycode 51 = n
+keycode 52 = m
+keycode 53 = comma less
+ alt keycode 51 = Meta_comma
+keycode 54 = period greater
+ control keycode 52 = Compose
+ alt keycode 52 = Meta_period
+keycode 55 = slash question
+ control keycode 53 = Delete
+ alt keycode 53 = Meta_slash
+keycode 57 = Shift
+keycode 58 = Control
+keycode 60 = Alt
+keycode 61 = space space
+ control keycode 61 = nul
+ alt keycode 61 = Meta_space
+keycode 62 = Alt
+
+keycode 75 = Insert
+keycode 76 = Delete
+
+keycode 83 = Up
+keycode 84 = Down
+
+keycode 85 = Prior
+ shift keycode 85 = Scroll_Backward
+keycode 86 = Next
+ shift keycode 86 = Scroll_Forward
+keycode 89 = Right
+ alt keycode 89 = Incr_Console
+keycode 79 = Left
+ alt keycode 79 = Decr_Console
+
+keycode 90 = Num_Lock
+ shift keycode 90 = Bare_Num_Lock
+
+keycode 91 = minus
+keycode 92 = plus
+keycode 93 = KP_Multiply
+keycode 94 = period
+keycode 95 = KP_Divide
+
+keycode 107 = Select
+keycode 108 = Down
+
+keycode 110 = Escape Escape
+ alt keycode 1 = Meta_Escape
+
+keycode 112 = F1 F11 Console_13
+ control keycode 112 = F1
+ alt keycode 112 = Console_1
+ control alt keycode 112 = Console_1
+keycode 113 = F2 F12 Console_14
+ control keycode 113 = F2
+ alt keycode 113 = Console_2
+ control alt keycode 113 = Console_2
+keycode 114 = F3 F13 Console_15
+ control keycode 114 = F3
+ alt keycode 114 = Console_3
+ control alt keycode 114 = Console_3
+keycode 115 = F4 F14 Console_16
+ control keycode 115 = F4
+ alt keycode 115 = Console_4
+ control alt keycode 115 = Console_4
+keycode 116 = F5 F15 Console_17
+ control keycode 116 = F5
+ alt keycode 116 = Console_5
+ control alt keycode 116 = Console_5
+keycode 117 = F6 F16 Console_18
+ control keycode 117 = F6
+ alt keycode 117 = Console_6
+ control alt keycode 117 = Console_6
+keycode 118 = F7 F17 Console_19
+ control keycode 118 = F7
+ alt keycode 118 = Console_7
+ control alt keycode 118 = Console_7
+keycode 119 = F8 F18 Console_20
+ control keycode 119 = F8
+ alt keycode 119 = Console_8
+ control alt keycode 119 = Console_8
+keycode 120 = F9 F19 Console_21
+ control keycode 120 = F9
+ alt keycode 120 = Console_9
+ control alt keycode 120 = Console_9
+keycode 121 = F10 F20 Console_22
+ control keycode 121 = F10
+ alt keycode 121 = Console_10
+ control alt keycode 121 = Console_10
+
+keycode 126 = Pause
+
+
+string F1 = "\033[[A"
+string F2 = "\033[[B"
+string F3 = "\033[[C"
+string F4 = "\033[[D"
+string F5 = "\033[[E"
+string F6 = "\033[17~"
+string F7 = "\033[18~"
+string F8 = "\033[19~"
+string F9 = "\033[20~"
+string F10 = "\033[21~"
+string F11 = "\033[23~"
+string F12 = "\033[24~"
+string F13 = "\033[25~"
+string F14 = "\033[26~"
+string F15 = "\033[28~"
+string F16 = "\033[29~"
+string F17 = "\033[31~"
+string F18 = "\033[32~"
+string F19 = "\033[33~"
+string F20 = "\033[34~"
+string Find = "\033[1~"
+string Insert = "\033[2~"
+string Remove = "\033[3~"
+string Select = "\033[4~"
+string Prior = "\033[5~"
+string Next = "\033[6~"
+string Macro = "\033[M"
+string Pause = "\033[P"
+compose '`' 'A' to 'À'
+compose '`' 'a' to 'à'
+compose '\'' 'A' to 'Á'
+compose '\'' 'a' to 'á'
+compose '^' 'A' to 'Â'
+compose '^' 'a' to 'â'
+compose '~' 'A' to 'Ã'
+compose '~' 'a' to 'ã'
+compose '"' 'A' to 'Ä'
+compose '"' 'a' to 'ä'
+compose 'O' 'A' to 'Å'
+compose 'o' 'a' to 'å'
+compose '0' 'A' to 'Å'
+compose '0' 'a' to 'å'
+compose 'A' 'A' to 'Å'
+compose 'a' 'a' to 'å'
+compose 'A' 'E' to 'Æ'
+compose 'a' 'e' to 'æ'
+compose ',' 'C' to 'Ç'
+compose ',' 'c' to 'ç'
+compose '`' 'E' to 'È'
+compose '`' 'e' to 'è'
+compose '\'' 'E' to 'É'
+compose '\'' 'e' to 'é'
+compose '^' 'E' to 'Ê'
+compose '^' 'e' to 'ê'
+compose '"' 'E' to 'Ë'
+compose '"' 'e' to 'ë'
+compose '`' 'I' to 'Ì'
+compose '`' 'i' to 'ì'
+compose '\'' 'I' to 'Í'
+compose '\'' 'i' to 'í'
+compose '^' 'I' to 'Î'
+compose '^' 'i' to 'î'
+compose '"' 'I' to 'Ï'
+compose '"' 'i' to 'ï'
+compose '-' 'D' to 'Ð'
+compose '-' 'd' to 'ð'
+compose '~' 'N' to 'Ñ'
+compose '~' 'n' to 'ñ'
+compose '`' 'O' to 'Ò'
+compose '`' 'o' to 'ò'
+compose '\'' 'O' to 'Ó'
+compose '\'' 'o' to 'ó'
+compose '^' 'O' to 'Ô'
+compose '^' 'o' to 'ô'
+compose '~' 'O' to 'Õ'
+compose '~' 'o' to 'õ'
+compose '"' 'O' to 'Ö'
+compose '"' 'o' to 'ö'
+compose '/' 'O' to 'Ø'
+compose '/' 'o' to 'ø'
+compose '`' 'U' to 'Ù'
+compose '`' 'u' to 'ù'
+compose '\'' 'U' to 'Ú'
+compose '\'' 'u' to 'ú'
+compose '^' 'U' to 'Û'
+compose '^' 'u' to 'û'
+compose '"' 'U' to 'Ü'
+compose '"' 'u' to 'ü'
+compose '\'' 'Y' to 'Ý'
+compose '\'' 'y' to 'ý'
+compose 'T' 'H' to 'Þ'
+compose 't' 'h' to 'þ'
+compose 's' 's' to 'ß'
+compose '"' 'y' to 'ÿ'
+compose 's' 'z' to 'ß'
+compose 'i' 'j' to 'ÿ'
diff --git a/drivers/ide/Config.in b/drivers/ide/Config.in
index a157767f3..a2c0a282c 100644
--- a/drivers/ide/Config.in
+++ b/drivers/ide/Config.in
@@ -64,6 +64,10 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
dep_mbool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI
dep_mbool ' PIIXn Tuning support' CONFIG_PIIX_TUNING $CONFIG_BLK_DEV_PIIX $CONFIG_IDEDMA_PCI_AUTO
fi
+ if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then
+ dep_mbool ' IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI
+ dep_mbool ' IT8172 IDE Tuning support' CONFIG_IT8172_TUNING $CONFIG_BLK_DEV_IT8172 $CONFIG_IDEDMA_PCI_AUTO
+ fi
dep_bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 $CONFIG_EXPERIMENTAL
dep_bool ' PROMISE PDC20246/PDC20262/PDC20267 support' CONFIG_BLK_DEV_PDC202XX $CONFIG_BLK_DEV_IDEDMA_PCI
@@ -159,6 +163,7 @@ if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \
"$CONFIG_BLK_DEV_OSB4" = "y" -o \
"$CONFIG_BLK_DEV_PDC202XX" = "y" -o \
"$CONFIG_BLK_DEV_PIIX" = "y" -o \
+ "$CONFIG_BLK_DEV_IT8172" = "y" -o \
"$CONFIG_BLK_DEV_SIS5513" = "y" -o \
"$CONFIG_BLK_DEV_SLC90E66" = "y" -o \
"$CONFIG_BLK_DEV_SL82C105" = "y" -o \
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index c2d8a5644..05dcb6a65 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o
obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o
+obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o
ide-obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o
ide-obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c
index 7ea7a61e5..a2afee031 100644
--- a/drivers/ide/ide-pci.c
+++ b/drivers/ide/ide-pci.c
@@ -74,6 +74,7 @@
#define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409})
#define DEVID_SLC90E66 ((ide_pci_devid_t){PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1})
#define DEVID_OSB4 ((ide_pci_devid_t){PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE})
+#define DEVID_ITE8172G ((ide_pci_devid_t){PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G})
#define IDE_IGNORE ((void *)-1)
@@ -246,6 +247,18 @@ extern void ide_init_piix(ide_hwif_t *);
#define INIT_PIIX NULL
#endif
+#ifdef CONFIG_BLK_DEV_IT8172
+extern unsigned int pci_init_it8172(struct pci_dev *, const char *);
+extern unsigned int ata66_it8172(ide_hwif_t *);
+extern void ide_init_it8172(ide_hwif_t *);
+#define PCI_IT8172 &pci_init_it8172
+#define INIT_IT8172 &ide_init_it8172
+#else
+#define PCI_IT8172 NULL
+#define ATA66_IT8172 NULL
+#define INIT_IT8172 NULL
+#endif
+
#ifdef CONFIG_BLK_DEV_RZ1000
extern void ide_init_rz1000(ide_hwif_t *);
#define INIT_RZ1000 &ide_init_rz1000
@@ -381,6 +394,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
{DEVID_AMD7409, "AMD7409", PCI_AMD7409, ATA66_AMD7409, INIT_AMD7409, DMA_AMD7409, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 },
{DEVID_SLC90E66,"SLC90E66", PCI_SLC90E66, ATA66_SLC90E66, INIT_SLC90E66, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_OSB4, "ServerWorks OSB4", PCI_OSB4, ATA66_OSB4, INIT_OSB4, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_ITE8172G,"IT8172G", PCI_IT8172, NULL, INIT_IT8172, NULL, {{0x00,0x00,0x00}, {0x40,0x00,0x01}}, ON_BOARD, 0 },
{IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }};
/*
@@ -784,6 +798,8 @@ void __init ide_scan_pcidev (struct pci_dev *dev)
return;
else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))
return; /* CY82C693 is more than only a IDE controller */
+ else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_ITE8172G) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))
+ return; /* IT8172G is also more than only an IDE controller */
else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1))
return; /* UM8886A/BF pair */
else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366))
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c
new file mode 100644
index 000000000..937d3e6d1
--- /dev/null
+++ b/drivers/ide/it8172.c
@@ -0,0 +1,283 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * IT8172 IDE controller support
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * stevel@mvista.com or support@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/it8172/it8172_int.h>
+
+#include "ide_modes.h"
+
+/*
+ * Prototypes
+ */
+static void it8172_tune_drive (ide_drive_t *drive, byte pio);
+#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IT8172_TUNING)
+static byte it8172_dma_2_pio (byte xfer_rate);
+static int it8172_tune_chipset (ide_drive_t *drive, byte speed);
+static int it8172_config_drive_for_dma (ide_drive_t *drive);
+static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
+#endif
+unsigned int __init pci_init_it8172 (struct pci_dev *dev, const char *name);
+void __init ide_init_it8172 (ide_hwif_t *hwif);
+
+
+/*
+ * Based on settings done by AMI BIOS
+ * (might be usefull if drive is not registered in CMOS for any reason).
+ */
+static void it8172_tune_drive (ide_drive_t *drive, byte pio)
+{
+ unsigned long flags;
+ u16 master_data;
+ byte slave_data;
+ int is_slave = (&HWIF(drive)->drives[1] == drive);
+ int master_port = HWIF(drive)->index ? 0x42 : 0x40;
+ int slave_port = 0x44;
+ /* ISP RTC */
+ byte timings[][2] = { { 0, 0 },
+ { 0, 0 },
+ { 1, 0 },
+ { 2, 1 },
+ { 2, 3 }, };
+
+ pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
+ pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
+ if (is_slave) {
+ master_data = master_data | 0x4000;
+ if (pio > 1)
+ /* enable PPE, IE and TIME */
+ master_data = master_data | 0x0070;
+ pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data);
+ slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0);
+ slave_data = slave_data |
+ ((timings[pio][0] << 2) | (timings[pio][1]
+ << (HWIF(drive)->index ? 4 : 0)));
+ } else {
+ master_data = master_data & 0xccf8;
+ if (pio > 1)
+ /* enable PPE, IE and TIME */
+ master_data = master_data | 0x0007;
+ master_data = master_data | (timings[pio][0] << 12) |
+ (timings[pio][1] << 8);
+ }
+ save_flags(flags);
+ cli();
+ pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data);
+ if (is_slave)
+ pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data);
+ restore_flags(flags);
+}
+
+#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IT8172_TUNING)
+/*
+ *
+ */
+static byte it8172_dma_2_pio (byte xfer_rate)
+{
+ switch(xfer_rate) {
+ case XFER_UDMA_5:
+ case XFER_UDMA_4:
+ case XFER_UDMA_3:
+ case XFER_UDMA_2:
+ case XFER_UDMA_1:
+ case XFER_UDMA_0:
+ case XFER_MW_DMA_2:
+ case XFER_PIO_4:
+ return 4;
+ case XFER_MW_DMA_1:
+ case XFER_PIO_3:
+ return 3;
+ case XFER_SW_DMA_2:
+ case XFER_PIO_2:
+ return 2;
+ case XFER_MW_DMA_0:
+ case XFER_SW_DMA_1:
+ case XFER_SW_DMA_0:
+ case XFER_PIO_1:
+ case XFER_PIO_0:
+ case XFER_PIO_SLOW:
+ default:
+ return 0;
+ }
+}
+
+static int it8172_tune_chipset (ide_drive_t *drive, byte speed)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct pci_dev *dev = hwif->pci_dev;
+ int a_speed = 3 << (drive->dn * 4);
+ int u_flag = 1 << drive->dn;
+ int u_speed = 0;
+ int err = 0;
+ byte reg48, reg4a;
+
+ pci_read_config_byte(dev, 0x48, &reg48);
+ pci_read_config_byte(dev, 0x4a, &reg4a);
+
+ switch(speed) {
+ case XFER_UDMA_4:
+ case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
+ case XFER_UDMA_5:
+ case XFER_UDMA_3:
+ case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break;
+ case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break;
+ case XFER_MW_DMA_2:
+ case XFER_MW_DMA_1:
+ case XFER_SW_DMA_2: break;
+ default: return -1;
+ }
+
+ if (speed >= XFER_UDMA_0) {
+ if (!(reg48 & u_flag))
+ pci_write_config_byte(dev, 0x48, reg48|u_flag);
+ if (!(reg4a & u_speed)) {
+ pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
+ pci_write_config_byte(dev, 0x4a, reg4a|u_speed);
+ }
+ }
+ if (speed < XFER_UDMA_0) {
+ if (reg48 & u_flag)
+ pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
+ if (reg4a & a_speed)
+ pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
+ }
+
+ it8172_tune_drive(drive, it8172_dma_2_pio(speed));
+
+#if IT8172_DEBUG
+ printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
+#endif
+ if (!drive->init_speed)
+ drive->init_speed = speed;
+ err = ide_config_drive_speed(drive, speed);
+ drive->current_speed = speed;
+ return err;
+}
+
+static int it8172_config_drive_for_dma (ide_drive_t *drive)
+{
+ struct hd_driveid *id = drive->id;
+ byte speed;
+
+ if (id->dma_ultra & 0x0010) {
+ speed = XFER_UDMA_2;
+ } else if (id->dma_ultra & 0x0008) {
+ speed = XFER_UDMA_1;
+ } else if (id->dma_ultra & 0x0004) {
+ speed = XFER_UDMA_2;
+ } else if (id->dma_ultra & 0x0002) {
+ speed = XFER_UDMA_1;
+ } else if (id->dma_ultra & 0x0001) {
+ speed = XFER_UDMA_0;
+ } else if (id->dma_mword & 0x0004) {
+ speed = XFER_MW_DMA_2;
+ } else if (id->dma_mword & 0x0002) {
+ speed = XFER_MW_DMA_1;
+ } else if (id->dma_1word & 0x0004) {
+ speed = XFER_SW_DMA_2;
+ } else {
+ speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+ }
+
+ (void) it8172_tune_chipset(drive, speed);
+
+ return ((int)((id->dma_ultra >> 11) & 7) ? ide_dma_on :
+ ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
+ ((id->dma_mword >> 8) & 7) ? ide_dma_on :
+ ((id->dma_1word >> 8) & 7) ? ide_dma_on :
+ ide_dma_off_quietly);
+}
+
+static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
+{
+ switch (func) {
+ case ide_dma_check:
+ return ide_dmaproc((ide_dma_action_t)it8172_config_drive_for_dma(drive),
+ drive);
+ default :
+ break;
+ }
+ /* Other cases are done by generic IDE-DMA code. */
+ return ide_dmaproc(func, drive);
+}
+#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_IT8172_TUNING) */
+
+unsigned int __init pci_init_it8172 (struct pci_dev *dev, const char *name)
+{
+ unsigned char progif;
+
+ /*
+ * Place both IDE interfaces into PCI "native" mode
+ */
+ (void)pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
+ (void)pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x05);
+
+ return IT8172_IDE_IRQ;
+}
+
+
+void __init ide_init_it8172 (ide_hwif_t *hwif)
+{
+ struct pci_dev* dev = hwif->pci_dev;
+ unsigned long cmdBase, ctrlBase;
+
+ hwif->tuneproc = &it8172_tune_drive;
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
+
+ if (!hwif->dma_base)
+ return;
+
+#ifndef CONFIG_BLK_DEV_IDEDMA
+ hwif->autodma = 0;
+#else /* CONFIG_BLK_DEV_IDEDMA */
+#ifdef CONFIG_IT8172_TUNING
+ hwif->autodma = 1;
+ hwif->dmaproc = &it8172_dmaproc;
+ hwif->speedproc = &it8172_tune_chipset;
+#endif /* CONFIG_IT8172_TUNING */
+#endif /* !CONFIG_BLK_DEV_IDEDMA */
+
+ cmdBase = dev->resource[0].start;
+ ctrlBase = dev->resource[1].start;
+
+ ide_init_hwif_ports(&hwif->hw, cmdBase, ctrlBase | 2, NULL);
+ memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+ hwif->noprobe = 0;
+}