Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
This commit is contained in:
Linus Torvalds
2005-04-16 15:20:36 -07:00
commit 1da177e4c3
17291 changed files with 6718755 additions and 0 deletions
+198
View File
@@ -0,0 +1,198 @@
menu "Macintosh device drivers"
depends on PPC || MAC
config ADB
bool "Apple Desktop Bus (ADB) support"
depends on MAC || PPC_PMAC
help
Apple Desktop Bus (ADB) support is for support of devices which
are connected to an ADB port. ADB devices tend to have 4 pins.
If you have an Apple Macintosh prior to the iMac, an iBook or
PowerBook, or a "Blue and White G3", you probably want to say Y
here. Otherwise say N.
config ADB_MACII
bool "Include Mac II ADB driver"
depends on ADB && MAC
help
Say Y here if want your kernel to support Macintosh systems that use
the Mac II style ADB. This includes the II, IIx, IIcx, SE/30, IIci,
Quadra 610, Quadra 650, Quadra 700, Quadra 800, Centris 610 and
Centris 650.
config ADB_MACIISI
bool "Include Mac IIsi ADB driver"
depends on ADB && MAC
help
Say Y here if want your kernel to support Macintosh systems that use
the Mac IIsi style ADB. This includes the IIsi, IIvi, IIvx, Classic
II, LC, LC II, LC III, Performa 460, and the Performa 600.
config ADB_IOP
bool "Include IOP (IIfx/Quadra 9x0) ADB driver"
depends on ADB && MAC
help
The I/O Processor (IOP) is an Apple custom IC designed to provide
intelligent support for I/O controllers. It is described at
<http://www.angelfire.com/ca2/dev68k/iopdesc.html> to enable direct
support for it, say 'Y' here.
config ADB_PMU68K
bool "Include PMU (Powerbook) ADB driver"
depends on ADB && MAC
help
Say Y here if want your kernel to support the m68k based Powerbooks.
This includes the PowerBook 140, PowerBook 145, PowerBook 150,
PowerBook 160, PowerBook 165, PowerBook 165c, PowerBook 170,
PowerBook 180, PowerBook, 180c, PowerBook 190cs, PowerBook 520,
PowerBook Duo 210, PowerBook Duo 230, PowerBook Duo 250,
PowerBook Duo 270c, PowerBook Duo 280 and PowerBook Duo 280c.
# we want to change this to something like CONFIG_SYSCTRL_CUDA/PMU
config ADB_CUDA
bool "Support for CUDA based Macs and PowerMacs"
depends on (ADB || PPC_PMAC) && !PPC_PMAC64
help
This provides support for CUDA based Macintosh and Power Macintosh
systems. This includes many m68k based Macs (Color Classic, Mac TV,
Performa 475, Performa 520, Performa 550, Performa 575,
Performa 588, Quadra 605, Quadra 630, Quadra/Centris 660AV, and
Quadra 840AV), most OldWorld PowerMacs, the first generation iMacs,
the Blue&White G3 and the "Yikes" G4 (PCI Graphics). All later
models should use CONFIG_ADB_PMU instead. It is safe to say Y here
even if your machine doesn't have a CUDA.
If unsure say Y.
config ADB_PMU
bool "Support for PMU based PowerMacs"
depends on PPC_PMAC
help
On PowerBooks, iBooks, and recent iMacs and Power Macintoshes, the
PMU is an embedded microprocessor whose primary function is to
control system power, and battery charging on the portable models.
The PMU also controls the ADB (Apple Desktop Bus) which connects to
the keyboard and mouse on some machines, as well as the non-volatile
RAM and the RTC (real time clock) chip. Say Y to enable support for
this device; you should do so if your machine is one of those
mentioned above.
config PMAC_SMU
bool "Support for SMU based PowerMacs"
depends on PPC_PMAC64
help
This option adds support for the newer G5 iMacs and PowerMacs based
on the "SMU" system control chip which replaces the old PMU.
If you don't know, say Y.
config PMAC_PBOOK
bool "Power management support for PowerBooks"
depends on ADB_PMU
---help---
This provides support for putting a PowerBook to sleep; it also
enables media bay support. Power management works on the
PB2400/3400/3500, Wallstreet, Lombard, and Bronze PowerBook G3 and
the Titanium Powerbook G4, as well as the iBooks. You should get
the power management daemon, pmud, to make it work and you must have
the /dev/pmu device (see the pmud README).
Get pmud from <ftp://ftp.samba.org/pub/ppclinux/pmud/>.
If you have a PowerBook, you should say Y here.
You may also want to compile the dma sound driver as a module and
have it autoloaded. The act of removing the module shuts down the
sound hardware for more power savings.
config PM
bool
depends on PPC_PMAC && ADB_PMU && PMAC_PBOOK
default y
config PMAC_APM_EMU
tristate "APM emulation"
depends on PMAC_PBOOK
# made a separate option since backlight may end up beeing used
# on non-powerbook machines (but only on PMU based ones AFAIK)
config PMAC_BACKLIGHT
bool "Backlight control for LCD screens"
depends on ADB_PMU
help
Say Y here to build in code to manage the LCD backlight on a
Macintosh PowerBook. With this code, the backlight will be turned
on and off appropriately on power-management and lid-open/lid-closed
events; also, the PowerBook button device will be enabled so you can
change the screen brightness.
config MAC_SERIAL
tristate "Support for PowerMac serial ports (OBSOLETE DRIVER)"
depends on PPC_PMAC && BROKEN
help
This driver is obsolete. Use CONFIG_SERIAL_PMACZILOG in
"Character devices --> Serial drivers --> PowerMac z85c30" option.
config ADB_MACIO
bool "Include MacIO (CHRP) ADB driver"
depends on ADB && PPC_CHRP && !PPC_PMAC64
help
Say Y here to include direct support for the ADB controller in the
Hydra chip used on PowerPC Macintoshes of the CHRP type. (The Hydra
also includes a MESH II SCSI controller, DBDMA controller, VIA chip,
OpenPIC controller and two RS422/Geoports.)
config INPUT_ADBHID
bool "Support for ADB input devices (keyboard, mice, ...)"
depends on ADB && INPUT=y
help
Say Y here if you want to have ADB (Apple Desktop Bus) HID devices
such as keyboards, mice, joysticks, trackpads or graphic tablets
handled by the input layer. If you say Y here, make sure to say Y to
the corresponding drivers "Keyboard support" (CONFIG_INPUT_KEYBDEV),
"Mouse Support" (CONFIG_INPUT_MOUSEDEV) and "Event interface
support" (CONFIG_INPUT_EVDEV) as well.
If unsure, say Y.
config MAC_EMUMOUSEBTN
bool "Support for mouse button 2+3 emulation"
depends on INPUT_ADBHID
help
This provides generic support for emulating the 2nd and 3rd mouse
button with keypresses. If you say Y here, the emulation is still
disabled by default. The emulation is controlled by these sysctl
entries:
/proc/sys/dev/mac_hid/mouse_button_emulation
/proc/sys/dev/mac_hid/mouse_button2_keycode
/proc/sys/dev/mac_hid/mouse_button3_keycode
If you have an Apple machine with a 1-button mouse, say Y here.
config THERM_WINDTUNNEL
tristate "Support for thermal management on Windtunnel G4s"
depends on I2C && I2C_KEYWEST && PPC_PMAC && !PPC_PMAC64
help
This driver provides some thermostat and fan control for the desktop
G4 "Windtunnel"
config THERM_ADT746X
tristate "Support for thermal mgmnt on laptops with ADT 746x chipset"
depends on I2C && I2C_KEYWEST && PPC_PMAC && !PPC_PMAC64
help
This driver provides some thermostat and fan control for the
iBook G4, and the ATI based aluminium PowerBooks, allowing slighlty
better fan behaviour by default, and some manual control.
config THERM_PM72
tristate "Support for thermal management on PowerMac G5"
depends on I2C && I2C_KEYWEST && PPC_PMAC64
help
This driver provides thermostat and fan control for the desktop
G5 machines.
config ANSLCD
tristate "Support for ANS LCD display"
depends on ADB_CUDA && PPC_PMAC
endmenu
+29
View File
@@ -0,0 +1,29 @@
#
# Makefile for the Macintosh-specific device drivers.
#
# Each configuration option enables a list of files.
obj-$(CONFIG_PPC_PMAC) += macio_asic.o
obj-$(CONFIG_PMAC_PBOOK) += mediabay.o
obj-$(CONFIG_MAC_SERIAL) += macserial.o
obj-$(CONFIG_MAC_EMUMOUSEBTN) += mac_hid.o
obj-$(CONFIG_INPUT_ADBHID) += adbhid.o
obj-$(CONFIG_ANSLCD) += ans-lcd.o
obj-$(CONFIG_ADB_PMU) += via-pmu.o
obj-$(CONFIG_ADB_CUDA) += via-cuda.o
obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o
obj-$(CONFIG_PMAC_SMU) += smu.o
obj-$(CONFIG_ADB) += adb.o
obj-$(CONFIG_ADB_MACII) += via-macii.o
obj-$(CONFIG_ADB_MACIISI) += via-maciisi.o
obj-$(CONFIG_ADB_IOP) += adb-iop.o
obj-$(CONFIG_ADB_PMU68K) += via-pmu68k.o
obj-$(CONFIG_ADB_MACIO) += macio-adb.o
obj-$(CONFIG_THERM_PM72) += therm_pm72.o
obj-$(CONFIG_THERM_WINDTUNNEL) += therm_windtunnel.o
obj-$(CONFIG_THERM_ADT746X) += therm_adt746x.o
+287
View File
@@ -0,0 +1,287 @@
/*
* I/O Processor (IOP) ADB Driver
* Written and (C) 1999 by Joshua M. Thompson (funaho@jurai.org)
* Based on via-cuda.c by Paul Mackerras.
*
* 1999-07-01 (jmt) - First implementation for new driver architecture.
*
* 1999-07-31 (jmt) - First working version.
*
* TODO:
*
* o Implement SRQ handling.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <asm/bootinfo.h>
#include <asm/macintosh.h>
#include <asm/macints.h>
#include <asm/mac_iop.h>
#include <asm/mac_oss.h>
#include <asm/adb_iop.h>
#include <linux/adb.h>
/*#define DEBUG_ADB_IOP*/
extern void iop_ism_irq(int, void *, struct pt_regs *);
static struct adb_request *current_req;
static struct adb_request *last_req;
#if 0
static unsigned char reply_buff[16];
static unsigned char *reply_ptr;
#endif
static enum adb_iop_state {
idle,
sending,
awaiting_reply
} adb_iop_state;
static void adb_iop_start(void);
static int adb_iop_probe(void);
static int adb_iop_init(void);
static int adb_iop_send_request(struct adb_request *, int);
static int adb_iop_write(struct adb_request *);
static int adb_iop_autopoll(int);
static void adb_iop_poll(void);
static int adb_iop_reset_bus(void);
struct adb_driver adb_iop_driver = {
"ISM IOP",
adb_iop_probe,
adb_iop_init,
adb_iop_send_request,
adb_iop_autopoll,
adb_iop_poll,
adb_iop_reset_bus
};
static void adb_iop_end_req(struct adb_request *req, int state)
{
req->complete = 1;
current_req = req->next;
if (req->done) (*req->done)(req);
adb_iop_state = state;
}
/*
* Completion routine for ADB commands sent to the IOP.
*
* This will be called when a packet has been successfully sent.
*/
static void adb_iop_complete(struct iop_msg *msg, struct pt_regs *regs)
{
struct adb_request *req;
uint flags;
local_irq_save(flags);
req = current_req;
if ((adb_iop_state == sending) && req && req->reply_expected) {
adb_iop_state = awaiting_reply;
}
local_irq_restore(flags);
}
/*
* Listen for ADB messages from the IOP.
*
* This will be called when unsolicited messages (usually replies to TALK
* commands or autopoll packets) are received.
*/
static void adb_iop_listen(struct iop_msg *msg, struct pt_regs *regs)
{
struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message;
struct adb_request *req;
uint flags;
#ifdef DEBUG_ADB_IOP
int i;
#endif
local_irq_save(flags);
req = current_req;
#ifdef DEBUG_ADB_IOP
printk("adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X", req,
(uint) amsg->count + 2, (uint) amsg->flags, (uint) amsg->cmd);
for (i = 0; i < amsg->count; i++)
printk(" %02X", (uint) amsg->data[i]);
printk("\n");
#endif
/* Handle a timeout. Timeout packets seem to occur even after */
/* we've gotten a valid reply to a TALK, so I'm assuming that */
/* a "timeout" is actually more like an "end-of-data" signal. */
/* We need to send back a timeout packet to the IOP to shut */
/* it up, plus complete the current request, if any. */
if (amsg->flags & ADB_IOP_TIMEOUT) {
msg->reply[0] = ADB_IOP_TIMEOUT | ADB_IOP_AUTOPOLL;
msg->reply[1] = 0;
msg->reply[2] = 0;
if (req && (adb_iop_state != idle)) {
adb_iop_end_req(req, idle);
}
} else {
/* TODO: is it possible for more than one chunk of data */
/* to arrive before the timeout? If so we need to */
/* use reply_ptr here like the other drivers do. */
if ((adb_iop_state == awaiting_reply) &&
(amsg->flags & ADB_IOP_EXPLICIT)) {
req->reply_len = amsg->count + 1;
memcpy(req->reply, &amsg->cmd, req->reply_len);
} else {
adb_input(&amsg->cmd, amsg->count + 1, regs,
amsg->flags & ADB_IOP_AUTOPOLL);
}
memcpy(msg->reply, msg->message, IOP_MSG_LEN);
}
iop_complete_message(msg);
local_irq_restore(flags);
}
/*
* Start sending an ADB packet, IOP style
*
* There isn't much to do other than hand the packet over to the IOP
* after encapsulating it in an adb_iopmsg.
*/
static void adb_iop_start(void)
{
unsigned long flags;
struct adb_request *req;
struct adb_iopmsg amsg;
#ifdef DEBUG_ADB_IOP
int i;
#endif
/* get the packet to send */
req = current_req;
if (!req) return;
local_irq_save(flags);
#ifdef DEBUG_ADB_IOP
printk("adb_iop_start %p: sending packet, %d bytes:", req, req->nbytes);
for (i = 0 ; i < req->nbytes ; i++)
printk(" %02X", (uint) req->data[i]);
printk("\n");
#endif
/* The IOP takes MacII-style packets, so */
/* strip the initial ADB_PACKET byte. */
amsg.flags = ADB_IOP_EXPLICIT;
amsg.count = req->nbytes - 2;
/* amsg.data immediately follows amsg.cmd, effectively making */
/* amsg.cmd a pointer to the beginning of a full ADB packet. */
memcpy(&amsg.cmd, req->data + 1, req->nbytes - 1);
req->sent = 1;
adb_iop_state = sending;
local_irq_restore(flags);
/* Now send it. The IOP manager will call adb_iop_complete */
/* when the packet has been sent. */
iop_send_message(ADB_IOP, ADB_CHAN, req,
sizeof(amsg), (__u8 *) &amsg, adb_iop_complete);
}
int adb_iop_probe(void)
{
if (!iop_ism_present) return -ENODEV;
return 0;
}
int adb_iop_init(void)
{
printk("adb: IOP ISM driver v0.4 for Unified ADB.\n");
iop_listen(ADB_IOP, ADB_CHAN, adb_iop_listen, "ADB");
return 0;
}
int adb_iop_send_request(struct adb_request *req, int sync)
{
int err;
err = adb_iop_write(req);
if (err) return err;
if (sync) {
while (!req->complete) adb_iop_poll();
}
return 0;
}
static int adb_iop_write(struct adb_request *req)
{
unsigned long flags;
if ((req->nbytes < 2) || (req->data[0] != ADB_PACKET)) {
req->complete = 1;
return -EINVAL;
}
local_irq_save(flags);
req->next = 0;
req->sent = 0;
req->complete = 0;
req->reply_len = 0;
if (current_req != 0) {
last_req->next = req;
last_req = req;
} else {
current_req = req;
last_req = req;
}
local_irq_restore(flags);
if (adb_iop_state == idle) adb_iop_start();
return 0;
}
int adb_iop_autopoll(int devs)
{
/* TODO: how do we enable/disable autopoll? */
return 0;
}
void adb_iop_poll(void)
{
if (adb_iop_state == idle) adb_iop_start();
iop_ism_irq(0, (void *) ADB_IOP, NULL);
}
int adb_iop_reset_bus(void)
{
struct adb_request req = {
.reply_expected = 0,
.nbytes = 2,
.data = { ADB_PACKET, 0 },
};
adb_iop_write(&req);
while (!req.complete) {
adb_iop_poll();
schedule();
}
return 0;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+186
View File
@@ -0,0 +1,186 @@
/*
* /dev/lcd driver for Apple Network Servers.
*/
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/sections.h>
#include <asm/prom.h>
#include <asm/ans-lcd.h>
#include <asm/io.h>
#define ANSLCD_ADDR 0xf301c000
#define ANSLCD_CTRL_IX 0x00
#define ANSLCD_DATA_IX 0x10
static unsigned long anslcd_short_delay = 80;
static unsigned long anslcd_long_delay = 3280;
static volatile unsigned char __iomem *anslcd_ptr;
#undef DEBUG
static void __pmac
anslcd_write_byte_ctrl ( unsigned char c )
{
#ifdef DEBUG
printk(KERN_DEBUG "LCD: CTRL byte: %02x\n",c);
#endif
out_8(anslcd_ptr + ANSLCD_CTRL_IX, c);
switch(c) {
case 1:
case 2:
case 3:
udelay(anslcd_long_delay); break;
default: udelay(anslcd_short_delay);
}
}
static void __pmac
anslcd_write_byte_data ( unsigned char c )
{
out_8(anslcd_ptr + ANSLCD_DATA_IX, c);
udelay(anslcd_short_delay);
}
static ssize_t __pmac
anslcd_write( struct file * file, const char __user * buf,
size_t count, loff_t *ppos )
{
const char __user *p = buf;
int i;
#ifdef DEBUG
printk(KERN_DEBUG "LCD: write\n");
#endif
if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;
for ( i = *ppos; count > 0; ++i, ++p, --count )
{
char c;
__get_user(c, p);
anslcd_write_byte_data( c );
}
*ppos = i;
return p - buf;
}
static int __pmac
anslcd_ioctl( struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg )
{
char ch, __user *temp;
#ifdef DEBUG
printk(KERN_DEBUG "LCD: ioctl(%d,%d)\n",cmd,arg);
#endif
switch ( cmd )
{
case ANSLCD_CLEAR:
anslcd_write_byte_ctrl ( 0x38 );
anslcd_write_byte_ctrl ( 0x0f );
anslcd_write_byte_ctrl ( 0x06 );
anslcd_write_byte_ctrl ( 0x01 );
anslcd_write_byte_ctrl ( 0x02 );
return 0;
case ANSLCD_SENDCTRL:
temp = (char __user *) arg;
__get_user(ch, temp);
for (; ch; temp++) { /* FIXME: This is ugly, but should work, as a \0 byte is not a valid command code */
anslcd_write_byte_ctrl ( ch );
__get_user(ch, temp);
}
return 0;
case ANSLCD_SETSHORTDELAY:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
anslcd_short_delay=arg;
return 0;
case ANSLCD_SETLONGDELAY:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
anslcd_long_delay=arg;
return 0;
default:
return -EINVAL;
}
}
static int __pmac
anslcd_open( struct inode * inode, struct file * file )
{
return 0;
}
struct file_operations anslcd_fops = {
.write = anslcd_write,
.ioctl = anslcd_ioctl,
.open = anslcd_open,
};
static struct miscdevice anslcd_dev = {
ANSLCD_MINOR,
"anslcd",
&anslcd_fops
};
const char anslcd_logo[] = "********************" /* Line #1 */
"* LINUX! *" /* Line #3 */
"* Welcome to *" /* Line #2 */
"********************"; /* Line #4 */
static int __init
anslcd_init(void)
{
int a;
int retval;
struct device_node* node;
node = find_devices("lcd");
if (!node || !node->parent)
return -ENODEV;
if (strcmp(node->parent->name, "gc"))
return -ENODEV;
anslcd_ptr = ioremap(ANSLCD_ADDR, 0x20);
retval = misc_register(&anslcd_dev);
if(retval < 0){
printk(KERN_INFO "LCD: misc_register failed\n");
iounmap(anslcd_ptr);
return retval;
}
#ifdef DEBUG
printk(KERN_DEBUG "LCD: init\n");
#endif
anslcd_write_byte_ctrl ( 0x38 );
anslcd_write_byte_ctrl ( 0x0c );
anslcd_write_byte_ctrl ( 0x06 );
anslcd_write_byte_ctrl ( 0x01 );
anslcd_write_byte_ctrl ( 0x02 );
for(a=0;a<80;a++) {
anslcd_write_byte_data(anslcd_logo[a]);
}
return 0;
}
static void __exit
anslcd_exit(void)
{
misc_deregister(&anslcd_dev);
iounmap(anslcd_ptr);
}
module_init(anslcd_init);
module_exit(anslcd_exit);
File diff suppressed because it is too large Load Diff
+140
View File
@@ -0,0 +1,140 @@
/*
* drivers/macintosh/mac_hid.c
*
* HID support stuff for Macintosh computers.
*
* Copyright (C) 2000 Franz Sirl.
*
* This file will soon be removed in favor of an uinput userspace tool.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/sysctl.h>
#include <linux/input.h>
#include <linux/module.h>
static struct input_dev emumousebtn;
static void emumousebtn_input_register(void);
static int mouse_emulate_buttons = 0;
static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */
static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */
static int mouse_last_keycode = 0;
#if defined(CONFIG_SYSCTL)
/* file(s) in /proc/sys/dev/mac_hid */
ctl_table mac_hid_files[] = {
{
.ctl_name = DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
.procname = "mouse_button_emulation",
.data = &mouse_emulate_buttons,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,
.procname = "mouse_button2_keycode",
.data = &mouse_button2_keycode,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,
.procname = "mouse_button3_keycode",
.data = &mouse_button3_keycode,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{ .ctl_name = 0 }
};
/* dir in /proc/sys/dev */
ctl_table mac_hid_dir[] = {
{
.ctl_name = DEV_MAC_HID,
.procname = "mac_hid",
.maxlen = 0,
.mode = 0555,
.child = mac_hid_files,
},
{ .ctl_name = 0 }
};
/* /proc/sys/dev itself, in case that is not there yet */
ctl_table mac_hid_root_dir[] = {
{
.ctl_name = CTL_DEV,
.procname = "dev",
.maxlen = 0,
.mode = 0555,
.child = mac_hid_dir,
},
{ .ctl_name = 0 }
};
static struct ctl_table_header *mac_hid_sysctl_header;
#endif /* endif CONFIG_SYSCTL */
int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
{
switch (caller) {
case 1:
/* Called from keyboard.c */
if (mouse_emulate_buttons
&& (keycode == mouse_button2_keycode
|| keycode == mouse_button3_keycode)) {
if (mouse_emulate_buttons == 1) {
input_report_key(&emumousebtn,
keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
down);
input_sync(&emumousebtn);
return 1;
}
mouse_last_keycode = down ? keycode : 0;
}
break;
}
return 0;
}
EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons);
static void emumousebtn_input_register(void)
{
emumousebtn.name = "Macintosh mouse button emulation";
init_input_dev(&emumousebtn);
emumousebtn.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
emumousebtn.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
emumousebtn.relbit[0] = BIT(REL_X) | BIT(REL_Y);
emumousebtn.id.bustype = BUS_ADB;
emumousebtn.id.vendor = 0x0001;
emumousebtn.id.product = 0x0001;
emumousebtn.id.version = 0x0100;
input_register_device(&emumousebtn);
printk(KERN_INFO "input: Macintosh mouse button emulation\n");
}
int __init mac_hid_init(void)
{
emumousebtn_input_register();
#if defined(CONFIG_SYSCTL)
mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir, 1);
#endif /* CONFIG_SYSCTL */
return 0;
}
device_initcall(mac_hid_init);
+284
View File
@@ -0,0 +1,284 @@
/*
* Driver for the ADB controller in the Mac I/O (Hydra) chip.
*/
#include <stdarg.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <asm/prom.h>
#include <linux/adb.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/hydra.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <linux/init.h>
struct preg {
unsigned char r;
char pad[15];
};
struct adb_regs {
struct preg intr;
struct preg data[9];
struct preg intr_enb;
struct preg dcount;
struct preg error;
struct preg ctrl;
struct preg autopoll;
struct preg active_hi;
struct preg active_lo;
struct preg test;
};
/* Bits in intr and intr_enb registers */
#define DFB 1 /* data from bus */
#define TAG 2 /* transfer access grant */
/* Bits in dcount register */
#define HMB 0x0f /* how many bytes */
#define APD 0x10 /* auto-poll data */
/* Bits in error register */
#define NRE 1 /* no response error */
#define DLE 2 /* data lost error */
/* Bits in ctrl register */
#define TAR 1 /* transfer access request */
#define DTB 2 /* data to bus */
#define CRE 4 /* command response expected */
#define ADB_RST 8 /* ADB reset */
/* Bits in autopoll register */
#define APE 1 /* autopoll enable */
static volatile struct adb_regs __iomem *adb;
static struct adb_request *current_req, *last_req;
static DEFINE_SPINLOCK(macio_lock);
static int macio_probe(void);
static int macio_init(void);
static irqreturn_t macio_adb_interrupt(int irq, void *arg, struct pt_regs *regs);
static int macio_send_request(struct adb_request *req, int sync);
static int macio_adb_autopoll(int devs);
static void macio_adb_poll(void);
static int macio_adb_reset_bus(void);
struct adb_driver macio_adb_driver = {
"MACIO",
macio_probe,
macio_init,
macio_send_request,
/*macio_write,*/
macio_adb_autopoll,
macio_adb_poll,
macio_adb_reset_bus
};
int macio_probe(void)
{
return find_compatible_devices("adb", "chrp,adb0")? 0: -ENODEV;
}
int macio_init(void)
{
struct device_node *adbs;
adbs = find_compatible_devices("adb", "chrp,adb0");
if (adbs == 0)
return -ENXIO;
#if 0
{ int i;
printk("macio_adb_init: node = %p, addrs =", adbs->node);
for (i = 0; i < adbs->n_addrs; ++i)
printk(" %x(%x)", adbs->addrs[i].address, adbs->addrs[i].size);
printk(", intrs =");
for (i = 0; i < adbs->n_intrs; ++i)
printk(" %x", adbs->intrs[i].line);
printk("\n"); }
#endif
adb = ioremap(adbs->addrs->address, sizeof(struct adb_regs));
out_8(&adb->ctrl.r, 0);
out_8(&adb->intr.r, 0);
out_8(&adb->error.r, 0);
out_8(&adb->active_hi.r, 0xff); /* for now, set all devices active */
out_8(&adb->active_lo.r, 0xff);
out_8(&adb->autopoll.r, APE);
if (request_irq(adbs->intrs[0].line, macio_adb_interrupt,
0, "ADB", (void *)0)) {
printk(KERN_ERR "ADB: can't get irq %d\n",
adbs->intrs[0].line);
return -EAGAIN;
}
out_8(&adb->intr_enb.r, DFB | TAG);
printk("adb: mac-io driver 1.0 for unified ADB\n");
return 0;
}
static int macio_adb_autopoll(int devs)
{
unsigned long flags;
spin_lock_irqsave(&macio_lock, flags);
out_8(&adb->active_hi.r, devs >> 8);
out_8(&adb->active_lo.r, devs);
out_8(&adb->autopoll.r, devs? APE: 0);
spin_unlock_irqrestore(&macio_lock, flags);
return 0;
}
static int macio_adb_reset_bus(void)
{
unsigned long flags;
int timeout = 1000000;
/* Hrm... we may want to not lock interrupts for so
* long ... oh well, who uses that chip anyway ? :)
* That function will be seldomly used during boot
* on rare machines, so...
*/
spin_lock_irqsave(&macio_lock, flags);
out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | ADB_RST);
while ((in_8(&adb->ctrl.r) & ADB_RST) != 0) {
if (--timeout == 0) {
out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) & ~ADB_RST);
return -1;
}
}
spin_unlock_irqrestore(&macio_lock, flags);
return 0;
}
/* Send an ADB command */
static int macio_send_request(struct adb_request *req, int sync)
{
unsigned long flags;
int i;
if (req->data[0] != ADB_PACKET)
return -EINVAL;
for (i = 0; i < req->nbytes - 1; ++i)
req->data[i] = req->data[i+1];
--req->nbytes;
req->next = NULL;
req->sent = 0;
req->complete = 0;
req->reply_len = 0;
spin_lock_irqsave(&macio_lock, flags);
if (current_req != 0) {
last_req->next = req;
last_req = req;
} else {
current_req = last_req = req;
out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
}
spin_unlock_irqrestore(&macio_lock, flags);
if (sync) {
while (!req->complete)
macio_adb_poll();
}
return 0;
}
static irqreturn_t macio_adb_interrupt(int irq, void *arg,
struct pt_regs *regs)
{
int i, n, err;
struct adb_request *req = NULL;
unsigned char ibuf[16];
int ibuf_len = 0;
int complete = 0;
int autopoll = 0;
int handled = 0;
spin_lock(&macio_lock);
if (in_8(&adb->intr.r) & TAG) {
handled = 1;
if ((req = current_req) != 0) {
/* put the current request in */
for (i = 0; i < req->nbytes; ++i)
out_8(&adb->data[i].r, req->data[i]);
out_8(&adb->dcount.r, req->nbytes & HMB);
req->sent = 1;
if (req->reply_expected) {
out_8(&adb->ctrl.r, DTB + CRE);
} else {
out_8(&adb->ctrl.r, DTB);
current_req = req->next;
complete = 1;
if (current_req)
out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
}
}
out_8(&adb->intr.r, 0);
}
if (in_8(&adb->intr.r) & DFB) {
handled = 1;
err = in_8(&adb->error.r);
if (current_req && current_req->sent) {
/* this is the response to a command */
req = current_req;
if (err == 0) {
req->reply_len = in_8(&adb->dcount.r) & HMB;
for (i = 0; i < req->reply_len; ++i)
req->reply[i] = in_8(&adb->data[i].r);
}
current_req = req->next;
complete = 1;
if (current_req)
out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
} else if (err == 0) {
/* autopoll data */
n = in_8(&adb->dcount.r) & HMB;
for (i = 0; i < n; ++i)
ibuf[i] = in_8(&adb->data[i].r);
ibuf_len = n;
autopoll = (in_8(&adb->dcount.r) & APD) != 0;
}
out_8(&adb->error.r, 0);
out_8(&adb->intr.r, 0);
}
spin_unlock(&macio_lock);
if (complete && req) {
void (*done)(struct adb_request *) = req->done;
mb();
req->complete = 1;
/* Here, we assume that if the request has a done member, the
* struct request will survive to setting req->complete to 1
*/
if (done)
(*done)(req);
}
if (ibuf_len)
adb_input(ibuf, ibuf_len, regs, autopoll);
return IRQ_RETVAL(handled);
}
static void macio_adb_poll(void)
{
unsigned long flags;
local_irq_save(flags);
if (in_8(&adb->intr.r) != 0)
macio_adb_interrupt(0, NULL, NULL);
local_irq_restore(flags);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+461
View File
@@ -0,0 +1,461 @@
/*
* macserial.h: Definitions for the Macintosh Z8530 serial driver.
*
* Adapted from drivers/sbus/char/sunserial.h by Paul Mackerras.
*
* Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
#ifndef _MACSERIAL_H
#define _MACSERIAL_H
#include <linux/spinlock.h>
#define NUM_ZSREGS 16
struct serial_struct {
int type;
int line;
int port;
int irq;
int flags;
int xmit_fifo_size;
int custom_divisor;
int baud_base;
unsigned short close_delay;
char reserved_char[2];
int hub6;
unsigned short closing_wait; /* time to wait before closing */
unsigned short closing_wait2; /* no longer used... */
int reserved[4];
};
/*
* For the close wait times, 0 means wait forever for serial port to
* flush its output. 65535 means don't wait at all.
*/
#define ZILOG_CLOSING_WAIT_INF 0
#define ZILOG_CLOSING_WAIT_NONE 65535
/*
* Definitions for ZILOG_struct (and serial_struct) flags field
*/
#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes
* on the callout port */
#define ZILOG_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */
#define ZILOG_SAK 0x0004 /* Secure Attention Key (Orange book) */
#define ZILOG_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
#define ZILOG_SPD_MASK 0x0030
#define ZILOG_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */
#define ZILOG_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */
#define ZILOG_SPD_CUST 0x0030 /* Use user-specified divisor */
#define ZILOG_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */
#define ZILOG_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */
#define ZILOG_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
#define ZILOG_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */
#define ZILOG_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */
#define ZILOG_FLAGS 0x0FFF /* Possible legal ZILOG flags */
#define ZILOG_USR_MASK 0x0430 /* Legal flags that non-privileged
* users can set or reset */
/* Internal flags used only by kernel/chr_drv/serial.c */
#define ZILOG_INITIALIZED 0x80000000 /* Serial port was initialized */
#define ZILOG_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */
#define ZILOG_NORMAL_ACTIVE 0x20000000 /* Normal device is active */
#define ZILOG_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */
#define ZILOG_CLOSING 0x08000000 /* Serial port is closing */
#define ZILOG_CTS_FLOW 0x04000000 /* Do CTS flow control */
#define ZILOG_CHECK_CD 0x02000000 /* i.e., CLOCAL */
#define ZILOG_SLEEPING 0x01000000 /* have shut it down for sleep */
/* Software state per channel */
#ifdef __KERNEL__
/*
* This is our internal structure for each serial port's state.
*
* Many fields are paralleled by the structure used by the serial_struct
* structure.
*
* For definitions of the flags field, see tty.h
*/
struct mac_serial;
struct mac_zschannel {
volatile unsigned char* control;
volatile unsigned char* data;
spinlock_t lock;
/* Used for debugging */
struct mac_serial* parent;
};
struct mac_dma {
volatile struct dbdma_regs dma;
volatile unsigned short res_count;
volatile unsigned short command;
volatile unsigned int buf_addr;
};
struct mac_serial {
struct mac_serial *zs_next; /* For IRQ servicing chain */
struct mac_zschannel *zs_channel; /* Channel registers */
struct mac_zschannel *zs_chan_a; /* A side registers */
unsigned char read_reg_zero;
struct device_node* dev_node;
spinlock_t lock;
char soft_carrier; /* Use soft carrier on this channel */
char break_abort; /* Is serial console in, so process brk/abrt */
char kgdb_channel; /* Kgdb is running on this channel */
char is_cons; /* Is this our console. */
char is_internal_modem; /* is connected to an internal modem */
char is_irda; /* is connected to an IrDA codec */
int port_type; /* Port type for pmac_feature */
unsigned char tx_active; /* character is being xmitted */
unsigned char tx_stopped; /* output is suspended */
unsigned char power_wait; /* waiting for power-up delay to expire */
/* We need to know the current clock divisor
* to read the bps rate the chip has currently
* loaded.
*/
unsigned char clk_divisor; /* May be 1, 16, 32, or 64 */
int zs_baud;
/* Current write register values */
unsigned char curregs[NUM_ZSREGS];
/* Values we need to set next opportunity */
unsigned char pendregs[NUM_ZSREGS];
char change_needed;
int magic;
int baud_base;
int port;
int irq;
int flags; /* defined in tty.h */
int type; /* UART type */
struct tty_struct *tty;
int read_status_mask;
int ignore_status_mask;
int timeout;
int xmit_fifo_size;
int custom_divisor;
int x_char; /* xon/xoff character */
int close_delay;
unsigned short closing_wait;
unsigned short closing_wait2;
unsigned long event;
unsigned long last_active;
int line;
int count; /* # of fd on device */
int blocked_open; /* # of blocked opens */
unsigned char *xmit_buf;
int xmit_head;
int xmit_tail;
int xmit_cnt;
struct work_struct tqueue;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
volatile struct dbdma_regs *tx_dma;
int tx_dma_irq;
volatile struct dbdma_cmd *tx_cmds;
volatile struct mac_dma *rx;
int rx_dma_irq;
volatile struct dbdma_cmd **rx_cmds;
unsigned char **rx_char_buf;
unsigned char **rx_flag_buf;
#define RX_BUF_SIZE 256
int rx_nbuf;
int rx_done_bytes;
int rx_ubuf;
int rx_fbuf;
#define RX_NO_FBUF (-1)
int rx_cbuf;
spinlock_t rx_dma_lock;
int has_dma;
int dma_initted;
void *dma_priv;
struct timer_list poll_dma_timer;
#define RX_DMA_TIMER (jiffies + 10*HZ/1000)
struct timer_list powerup_timer;
};
#define SERIAL_MAGIC 0x5301
/*
* The size of the serial xmit buffer is 1 page, or 4096 bytes
*/
#define SERIAL_XMIT_SIZE 4096
/*
* Events are used to schedule things to happen at timer-interrupt
* time, instead of at rs interrupt time.
*/
#define RS_EVENT_WRITE_WAKEUP 0
#endif /* __KERNEL__ */
/* Conversion routines to/from brg time constants from/to bits
* per second.
*/
#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2))
#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2)
/* The Zilog register set */
#define FLAG 0x7e
/* Write Register 0 */
#define R0 0 /* Register selects */
#define R1 1
#define R2 2
#define R3 3
#define R4 4
#define R5 5
#define R6 6
#define R7 7
#define R8 8
#define R9 9
#define R10 10
#define R11 11
#define R12 12
#define R13 13
#define R14 14
#define R15 15
#define NULLCODE 0 /* Null Code */
#define POINT_HIGH 0x8 /* Select upper half of registers */
#define RES_EXT_INT 0x10 /* Reset Ext. Status Interrupts */
#define SEND_ABORT 0x18 /* HDLC Abort */
#define RES_RxINT_FC 0x20 /* Reset RxINT on First Character */
#define RES_Tx_P 0x28 /* Reset TxINT Pending */
#define ERR_RES 0x30 /* Error Reset */
#define RES_H_IUS 0x38 /* Reset highest IUS */
#define RES_Rx_CRC 0x40 /* Reset Rx CRC Checker */
#define RES_Tx_CRC 0x80 /* Reset Tx CRC Checker */
#define RES_EOM_L 0xC0 /* Reset EOM latch */
/* Write Register 1 */
#define EXT_INT_ENAB 0x1 /* Ext Int Enable */
#define TxINT_ENAB 0x2 /* Tx Int Enable */
#define PAR_SPEC 0x4 /* Parity is special condition */
#define RxINT_DISAB 0 /* Rx Int Disable */
#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */
#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */
#define INT_ERR_Rx 0x18 /* Int on error only */
#define WT_RDY_RT 0x20 /* W/Req reflects recv if 1, xmit if 0 */
#define WT_FN_RDYFN 0x40 /* W/Req pin is DMA request if 1, wait if 0 */
#define WT_RDY_ENAB 0x80 /* Enable W/Req pin */
/* Write Register #2 (Interrupt Vector) */
/* Write Register 3 */
#define RxENABLE 0x1 /* Rx Enable */
#define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */
#define ADD_SM 0x4 /* Address Search Mode (SDLC) */
#define RxCRC_ENAB 0x8 /* Rx CRC Enable */
#define ENT_HM 0x10 /* Enter Hunt Mode */
#define AUTO_ENAB 0x20 /* Auto Enables */
#define Rx5 0x0 /* Rx 5 Bits/Character */
#define Rx7 0x40 /* Rx 7 Bits/Character */
#define Rx6 0x80 /* Rx 6 Bits/Character */
#define Rx8 0xc0 /* Rx 8 Bits/Character */
#define RxNBITS_MASK 0xc0
/* Write Register 4 */
#define PAR_ENA 0x1 /* Parity Enable */
#define PAR_EVEN 0x2 /* Parity Even/Odd* */
#define SYNC_ENAB 0 /* Sync Modes Enable */
#define SB1 0x4 /* 1 stop bit/char */
#define SB15 0x8 /* 1.5 stop bits/char */
#define SB2 0xc /* 2 stop bits/char */
#define SB_MASK 0xc
#define MONSYNC 0 /* 8 Bit Sync character */
#define BISYNC 0x10 /* 16 bit sync character */
#define SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */
#define EXTSYNC 0x30 /* External Sync Mode */
#define X1CLK 0x0 /* x1 clock mode */
#define X16CLK 0x40 /* x16 clock mode */
#define X32CLK 0x80 /* x32 clock mode */
#define X64CLK 0xC0 /* x64 clock mode */
#define XCLK_MASK 0xC0
/* Write Register 5 */
#define TxCRC_ENAB 0x1 /* Tx CRC Enable */
#define RTS 0x2 /* RTS */
#define SDLC_CRC 0x4 /* SDLC/CRC-16 */
#define TxENAB 0x8 /* Tx Enable */
#define SND_BRK 0x10 /* Send Break */
#define Tx5 0x0 /* Tx 5 bits (or less)/character */
#define Tx7 0x20 /* Tx 7 bits/character */
#define Tx6 0x40 /* Tx 6 bits/character */
#define Tx8 0x60 /* Tx 8 bits/character */
#define TxNBITS_MASK 0x60
#define DTR 0x80 /* DTR */
/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */
/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
/* Write Register 7' (Some enhanced feature control) */
#define ENEXREAD 0x40 /* Enable read of some write registers */
/* Write Register 8 (transmit buffer) */
/* Write Register 9 (Master interrupt control) */
#define VIS 1 /* Vector Includes Status */
#define NV 2 /* No Vector */
#define DLC 4 /* Disable Lower Chain */
#define MIE 8 /* Master Interrupt Enable */
#define STATHI 0x10 /* Status high */
#define NORESET 0 /* No reset on write to R9 */
#define CHRB 0x40 /* Reset channel B */
#define CHRA 0x80 /* Reset channel A */
#define FHWRES 0xc0 /* Force hardware reset */
/* Write Register 10 (misc control bits) */
#define BIT6 1 /* 6 bit/8bit sync */
#define LOOPMODE 2 /* SDLC Loop mode */
#define ABUNDER 4 /* Abort/flag on SDLC xmit underrun */
#define MARKIDLE 8 /* Mark/flag on idle */
#define GAOP 0x10 /* Go active on poll */
#define NRZ 0 /* NRZ mode */
#define NRZI 0x20 /* NRZI mode */
#define FM1 0x40 /* FM1 (transition = 1) */
#define FM0 0x60 /* FM0 (transition = 0) */
#define CRCPS 0x80 /* CRC Preset I/O */
/* Write Register 11 (Clock Mode control) */
#define TRxCXT 0 /* TRxC = Xtal output */
#define TRxCTC 1 /* TRxC = Transmit clock */
#define TRxCBR 2 /* TRxC = BR Generator Output */
#define TRxCDP 3 /* TRxC = DPLL output */
#define TRxCOI 4 /* TRxC O/I */
#define TCRTxCP 0 /* Transmit clock = RTxC pin */
#define TCTRxCP 8 /* Transmit clock = TRxC pin */
#define TCBR 0x10 /* Transmit clock = BR Generator output */
#define TCDPLL 0x18 /* Transmit clock = DPLL output */
#define RCRTxCP 0 /* Receive clock = RTxC pin */
#define RCTRxCP 0x20 /* Receive clock = TRxC pin */
#define RCBR 0x40 /* Receive clock = BR Generator output */
#define RCDPLL 0x60 /* Receive clock = DPLL output */
#define RTxCX 0x80 /* RTxC Xtal/No Xtal */
/* Write Register 12 (lower byte of baud rate generator time constant) */
/* Write Register 13 (upper byte of baud rate generator time constant) */
/* Write Register 14 (Misc control bits) */
#define BRENABL 1 /* Baud rate generator enable */
#define BRSRC 2 /* Baud rate generator source */
#define DTRREQ 4 /* DTR/Request function */
#define AUTOECHO 8 /* Auto Echo */
#define LOOPBAK 0x10 /* Local loopback */
#define SEARCH 0x20 /* Enter search mode */
#define RMC 0x40 /* Reset missing clock */
#define DISDPLL 0x60 /* Disable DPLL */
#define SSBR 0x80 /* Set DPLL source = BR generator */
#define SSRTxC 0xa0 /* Set DPLL source = RTxC */
#define SFMM 0xc0 /* Set FM mode */
#define SNRZI 0xe0 /* Set NRZI mode */
/* Write Register 15 (external/status interrupt control) */
#define EN85C30 1 /* Enable some 85c30-enhanced registers */
#define ZCIE 2 /* Zero count IE */
#define ENSTFIFO 4 /* Enable status FIFO (SDLC) */
#define DCDIE 8 /* DCD IE */
#define SYNCIE 0x10 /* Sync/hunt IE */
#define CTSIE 0x20 /* CTS IE */
#define TxUIE 0x40 /* Tx Underrun/EOM IE */
#define BRKIE 0x80 /* Break/Abort IE */
/* Read Register 0 */
#define Rx_CH_AV 0x1 /* Rx Character Available */
#define ZCOUNT 0x2 /* Zero count */
#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */
#define DCD 0x8 /* DCD */
#define SYNC_HUNT 0x10 /* Sync/hunt */
#define CTS 0x20 /* CTS */
#define TxEOM 0x40 /* Tx underrun */
#define BRK_ABRT 0x80 /* Break/Abort */
/* Read Register 1 */
#define ALL_SNT 0x1 /* All sent */
/* Residue Data for 8 Rx bits/char programmed */
#define RES3 0x8 /* 0/3 */
#define RES4 0x4 /* 0/4 */
#define RES5 0xc /* 0/5 */
#define RES6 0x2 /* 0/6 */
#define RES7 0xa /* 0/7 */
#define RES8 0x6 /* 0/8 */
#define RES18 0xe /* 1/8 */
#define RES28 0x0 /* 2/8 */
/* Special Rx Condition Interrupts */
#define PAR_ERR 0x10 /* Parity error */
#define Rx_OVR 0x20 /* Rx Overrun Error */
#define FRM_ERR 0x40 /* CRC/Framing Error */
#define END_FR 0x80 /* End of Frame (SDLC) */
/* Read Register 2 (channel b only) - Interrupt vector */
#define CHB_Tx_EMPTY 0x00
#define CHB_EXT_STAT 0x02
#define CHB_Rx_AVAIL 0x04
#define CHB_SPECIAL 0x06
#define CHA_Tx_EMPTY 0x08
#define CHA_EXT_STAT 0x0a
#define CHA_Rx_AVAIL 0x0c
#define CHA_SPECIAL 0x0e
#define STATUS_MASK 0x06
/* Read Register 3 (interrupt pending register) ch a only */
#define CHBEXT 0x1 /* Channel B Ext/Stat IP */
#define CHBTxIP 0x2 /* Channel B Tx IP */
#define CHBRxIP 0x4 /* Channel B Rx IP */
#define CHAEXT 0x8 /* Channel A Ext/Stat IP */
#define CHATxIP 0x10 /* Channel A Tx IP */
#define CHARxIP 0x20 /* Channel A Rx IP */
/* Read Register 8 (receive data register) */
/* Read Register 10 (misc status bits) */
#define ONLOOP 2 /* On loop */
#define LOOPSEND 0x10 /* Loop sending */
#define CLK2MIS 0x40 /* Two clocks missing */
#define CLK1MIS 0x80 /* One clock missing */
/* Read Register 12 (lower byte of baud rate generator constant) */
/* Read Register 13 (upper byte of baud rate generator constant) */
/* Read Register 15 (value of WR 15) */
/* Misc macros */
#define ZS_CLEARERR(channel) (write_zsreg(channel, 0, ERR_RES))
#define ZS_CLEARFIFO(channel) do { volatile unsigned char garbage; \
garbage = read_zsdata(channel); \
garbage = read_zsdata(channel); \
garbage = read_zsdata(channel); \
} while(0)
#endif /* !(_MACSERIAL_H) */
File diff suppressed because it is too large Load Diff
+131
View File
@@ -0,0 +1,131 @@
/*
* /dev/nvram driver for Power Macintosh.
*/
#define NVRAM_VERSION "1.0"
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/fcntl.h>
#include <linux/nvram.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/nvram.h>
#define NVRAM_SIZE 8192
static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
{
lock_kernel();
switch (origin) {
case 1:
offset += file->f_pos;
break;
case 2:
offset += NVRAM_SIZE;
break;
}
if (offset < 0) {
unlock_kernel();
return -EINVAL;
}
file->f_pos = offset;
unlock_kernel();
return file->f_pos;
}
static ssize_t read_nvram(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
unsigned int i;
char __user *p = buf;
if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
if (*ppos >= NVRAM_SIZE)
return 0;
for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count)
if (__put_user(nvram_read_byte(i), p))
return -EFAULT;
*ppos = i;
return p - buf;
}
static ssize_t write_nvram(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
unsigned int i;
const char __user *p = buf;
char c;
if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;
if (*ppos >= NVRAM_SIZE)
return 0;
for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) {
if (__get_user(c, p))
return -EFAULT;
nvram_write_byte(c, i);
}
*ppos = i;
return p - buf;
}
static int nvram_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
switch(cmd) {
case PMAC_NVRAM_GET_OFFSET:
{
int part, offset;
if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
return -EFAULT;
if (part < pmac_nvram_OF || part > pmac_nvram_NR)
return -EINVAL;
offset = pmac_get_partition(part);
if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 0)
return -EFAULT;
break;
}
default:
return -EINVAL;
}
return 0;
}
struct file_operations nvram_fops = {
.owner = THIS_MODULE,
.llseek = nvram_llseek,
.read = read_nvram,
.write = write_nvram,
.ioctl = nvram_ioctl,
};
static struct miscdevice nvram_dev = {
NVRAM_MINOR,
"nvram",
&nvram_fops
};
int __init nvram_init(void)
{
printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n",
NVRAM_VERSION);
return misc_register(&nvram_dev);
}
void __exit nvram_cleanup(void)
{
misc_deregister( &nvram_dev );
}
module_init(nvram_init);
module_exit(nvram_cleanup);
MODULE_LICENSE("GPL");
+364
View File
@@ -0,0 +1,364 @@
/*
* PowerMac G5 SMU driver
*
* Copyright 2004 J. Mayer <l_indien@magic.fr>
* Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
*
* Released under the term of the GNU GPL v2.
*/
/*
* For now, this driver includes:
* - RTC get & set
* - reboot & shutdown commands
* all synchronous with IRQ disabled (ugh)
*
* TODO:
* rework in a way the PMU driver works, that is asynchronous
* with a queue of commands. I'll do that as soon as I have an
* SMU based machine at hand. Some more cleanup is needed too,
* like maybe fitting it into a platform device, etc...
* Also check what's up with cache coherency, and if we really
* can't do better than flushing the cache, maybe build a table
* of command len/reply len like the PMU driver to only flush
* what is actually necessary.
* --BenH.
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/dmapool.h>
#include <linux/bootmem.h>
#include <linux/vmalloc.h>
#include <linux/highmem.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/rtc.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/smu.h>
#include <asm/sections.h>
#include <asm/abs_addr.h>
#define DEBUG_SMU 1
#ifdef DEBUG_SMU
#define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0)
#else
#define DPRINTK(fmt, args...) do { } while (0)
#endif
/*
* This is the command buffer passed to the SMU hardware
*/
struct smu_cmd_buf {
u8 cmd;
u8 length;
u8 data[0x0FFE];
};
struct smu_device {
spinlock_t lock;
struct device_node *of_node;
int db_ack; /* doorbell ack GPIO */
int db_req; /* doorbell req GPIO */
u32 __iomem *db_buf; /* doorbell buffer */
struct smu_cmd_buf *cmd_buf; /* command buffer virtual */
u32 cmd_buf_abs; /* command buffer absolute */
};
/*
* I don't think there will ever be more than one SMU, so
* for now, just hard code that
*/
static struct smu_device *smu;
/*
* SMU low level communication stuff
*/
static inline int smu_cmd_stat(struct smu_cmd_buf *cmd_buf, u8 cmd_ack)
{
rmb();
return cmd_buf->cmd == cmd_ack && cmd_buf->length != 0;
}
static inline u8 smu_save_ack_cmd(struct smu_cmd_buf *cmd_buf)
{
return (~cmd_buf->cmd) & 0xff;
}
static void smu_send_cmd(struct smu_device *dev)
{
/* SMU command buf is currently cacheable, we need a physical
* address. This isn't exactly a DMA mapping here, I suspect
* the SMU is actually communicating with us via i2c to the
* northbridge or the CPU to access RAM.
*/
writel(dev->cmd_buf_abs, dev->db_buf);
/* Ring the SMU doorbell */
pmac_do_feature_call(PMAC_FTR_WRITE_GPIO, NULL, dev->db_req, 4);
pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, dev->db_req, 4);
}
static int smu_cmd_done(struct smu_device *dev)
{
unsigned long wait = 0;
int gpio;
/* Check the SMU doorbell */
do {
gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO,
NULL, dev->db_ack);
if ((gpio & 7) == 7)
return 0;
udelay(100);
} while(++wait < 10000);
printk(KERN_ERR "SMU timeout !\n");
return -ENXIO;
}
static int smu_do_cmd(struct smu_device *dev)
{
int rc;
u8 cmd_ack;
DPRINTK("SMU do_cmd %02x len=%d %02x\n",
dev->cmd_buf->cmd, dev->cmd_buf->length,
dev->cmd_buf->data[0]);
cmd_ack = smu_save_ack_cmd(dev->cmd_buf);
/* Clear cmd_buf cache lines */
flush_inval_dcache_range((unsigned long)dev->cmd_buf,
((unsigned long)dev->cmd_buf) +
sizeof(struct smu_cmd_buf));
smu_send_cmd(dev);
rc = smu_cmd_done(dev);
if (rc == 0)
rc = smu_cmd_stat(dev->cmd_buf, cmd_ack) ? 0 : -1;
DPRINTK("SMU do_cmd %02x len=%d %02x => %d (%02x)\n",
dev->cmd_buf->cmd, dev->cmd_buf->length,
dev->cmd_buf->data[0], rc, cmd_ack);
return rc;
}
/* RTC low level commands */
static inline int bcd2hex (int n)
{
return (((n & 0xf0) >> 4) * 10) + (n & 0xf);
}
static inline int hex2bcd (int n)
{
return ((n / 10) << 4) + (n % 10);
}
#if 0
static inline void smu_fill_set_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf)
{
cmd_buf->cmd = 0x8e;
cmd_buf->length = 8;
cmd_buf->data[0] = 0x00;
memset(cmd_buf->data + 1, 0, 7);
}
static inline void smu_fill_get_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf)
{
cmd_buf->cmd = 0x8e;
cmd_buf->length = 1;
cmd_buf->data[0] = 0x01;
}
static inline void smu_fill_dis_pwrup_timer_cmd(struct smu_cmd_buf *cmd_buf)
{
cmd_buf->cmd = 0x8e;
cmd_buf->length = 1;
cmd_buf->data[0] = 0x02;
}
#endif
static inline void smu_fill_set_rtc_cmd(struct smu_cmd_buf *cmd_buf,
struct rtc_time *time)
{
cmd_buf->cmd = 0x8e;
cmd_buf->length = 8;
cmd_buf->data[0] = 0x80;
cmd_buf->data[1] = hex2bcd(time->tm_sec);
cmd_buf->data[2] = hex2bcd(time->tm_min);
cmd_buf->data[3] = hex2bcd(time->tm_hour);
cmd_buf->data[4] = time->tm_wday;
cmd_buf->data[5] = hex2bcd(time->tm_mday);
cmd_buf->data[6] = hex2bcd(time->tm_mon) + 1;
cmd_buf->data[7] = hex2bcd(time->tm_year - 100);
}
static inline void smu_fill_get_rtc_cmd(struct smu_cmd_buf *cmd_buf)
{
cmd_buf->cmd = 0x8e;
cmd_buf->length = 1;
cmd_buf->data[0] = 0x81;
}
static void smu_parse_get_rtc_reply(struct smu_cmd_buf *cmd_buf,
struct rtc_time *time)
{
time->tm_sec = bcd2hex(cmd_buf->data[0]);
time->tm_min = bcd2hex(cmd_buf->data[1]);
time->tm_hour = bcd2hex(cmd_buf->data[2]);
time->tm_wday = bcd2hex(cmd_buf->data[3]);
time->tm_mday = bcd2hex(cmd_buf->data[4]);
time->tm_mon = bcd2hex(cmd_buf->data[5]) - 1;
time->tm_year = bcd2hex(cmd_buf->data[6]) + 100;
}
int smu_get_rtc_time(struct rtc_time *time)
{
unsigned long flags;
int rc;
if (smu == NULL)
return -ENODEV;
memset(time, 0, sizeof(struct rtc_time));
spin_lock_irqsave(&smu->lock, flags);
smu_fill_get_rtc_cmd(smu->cmd_buf);
rc = smu_do_cmd(smu);
if (rc == 0)
smu_parse_get_rtc_reply(smu->cmd_buf, time);
spin_unlock_irqrestore(&smu->lock, flags);
return rc;
}
int smu_set_rtc_time(struct rtc_time *time)
{
unsigned long flags;
int rc;
if (smu == NULL)
return -ENODEV;
spin_lock_irqsave(&smu->lock, flags);
smu_fill_set_rtc_cmd(smu->cmd_buf, time);
rc = smu_do_cmd(smu);
spin_unlock_irqrestore(&smu->lock, flags);
return rc;
}
void smu_shutdown(void)
{
const unsigned char *command = "SHUTDOWN";
unsigned long flags;
if (smu == NULL)
return;
spin_lock_irqsave(&smu->lock, flags);
smu->cmd_buf->cmd = 0xaa;
smu->cmd_buf->length = strlen(command);
strcpy(smu->cmd_buf->data, command);
smu_do_cmd(smu);
for (;;)
;
spin_unlock_irqrestore(&smu->lock, flags);
}
void smu_restart(void)
{
const unsigned char *command = "RESTART";
unsigned long flags;
if (smu == NULL)
return;
spin_lock_irqsave(&smu->lock, flags);
smu->cmd_buf->cmd = 0xaa;
smu->cmd_buf->length = strlen(command);
strcpy(smu->cmd_buf->data, command);
smu_do_cmd(smu);
for (;;)
;
spin_unlock_irqrestore(&smu->lock, flags);
}
int smu_present(void)
{
return smu != NULL;
}
int smu_init (void)
{
struct device_node *np;
u32 *data;
np = of_find_node_by_type(NULL, "smu");
if (np == NULL)
return -ENODEV;
if (smu_cmdbuf_abs == 0) {
printk(KERN_ERR "SMU: Command buffer not allocated !\n");
return -EINVAL;
}
smu = alloc_bootmem(sizeof(struct smu_device));
if (smu == NULL)
return -ENOMEM;
memset(smu, 0, sizeof(*smu));
spin_lock_init(&smu->lock);
smu->of_node = np;
/* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a
* 32 bits value safely
*/
smu->cmd_buf_abs = (u32)smu_cmdbuf_abs;
smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs);
np = of_find_node_by_name(NULL, "smu-doorbell");
if (np == NULL) {
printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n");
goto fail;
}
data = (u32 *)get_property(np, "reg", NULL);
of_node_put(np);
if (data == NULL) {
printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n");
goto fail;
}
/* Current setup has one doorbell GPIO that does both doorbell
* and ack. GPIOs are at 0x50, best would be to find that out
* in the device-tree though.
*/
smu->db_req = 0x50 + *data;
smu->db_ack = 0x50 + *data;
/* Doorbell buffer is currently hard-coded, I didn't find a proper
* device-tree entry giving the address. Best would probably to use
* an offset for K2 base though, but let's do it that way for now.
*/
smu->db_buf = ioremap(0x8000860c, 0x1000);
if (smu->db_buf == NULL) {
printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n");
goto fail;
}
sys_ctrler = SYS_CTRLER_SMU;
return 0;
fail:
smu = NULL;
return -ENXIO;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+297
View File
@@ -0,0 +1,297 @@
#ifndef __THERM_PMAC_7_2_H__
#define __THERM_PMAC_7_2_H__
typedef unsigned short fu16;
typedef int fs32;
typedef short fs16;
struct mpu_data
{
u8 signature; /* 0x00 - EEPROM sig. */
u8 bytes_used; /* 0x01 - Bytes used in eeprom (160 ?) */
u8 size; /* 0x02 - EEPROM size (256 ?) */
u8 version; /* 0x03 - EEPROM version */
u32 data_revision; /* 0x04 - Dataset revision */
u8 processor_bin_code[3]; /* 0x08 - Processor BIN code */
u8 bin_code_expansion; /* 0x0b - ??? (padding ?) */
u8 processor_num; /* 0x0c - Number of CPUs on this MPU */
u8 input_mul_bus_div; /* 0x0d - Clock input multiplier/bus divider */
u8 reserved1[2]; /* 0x0e - */
u32 input_clk_freq_high; /* 0x10 - Input clock frequency high */
u8 cpu_nb_target_cycles; /* 0x14 - ??? */
u8 cpu_statlat; /* 0x15 - ??? */
u8 cpu_snooplat; /* 0x16 - ??? */
u8 cpu_snoopacc; /* 0x17 - ??? */
u8 nb_paamwin; /* 0x18 - ??? */
u8 nb_statlat; /* 0x19 - ??? */
u8 nb_snooplat; /* 0x1a - ??? */
u8 nb_snoopwin; /* 0x1b - ??? */
u8 api_bus_mode; /* 0x1c - ??? */
u8 reserved2[3]; /* 0x1d - */
u32 input_clk_freq_low; /* 0x20 - Input clock frequency low */
u8 processor_card_slot; /* 0x24 - Processor card slot number */
u8 reserved3[2]; /* 0x25 - */
u8 padjmax; /* 0x27 - Max power adjustment (Not in OF!) */
u8 ttarget; /* 0x28 - Target temperature */
u8 tmax; /* 0x29 - Max temperature */
u8 pmaxh; /* 0x2a - Max power */
u8 tguardband; /* 0x2b - Guardband temp ??? Hist. len in OSX */
fs32 pid_gp; /* 0x2c - PID proportional gain */
fs32 pid_gr; /* 0x30 - PID reset gain */
fs32 pid_gd; /* 0x34 - PID derivative gain */
fu16 voph; /* 0x38 - Vop High */
fu16 vopl; /* 0x3a - Vop Low */
fs16 nactual_die; /* 0x3c - nActual Die */
fs16 nactual_heatsink; /* 0x3e - nActual Heatsink */
fs16 nactual_system; /* 0x40 - nActual System */
u16 calibration_flags; /* 0x42 - Calibration flags */
fu16 mdiode; /* 0x44 - Diode M value (scaling factor) */
fs16 bdiode; /* 0x46 - Diode B value (offset) */
fs32 theta_heat_sink; /* 0x48 - Theta heat sink */
u16 rminn_intake_fan; /* 0x4c - Intake fan min RPM */
u16 rmaxn_intake_fan; /* 0x4e - Intake fan max RPM */
u16 rminn_exhaust_fan; /* 0x50 - Exhaust fan min RPM */
u16 rmaxn_exhaust_fan; /* 0x52 - Exhaust fan max RPM */
u8 processor_part_num[8]; /* 0x54 - Processor part number XX pumps min/max */
u32 processor_lot_num; /* 0x5c - Processor lot number */
u8 orig_card_sernum[0x10]; /* 0x60 - Card original serial number */
u8 curr_card_sernum[0x10]; /* 0x70 - Card current serial number */
u8 mlb_sernum[0x18]; /* 0x80 - MLB serial number */
u32 checksum1; /* 0x98 - */
u32 checksum2; /* 0x9c - */
}; /* Total size = 0xa0 */
/* Display a 16.16 fixed point value */
#define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16)
/*
* Maximum number of seconds to be in critical state (after a
* normal shutdown attempt). If the machine isn't down after
* this counter elapses, we force an immediate machine power
* off.
*/
#define MAX_CRITICAL_STATE 30
static char * critical_overtemp_path = "/sbin/critical_overtemp";
/*
* This option is "weird" :) Basically, if you define this to 1
* the control loop for the RPMs fans (not PWMs) will apply the
* correction factor obtained from the PID to the _actual_ RPM
* speed read from the FCU.
* If you define the below constant to 0, then it will be
* applied to the setpoint RPM speed, that is basically the
* speed we proviously "asked" for.
*
* I'm not sure which of these Apple's algorithm is supposed
* to use
*/
#define RPM_PID_USE_ACTUAL_SPEED 0
/*
* i2c IDs. Currently, we hard code those and assume that
* the FCU is on U3 bus 1 while all sensors are on U3 bus
* 0. This appear to be safe enough for this first version
* of the driver, though I would accept any clean patch
* doing a better use of the device-tree without turning the
* while i2c registration mecanism into a racy mess
*
* Note: Xserve changed this. We have some bits on the K2 bus,
* which I arbitrarily set to 0x200. Ultimately, we really want
* too lookup these in the device-tree though
*/
#define FAN_CTRLER_ID 0x15e
#define SUPPLY_MONITOR_ID 0x58
#define SUPPLY_MONITORB_ID 0x5a
#define DRIVES_DALLAS_ID 0x94
#define BACKSIDE_MAX_ID 0x98
#define XSERVE_DIMMS_LM87 0x25a
/*
* Some MAX6690, DS1775, LM87 register definitions
*/
#define MAX6690_INT_TEMP 0
#define MAX6690_EXT_TEMP 1
#define DS1775_TEMP 0
#define LM87_INT_TEMP 0x27
/*
* Scaling factors for the AD7417 ADC converters (except
* for the CPU diode which is obtained from the EEPROM).
* Those values are obtained from the property list of
* the darwin driver
*/
#define ADC_12V_CURRENT_SCALE 0x0320 /* _AD2 */
#define ADC_CPU_VOLTAGE_SCALE 0x00a0 /* _AD3 */
#define ADC_CPU_CURRENT_SCALE 0x1f40 /* _AD4 */
/*
* PID factors for the U3/Backside fan control loop. We have 2 sets
* of values here, one set for U3 and one set for U3H
*/
#define BACKSIDE_FAN_PWM_DEFAULT_ID 1
#define BACKSIDE_FAN_PWM_INDEX 0
#define BACKSIDE_PID_U3_G_d 0x02800000
#define BACKSIDE_PID_U3H_G_d 0x01400000
#define BACKSIDE_PID_RACK_G_d 0x00500000
#define BACKSIDE_PID_G_p 0x00500000
#define BACKSIDE_PID_RACK_G_p 0x0004cccc
#define BACKSIDE_PID_G_r 0x00000000
#define BACKSIDE_PID_U3_INPUT_TARGET 0x00410000
#define BACKSIDE_PID_U3H_INPUT_TARGET 0x004b0000
#define BACKSIDE_PID_RACK_INPUT_TARGET 0x00460000
#define BACKSIDE_PID_INTERVAL 5
#define BACKSIDE_PID_RACK_INTERVAL 1
#define BACKSIDE_PID_OUTPUT_MAX 100
#define BACKSIDE_PID_U3_OUTPUT_MIN 20
#define BACKSIDE_PID_U3H_OUTPUT_MIN 20
#define BACKSIDE_PID_HISTORY_SIZE 2
struct basckside_pid_params
{
s32 G_d;
s32 G_p;
s32 G_r;
s32 input_target;
s32 output_min;
s32 output_max;
s32 interval;
int additive;
};
struct backside_pid_state
{
int ticks;
struct i2c_client * monitor;
s32 sample_history[BACKSIDE_PID_HISTORY_SIZE];
s32 error_history[BACKSIDE_PID_HISTORY_SIZE];
int cur_sample;
s32 last_temp;
int pwm;
int first;
};
/*
* PID factors for the Drive Bay fan control loop
*/
#define DRIVES_FAN_RPM_DEFAULT_ID 2
#define DRIVES_FAN_RPM_INDEX 1
#define DRIVES_PID_G_d 0x01e00000
#define DRIVES_PID_G_p 0x00500000
#define DRIVES_PID_G_r 0x00000000
#define DRIVES_PID_INPUT_TARGET 0x00280000
#define DRIVES_PID_INTERVAL 5
#define DRIVES_PID_OUTPUT_MAX 4000
#define DRIVES_PID_OUTPUT_MIN 300
#define DRIVES_PID_HISTORY_SIZE 2
struct drives_pid_state
{
int ticks;
struct i2c_client * monitor;
s32 sample_history[BACKSIDE_PID_HISTORY_SIZE];
s32 error_history[BACKSIDE_PID_HISTORY_SIZE];
int cur_sample;
s32 last_temp;
int rpm;
int first;
};
#define SLOTS_FAN_PWM_DEFAULT_ID 2
#define SLOTS_FAN_PWM_INDEX 2
#define SLOTS_FAN_DEFAULT_PWM 50 /* Do better here ! */
/*
* PID factors for the Xserve DIMM control loop
*/
#define DIMM_PID_G_d 0
#define DIMM_PID_G_p 0
#define DIMM_PID_G_r 0x6553600
#define DIMM_PID_INPUT_TARGET 3276800
#define DIMM_PID_INTERVAL 1
#define DIMM_PID_OUTPUT_MAX 14000
#define DIMM_PID_OUTPUT_MIN 4000
#define DIMM_PID_HISTORY_SIZE 20
struct dimm_pid_state
{
int ticks;
struct i2c_client * monitor;
s32 sample_history[DIMM_PID_HISTORY_SIZE];
s32 error_history[DIMM_PID_HISTORY_SIZE];
int cur_sample;
s32 last_temp;
int first;
int output;
};
/* Desktops */
#define CPUA_INTAKE_FAN_RPM_DEFAULT_ID 3
#define CPUA_EXHAUST_FAN_RPM_DEFAULT_ID 4
#define CPUB_INTAKE_FAN_RPM_DEFAULT_ID 5
#define CPUB_EXHAUST_FAN_RPM_DEFAULT_ID 6
#define CPUA_INTAKE_FAN_RPM_INDEX 3
#define CPUA_EXHAUST_FAN_RPM_INDEX 4
#define CPUB_INTAKE_FAN_RPM_INDEX 5
#define CPUB_EXHAUST_FAN_RPM_INDEX 6
#define CPU_INTAKE_SCALE 0x0000f852
#define CPU_TEMP_HISTORY_SIZE 2
#define CPU_POWER_HISTORY_SIZE 10
#define CPU_PID_INTERVAL 1
#define CPU_MAX_OVERTEMP 30
#define CPUA_PUMP_RPM_INDEX 7
#define CPUB_PUMP_RPM_INDEX 8
#define CPU_PUMP_OUTPUT_MAX 3200
#define CPU_PUMP_OUTPUT_MIN 1250
/* Xserve */
#define CPU_A1_FAN_RPM_INDEX 9
#define CPU_A2_FAN_RPM_INDEX 10
#define CPU_A3_FAN_RPM_INDEX 11
#define CPU_B1_FAN_RPM_INDEX 12
#define CPU_B2_FAN_RPM_INDEX 13
#define CPU_B3_FAN_RPM_INDEX 14
struct cpu_pid_state
{
int index;
struct i2c_client * monitor;
struct mpu_data mpu;
int overtemp;
s32 temp_history[CPU_TEMP_HISTORY_SIZE];
int cur_temp;
s32 power_history[CPU_POWER_HISTORY_SIZE];
s32 error_history[CPU_POWER_HISTORY_SIZE];
int cur_power;
int count_power;
int rpm;
int intake_rpm;
s32 voltage;
s32 current_a;
s32 last_temp;
s32 last_power;
int first;
u8 adc_config;
s32 pump_min;
s32 pump_max;
};
/*
* Driver state
*/
enum {
state_detached,
state_attaching,
state_attached,
state_detaching,
};
#endif /* __THERM_PMAC_7_2_H__ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More