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
nexedi
linux
Commits
7cfccad5
Commit
7cfccad5
authored
Oct 01, 2002
by
Russell King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ARM] iPAQ updates from Jamey Hicks
parent
e9174866
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
610 additions
and
287 deletions
+610
-287
arch/arm/mach-sa1100/h3600.c
arch/arm/mach-sa1100/h3600.c
+545
-248
include/asm-arm/arch-sa1100/h3600.h
include/asm-arm/arch-sa1100/h3600.h
+65
-39
No files found.
arch/arm/mach-sa1100/h3600.c
View file @
7cfccad5
...
...
@@ -24,65 +24,171 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/serial_core.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
#include <asm/mach/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h>
#include <linux/serial_core.h>
#include <asm/arch/h3600.h>
#if defined (CONFIG_SA1100_H3600) || defined (CONFIG_SA1100_H3100)
#include <asm/arch/h3600_gpio.h>
#endif
#ifdef CONFIG_SA1100_H3800
#include <asm/arch/h3600_asic.h>
#endif
#include "generic.h"
struct
ipaq_model_ops
ipaq_model_ops
;
EXPORT_SYMBOL
(
ipaq_model_ops
);
static
void
msleep
(
unsigned
int
msec
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
((
msec
*
HZ
+
999
)
/
1000
);
}
/*
* H3600 has extended, write-only memory-mapped GPIO's
* H3100 has 1/2 extended, write-only GPIO and 1/2 on
* regular GPIO lines.
* H3800 has memory-mapped GPIO through ASIC1 & 2
* low-level UART features
*/
#define H3600_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
static
void
h3600_uart_set_mctrl
(
struct
uart_port
*
port
,
u_int
mctrl
)
{
if
(
port
->
mapbase
==
_Ser3UTCR0
)
{
if
(
mctrl
&
TIOCM_RTS
)
GPCR
=
GPIO_H3600_COM_RTS
;
else
GPSR
=
GPIO_H3600_COM_RTS
;
}
}
static
unsigned
int
h3600_egpio
;
static
u_int
h3600_uart_get_mctrl
(
struct
uart_port
*
port
)
{
u_int
ret
=
TIOCM_CD
|
TIOCM_CTS
|
TIOCM_DSR
;
/************************* H3100 *************************/
if
(
port
->
mapbase
==
_Ser3UTCR0
)
{
int
gplr
=
GPLR
;
/* DCD and CTS bits are inverted in GPLR by RS232 transceiver */
if
(
gplr
&
GPIO_H3600_COM_DCD
)
ret
&=
~
TIOCM_CD
;
if
(
gplr
&
GPIO_H3600_COM_CTS
)
ret
&=
~
TIOCM_CTS
;
}
#define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON \
| GPIO_H3100_GPIO3 \
| GPIO_H3100_QMUTE \
| GPIO_H3100_LCD_3V_ON \
| GPIO_H3100_AUD_ON \
| GPIO_H3100_AUD_PWR_ON \
| GPIO_H3100_IR_ON \
| GPIO_H3100_IR_FSEL)
return
ret
;
}
static
void
h3
100_init_egpio
(
void
)
static
void
h3
600_uart_pm
(
struct
uart_port
*
port
,
u_int
state
,
u_int
oldstate
)
{
GPDR
|=
H3100_DIRECT_EGPIO
;
GPCR
=
H3100_DIRECT_EGPIO
;
/* Initially all off */
if
(
port
->
mapbase
==
_Ser2UTCR0
)
{
/* TODO: REMOVE THIS */
assign_h3600_egpio
(
IPAQ_EGPIO_IR_ON
,
!
state
);
}
else
if
(
port
->
mapbase
==
_Ser3UTCR0
)
{
assign_h3600_egpio
(
IPAQ_EGPIO_RS232_ON
,
!
state
);
}
}
/* Older bootldrs put GPIO2-9 in alternate mode on the
assumption that they are used for video */
GAFR
&=
~
H3100_DIRECT_EGPIO
;
/*
* Enable/Disable wake up events for this serial port.
* Obviously, we only support this on the normal COM port.
*/
static
int
h3600_uart_set_wake
(
struct
uart_port
*
port
,
u_int
enable
)
{
int
err
=
-
EINVAL
;
if
(
port
->
mapbase
==
_Ser3UTCR0
)
{
if
(
enable
)
PWER
|=
PWER_GPIO23
|
PWER_GPIO25
;
/* DCD and CTS */
else
PWER
&=
~
(
PWER_GPIO23
|
PWER_GPIO25
);
/* DCD and CTS */
err
=
0
;
}
return
err
;
}
static
struct
sa1100_port_fns
h3600_port_fns
__initdata
=
{
.
set_mctrl
=
h3600_uart_set_mctrl
,
.
get_mctrl
=
h3600_uart_get_mctrl
,
.
pm
=
h3600_uart_pm
,
.
set_wake
=
h3600_uart_set_wake
,
};
/*
* helper for sa1100fb
*/
static
void
h3xxx_lcd_power
(
int
enable
)
{
assign_h3600_egpio
(
IPAQ_EGPIO_LCD_POWER
,
enable
);
}
static
struct
map_desc
h3600_io_desc
[]
__initdata
=
{
/* virtual physical length type */
{
H3600_BANK_2_VIRT
,
SA1100_CS2_PHYS
,
0x02800000
,
MT_DEVICE
},
/* static memory bank 2 CS#2 */
{
H3600_BANK_4_VIRT
,
SA1100_CS4_PHYS
,
0x00800000
,
MT_DEVICE
},
/* static memory bank 4 CS#4 */
{
H3600_EGPIO_VIRT
,
H3600_EGPIO_PHYS
,
0x01000000
,
MT_DEVICE
},
/* EGPIO 0 CS#5 */
};
/*
* Common map_io initialization
*/
static
void
__init
h3xxx_map_io
(
void
)
{
sa1100_map_io
();
iotable_init
(
h3600_io_desc
,
ARRAY_SIZE
(
h3600_io_desc
));
sa1100_register_uart_fns
(
&
h3600_port_fns
);
sa1100_register_uart
(
0
,
3
);
/* Common serial port */
// sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
/* Ensure those pins are outputs and driving low */
PPDR
|=
PPC_TXD4
|
PPC_SCLK
|
PPC_SFRM
;
PPSR
&=
~
(
PPC_TXD4
|
PPC_SCLK
|
PPC_SFRM
);
/* Configure suspend conditions */
PGSR
=
0
;
PWER
=
PWER_GPIO0
|
PWER_RTC
;
PCFR
=
PCFR_OPDE
;
PSDR
=
0
;
sa1100fb_lcd_power
=
h3xxx_lcd_power
;
}
h3600_egpio
=
EGPIO_H3600_RS232_ON
;
H3600_EGPIO
=
h3600_egpio
;
static
__inline__
void
do_blank
(
int
setp
)
{
if
(
ipaq_model_ops
.
blank_callback
)
ipaq_model_ops
.
blank_callback
(
1
-
setp
);
}
static
void
h3100_control_egpio
(
enum
ipaq_egpio_type
x
,
int
setp
)
/************************* H3100 *************************/
#ifdef CONFIG_SA1100_H3100
#define H3100_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
static
unsigned
int
h3100_egpio
=
0
;
static
void
h3100_control_egpio
(
enum
ipaq_egpio_type
x
,
int
setp
)
{
unsigned
int
egpio
=
0
;
long
gpio
=
0
;
unsigned
long
flags
;
switch
(
x
)
{
case
IPAQ_EGPIO_LCD_
ON
:
case
IPAQ_EGPIO_LCD_
POWER
:
egpio
|=
EGPIO_H3600_LCD_ON
;
gpio
|=
GPIO_H3100_LCD_3V_ON
;
do_blank
(
setp
);
break
;
case
IPAQ_EGPIO_LCD_ENABLE
:
break
;
case
IPAQ_EGPIO_CODEC_NRESET
:
egpio
|=
EGPIO_H3600_CODEC_NRESET
;
...
...
@@ -120,66 +226,104 @@ static void h3100_control_egpio( enum ipaq_egpio_type x, int setp )
break
;
}
local_irq_save
(
flags
);
if
(
setp
)
{
h3600_egpio
|=
egpio
;
GPSR
=
gpio
;
}
else
{
h3600_egpio
&=
~
egpio
;
GPCR
=
gpio
;
}
H3600_EGPIO
=
h3600_egpio
;
local_irq_restore
(
flags
);
/*
if ( x != IPAQ_EGPIO_VPP_ON ) {
printk("%s: type=%d (%s) gpio=0x%x (0x%x) egpio=0x%x (0x%x) setp=%d\n",
__FUNCTION__,
x, egpio_names[x], GPLR, gpio, h3600_egpio, egpio, setp );
if
(
egpio
||
gpio
)
{
local_irq_save
(
flags
);
if
(
setp
)
{
h3100_egpio
|=
egpio
;
GPSR
=
gpio
;
}
else
{
h3100_egpio
&=
~
egpio
;
GPCR
=
gpio
;
}
H3100_EGPIO
=
h3100_egpio
;
local_irq_restore
(
flags
);
}
*/
}
static
unsigned
long
h3100_read_egpio
(
void
)
static
unsigned
long
h3100_read_egpio
(
void
)
{
return
h3600_egpio
;
return
h3100_egpio
;
}
static
int
h3100_pm_callback
(
int
req
)
{
if
(
ipaq_model_ops
.
pm_callback_aux
)
return
ipaq_model_ops
.
pm_callback_aux
(
req
);
return
0
;
}
static
struct
ipaq_model_ops
h3100_model_ops
__initdata
=
{
model
:
IPAQ_H3100
,
generic_name
:
"3100"
,
initialize
:
h3100_init_egpio
,
control
:
h3100_control_egpio
,
read
:
h3100_read_egpio
.
generic_name
=
"3100"
,
.
control
=
h3100_control_egpio
,
.
read
=
h3100_read_egpio
,
.
pm_callback
=
h3100_pm_callback
};
#define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON \
| GPIO_H3100_GPIO3 \
| GPIO_H3100_QMUTE \
| GPIO_H3100_LCD_3V_ON \
| GPIO_H3100_AUD_ON \
| GPIO_H3100_AUD_PWR_ON \
| GPIO_H3100_IR_ON \
| GPIO_H3100_IR_FSEL)
/************************* H3600 *************************/
static
void
h3600_init_egpio
(
void
)
static
void
__init
h3100_map_io
(
void
)
{
h3600_egpio
=
EGPIO_H3600_RS232_ON
;
H3600_EGPIO
=
h3600_egpio
;
h3xxx_map_io
();
/* Initialize h3100-specific values here */
GPCR
=
0x0fffffff
;
/* All outputs are set low by default */
GPDR
=
GPIO_H3600_COM_RTS
|
GPIO_H3600_L3_CLOCK
|
GPIO_H3600_L3_MODE
|
GPIO_H3600_L3_DATA
|
GPIO_H3600_CLK_SET1
|
GPIO_H3600_CLK_SET0
|
H3100_DIRECT_EGPIO
;
/* Older bootldrs put GPIO2-9 in alternate mode on the
assumption that they are used for video */
GAFR
&=
~
H3100_DIRECT_EGPIO
;
H3100_EGPIO
=
h3100_egpio
;
ipaq_model_ops
=
h3100_model_ops
;
}
static
void
h3600_control_egpio
(
enum
ipaq_egpio_type
x
,
int
setp
)
MACHINE_START
(
H3100
,
"Compaq iPAQ H3100"
)
BOOT_MEM
(
0xc0000000
,
0x80000000
,
0xf8000000
)
BOOT_PARAMS
(
0xc0000100
)
MAPIO
(
h3100_map_io
)
INITIRQ
(
sa1100_init_irq
)
MACHINE_END
#endif
/* CONFIG_SA1100_H3100 */
/************************* H3600 *************************/
#ifdef CONFIG_SA1100_H3600
#define H3600_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
static
unsigned
int
h3600_egpio
=
EGPIO_H3600_RS232_ON
;
static
void
h3600_control_egpio
(
enum
ipaq_egpio_type
x
,
int
setp
)
{
unsigned
int
egpio
=
0
;
unsigned
long
flags
;
switch
(
x
)
{
case
IPAQ_EGPIO_LCD_
ON
:
case
IPAQ_EGPIO_LCD_
POWER
:
egpio
|=
EGPIO_H3600_LCD_ON
|
EGPIO_H3600_LCD_PCI
|
EGPIO_H3600_LCD_5V_ON
|
EGPIO_H3600_LVDD_ON
;
do_blank
(
setp
);
break
;
case
IPAQ_EGPIO_LCD_ENABLE
:
break
;
case
IPAQ_EGPIO_CODEC_NRESET
:
egpio
|=
EGPIO_H3600_CODEC_NRESET
;
break
;
case
IPAQ_EGPIO_AUDIO_ON
:
egpio
|=
EGPIO_H3600_AUD_AMP_ON
|
EGPIO_H3600_AUD_PWR_ON
;
EGPIO_H3600_AUD_PWR_ON
;
break
;
case
IPAQ_EGPIO_QMUTE
:
egpio
|=
EGPIO_H3600_QMUTE
;
...
...
@@ -210,288 +354,441 @@ static void h3600_control_egpio( enum ipaq_egpio_type x, int setp )
break
;
}
local_irq_save
(
flags
);
if
(
setp
)
h3600_egpio
|=
egpio
;
else
h3600_egpio
&=
~
egpio
;
H3600_EGPIO
=
h3600_egpio
;
local_irq_restore
(
flags
);
if
(
egpio
)
{
local_irq_save
(
flags
);
if
(
setp
)
h3600_egpio
|=
egpio
;
else
h3600_egpio
&=
~
egpio
;
H3600_EGPIO
=
h3600_egpio
;
local_irq_restore
(
flags
);
}
}
static
unsigned
long
h3600_read_egpio
(
void
)
static
unsigned
long
h3600_read_egpio
(
void
)
{
return
h3600_egpio
;
}
static
int
h3600_pm_callback
(
int
req
)
{
if
(
ipaq_model_ops
.
pm_callback_aux
)
return
ipaq_model_ops
.
pm_callback_aux
(
req
);
return
0
;
}
static
struct
ipaq_model_ops
h3600_model_ops
__initdata
=
{
model
:
IPAQ_H3600
,
generic_name
:
"3600"
,
initialize
:
h3600_init_egpio
,
control
:
h3600_control_egpio
,
read
:
h3600_read_egpio
.
generic_name
=
"3600"
,
.
control
=
h3600_control_egpio
,
.
read
=
h3600_read_egpio
,
.
pm_callback
=
h3600_pm_callback
};
/************************* H3800 *************************/
static
void
__init
h3600_map_io
(
void
)
{
h3xxx_map_io
();
#define ASIC1_OUTPUTS 0x7fff
/* First 15 bits are used
*/
/* Initialize h3600-specific values here
*/
static
unsigned
int
h3800_asic1_gpio
;
static
unsigned
int
h3800_asic2_gpio
;
GPCR
=
0x0fffffff
;
/* All outputs are set low by default */
GPDR
=
GPIO_H3600_COM_RTS
|
GPIO_H3600_L3_CLOCK
|
GPIO_H3600_L3_MODE
|
GPIO_H3600_L3_DATA
|
GPIO_H3600_CLK_SET1
|
GPIO_H3600_CLK_SET0
|
GPIO_LDD15
|
GPIO_LDD14
|
GPIO_LDD13
|
GPIO_LDD12
|
GPIO_LDD11
|
GPIO_LDD10
|
GPIO_LDD9
|
GPIO_LDD8
;
static
void
h3800_init_egpio
(
void
)
{
/* Set up ASIC #1 */
H3800_ASIC1_GPIO_Direction
=
ASIC1_OUTPUTS
;
/* All outputs */
H3800_ASIC1_GPIO_Mask
=
ASIC1_OUTPUTS
;
/* No interrupts */
H3800_ASIC1_GPIO_SleepMask
=
ASIC1_OUTPUTS
;
H3800_ASIC1_GPIO_SleepDir
=
ASIC1_OUTPUTS
;
H3800_ASIC1_GPIO_SleepOut
=
GPIO_H3800_ASIC1_EAR_ON_N
;
H3800_ASIC1_GPIO_BattFaultDir
=
ASIC1_OUTPUTS
;
H3800_ASIC1_GPIO_BattFaultOut
=
GPIO_H3800_ASIC1_EAR_ON_N
;
H3600_EGPIO
=
h3600_egpio
;
/* Maintains across sleep? */
ipaq_model_ops
=
h3600_model_ops
;
}
MACHINE_START
(
H3600
,
"Compaq iPAQ H3600"
)
BOOT_MEM
(
0xc0000000
,
0x80000000
,
0xf8000000
)
BOOT_PARAMS
(
0xc0000100
)
MAPIO
(
h3600_map_io
)
INITIRQ
(
sa1100_init_irq
)
MACHINE_END
h3800_asic1_gpio
=
GPIO_H3800_ASIC1_IR_ON_N
/* TODO: Check IR level */
|
GPIO_H3800_ASIC1_RS232_ON
|
GPIO_H3800_ASIC1_EAR_ON_N
;
#endif
/* CONFIG_SA1100_H3600 */
H3800_ASIC1_GPIO_Out
=
h3800_asic1_gpio
;
#ifdef CONFIG_SA1100_H3800
/* Set up ASIC #2 */
H3800_ASIC2_GPIO_Direction
=
GPIO_H3800_ASIC2_PEN_IRQ
|
GPIO_H3800_ASIC2_SD_DETECT
|
GPIO_H3800_ASIC2_EAR_IN_N
|
GPIO_H3800_ASIC2_USB_DETECT_N
|
GPIO_H3800_ASIC2_SD_CON_SLT
;
#define SET_ASIC1(x) \
do {if (setp) { H3800_ASIC1_GPIO_OUT |= (x); } else { H3800_ASIC1_GPIO_OUT &= ~(x); }} while(0)
h3800_asic2_gpio
=
GPIO_H3800_ASIC2_IN_Y1_N
|
GPIO_H3800_ASIC2_IN_X1_N
;
H3800_ASIC2_GPIO_Data
=
h3800_asic2_gpio
;
H3800_ASIC2_GPIO_BattFaultOut
=
h3800_asic2_gpio
;
#define SET_ASIC2(x) \
do {if (setp) { H3800_ASIC2_GPIOPIOD |= (x); } else { H3800_ASIC2_GPIOPIOD &= ~(x); }} while(0)
/* TODO : Set sleep states & battery fault states */
#define CLEAR_ASIC1(x) \
do {if (setp) { H3800_ASIC1_GPIO_OUT &= ~(x); } else { H3800_ASIC1_GPIO_OUT |= (x); }} while(0)
/* Clear VPP Enable */
H3800_ASIC1_FlashWP_VPP_ON
=
0
;
#define CLEAR_ASIC2(x) \
do {if (setp) { H3800_ASIC2_GPIOPIOD &= ~(x); } else { H3800_ASIC2_GPIOPIOD |= (x); }} while(0)
/*
On screen enable, we get
h3800_video_power_on(1)
LCD controller starts
h3800_video_lcd_enable(1)
On screen disable, we get
h3800_video_lcd_enable(0)
LCD controller stops
h3800_video_power_on(0)
*/
static
void
h3800_video_power_on
(
int
setp
)
{
if
(
setp
)
{
H3800_ASIC1_GPIO_OUT
|=
GPIO1_LCD_ON
;
msleep
(
30
);
H3800_ASIC1_GPIO_OUT
|=
GPIO1_VGL_ON
;
msleep
(
5
);
H3800_ASIC1_GPIO_OUT
|=
GPIO1_VGH_ON
;
msleep
(
50
);
H3800_ASIC1_GPIO_OUT
|=
GPIO1_LCD_5V_ON
;
msleep
(
5
);
}
else
{
msleep
(
5
);
H3800_ASIC1_GPIO_OUT
&=
~
GPIO1_LCD_5V_ON
;
msleep
(
50
);
H3800_ASIC1_GPIO_OUT
&=
~
GPIO1_VGL_ON
;
msleep
(
5
);
H3800_ASIC1_GPIO_OUT
&=
~
GPIO1_VGH_ON
;
msleep
(
100
);
H3800_ASIC1_GPIO_OUT
&=
~
GPIO1_LCD_ON
;
}
}
static
void
h3800_
control_egpio
(
enum
ipaq_egpio_type
x
,
int
setp
)
static
void
h3800_
video_lcd_enable
(
int
setp
)
{
unsigned
int
set_asic1_egpio
=
0
;
unsigned
int
clear_asic1_egpio
=
0
;
unsigned
long
flags
;
if
(
setp
)
{
msleep
(
17
);
// Wait one from before turning on
H3800_ASIC1_GPIO_OUT
|=
GPIO1_LCD_PCI
;
}
else
{
H3800_ASIC1_GPIO_OUT
&=
~
GPIO1_LCD_PCI
;
msleep
(
30
);
// Wait before turning off
}
}
static
void
h3800_control_egpio
(
enum
ipaq_egpio_type
x
,
int
setp
)
{
switch
(
x
)
{
case
IPAQ_EGPIO_LCD_ON
:
set_asic1_egpio
|=
GPIO_H3800_ASIC1_LCD_5V_ON
|
GPIO_H3800_ASIC1_LCD_ON
|
GPIO_H3800_ASIC1_LCD_PCI
|
GPIO_H3800_ASIC1_VGH_ON
|
GPIO_H3800_ASIC1_VGL_ON
;
case
IPAQ_EGPIO_LCD_POWER
:
h3800_video_power_on
(
setp
);
break
;
case
IPAQ_EGPIO_CODEC_NRESET
:
case
IPAQ_EGPIO_LCD_ENABLE
:
h3800_video_lcd_enable
(
setp
);
break
;
case
IPAQ_EGPIO_CODEC_NRESET
:
case
IPAQ_EGPIO_AUDIO_ON
:
break
;
case
IPAQ_EGPIO_QMUTE
:
printk
(
__FUNCTION__
": error - should not be called
\n
"
);
break
;
case
IPAQ_EGPIO_OPT_NVRAM_ON
:
SET_ASIC2
(
GPIO2_OPT_ON_NVRAM
);
break
;
case
IPAQ_EGPIO_OPT_ON
:
SET_ASIC2
(
GPIO2_OPT_ON
);
break
;
case
IPAQ_EGPIO_CARD_RESET
:
SET_ASIC2
(
GPIO2_OPT_PCM_RESET
);
break
;
case
IPAQ_EGPIO_OPT_RESET
:
SET_ASIC2
(
GPIO2_OPT_RESET
);
break
;
case
IPAQ_EGPIO_IR_ON
:
clear_asic1_egpio
|=
GPIO_H3800_ASIC1_IR_ON_N
;
/* TODO : This is backwards? */
CLEAR_ASIC1
(
GPIO1_IR_ON_N
);
break
;
case
IPAQ_EGPIO_IR_FSEL
:
break
;
case
IPAQ_EGPIO_RS232_ON
:
set_asic1_egpio
|=
GPIO_H3800_ASIC1_RS232_ON
;
SET_ASIC1
(
GPIO1_RS232_ON
)
;
break
;
case
IPAQ_EGPIO_VPP_ON
:
H3800_ASIC
1
_FlashWP_VPP_ON
=
setp
;
H3800_ASIC
2
_FlashWP_VPP_ON
=
setp
;
break
;
}
}
local_irq_save
(
flags
);
if
(
setp
)
{
h3800_asic1_gpio
|=
set_asic1_egpio
;
h3800_asic1_gpio
&=
~
clear_asic1_egpio
;
}
else
{
h3800_asic1_gpio
&=
~
set_asic1_egpio
;
h3800_asic1_gpio
|=
clear_asic1_egpio
;
}
H3800_ASIC1_GPIO_Out
=
h3800_asic1_gpio
;
local_irq_restore
(
flags
);
static
unsigned
long
h3800_read_egpio
(
void
)
{
return
H3800_ASIC1_GPIO_OUT
|
(
H3800_ASIC2_GPIOPIOD
<<
16
);
}
static
unsigned
long
h3800_read_egpio
(
void
)
/* We need to fix ASIC2 GPIO over suspend/resume. At the moment,
it doesn't appear that ASIC1 GPIO has the same problem */
static
int
h3800_pm_callback
(
int
req
)
{
return
h3800_asic1_gpio
|
(
h3800_asic2_gpio
<<
16
);
static
u16
asic1_data
;
static
u16
asic2_data
;
int
result
=
0
;
printk
(
__FUNCTION__
" %d
\n
"
,
req
);
switch
(
req
)
{
case
PM_RESUME
:
MSC2
=
(
MSC2
&
0x0000ffff
)
|
0xE4510000
;
/* Set MSC2 correctly */
H3800_ASIC2_GPIOPIOD
=
asic2_data
;
H3800_ASIC2_GPIODIR
=
GPIO2_PEN_IRQ
|
GPIO2_SD_DETECT
|
GPIO2_EAR_IN_N
|
GPIO2_USB_DETECT_N
|
GPIO2_SD_CON_SLT
;
H3800_ASIC1_GPIO_OUT
=
asic1_data
;
if
(
ipaq_model_ops
.
pm_callback_aux
)
result
=
ipaq_model_ops
.
pm_callback_aux
(
req
);
break
;
case
PM_SUSPEND
:
if
(
ipaq_model_ops
.
pm_callback_aux
&&
((
result
=
ipaq_model_ops
.
pm_callback_aux
(
req
))
!=
0
))
return
result
;
asic1_data
=
H3800_ASIC1_GPIO_OUT
;
asic2_data
=
H3800_ASIC2_GPIOPIOD
;
break
;
default:
printk
(
__FUNCTION__
": unrecognized PM callback
\n
"
);
break
;
}
return
result
;
}
static
struct
ipaq_model_ops
h3800_model_ops
__initdata
=
{
model
:
IPAQ_H3800
,
generic_name
:
"3800"
,
initialize
:
h3800_init_egpio
,
control
:
h3800_control_egpio
,
read
:
h3800_read_egpio
.
generic_name
=
"3800"
,
.
control
=
h3800_control_egpio
,
.
read
=
h3800_read_egpio
,
.
pm_callback
=
h3800_pm_callback
};
#define MAX_ASIC_ISR_LOOPS 20
/* The order of these is important - see #include <asm/arch/irqs.h> */
static
u32
kpio_irq_mask
[]
=
{
KPIO_KEY_ALL
,
KPIO_SPI_INT
,
KPIO_OWM_INT
,
KPIO_ADC_INT
,
KPIO_UART_0_INT
,
KPIO_UART_1_INT
,
KPIO_TIMER_0_INT
,
KPIO_TIMER_1_INT
,
KPIO_TIMER_2_INT
};
static
u32
gpio_irq_mask
[]
=
{
GPIO2_PEN_IRQ
,
GPIO2_SD_DETECT
,
GPIO2_EAR_IN_N
,
GPIO2_USB_DETECT_N
,
GPIO2_SD_CON_SLT
,
};
static
void
h3
600_lcd_power
(
int
on
)
static
void
h3
800_IRQ_demux
(
unsigned
int
irq
,
struct
irqdesc
*
desc
,
struct
pt_regs
*
regs
)
{
if
(
on
)
set_h3600_egpio
(
IPAQ_EGPIO_LCD_ON
);
else
clr_h3600_egpio
(
IPAQ_EGPIO_LCD_ON
);
}
int
i
;
if
(
0
)
printk
(
__FUNCTION__
": interrupt received
\n
"
);
struct
ipaq_model_ops
ipaq_model_ops
;
EXPORT_SYMBOL
(
ipaq_model_ops
);
desc
->
chip
->
ack
(
irq
);
static
int
__init
h3600_init_model_ops
(
void
)
{
if
(
machine_is_h3xxx
())
{
sa1100fb_lcd_power
=
h3600_lcd_power
;
if
(
machine_is_h3100
())
{
ipaq_model_ops
=
h3100_model_ops
;
}
else
if
(
machine_is_h3600
())
{
ipaq_model_ops
=
h3600_model_ops
;
}
else
if
(
machine_is_h3800
())
{
ipaq_model_ops
=
h3800_model_ops
;
}
init_h3600_egpio
();
for
(
i
=
0
;
i
<
MAX_ASIC_ISR_LOOPS
&&
(
GPLR
&
GPIO_H3800_ASIC
);
i
++
)
{
u32
irq
;
int
j
;
/* KPIO */
irq
=
H3800_ASIC2_KPIINTFLAG
;
if
(
0
)
printk
(
__FUNCTION__
" KPIO 0x%08X
\n
"
,
irq
);
for
(
j
=
0
;
j
<
H3800_KPIO_IRQ_COUNT
;
j
++
)
if
(
irq
&
kpio_irq_mask
[
j
])
do_edge_IRQ
(
H3800_KPIO_IRQ_COUNT
+
j
,
irq_desc
+
H3800_KPIO_IRQ_COUNT
+
j
,
regs
);
/* GPIO2 */
irq
=
H3800_ASIC2_GPIINTFLAG
;
if
(
0
)
printk
(
__FUNCTION__
" GPIO 0x%08X
\n
"
,
irq
);
for
(
j
=
0
;
j
<
H3800_GPIO_IRQ_COUNT
;
j
++
)
if
(
irq
&
gpio_irq_mask
[
j
])
do_edge_IRQ
(
H3800_GPIO_IRQ_COUNT
+
j
,
irq_desc
+
H3800_GPIO_IRQ_COUNT
+
j
,
regs
);
}
return
0
;
if
(
i
>=
MAX_ASIC_ISR_LOOPS
)
printk
(
__FUNCTION__
": interrupt processing overrun
\n
"
);
/* For level-based interrupts */
desc
->
chip
->
unmask
(
irq
);
}
__initcall
(
h3600_init_model_ops
);
static
struct
irqaction
h3800_irq
=
{
.
name
=
"h3800_asic"
,
.
handler
=
h3800_IRQ_demux
,
.
flags
=
SA_INTERRUPT
,
};
u32
kpio_int_shadow
=
0
;
/*
* low-level UART features
/* mask_ack <- IRQ is first serviced.
mask <- IRQ is disabled.
unmask <- IRQ is enabled
The INTCLR registers are poorly documented. I believe that writing
a "1" to the register clears the specific interrupt, but the documentation
indicates writing a "0" clears the interrupt. In any case, they shouldn't
be read (that's the INTFLAG register)
*/
static
void
h3
600_uart_set_mctrl
(
struct
uart_port
*
port
,
u_int
mctrl
)
static
void
h3
800_mask_ack_kpio_irq
(
unsigned
int
irq
)
{
if
(
port
->
mapbase
==
_Ser3UTCR0
)
{
if
(
mctrl
&
TIOCM_RTS
)
GPCR
=
GPIO_H3600_COM_RTS
;
else
GPSR
=
GPIO_H3600_COM_RTS
;
}
u32
mask
=
kpio_irq_mask
[
irq
-
H3800_KPIO_IRQ_START
];
kpio_int_shadow
&=
~
mask
;
H3800_ASIC2_KPIINTSTAT
=
kpio_int_shadow
;
H3800_ASIC2_KPIINTCLR
=
mask
;
}
static
u_int
h3600_uart_get_mctrl
(
struct
uart_port
*
port
)
static
void
h3800_mask_kpio_irq
(
unsigned
int
irq
)
{
u_int
ret
=
TIOCM_CD
|
TIOCM_CTS
|
TIOCM_DSR
;
u32
mask
=
kpio_irq_mask
[
irq
-
H3800_KPIO_IRQ_START
];
kpio_int_shadow
&=
~
mask
;
H3800_ASIC2_KPIINTSTAT
=
kpio_int_shadow
;
}
if
(
port
->
mapbase
==
_Ser3UTCR0
)
{
int
gplr
=
GPLR
;
if
(
gplr
&
GPIO_H3600_COM_DCD
)
ret
&=
~
TIOCM_CD
;
if
(
gplr
&
GPIO_H3600_COM_CTS
)
ret
&=
~
TIOCM_CTS
;
}
static
void
h3800_unmask_kpio_irq
(
unsigned
int
irq
)
{
u32
mask
=
kpio_irq_mask
[
irq
-
H3800_KPIO_IRQ_START
];
kpio_int_shadow
|=
mask
;
H3800_ASIC2_KPIINTSTAT
=
kpio_int_shadow
;
}
return
ret
;
static
void
h3800_mask_ack_gpio_irq
(
unsigned
int
irq
)
{
u32
mask
=
gpio_irq_mask
[
irq
-
H3800_GPIO_IRQ_START
];
H3800_ASIC2_GPIINTSTAT
&=
~
mask
;
H3800_ASIC2_GPIINTCLR
=
mask
;
}
static
void
h3
600_uart_pm
(
struct
uart_port
*
port
,
u_int
state
,
u_int
oldstate
)
static
void
h3
800_mask_gpio_irq
(
unsigned
int
irq
)
{
if
(
port
->
mapbase
==
_Ser2UTCR0
)
{
assign_h3600_egpio
(
IPAQ_EGPIO_IR_ON
,
!
state
);
}
else
if
(
port
->
mapbase
==
_Ser3UTCR0
)
{
assign_h3600_egpio
(
IPAQ_EGPIO_RS232_ON
,
!
state
);
u32
mask
=
gpio_irq_mask
[
irq
-
H3800_GPIO_IRQ_START
];
H3800_ASIC2_GPIINTSTAT
&=
~
mask
;
}
static
void
h3800_unmask_gpio_irq
(
unsigned
int
irq
)
{
u32
mask
=
gpio_irq_mask
[
irq
-
H3800_GPIO_IRQ_START
];
H3800_ASIC2_GPIINTSTAT
|=
mask
;
}
/*
* Enable/Disable wake up events for this serial port.
* Obviously, we only support this on the normal COM port.
*/
static
int
h3600_uart_set_wake
(
struct
uart_port
*
port
,
u_int
enable
)
static
void
__init
h3800_init_irq
(
void
)
{
int
err
=
-
EINVAL
;
int
i
;
if
(
port
->
mapbase
==
_Ser3UTCR0
)
{
if
(
enable
)
PWER
|=
PWER_GPIO23
|
PWER_GPIO25
;
/* DCD and CTS */
else
PWER
&=
~
(
PWER_GPIO23
|
PWER_GPIO25
);
/* DCD and CTS */
err
=
0
;
/* Initialize standard IRQs */
sa1100_init_irq
();
/* Disable all IRQs and set up clock */
H3800_ASIC2_KPIINTSTAT
=
0
;
/* Disable all interrupts */
H3800_ASIC2_GPIINTSTAT
=
0
;
H3800_ASIC2_KPIINTCLR
=
0
;
/* Clear all KPIO interrupts */
H3800_ASIC2_GPIINTCLR
=
0
;
/* Clear all GPIO interrupts */
// H3800_ASIC2_KPIINTCLR = 0xffff; /* Clear all KPIO interrupts */
// H3800_ASIC2_GPIINTCLR = 0xffff; /* Clear all GPIO interrupts */
H3800_ASIC2_CLOCK_Enable
|=
ASIC2_CLOCK_EX0
;
/* 32 kHZ crystal on */
H3800_ASIC2_INTR_ClockPrescale
|=
ASIC2_INTCPS_SET
;
H3800_ASIC2_INTR_ClockPrescale
=
ASIC2_INTCPS_CPS
(
0x0e
)
|
ASIC2_INTCPS_SET
;
H3800_ASIC2_INTR_TimerSet
=
1
;
#if 0
for (i = 0; i < H3800_KPIO_IRQ_COUNT; i++) {
int irq = i + H3800_KPIO_IRQ_START;
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
set_irq_chip(irq, &h3800_kpio_irqchip);
}
return
err
;
for (i = 0; i < H3800_GPIO_IRQ_COUNT; i++) {
int irq = i + H3800_GPIO_IRQ_START;
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
set_irq_chip(irq, &h3800_gpio_irqchip);
}
#endif
set_irq_type
(
IRQ_GPIO_H3800_ASIC
,
IRQT_RISING
);
set_irq_chained_handler
(
IRQ_GPIO_H3800_ASIC
,
&
h3800_IRQ_demux
);
}
static
struct
sa1100_port_fns
h3600_port_fns
__initdata
=
{
.
set_mctrl
=
h3600_uart_set_mctrl
,
.
get_mctrl
=
h3600_uart_get_mctrl
,
.
pm
=
h3600_uart_pm
,
.
set_wake
=
h3600_uart_set_wake
,
};
static
struct
map_desc
h3600_io_desc
[]
__initdata
=
{
/* virtual physical length type */
{
H3600_EGPIO_VIRT
,
0x49000000
,
0x01000000
,
MT_DEVICE
},
/* EGPIO 0 CS#5 */
{
H3600_BANK_2_VIRT
,
0x10000000
,
0x02800000
,
MT_DEVICE
},
/* static memory bank 2 CS#2 */
{
H3600_BANK_4_VIRT
,
0x40000000
,
0x00800000
,
MT_DEVICE
}
/* static memory bank 4 CS#4 */
};
#define ASIC1_OUTPUTS 0x7fff
/* First 15 bits are used */
static
void
__init
h3
6
00_map_io
(
void
)
static
void
__init
h3
8
00_map_io
(
void
)
{
sa1100_map_io
();
iotable_init
(
h3600_io_desc
,
ARRAY_SIZE
(
h3600_io_desc
));
h3xxx_map_io
();
/* Add wakeup on AC plug/unplug */
PWER
|=
PWER_GPIO12
;
/* Initialize h3800-specific values here */
GPCR
=
0x0fffffff
;
/* All outputs are set low by default */
GAFR
=
GPIO_H3800_CLK_OUT
|
GPIO_LDD15
|
GPIO_LDD14
|
GPIO_LDD13
|
GPIO_LDD12
|
GPIO_LDD11
|
GPIO_LDD10
|
GPIO_LDD9
|
GPIO_LDD8
;
GPDR
=
GPIO_H3800_CLK_OUT
|
GPIO_H3600_COM_RTS
|
GPIO_H3600_L3_CLOCK
|
GPIO_H3600_L3_MODE
|
GPIO_H3600_L3_DATA
|
GPIO_LDD15
|
GPIO_LDD14
|
GPIO_LDD13
|
GPIO_LDD12
|
GPIO_LDD11
|
GPIO_LDD10
|
GPIO_LDD9
|
GPIO_LDD8
;
TUCR
=
TUCR_3_6864MHz
;
/* Seems to be used only for the Bluetooth UART */
/* Fix the memory bus */
MSC2
=
(
MSC2
&
0x0000ffff
)
|
0xE4510000
;
sa1100_register_uart_fns
(
&
h3600_port_fns
);
sa1100_register_uart
(
0
,
3
);
sa1100_register_uart
(
1
,
1
);
/* isn't this one driven elsewhere? */
/*
* Default GPIO settings. Should be set by machine
*/
GPCR
=
0x0fffffff
;
// GPDR = 0x0401f3fc;
GPDR
=
GPIO_H3600_COM_RTS
|
GPIO_H3600_L3_CLOCK
|
GPIO_H3600_L3_MODE
|
GPIO_H3600_L3_DATA
|
GPIO_H3600_CLK_SET1
|
GPIO_H3600_CLK_SET0
|
GPIO_LDD15
|
GPIO_LDD14
|
GPIO_LDD13
|
GPIO_LDD12
|
GPIO_LDD11
|
GPIO_LDD10
|
GPIO_LDD9
|
GPIO_LDD8
;
/* Set up ASIC #1 */
H3800_ASIC1_GPIO_DIR
=
ASIC1_OUTPUTS
;
/* All outputs */
H3800_ASIC1_GPIO_MASK
=
ASIC1_OUTPUTS
;
/* No interrupts */
H3800_ASIC1_GPIO_SLEEP_MASK
=
ASIC1_OUTPUTS
;
H3800_ASIC1_GPIO_SLEEP_DIR
=
ASIC1_OUTPUTS
;
H3800_ASIC1_GPIO_SLEEP_OUT
=
GPIO1_EAR_ON_N
;
H3800_ASIC1_GPIO_BATT_FAULT_DIR
=
ASIC1_OUTPUTS
;
H3800_ASIC1_GPIO_BATT_FAULT_OUT
=
GPIO1_EAR_ON_N
;
H3800_ASIC1_GPIO_OUT
=
GPIO1_IR_ON_N
|
GPIO1_RS232_ON
|
GPIO1_EAR_ON_N
;
init_h3600_egpio
();
/* Set up ASIC #2 */
H3800_ASIC2_GPIOPIOD
=
GPIO2_IN_Y1_N
|
GPIO2_IN_X1_N
;
H3800_ASIC2_GPOBFSTAT
=
GPIO2_IN_Y1_N
|
GPIO2_IN_X1_N
;
/*
* Ensure those pins are outputs and driving low.
*/
PPDR
|=
PPC_TXD4
|
PPC_SCLK
|
PPC_SFRM
;
PPSR
&=
~
(
PPC_TXD4
|
PPC_SCLK
|
PPC_SFRM
)
;
H3800_ASIC2_GPIODIR
=
GPIO2_PEN_IRQ
|
GPIO2_SD_DETECT
|
GPIO2_EAR_IN_N
|
GPIO2_USB_DETECT_N
|
GPIO2_SD_CON_SLT
;
/*
Configure suspend condition
s */
PGSR
=
0
;
PWER
=
PWER_GPIO0
|
PWER_RTC
;
PCFR
=
PCFR_OPDE
;
PSDR
=
0
;
/*
TODO : Set sleep states & battery fault state
s */
/* Clear VPP Enable */
H3800_ASIC2_FlashWP_VPP_ON
=
0
;
ipaq_model_ops
=
h3800_model_ops
;
}
MACHINE_START
(
H3600
,
"Compaq iPAQ H3600"
)
BOOT_MEM
(
0xc0000000
,
0x80000000
,
0xf8000000
)
BOOT_PARAMS
(
0xc0000100
)
MAPIO
(
h3600_map_io
)
INITIRQ
(
sa1100_init_irq
)
MACHINE_END
MACHINE_START
(
H3100
,
"Compaq iPAQ H3100"
)
BOOT_MEM
(
0xc0000000
,
0x80000000
,
0xf8000000
)
BOOT_PARAMS
(
0xc0000100
)
MAPIO
(
h3600_map_io
)
INITIRQ
(
sa1100_init_irq
)
MACHINE_END
MACHINE_START
(
H3800
,
"Compaq iPAQ H3800"
)
BOOT_MEM
(
0xc0000000
,
0x80000000
,
0xf8000000
)
BOOT_PARAMS
(
0xc0000100
)
MAPIO
(
h3
6
00_map_io
)
INITIRQ
(
sa11
00_init_irq
)
MAPIO
(
h3
8
00_map_io
)
INITIRQ
(
h38
00_init_irq
)
MACHINE_END
#endif
/* CONFIG_SA1100_H3800 */
include/asm-arm/arch-sa1100/h3600.h
View file @
7cfccad5
...
...
@@ -16,7 +16,7 @@
*
* History:
*
* 2001-10-??
Andrew Christian Added support for iPAQ H3800
* 2001-10-??
Andrew Christian Added support for iPAQ H3800
*
*/
...
...
@@ -26,6 +26,11 @@
/* generalized support for H3xxx series Compaq Pocket PC's */
#define machine_is_h3xxx() (machine_is_h3100() || machine_is_h3600() || machine_is_h3800())
/* Physical memory regions corresponding to chip selects */
#define H3600_EGPIO_PHYS (SA1100_CS5_PHYS + 0x01000000)
#define H3600_BANK_2_PHYS SA1100_CS2_PHYS
#define H3600_BANK_4_PHYS SA1100_CS4_PHYS
/* Virtual memory regions corresponding to chip selects 2 & 4 (used on sleeves) */
#define H3600_EGPIO_VIRT 0xf0000000
#define H3600_BANK_2_VIRT 0xf1000000
...
...
@@ -36,8 +41,7 @@
--- these are common across all current iPAQ platforms
*/
#define GPIO_H3600_NPOWER_BUTTON GPIO_GPIO (0)
/* Also known as the "off button" */
#define GPIO_H3600_MICROCONTROLLER GPIO_GPIO (1)
/* From ASIC2 on H3800 */
#define GPIO_H3600_NPOWER_BUTTON GPIO_GPIO (0)
/* Also known as the "off button" */
#define GPIO_H3600_PCMCIA_CD1 GPIO_GPIO (10)
#define GPIO_H3600_PCMCIA_IRQ1 GPIO_GPIO (11)
...
...
@@ -56,83 +60,105 @@
#define GPIO_H3600_COM_CTS GPIO_GPIO (25)
#define GPIO_H3600_COM_RTS GPIO_GPIO (26)
#define IRQ_GPIO_H3600_NPOWER_BUTTON IRQ_GPIO0
#define IRQ_GPIO_H3600_MICROCONTROLLER IRQ_GPIO1
#define IRQ_GPIO_H3600_NPOWER_BUTTON IRQ_GPIO0
#define IRQ_GPIO_H3600_PCMCIA_CD1 IRQ_GPIO10
#define IRQ_GPIO_H3600_PCMCIA_IRQ1 IRQ_GPIO11
#define IRQ_GPIO_H3600_PCMCIA_CD0 IRQ_GPIO17
#define IRQ_GPIO_H3600_PCMCIA_IRQ0 IRQ_GPIO21
#define IRQ_GPIO_H3600_COM_DCD
IRQ_GPIO23
#define IRQ_GPIO_H3600_COM_DCD
IRQ_GPIO23
#define IRQ_GPIO_H3600_OPT_IRQ IRQ_GPIO24
#define IRQ_GPIO_H3600_COM_CTS
IRQ_GPIO25
#define IRQ_GPIO_H3600_COM_CTS
IRQ_GPIO25
#ifndef __ASSEMBLY__
enum
ipaq_model
{
IPAQ_H3100
,
IPAQ_H3600
,
IPAQ_H3800
};
enum
ipaq_egpio_type
{
IPAQ_EGPIO_LCD_
ON
,
/* Power to the LCD panel */
IPAQ_EGPIO_LCD_
POWER
,
/* Power to the LCD panel */
IPAQ_EGPIO_CODEC_NRESET
,
/* Clear to reset the audio codec (remember to return high) */
IPAQ_EGPIO_AUDIO_ON
,
/* Audio power */
IPAQ_EGPIO_QMUTE
,
/* Audio muting */
IPAQ_EGPIO_AUDIO_ON
,
/* Audio power */
IPAQ_EGPIO_QMUTE
,
/* Audio muting */
IPAQ_EGPIO_OPT_NVRAM_ON
,
/* Non-volatile RAM on extension sleeves (SPI interface) */
IPAQ_EGPIO_OPT_ON
,
/* Power to extension sleeves */
IPAQ_EGPIO_CARD_RESET
,
/* Reset PCMCIA cards on extension sleeve (???) */
IPAQ_EGPIO_OPT_RESET
,
/* Reset option pack (???) */
IPAQ_EGPIO_IR_ON
,
/* IR sensor/emitter power */
IPAQ_EGPIO_IR_FSEL
,
/* IR speed selection 1->fast, 0->slow */
IPAQ_EGPIO_RS232_ON
,
/* Maxim RS232 chip power */
IPAQ_EGPIO_VPP_ON
,
/* Turn on power to flash programming */
IPAQ_EGPIO_OPT_ON
,
/* Power to extension sleeves */
IPAQ_EGPIO_CARD_RESET
,
/* Reset PCMCIA cards on extension sleeve (???) */
IPAQ_EGPIO_OPT_RESET
,
/* Reset option pack (???) */
IPAQ_EGPIO_IR_ON
,
/* IR sensor/emitter power */
IPAQ_EGPIO_IR_FSEL
,
/* IR speed selection 1->fast, 0->slow */
IPAQ_EGPIO_RS232_ON
,
/* Maxim RS232 chip power */
IPAQ_EGPIO_VPP_ON
,
/* Turn on power to flash programming */
IPAQ_EGPIO_LCD_ENABLE
,
/* Enable/disable LCD controller */
};
struct
ipaq_model_ops
{
enum
ipaq_model
model
;
const
char
*
generic_name
;
void
(
*
initialize
)(
void
);
void
(
*
control
)(
enum
ipaq_egpio_type
,
int
);
void
(
*
control
)(
enum
ipaq_egpio_type
,
int
);
unsigned
long
(
*
read
)(
void
);
void
(
*
blank_callback
)(
int
blank
);
int
(
*
pm_callback
)(
int
req
);
/* Primary model callback */
int
(
*
pm_callback_aux
)(
int
req
);
/* Secondary callback (used by HAL modules) */
};
extern
struct
ipaq_model_ops
ipaq_model_ops
;
static
__inline__
enum
ipaq_model
h3600_model
(
void
)
{
return
ipaq_model_ops
.
model
;
}
static
__inline__
const
char
*
h3600_generic_name
(
void
)
{
static
__inline__
const
char
*
h3600_generic_name
(
void
)
{
return
ipaq_model_ops
.
generic_name
;
}
static
__inline__
void
init_h3600_egpio
(
void
)
{
if
(
ipaq_model_ops
.
initialize
)
ipaq_model_ops
.
initialize
();
}
static
__inline__
void
assign_h3600_egpio
(
enum
ipaq_egpio_type
x
,
int
level
)
{
static
__inline__
void
assign_h3600_egpio
(
enum
ipaq_egpio_type
x
,
int
level
)
{
if
(
ipaq_model_ops
.
control
)
ipaq_model_ops
.
control
(
x
,
level
);
}
static
__inline__
void
clr_h3600_egpio
(
enum
ipaq_egpio_type
x
)
{
static
__inline__
void
clr_h3600_egpio
(
enum
ipaq_egpio_type
x
)
{
if
(
ipaq_model_ops
.
control
)
ipaq_model_ops
.
control
(
x
,
0
);
}
static
__inline__
void
set_h3600_egpio
(
enum
ipaq_egpio_type
x
)
{
static
__inline__
void
set_h3600_egpio
(
enum
ipaq_egpio_type
x
)
{
if
(
ipaq_model_ops
.
control
)
ipaq_model_ops
.
control
(
x
,
1
);
}
static
__inline__
unsigned
long
read_h3600_egpio
(
void
)
{
static
__inline__
unsigned
long
read_h3600_egpio
(
void
)
{
if
(
ipaq_model_ops
.
read
)
return
ipaq_model_ops
.
read
();
return
0
;
}
static
__inline__
int
h3600_register_blank_callback
(
void
(
*
f
)(
int
))
{
ipaq_model_ops
.
blank_callback
=
f
;
return
0
;
}
static
__inline__
void
h3600_unregister_blank_callback
(
void
(
*
f
)(
int
))
{
ipaq_model_ops
.
blank_callback
=
NULL
;
}
static
__inline__
int
h3600_register_pm_callback
(
int
(
*
f
)(
int
))
{
ipaq_model_ops
.
pm_callback_aux
=
f
;
return
0
;
}
static
__inline__
void
h3600_unregister_pm_callback
(
int
(
*
f
)(
int
))
{
ipaq_model_ops
.
pm_callback_aux
=
NULL
;
}
static
__inline__
int
h3600_power_management
(
int
req
)
{
if
(
ipaq_model_ops
.
pm_callback
)
return
ipaq_model_ops
.
pm_callback
(
req
);
return
0
;
}
#endif
/* ASSEMBLY */
#endif
/* _INCLUDE_H3600_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