Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
3535c4c0
Commit
3535c4c0
authored
Jul 11, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove obsoleted drivers/char/h8.c drivers/char/h8.h.
parent
1baaf2ab
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
0 additions
and
1426 deletions
+0
-1426
drivers/char/h8.c
drivers/char/h8.c
+0
-1180
drivers/char/h8.h
drivers/char/h8.h
+0
-246
No files found.
drivers/char/h8.c
deleted
100644 → 0
View file @
1baaf2ab
/*
* Hitachi H8/337 Microcontroller driver
*
* The H8 is used to deal with the power and thermal environment
* of a system.
*
* Fixes:
* June 1999, AV added releasing /proc/driver/h8
* Feb 2000, Borislav Deianov
* changed queues to use list.h instead of lists.h
*/
#include <linux/config.h>
#include <linux/module.h>
#include <asm/system.h>
#include <asm/io.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/timer.h>
#include <linux/fcntl.h>
#include <linux/linkage.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
#include <linux/miscdevice.h>
#include <linux/list.h>
#include <linux/ioport.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/slab.h>
#include "h8.h"
#define DEBUG_H8
#ifdef DEBUG_H8
#define Dprintk printk
#else
#define Dprintk
#endif
#define XDprintk if(h8_debug==-1)printk
/*
* The h8 device is one of the misc char devices.
*/
#define H8_MINOR_DEV 140
/*
* Forward declarations.
*/
static
int
h8_init
(
void
);
static
int
h8_display_blank
(
void
);
static
int
h8_display_unblank
(
void
);
static
void
h8_intr
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
int
h8_get_info
(
char
*
,
char
**
,
off_t
,
int
);
/*
* Support Routines.
*/
static
void
h8_hw_init
(
void
);
static
void
h8_start_new_cmd
(
void
);
static
void
h8_send_next_cmd_byte
(
void
);
static
void
h8_read_event_status
(
void
);
static
void
h8_sync
(
void
);
static
void
h8_q_cmd
(
u_char
*
,
int
,
int
);
static
void
h8_cmd_done
(
h8_cmd_q_t
*
qp
);
static
int
h8_alloc_queues
(
void
);
static
u_long
h8_get_cpu_speed
(
void
);
static
int
h8_get_curr_temp
(
u_char
curr_temp
[]);
static
void
h8_get_max_temp
(
void
);
static
void
h8_get_upper_therm_thold
(
void
);
static
void
h8_set_upper_therm_thold
(
int
);
static
int
h8_get_ext_status
(
u_char
stat_word
[]);
static
int
h8_monitor_thread
(
void
*
);
static
int
h8_manage_therm
(
void
);
static
void
h8_set_cpu_speed
(
int
speed_divisor
);
static
void
h8_start_monitor_timer
(
unsigned
long
secs
);
static
void
h8_activate_monitor
(
unsigned
long
unused
);
/* in arch/alpha/kernel/lca.c */
extern
void
lca_clock_print
(
void
);
extern
int
lca_get_clock
(
void
);
extern
void
lca_clock_fiddle
(
int
);
static
void
h8_set_event_mask
(
int
);
static
void
h8_clear_event_mask
(
int
);
/*
* Driver structures
*/
static
struct
timer_list
h8_monitor_timer
;
static
int
h8_monitor_timer_active
=
0
;
static
char
driver_version
[]
=
"X0.0"
;
/* no spaces */
static
union
intr_buf
intrbuf
;
static
int
intr_buf_ptr
;
static
union
intr_buf
xx
;
static
u_char
last_temp
;
/*
* I/O Macros for register reads and writes.
*/
#define H8_READ(a) inb((a))
#define H8_WRITE(d,a) outb((d),(a))
#define H8_GET_STATUS H8_READ((h8_base) + H8_STATUS_REG_OFF)
#define H8_READ_DATA H8_READ((h8_base) + H8_DATA_REG_OFF)
#define WRITE_DATA(d) H8_WRITE((d), h8_base + H8_DATA_REG_OFF)
#define WRITE_CMD(d) H8_WRITE((d), h8_base + H8_CMD_REG_OFF)
static
unsigned
int
h8_base
=
H8_BASE_ADDR
;
static
unsigned
int
h8_irq
=
H8_IRQ
;
static
unsigned
int
h8_state
=
H8_IDLE
;
static
unsigned
int
h8_index
=
-
1
;
static
unsigned
int
h8_enabled
=
0
;
static
LIST_HEAD
(
h8_actq
);
static
LIST_HEAD
(
h8_cmdq
);
static
LIST_HEAD
(
h8_freeq
);
/*
* Globals used in thermal control of Alphabook1.
*/
static
int
cpu_speed_divisor
=
-
1
;
static
int
h8_event_mask
=
0
;
static
DECLARE_WAIT_QUEUE_HEAD
(
h8_monitor_wait
);
static
unsigned
int
h8_command_mask
=
0
;
static
int
h8_uthermal_threshold
=
DEFAULT_UTHERMAL_THRESHOLD
;
static
int
h8_uthermal_window
=
UTH_HYSTERESIS
;
static
int
h8_debug
=
0xfffffdfc
;
static
int
h8_ldamp
=
MHZ_115
;
static
int
h8_udamp
=
MHZ_57
;
static
u_char
h8_current_temp
=
0
;
static
u_char
h8_system_temp
=
0
;
static
int
h8_sync_channel
=
0
;
static
DECLARE_WAIT_QUEUE_HEAD
(
h8_sync_wait
);
static
int
h8_init_performed
;
/* CPU speeds and clock divisor values */
static
int
speed_tab
[
6
]
=
{
230
,
153
,
115
,
57
,
28
,
14
};
/*
* H8 interrupt handler
*/
static
void
h8_intr
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
u_char
stat_reg
,
data_reg
;
h8_cmd_q_t
*
qp
=
list_entry
(
h8_actq
.
next
,
h8_cmd_q_t
,
link
);
stat_reg
=
H8_GET_STATUS
;
data_reg
=
H8_READ_DATA
;
XDprintk
(
"h8_intr: state %d status 0x%x data 0x%x
\n
"
,
h8_state
,
stat_reg
,
data_reg
);
switch
(
h8_state
)
{
/* Response to an asynchronous event. */
case
H8_IDLE
:
{
/* H8_IDLE */
if
(
stat_reg
&
H8_OFULL
)
{
if
(
data_reg
==
H8_INTR
)
{
h8_state
=
H8_INTR_MODE
;
/* Executing a command to determine what happened. */
WRITE_CMD
(
H8_RD_EVENT_STATUS
);
intr_buf_ptr
=
1
;
WRITE_CMD
(
H8_RD_EVENT_STATUS
);
}
else
{
Dprintk
(
"h8_intr: idle stat 0x%x data 0x%x
\n
"
,
stat_reg
,
data_reg
);
}
}
else
{
Dprintk
(
"h8_intr: bogus interrupt
\n
"
);
}
break
;
}
case
H8_INTR_MODE
:
{
/* H8_INTR_MODE */
XDprintk
(
"H8 intr/intr_mode
\n
"
);
if
(
data_reg
==
H8_BYTE_LEVEL_ACK
)
{
return
;
}
else
if
(
data_reg
==
H8_CMD_ACK
)
{
return
;
}
else
{
intrbuf
.
byte
[
intr_buf_ptr
]
=
data_reg
;
if
(
!
intr_buf_ptr
)
{
h8_state
=
H8_IDLE
;
h8_read_event_status
();
}
intr_buf_ptr
--
;
}
break
;
}
/* Placed in this state by h8_start_new_cmd(). */
case
H8_XMIT
:
{
/* H8_XMIT */
XDprintk
(
"H8 intr/xmit
\n
"
);
/* If a byte level acknowledgement has been received */
if
(
data_reg
==
H8_BYTE_LEVEL_ACK
)
{
XDprintk
(
"H8 intr/xmit BYTE ACK
\n
"
);
qp
->
nacks
++
;
if
(
qp
->
nacks
>
qp
->
ncmd
)
if
(
h8_debug
&
0x1
)
Dprintk
(
"h8intr: bogus # of acks!
\n
"
);
/*
* If the number of bytes sent is less than the total
* number of bytes in the command.
*/
if
(
qp
->
cnt
<
qp
->
ncmd
)
{
h8_send_next_cmd_byte
();
}
return
;
/* If the complete command has produced an acknowledgement. */
}
else
if
(
data_reg
==
H8_CMD_ACK
)
{
XDprintk
(
"H8 intr/xmit CMD ACK
\n
"
);
/* If there are response bytes */
if
(
qp
->
nrsp
)
h8_state
=
H8_RCV
;
else
h8_state
=
H8_IDLE
;
qp
->
cnt
=
0
;
return
;
/* Error, need to start over with a clean slate. */
}
else
if
(
data_reg
==
H8_NACK
)
{
XDprintk
(
"h8_intr: NACK received restarting command
\n
"
);
qp
->
nacks
=
0
;
qp
->
cnt
=
0
;
h8_state
=
H8_IDLE
;
WRITE_CMD
(
H8_SYNC
);
return
;
}
else
{
Dprintk
(
"h8intr: xmit unknown data 0x%x
\n
"
,
data_reg
);
return
;
}
break
;
}
case
H8_RESYNC
:
{
/* H8_RESYNC */
XDprintk
(
"H8 intr/resync
\n
"
);
if
(
data_reg
==
H8_BYTE_LEVEL_ACK
)
{
return
;
}
else
if
(
data_reg
==
H8_SYNC_BYTE
)
{
h8_state
=
H8_IDLE
;
if
(
!
list_empty
(
&
h8_actq
))
h8_send_next_cmd_byte
();
}
else
{
Dprintk
(
"h8_intr: resync unknown data 0x%x
\n
"
,
data_reg
);
return
;
}
break
;
}
case
H8_RCV
:
{
/* H8_RCV */
XDprintk
(
"H8 intr/rcv
\n
"
);
if
(
qp
->
cnt
<
qp
->
nrsp
)
{
qp
->
rcvbuf
[
qp
->
cnt
]
=
data_reg
;
qp
->
cnt
++
;
/* If command reception finished. */
if
(
qp
->
cnt
==
qp
->
nrsp
)
{
h8_state
=
H8_IDLE
;
list_del
(
&
qp
->
link
);
h8_cmd_done
(
qp
);
/* More commands to send over? */
if
(
!
list_empty
(
&
h8_cmdq
))
h8_start_new_cmd
();
}
return
;
}
else
{
Dprintk
(
"h8intr: rcv overflow cmd 0x%x
\n
"
,
qp
->
cmdbuf
[
0
]);
}
break
;
}
default:
/* default */
Dprintk
(
"H8 intr/unknown
\n
"
);
break
;
}
return
;
}
static
void
__exit
h8_cleanup
(
void
)
{
remove_proc_entry
(
"driver/h8"
,
NULL
);
release_region
(
h8_base
,
8
);
free_irq
(
h8_irq
,
NULL
);
}
static
int
__init
h8_init
(
void
)
{
if
(
request_irq
(
h8_irq
,
h8_intr
,
SA_INTERRUPT
,
"h8"
,
NULL
))
{
printk
(
KERN_ERR
"H8: error: IRQ %d is not free
\n
"
,
h8_irq
);
return
-
EIO
;
}
printk
(
KERN_INFO
"H8 at 0x%x IRQ %d
\n
"
,
h8_base
,
h8_irq
);
if
(
!
request_region
(
h8_base
,
8
,
"h8"
))
{
free_irq
(
h8_irq
,
NULL
);
return
-
EIO
;
}
create_proc_info_entry
(
"driver/h8"
,
0
,
NULL
,
h8_get_info
);
h8_alloc_queues
();
h8_hw_init
();
kernel_thread
(
h8_monitor_thread
,
NULL
,
0
);
return
0
;
}
module_init
(
h8_init
);
module_exit
(
h8_cleanup
);
static
void
__init
h8_hw_init
(
void
)
{
u_char
buf
[
H8_MAX_CMD_SIZE
];
/* set CPU speed to max for booting */
h8_set_cpu_speed
(
MHZ_230
);
/*
* Initialize the H8
*/
h8_sync
();
/* activate interrupts */
/* To clear conditions left by console */
h8_read_event_status
();
/* Perform a conditioning read */
buf
[
0
]
=
H8_DEVICE_CONTROL
;
buf
[
1
]
=
0xff
;
buf
[
2
]
=
0x0
;
h8_q_cmd
(
buf
,
3
,
1
);
/* Turn on built-in and external mice, capture power switch */
buf
[
0
]
=
H8_DEVICE_CONTROL
;
buf
[
1
]
=
0x0
;
buf
[
2
]
=
H8_ENAB_INT_PTR
|
H8_ENAB_EXT_PTR
|
/*H8_DISAB_PWR_OFF_SW |*/
H8_ENAB_LOW_SPD_IND
;
h8_q_cmd
(
buf
,
3
,
1
);
h8_enabled
=
1
;
return
;
}
static
int
h8_get_info
(
char
*
buf
,
char
**
start
,
off_t
fpos
,
int
length
)
{
#ifdef CONFIG_PROC_FS
char
*
p
;
if
(
!
h8_enabled
)
return
0
;
p
=
buf
;
/*
0) Linux driver version (this will change if format changes)
1)
2)
3)
4)
*/
p
+=
sprintf
(
p
,
"%s
\n
"
,
driver_version
);
return
p
-
buf
;
#else
return
0
;
#endif
}
/* Called from console driver -- must make sure h8_enabled. */
static
int
h8_display_blank
(
void
)
{
#ifdef CONFIG_H8_DISPLAY_BLANK
int
error
;
if
(
!
h8_enabled
)
return
0
;
error
=
h8_set_display_power_state
(
H8_STATE_STANDBY
);
if
(
error
==
H8_SUCCESS
)
return
1
;
h8_error
(
"set display standby"
,
error
);
#endif
return
0
;
}
/* Called from console driver -- must make sure h8_enabled. */
static
int
h8_display_unblank
(
void
)
{
#ifdef CONFIG_H8_DISPLAY_BLANK
int
error
;
if
(
!
h8_enabled
)
return
0
;
error
=
h8_set_display_power_state
(
H8_STATE_READY
);
if
(
error
==
H8_SUCCESS
)
return
1
;
h8_error
(
"set display ready"
,
error
);
#endif
return
0
;
}
static
int
h8_alloc_queues
(
void
)
{
h8_cmd_q_t
*
qp
;
unsigned
long
flags
;
int
i
;
qp
=
(
h8_cmd_q_t
*
)
kmalloc
((
sizeof
(
h8_cmd_q_t
)
*
H8_Q_ALLOC_AMOUNT
),
GFP_KERNEL
);
if
(
!
qp
)
{
printk
(
KERN_ERR
"H8: could not allocate memory for command queue
\n
"
);
return
(
0
);
}
/* add to the free queue */
save_flags
(
flags
);
cli
();
for
(
i
=
0
;
i
<
H8_Q_ALLOC_AMOUNT
;
i
++
)
{
/* place each at front of freeq */
list_add
(
&
qp
[
i
].
link
,
&
h8_freeq
);
}
restore_flags
(
flags
);
return
(
1
);
}
/*
* Basic means by which commands are sent to the H8.
*/
void
h8_q_cmd
(
u_char
*
cmd
,
int
cmd_size
,
int
resp_size
)
{
h8_cmd_q_t
*
qp
;
unsigned
long
flags
;
int
i
;
/* get cmd buf */
save_flags
(
flags
);
cli
();
while
(
list_empty
(
&
h8_freeq
))
{
Dprintk
(
"H8: need to allocate more cmd buffers
\n
"
);
restore_flags
(
flags
);
h8_alloc_queues
();
save_flags
(
flags
);
cli
();
}
/* get first element from queue */
qp
=
list_entry
(
h8_freeq
.
next
,
h8_cmd_q_t
,
link
);
list_del
(
&
qp
->
link
);
restore_flags
(
flags
);
/* fill it in */
for
(
i
=
0
;
i
<
cmd_size
;
i
++
)
qp
->
cmdbuf
[
i
]
=
cmd
[
i
];
qp
->
ncmd
=
cmd_size
;
qp
->
nrsp
=
resp_size
;
/* queue it at the end of the cmd queue */
save_flags
(
flags
);
cli
();
/* XXX this actually puts it at the start of cmd queue, bug? */
list_add
(
&
qp
->
link
,
&
h8_cmdq
);
restore_flags
(
flags
);
h8_start_new_cmd
();
}
void
h8_start_new_cmd
(
void
)
{
unsigned
long
flags
;
h8_cmd_q_t
*
qp
;
save_flags
(
flags
);
cli
();
if
(
h8_state
!=
H8_IDLE
)
{
if
(
h8_debug
&
0x1
)
Dprintk
(
"h8_start_new_cmd: not idle
\n
"
);
restore_flags
(
flags
);
return
;
}
if
(
!
list_empty
(
&
h8_actq
))
{
Dprintk
(
"h8_start_new_cmd: inconsistency: IDLE with non-empty active queue!
\n
"
);
restore_flags
(
flags
);
return
;
}
if
(
list_empty
(
&
h8_cmdq
))
{
Dprintk
(
"h8_start_new_cmd: no command to dequeue
\n
"
);
restore_flags
(
flags
);
return
;
}
/*
* Take first command off of the command queue and put
* it on the active queue.
*/
qp
=
list_entry
(
h8_cmdq
.
next
,
h8_cmd_q_t
,
link
);
list_del
(
&
qp
->
link
);
/* XXX should this go to the end of the active queue? */
list_add
(
&
qp
->
link
,
&
h8_actq
);
h8_state
=
H8_XMIT
;
if
(
h8_debug
&
0x1
)
Dprintk
(
"h8_start_new_cmd: Starting a command
\n
"
);
qp
->
cnt
=
1
;
WRITE_CMD
(
qp
->
cmdbuf
[
0
]);
/* Kick it off */
restore_flags
(
flags
);
return
;
}
void
h8_send_next_cmd_byte
(
void
)
{
h8_cmd_q_t
*
qp
=
list_entry
(
h8_actq
.
next
,
h8_cmd_q_t
,
link
);
int
cnt
;
cnt
=
qp
->
cnt
;
qp
->
cnt
++
;
if
(
h8_debug
&
0x1
)
Dprintk
(
"h8 sending next cmd byte 0x%x (0x%x)
\n
"
,
cnt
,
qp
->
cmdbuf
[
cnt
]);
if
(
cnt
)
{
WRITE_DATA
(
qp
->
cmdbuf
[
cnt
]);
}
else
{
WRITE_CMD
(
qp
->
cmdbuf
[
cnt
]);
}
return
;
}
/*
* Synchronize H8 communications channel for command transmission.
*/
void
h8_sync
(
void
)
{
u_char
buf
[
H8_MAX_CMD_SIZE
];
buf
[
0
]
=
H8_SYNC
;
buf
[
1
]
=
H8_SYNC_BYTE
;
h8_q_cmd
(
buf
,
2
,
1
);
}
/*
* Responds to external interrupt. Reads event status word and
* decodes type of interrupt.
*/
void
h8_read_event_status
(
void
)
{
if
(
h8_debug
&
0x200
)
printk
(
KERN_DEBUG
"h8_read_event_status: value 0x%x
\n
"
,
intrbuf
.
word
);
/*
* Power related items
*/
if
(
intrbuf
.
word
&
H8_DC_CHANGE
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: DC_CHANGE
\n
"
);
/* see if dc added or removed, set batt/dc flag, send event */
h8_set_event_mask
(
H8_MANAGE_BATTERY
);
wake_up
(
&
h8_monitor_wait
);
}
if
(
intrbuf
.
word
&
H8_POWER_BUTTON
)
{
printk
(
KERN_CRIT
"Power switch pressed - please wait - preparing to power
off
\n
"
);
h8_set_event_mask
(
H8_POWER_BUTTON
);
wake_up
(
&
h8_monitor_wait
);
}
/*
* Thermal related items
*/
if
(
intrbuf
.
word
&
H8_THERMAL_THRESHOLD
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: THERMAL_THRESHOLD
\n
"
);
h8_set_event_mask
(
H8_MANAGE_UTHERM
);
wake_up
(
&
h8_monitor_wait
);
}
/*
* nops -for now
*/
if
(
intrbuf
.
word
&
H8_DOCKING_STATION_STATUS
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: DOCKING_STATION_STATUS
\n
"
);
/* read_ext_status */
}
if
(
intrbuf
.
word
&
H8_EXT_BATT_STATUS
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: EXT_BATT_STATUS
\n
"
);
}
if
(
intrbuf
.
word
&
H8_EXT_BATT_CHARGE_STATE
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: EXT_BATT_CHARGE_STATE
\n
"
);
}
if
(
intrbuf
.
word
&
H8_BATT_CHANGE_OVER
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: BATT_CHANGE_OVER
\n
"
);
}
if
(
intrbuf
.
word
&
H8_WATCHDOG
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: WATCHDOG
\n
"
);
/* nop */
}
if
(
intrbuf
.
word
&
H8_SHUTDOWN
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: SHUTDOWN
\n
"
);
/* nop */
}
if
(
intrbuf
.
word
&
H8_KEYBOARD
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: KEYBOARD
\n
"
);
/* nop */
}
if
(
intrbuf
.
word
&
H8_EXT_MOUSE_OR_CASE_SWITCH
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: EXT_MOUSE_OR_CASE_SWITCH
\n
"
);
/* read_ext_status*/
}
if
(
intrbuf
.
word
&
H8_INT_BATT_LOW
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: INT_BATT_LOW
\n
"
);
post
/* event, warn user */
}
if
(
intrbuf
.
word
&
H8_INT_BATT_CHARGE_STATE
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: INT_BATT_CHARGE_STATE
\n
"
);
/* nop - happens often */
}
if
(
intrbuf
.
word
&
H8_INT_BATT_STATUS
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: INT_BATT_STATUS
\n
"
);
}
if
(
intrbuf
.
word
&
H8_INT_BATT_CHARGE_THRESHOLD
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: INT_BATT_CHARGE_THRESHOLD
\n
"
);
/* nop - happens often */
}
if
(
intrbuf
.
word
&
H8_EXT_BATT_LOW
)
{
if
(
h8_debug
&
0x4
)
printk
(
KERN_DEBUG
"h8_read_event_status: EXT_BATT_LOW
\n
"
);
/*if no internal, post event, warn user */
/* else nop */
}
return
;
}
/*
* Function called when H8 has performed requested command.
*/
static
void
h8_cmd_done
(
h8_cmd_q_t
*
qp
)
{
/* what to do */
switch
(
qp
->
cmdbuf
[
0
])
{
case
H8_SYNC
:
if
(
h8_debug
&
0x40000
)
printk
(
KERN_DEBUG
"H8: Sync command done - byte returned was 0x%x
\n
"
,
qp
->
rcvbuf
[
0
]);
list_add
(
&
qp
->
link
,
&
h8_freeq
);
break
;
case
H8_RD_SN
:
case
H8_RD_ENET_ADDR
:
printk
(
KERN_DEBUG
"H8: read Ethernet address: command done - address: %x - %x - %x - %x - %x - %x
\n
"
,
qp
->
rcvbuf
[
0
],
qp
->
rcvbuf
[
1
],
qp
->
rcvbuf
[
2
],
qp
->
rcvbuf
[
3
],
qp
->
rcvbuf
[
4
],
qp
->
rcvbuf
[
5
]);
list_add
(
&
qp
->
link
,
&
h8_freeq
);
break
;
case
H8_RD_HW_VER
:
case
H8_RD_MIC_VER
:
case
H8_RD_MAX_TEMP
:
printk
(
KERN_DEBUG
"H8: Max recorded CPU temp %d, Sys temp %d
\n
"
,
qp
->
rcvbuf
[
0
],
qp
->
rcvbuf
[
1
]);
list_add
(
&
qp
->
link
,
&
h8_freeq
);
break
;
case
H8_RD_MIN_TEMP
:
printk
(
KERN_DEBUG
"H8: Min recorded CPU temp %d, Sys temp %d
\n
"
,
qp
->
rcvbuf
[
0
],
qp
->
rcvbuf
[
1
]);
list_add
(
&
qp
->
link
,
&
h8_freeq
);
break
;
case
H8_RD_CURR_TEMP
:
h8_sync_channel
|=
H8_RD_CURR_TEMP
;
xx
.
byte
[
0
]
=
qp
->
rcvbuf
[
0
];
xx
.
byte
[
1
]
=
qp
->
rcvbuf
[
1
];
wake_up
(
&
h8_sync_wait
);
list_add
(
&
qp
->
link
,
&
h8_freeq
);
break
;
case
H8_RD_SYS_VARIENT
:
case
H8_RD_PWR_ON_CYCLES
:
printk
(
KERN_DEBUG
" H8: RD_PWR_ON_CYCLES command done
\n
"
);
break
;
case
H8_RD_PWR_ON_SECS
:
printk
(
KERN_DEBUG
"H8: RD_PWR_ON_SECS command done
\n
"
);
break
;
case
H8_RD_RESET_STATUS
:
case
H8_RD_PWR_DN_STATUS
:
case
H8_RD_EVENT_STATUS
:
case
H8_RD_ROM_CKSM
:
case
H8_RD_EXT_STATUS
:
xx
.
byte
[
1
]
=
qp
->
rcvbuf
[
0
];
xx
.
byte
[
0
]
=
qp
->
rcvbuf
[
1
];
h8_sync_channel
|=
H8_GET_EXT_STATUS
;
wake_up
(
&
h8_sync_wait
);
list_add
(
&
qp
->
link
,
&
h8_freeq
);
break
;
case
H8_RD_USER_CFG
:
case
H8_RD_INT_BATT_VOLT
:
case
H8_RD_DC_INPUT_VOLT
:
case
H8_RD_HORIZ_PTR_VOLT
:
case
H8_RD_VERT_PTR_VOLT
:
case
H8_RD_EEPROM_STATUS
:
case
H8_RD_ERR_STATUS
:
case
H8_RD_NEW_BUSY_SPEED
:
case
H8_RD_CONFIG_INTERFACE
:
case
H8_RD_INT_BATT_STATUS
:
printk
(
KERN_DEBUG
"H8: Read int batt status cmd done - returned was %x %x %x
\n
"
,
qp
->
rcvbuf
[
0
],
qp
->
rcvbuf
[
1
],
qp
->
rcvbuf
[
2
]);
list_add
(
&
qp
->
link
,
&
h8_freeq
);
break
;
case
H8_RD_EXT_BATT_STATUS
:
case
H8_RD_PWR_UP_STATUS
:
case
H8_RD_EVENT_STATUS_MASK
:
case
H8_CTL_EMU_BITPORT
:
case
H8_DEVICE_CONTROL
:
if
(
h8_debug
&
0x20000
)
{
printk
(
KERN_DEBUG
"H8: Device control cmd done - byte returned was 0x%x
\n
"
,
qp
->
rcvbuf
[
0
]);
}
list_add
(
&
qp
->
link
,
&
h8_freeq
);
break
;
case
H8_CTL_TFT_BRT_DC
:
case
H8_CTL_WATCHDOG
:
case
H8_CTL_MIC_PROT
:
case
H8_CTL_INT_BATT_CHG
:
case
H8_CTL_EXT_BATT_CHG
:
case
H8_CTL_MARK_SPACE
:
case
H8_CTL_MOUSE_SENSITIVITY
:
case
H8_CTL_DIAG_MODE
:
case
H8_CTL_IDLE_AND_BUSY_SPDS
:
printk
(
KERN_DEBUG
"H8: Idle and busy speed command done
\n
"
);
break
;
case
H8_CTL_TFT_BRT_BATT
:
case
H8_CTL_UPPER_TEMP
:
if
(
h8_debug
&
0x10
)
{
XDprintk
(
"H8: ctl upper thermal thresh cmd done - returned was %d
\n
"
,
qp
->
rcvbuf
[
0
]);
}
list_add
(
&
qp
->
link
,
&
h8_freeq
);
break
;
case
H8_CTL_LOWER_TEMP
:
case
H8_CTL_TEMP_CUTOUT
:
case
H8_CTL_WAKEUP
:
case
H8_CTL_CHG_THRESHOLD
:
case
H8_CTL_TURBO_MODE
:
case
H8_SET_DIAG_STATUS
:
case
H8_SOFTWARE_RESET
:
case
H8_RECAL_PTR
:
case
H8_SET_INT_BATT_PERCENT
:
case
H8_WRT_CFG_INTERFACE_REG
:
case
H8_WRT_EVENT_STATUS_MASK
:
case
H8_ENTER_POST_MODE
:
case
H8_EXIT_POST_MODE
:
case
H8_RD_EEPROM
:
case
H8_WRT_EEPROM
:
case
H8_WRT_TO_STATUS_DISP
:
printk
(
"H8: Write IO status display command done
\n
"
);
break
;
case
H8_DEFINE_SPC_CHAR
:
case
H8_DEFINE_TABLE_STRING_ENTRY
:
case
H8_PERFORM_EMU_CMD
:
case
H8_EMU_RD_REG
:
case
H8_EMU_WRT_REG
:
case
H8_EMU_RD_RAM
:
case
H8_EMU_WRT_RAM
:
case
H8_BQ_RD_REG
:
case
H8_BQ_WRT_REG
:
case
H8_PWR_OFF
:
printk
(
KERN_DEBUG
"H8: misc command completed
\n
"
);
break
;
}
return
;
}
/*
* Retrieve the current CPU temperature and case temperature. Provides
* the feedback for the thermal control algorithm. Synchcronized via
* sleep() for priority so that no other actions in the process will take
* place before the data becomes available.
*/
int
h8_get_curr_temp
(
u_char
curr_temp
[])
{
u_char
buf
[
H8_MAX_CMD_SIZE
];
unsigned
long
flags
;
memset
(
buf
,
0
,
H8_MAX_CMD_SIZE
);
buf
[
0
]
=
H8_RD_CURR_TEMP
;
h8_q_cmd
(
buf
,
1
,
2
);
save_flags
(
flags
);
cli
();
while
((
h8_sync_channel
&
H8_RD_CURR_TEMP
)
==
0
)
sleep_on
(
&
h8_sync_wait
);
restore_flags
(
flags
);
h8_sync_channel
&=
~
H8_RD_CURR_TEMP
;
curr_temp
[
0
]
=
xx
.
byte
[
0
];
curr_temp
[
1
]
=
xx
.
byte
[
1
];
xx
.
word
=
0
;
if
(
h8_debug
&
0x8
)
printk
(
"H8: curr CPU temp %d, Sys temp %d
\n
"
,
curr_temp
[
0
],
curr_temp
[
1
]);
return
0
;
}
static
void
h8_get_max_temp
(
void
)
{
u_char
buf
[
H8_MAX_CMD_SIZE
];
buf
[
0
]
=
H8_RD_MAX_TEMP
;
h8_q_cmd
(
buf
,
1
,
2
);
}
/*
* Assigns an upper limit to the value of the H8 thermal interrupt.
* As an example setting a value of 115 F here will cause the
* interrupt to trigger when the CPU temperature reaches 115 F.
*/
static
void
h8_set_upper_therm_thold
(
int
thold
)
{
u_char
buf
[
H8_MAX_CMD_SIZE
];
/* write 0 to reinitialize interrupt */
buf
[
0
]
=
H8_CTL_UPPER_TEMP
;
buf
[
1
]
=
0x0
;
buf
[
2
]
=
0x0
;
h8_q_cmd
(
buf
,
3
,
1
);
/* Do it for real */
buf
[
0
]
=
H8_CTL_UPPER_TEMP
;
buf
[
1
]
=
0x0
;
buf
[
2
]
=
thold
;
h8_q_cmd
(
buf
,
3
,
1
);
}
static
void
h8_get_upper_therm_thold
(
void
)
{
u_char
buf
[
H8_MAX_CMD_SIZE
];
buf
[
0
]
=
H8_CTL_UPPER_TEMP
;
buf
[
1
]
=
0xff
;
buf
[
2
]
=
0
;
h8_q_cmd
(
buf
,
3
,
1
);
}
/*
* The external status word contains information on keyboard controller,
* power button, changes in external batt status, change in DC state,
* docking station, etc. General purpose querying use.
*/
int
h8_get_ext_status
(
u_char
stat_word
[])
{
u_char
buf
[
H8_MAX_CMD_SIZE
];
unsigned
long
flags
;
memset
(
buf
,
0
,
H8_MAX_CMD_SIZE
);
buf
[
0
]
=
H8_RD_EXT_STATUS
;
h8_q_cmd
(
buf
,
1
,
2
);
save_flags
(
flags
);
cli
();
while
((
h8_sync_channel
&
H8_GET_EXT_STATUS
)
==
0
)
sleep_on
(
&
h8_sync_wait
);
restore_flags
(
flags
);
h8_sync_channel
&=
~
H8_GET_EXT_STATUS
;
stat_word
[
0
]
=
xx
.
byte
[
0
];
stat_word
[
1
]
=
xx
.
byte
[
1
];
xx
.
word
=
0
;
if
(
h8_debug
&
0x8
)
printk
(
"H8: curr ext status %x, %x
\n
"
,
stat_word
[
0
],
stat_word
[
1
]);
return
0
;
}
/*
* Thread attached to task 0 manages thermal/physcial state of Alphabook.
* When a condition is detected by the interrupt service routine, the
* isr does a wakeup() on h8_monitor_wait. The mask value is then
* screened for the appropriate action.
*/
int
h8_monitor_thread
(
void
*
unused
)
{
u_char
curr_temp
[
2
];
/*
* Need a logic based safety valve here. During boot when this thread is
* started and the thermal interrupt is not yet initialized this logic
* checks the temperature and acts accordingly. When this path is acted
* upon system boot is painfully slow, however, the priority associated
* with overheating is high enough to warrant this action.
*/
h8_get_curr_temp
(
curr_temp
);
printk
(
KERN_INFO
"H8: Initial CPU temp: %d
\n
"
,
curr_temp
[
0
]);
if
(
curr_temp
[
0
]
>=
h8_uthermal_threshold
)
{
h8_set_event_mask
(
H8_MANAGE_UTHERM
);
h8_manage_therm
();
}
else
{
/*
* Arm the upper thermal limit of the H8 so that any temp in
* excess will trigger the thermal control mechanism.
*/
h8_set_upper_therm_thold
(
h8_uthermal_threshold
);
}
for
(;;)
{
sleep_on
(
&
h8_monitor_wait
);
if
(
h8_debug
&
0x2
)
printk
(
KERN_DEBUG
"h8_monitor_thread awakened, mask:%x
\n
"
,
h8_event_mask
);
if
(
h8_event_mask
&
(
H8_MANAGE_UTHERM
|
H8_MANAGE_LTHERM
))
{
h8_manage_therm
();
}
#if 0
if (h8_event_mask & H8_POWER_BUTTON) {
h8_system_down();
}
/*
* If an external DC supply is removed or added make
* appropriate CPU speed adjustments.
*/
if (h8_event_mask & H8_MANAGE_BATTERY) {
h8_run_level_3_manage(H8_RUN);
h8_clear_event_mask(H8_MANAGE_BATTERY);
}
#endif
}
}
/*
* Function implements the following policy. When the machine is booted
* the system is set to run at full clock speed. When the upper thermal
* threshold is reached as a result of full clock a damping factor is
* applied to cool off the cpu. The default value is one quarter clock
* (57 Mhz). When as a result of this cooling a temperature lower by
* hmc_uthermal_window is reached, the machine is reset to a higher
* speed, one half clock (115 Mhz). One half clock is maintained until
* the upper thermal threshold is again reached restarting the cycle.
*/
int
h8_manage_therm
(
void
)
{
u_char
curr_temp
[
2
];
if
(
h8_event_mask
&
H8_MANAGE_UTHERM
)
{
/* Upper thermal interrupt received, need to cool down. */
if
(
h8_debug
&
0x10
)
printk
(
KERN_WARNING
"H8: Thermal threshold %d F reached
\n
"
,
h8_uthermal_threshold
);
h8_set_cpu_speed
(
h8_udamp
);
h8_clear_event_mask
(
H8_MANAGE_UTHERM
);
h8_set_event_mask
(
H8_MANAGE_LTHERM
);
/* Check again in 30 seconds for CPU temperature */
h8_start_monitor_timer
(
H8_TIMEOUT_INTERVAL
);
}
else
if
(
h8_event_mask
&
H8_MANAGE_LTHERM
)
{
/* See how cool the system has become as a result
of the reduction in speed. */
h8_get_curr_temp
(
curr_temp
);
last_temp
=
curr_temp
[
0
];
if
(
curr_temp
[
0
]
<
(
h8_uthermal_threshold
-
h8_uthermal_window
))
{
/* System cooling has progressed to a point
that the CPU may be sped up. */
h8_set_upper_therm_thold
(
h8_uthermal_threshold
);
h8_set_cpu_speed
(
h8_ldamp
);
/* adjustable */
if
(
h8_debug
&
0x10
)
printk
(
KERN_WARNING
"H8: CPU cool, applying cpu_divisor: %d
\n
"
,
h8_ldamp
);
h8_clear_event_mask
(
H8_MANAGE_LTHERM
);
}
else
/* Not cool enough yet, check again in 30 seconds. */
h8_start_monitor_timer
(
H8_TIMEOUT_INTERVAL
);
}
else
{
}
return
0
;
}
/*
* Function conditions the value of global_rpb_counter before
* calling the primitive which causes the actual speed change.
*/
void
h8_set_cpu_speed
(
int
speed_divisor
)
{
#ifdef NOT_YET
/*
* global_rpb_counter is consumed by alpha_delay() in determining just
* how much time to delay. It is necessary that the number of microseconds
* in DELAY(n) be kept consistent over a variety of CPU clock speeds.
* To that end global_rpb_counter is here adjusted.
*/
switch
(
speed_divisor
)
{
case
0
:
global_rpb_counter
=
rpb
->
rpb_counter
*
2L
;
break
;
case
1
:
global_rpb_counter
=
rpb
->
rpb_counter
*
4L
/
3L
;
break
;
case
3
:
global_rpb_counter
=
rpb
->
rpb_counter
/
2L
;
break
;
case
4
:
global_rpb_counter
=
rpb
->
rpb_counter
/
4L
;
break
;
case
5
:
global_rpb_counter
=
rpb
->
rpb_counter
/
8L
;
break
;
/*
* This case most commonly needed for cpu_speed_divisor
* of 2 which is the value assigned by the firmware.
*/
default:
global_rpb_counter
=
rpb
->
rpb_counter
;
break
;
}
#endif
/* NOT_YET */
if
(
h8_debug
&
0x8
)
printk
(
KERN_DEBUG
"H8: Setting CPU speed to %d MHz
\n
"
,
speed_tab
[
speed_divisor
]);
/* Make the actual speed change */
lca_clock_fiddle
(
speed_divisor
);
}
/*
* Gets value stored in rpb representing CPU clock speed and adjusts this
* value based on the current clock speed divisor.
*/
u_long
h8_get_cpu_speed
(
void
)
{
u_long
speed
=
0
;
u_long
counter
;
#ifdef NOT_YET
counter
=
rpb
->
rpb_counter
/
1000000L
;
switch
(
alphabook_get_clock
())
{
case
0
:
speed
=
counter
*
2L
;
break
;
case
1
:
speed
=
counter
*
4L
/
3L
;
break
;
case
2
:
speed
=
counter
;
break
;
case
3
:
speed
=
counter
/
2L
;
break
;
case
4
:
speed
=
counter
/
4L
;
break
;
case
5
:
speed
=
counter
/
8L
;
break
;
default:
break
;
}
if
(
h8_debug
&
0x8
)
printk
(
KERN_DEBUG
"H8: CPU speed current setting: %d MHz
\n
"
,
speed
);
#endif
/* NOT_YET */
return
speed
;
}
static
void
h8_activate_monitor
(
unsigned
long
unused
)
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
h8_monitor_timer_active
=
0
;
restore_flags
(
flags
);
wake_up
(
&
h8_monitor_wait
);
}
static
void
h8_start_monitor_timer
(
unsigned
long
secs
)
{
unsigned
long
flags
;
if
(
h8_monitor_timer_active
)
return
;
save_flags
(
flags
);
cli
();
h8_monitor_timer_active
=
1
;
restore_flags
(
flags
);
init_timer
(
&
h8_monitor_timer
);
h8_monitor_timer
.
function
=
h8_activate_monitor
;
h8_monitor_timer
.
expires
=
secs
*
HZ
+
jiffies
;
add_timer
(
&
h8_monitor_timer
);
}
static
void
h8_set_event_mask
(
int
mask
)
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
h8_event_mask
|=
mask
;
restore_flags
(
flags
);
}
static
void
h8_clear_event_mask
(
int
mask
)
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
h8_event_mask
&=
(
~
mask
);
restore_flags
(
flags
);
}
MODULE_LICENSE
(
"GPL"
);
drivers/char/h8.h
deleted
100644 → 0
View file @
1baaf2ab
/*
*/
#ifndef __H8_H__
#define __H8_H__
/*
* Register address and offsets
*/
#define H8_BASE_ADDR 0x170
/* default */
#define H8_IRQ 9
/* default */
#define H8_STATUS_REG_OFF 0x4
#define H8_CMD_REG_OFF 0x4
#define H8_DATA_REG_OFF 0x0
/* H8 register bit definitions */
/* status register */
#define H8_OFULL 0x1
/* output data register full */
#define H8_IFULL 0x2
/* input data register full */
#define H8_CMD 0x8
/* command / not data */
#define H8_INTR 0xfa
#define H8_NACK 0xfc
#define H8_BYTE_LEVEL_ACK 0xfd
#define H8_CMD_ACK 0xfe
#define H8_SYNC_BYTE 0x99
/*
* H8 command definitions
*/
/* System info commands */
#define H8_SYNC 0x0
#define H8_RD_SN 0x1
#define H8_RD_ENET_ADDR 0x2
#define H8_RD_HW_VER 0x3
#define H8_RD_MIC_VER 0x4
#define H8_RD_MAX_TEMP 0x5
#define H8_RD_MIN_TEMP 0x6
#define H8_RD_CURR_TEMP 0x7
#define H8_RD_SYS_VARIENT 0x8
#define H8_RD_PWR_ON_CYCLES 0x9
#define H8_RD_PWR_ON_SECS 0xa
#define H8_RD_RESET_STATUS 0xb
#define H8_RD_PWR_DN_STATUS 0xc
#define H8_RD_EVENT_STATUS 0xd
#define H8_RD_ROM_CKSM 0xe
#define H8_RD_EXT_STATUS 0xf
#define H8_RD_USER_CFG 0x10
#define H8_RD_INT_BATT_VOLT 0x11
#define H8_RD_DC_INPUT_VOLT 0x12
#define H8_RD_HORIZ_PTR_VOLT 0x13
#define H8_RD_VERT_PTR_VOLT 0x14
#define H8_RD_EEPROM_STATUS 0x15
#define H8_RD_ERR_STATUS 0x16
#define H8_RD_NEW_BUSY_SPEED 0x17
#define H8_RD_CONFIG_INTERFACE 0x18
#define H8_RD_INT_BATT_STATUS 0x19
#define H8_RD_EXT_BATT_STATUS 0x1a
#define H8_RD_PWR_UP_STATUS 0x1b
#define H8_RD_EVENT_STATUS_MASK 0x56
/* Read/write/modify commands */
#define H8_CTL_EMU_BITPORT 0x32
#define H8_DEVICE_CONTROL 0x21
#define H8_CTL_TFT_BRT_DC 0x22
#define H8_CTL_WATCHDOG 0x23
#define H8_CTL_MIC_PROT 0x24
#define H8_CTL_INT_BATT_CHG 0x25
#define H8_CTL_EXT_BATT_CHG 0x26
#define H8_CTL_MARK_SPACE 0x27
#define H8_CTL_MOUSE_SENSITIVITY 0x28
#define H8_CTL_DIAG_MODE 0x29
#define H8_CTL_IDLE_AND_BUSY_SPDS 0x2a
#define H8_CTL_TFT_BRT_BATT 0x2b
#define H8_CTL_UPPER_TEMP 0x2c
#define H8_CTL_LOWER_TEMP 0x2d
#define H8_CTL_TEMP_CUTOUT 0x2e
#define H8_CTL_WAKEUP 0x2f
#define H8_CTL_CHG_THRESHOLD 0x30
#define H8_CTL_TURBO_MODE 0x31
#define H8_SET_DIAG_STATUS 0x40
#define H8_SOFTWARE_RESET 0x41
#define H8_RECAL_PTR 0x42
#define H8_SET_INT_BATT_PERCENT 0x43
#define H8_WRT_CFG_INTERFACE_REG 0x45
#define H8_WRT_EVENT_STATUS_MASK 0x57
#define H8_ENTER_POST_MODE 0x46
#define H8_EXIT_POST_MODE 0x47
/* Block transfer commands */
#define H8_RD_EEPROM 0x50
#define H8_WRT_EEPROM 0x51
#define H8_WRT_TO_STATUS_DISP 0x52
#define H8_DEFINE_SPC_CHAR 0x53
/* Generic commands */
#define H8_DEFINE_TABLE_STRING_ENTRY 0x60
/* Battery control commands */
#define H8_PERFORM_EMU_CMD 0x70
#define H8_EMU_RD_REG 0x71
#define H8_EMU_WRT_REG 0x72
#define H8_EMU_RD_RAM 0x73
#define H8_EMU_WRT_RAM 0x74
#define H8_BQ_RD_REG 0x75
#define H8_BQ_WRT_REG 0x76
/* System admin commands */
#define H8_PWR_OFF 0x80
/*
* H8 command related definitions
*/
/* device control argument bits */
#define H8_ENAB_EXTSMI 0x1
#define H8_DISAB_IRQ 0x2
#define H8_ENAB_FLASH_WRT 0x4
#define H8_ENAB_THERM 0x8
#define H8_ENAB_INT_PTR 0x10
#define H8_ENAB_LOW_SPD_IND 0x20
#define H8_ENAB_EXT_PTR 0x40
#define H8_DISAB_PWR_OFF_SW 0x80
#define H8_POWER_OFF 0x80
/* H8 read event status bits */
#define H8_DC_CHANGE 0x1
#define H8_INT_BATT_LOW 0x2
#define H8_INT_BATT_CHARGE_THRESHOLD 0x4
#define H8_INT_BATT_CHARGE_STATE 0x8
#define H8_INT_BATT_STATUS 0x10
#define H8_EXT_BATT_CHARGE_STATE 0x20
#define H8_EXT_BATT_LOW 0x40
#define H8_EXT_BATT_STATUS 0x80
#define H8_THERMAL_THRESHOLD 0x100
#define H8_WATCHDOG 0x200
#define H8_DOCKING_STATION_STATUS 0x400
#define H8_EXT_MOUSE_OR_CASE_SWITCH 0x800
#define H8_KEYBOARD 0x1000
#define H8_BATT_CHANGE_OVER 0x2000
#define H8_POWER_BUTTON 0x4000
#define H8_SHUTDOWN 0x8000
/* H8 control idle and busy speeds */
#define H8_SPEED_LOW 0x1
#define H8_SPEED_MED 0x2
#define H8_SPEED_HI 0x3
#define H8_SPEED_LOCKED 0x80
#define H8_MAX_CMD_SIZE 18
#define H8_Q_ALLOC_AMOUNT 10
/* H8 state field values */
#define H8_IDLE 1
#define H8_XMIT 2
#define H8_RCV 3
#define H8_RESYNC 4
#define H8_INTR_MODE 5
/* Mask values for control functions */
#define UTH_HYSTERESIS 5
#define DEFAULT_UTHERMAL_THRESHOLD 115
#define H8_TIMEOUT_INTERVAL 30
#define H8_RUN 4
#define H8_GET_MAX_TEMP 0x1
#define H8_GET_CURR_TEMP 0x2
#define H8_GET_UPPR_THRMAL_THOLD 0x4
#define H8_GET_ETHERNET_ADDR 0x8
#define H8_SYNC_OP 0x10
#define H8_SET_UPPR_THRMAL_THOLD 0x20
#define H8_GET_INT_BATT_STAT 0x40
#define H8_GET_CPU_SPD 0x80
#define H8_MANAGE_UTHERM 0x100
#define H8_MANAGE_LTHERM 0x200
#define H8_HALT 0x400
#define H8_CRASH 0x800
#define H8_GET_EXT_STATUS 0x10000
#define H8_MANAGE_QUIET 0x20000
#define H8_MANAGE_SPEEDUP 0x40000
#define H8_MANAGE_BATTERY 0x80000
#define H8_SYSTEM_DELAY_TEST 0x100000
#define H8_POWER_SWITCH_TEST 0x200000
/* CPU speeds and clock divisor values */
#define MHZ_14 5
#define MHZ_28 4
#define MHZ_57 3
#define MHZ_115 2
#define MHZ_230 0
/*
* H8 data
*/
struct
h8_data
{
u_int
ser_num
;
u_char
ether_add
[
6
];
u_short
hw_ver
;
u_short
mic_ver
;
u_short
max_tmp
;
u_short
min_tmp
;
u_short
cur_tmp
;
u_int
sys_var
;
u_int
pow_on
;
u_int
pow_on_secs
;
u_char
reset_status
;
u_char
pwr_dn_status
;
u_short
event_status
;
u_short
rom_cksm
;
u_short
ext_status
;
u_short
u_cfg
;
u_char
ibatt_volt
;
u_char
dc_volt
;
u_char
ptr_horiz
;
u_char
ptr_vert
;
u_char
eeprom_status
;
u_char
error_status
;
u_char
new_busy_speed
;
u_char
cfg_interface
;
u_short
int_batt_status
;
u_short
ext_batt_status
;
u_char
pow_up_status
;
u_char
event_status_mask
;
};
/*
* H8 command buffers
*/
typedef
struct
h8_cmd_q
{
struct
list_head
link
;
/* double linked list */
int
ncmd
;
/* number of bytes in command */
int
nrsp
;
/* number of bytes in response */
int
cnt
;
/* number of bytes sent/received */
int
nacks
;
/* number of byte level acks */
u_char
cmdbuf
[
H8_MAX_CMD_SIZE
];
/* buffer to store command */
u_char
rcvbuf
[
H8_MAX_CMD_SIZE
];
/* buffer to store response */
}
h8_cmd_q_t
;
union
intr_buf
{
u_char
byte
[
2
];
u_int
word
;
};
#endif
/* __H8_H_ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment