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
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