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
2fbc109c
Commit
2fbc109c
authored
Sep 30, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://bk.arm.linux.org.uk
into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents
1b8ad82f
93d84590
Changes
41
Hide whitespace changes
Inline
Side-by-side
Showing
41 changed files
with
2436 additions
and
1674 deletions
+2436
-1674
arch/arm/config.in
arch/arm/config.in
+10
-0
arch/arm/kernel/compat.c
arch/arm/kernel/compat.c
+3
-2
arch/arm/kernel/irq.c
arch/arm/kernel/irq.c
+11
-7
arch/arm/mach-sa1100/adsbitsy.c
arch/arm/mach-sa1100/adsbitsy.c
+1
-2
arch/arm/mach-sa1100/badge4.c
arch/arm/mach-sa1100/badge4.c
+1
-2
arch/arm/mach-sa1100/cpu-sa1100.c
arch/arm/mach-sa1100/cpu-sa1100.c
+29
-57
arch/arm/mach-sa1100/cpu-sa1110.c
arch/arm/mach-sa1100/cpu-sa1110.c
+31
-19
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/generic.c
+12
-6
arch/arm/mach-sa1100/generic.h
arch/arm/mach-sa1100/generic.h
+6
-0
arch/arm/mach-sa1100/graphicsmaster.c
arch/arm/mach-sa1100/graphicsmaster.c
+1
-2
arch/arm/mach-sa1100/h3600.c
arch/arm/mach-sa1100/h3600.c
+545
-248
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-sa1100/jornada720.c
+1
-6
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sa1100/neponset.c
+49
-9
arch/arm/mach-sa1100/pfs168.c
arch/arm/mach-sa1100/pfs168.c
+1
-2
arch/arm/mach-sa1100/pm.c
arch/arm/mach-sa1100/pm.c
+20
-1
arch/arm/mach-sa1100/sa1111.c
arch/arm/mach-sa1100/sa1111.c
+590
-138
arch/arm/mach-sa1100/sa1111.h
arch/arm/mach-sa1100/sa1111.h
+0
-20
arch/arm/mach-sa1100/stork.c
arch/arm/mach-sa1100/stork.c
+13
-0
arch/arm/mach-sa1100/system3.c
arch/arm/mach-sa1100/system3.c
+1
-2
arch/arm/mm/fault-common.c
arch/arm/mm/fault-common.c
+2
-2
arch/arm/tools/mach-types
arch/arm/tools/mach-types
+29
-1
drivers/input/serio/sa1111ps2.c
drivers/input/serio/sa1111ps2.c
+177
-98
drivers/pcmcia/Config.in
drivers/pcmcia/Config.in
+1
-0
drivers/pcmcia/Makefile
drivers/pcmcia/Makefile
+12
-8
drivers/pcmcia/sa1100_adsbitsy.c
drivers/pcmcia/sa1100_adsbitsy.c
+1
-0
drivers/pcmcia/sa1100_badge4.c
drivers/pcmcia/sa1100_badge4.c
+1
-0
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/sa1100_generic.c
+39
-84
drivers/pcmcia/sa1100_graphicsmaster.c
drivers/pcmcia/sa1100_graphicsmaster.c
+1
-0
drivers/pcmcia/sa1100_jornada720.c
drivers/pcmcia/sa1100_jornada720.c
+1
-0
drivers/pcmcia/sa1100_neponset.c
drivers/pcmcia/sa1100_neponset.c
+37
-31
drivers/pcmcia/sa1100_pfs168.c
drivers/pcmcia/sa1100_pfs168.c
+2
-1
drivers/pcmcia/sa1100_system3.c
drivers/pcmcia/sa1100_system3.c
+1
-0
drivers/pcmcia/sa1100_xp860.c
drivers/pcmcia/sa1100_xp860.c
+1
-0
drivers/pcmcia/sa1111_generic.c
drivers/pcmcia/sa1111_generic.c
+144
-18
drivers/usb/host/ohci-sa1111.c
drivers/usb/host/ohci-sa1111.c
+92
-44
drivers/video/sa1100fb.c
drivers/video/sa1100fb.c
+381
-680
drivers/video/sa1100fb.h
drivers/video/sa1100fb.h
+2
-1
include/asm-arm/arch-sa1100/h3600.h
include/asm-arm/arch-sa1100/h3600.h
+65
-39
include/asm-arm/arch-sa1100/irqs.h
include/asm-arm/arch-sa1100/irqs.h
+13
-13
include/asm-arm/hardware/sa1111.h
include/asm-arm/hardware/sa1111.h
+107
-125
include/asm-arm/pci.h
include/asm-arm/pci.h
+2
-6
No files found.
arch/arm/config.in
View file @
2fbc109c
...
...
@@ -335,6 +335,16 @@ hex 'Compressed ROM boot loader BSS address' CONFIG_ZBOOT_ROM_BSS 0
if [ "$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
dep_bool 'Support CPU clock change (EXPERIMENTAL)' CONFIG_CPU_FREQ $CONFIG_EXPERIMENTAL
else
define_bool CONFIG_CPU_FREQ n
fi
if [ "$CONFIG_CPU_FREQ" = "y" ]; then
define_bool CONFIG_CPU_FREQ_24_API y
define_bool CONFIG_CPU_FREQ_26_API y
else
define_bool CONFIG_CPU_FREQ_24_API n
define_bool CONFIG_CPU_FREQ_26_API n
fi
source drivers/pci/Config.in
...
...
arch/arm/kernel/compat.c
View file @
2fbc109c
...
...
@@ -95,13 +95,14 @@ static void __init build_tag_list(struct param_struct *params, void *taglist)
{
struct
tag
*
tag
=
taglist
;
printk
(
KERN_DEBUG
"Converting old-style param struct to taglist
\n
"
);
if
(
params
->
u1
.
s
.
page_size
!=
PAGE_SIZE
)
{
printk
(
KERN_WARNING
"Warning: bad configuration page, "
"trying to continue
\n
"
);
return
;
}
printk
(
KERN_DEBUG
"Converting old-style param struct to taglist
\n
"
);
#ifdef CONFIG_ARCH_NETWINDER
if
(
params
->
u1
.
s
.
nr_pages
!=
0x02000
&&
params
->
u1
.
s
.
nr_pages
!=
0x04000
&&
...
...
arch/arm/kernel/irq.c
View file @
2fbc109c
...
...
@@ -569,7 +569,7 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
* On a shared IRQ the caller must ensure the interrupt is disabled
* on the card it drives before calling this function.
*
* This function m
ay
be called from interrupt context.
* This function m
ust not
be called from interrupt context.
*/
void
free_irq
(
unsigned
int
irq
,
void
*
dev_id
)
{
...
...
@@ -591,15 +591,19 @@ void free_irq(unsigned int irq, void *dev_id)
/* Found it - now free it */
*
p
=
action
->
next
;
kfree
(
action
);
goto
out
;
break
;
}
printk
(
KERN_ERR
"Trying to free free IRQ%d
\n
"
,
irq
);
spin_unlock_irqrestore
(
&
irq_controller_lock
,
flags
);
if
(
!
action
)
{
printk
(
KERN_ERR
"Trying to free free IRQ%d
\n
"
,
irq
);
#ifdef CONFIG_DEBUG_ERRORS
__backtrace
();
__backtrace
();
#endif
out:
spin_unlock_irqrestore
(
&
irq_controller_lock
,
flags
);
}
else
{
synchronize_irq
(
irq
);
kfree
(
action
);
}
}
/* Start the interrupt probing. Unlike other architectures,
...
...
arch/arm/mach-sa1100/adsbitsy.c
View file @
2fbc109c
...
...
@@ -28,7 +28,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
static
int
__init
adsbitsy_init
(
void
)
{
...
...
@@ -53,7 +52,7 @@ static int __init adsbitsy_init(void)
/*
* Probe for SA1111.
*/
ret
=
sa1111_init
(
NULL
,
0x18000000
,
IRQ_GPIO0
);
ret
=
sa1111_init
(
0x18000000
,
IRQ_GPIO0
);
if
(
ret
<
0
)
return
ret
;
...
...
arch/arm/mach-sa1100/badge4.c
View file @
2fbc109c
...
...
@@ -32,7 +32,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
static
int
__init
badge4_sa1111_init
(
void
)
{
...
...
@@ -45,7 +44,7 @@ static int __init badge4_sa1111_init(void)
/*
* Probe for SA1111.
*/
return
sa1111_init
(
NULL
,
BADGE4_SA1111_BASE
,
BADGE4_IRQ_GPIO_SA1111
);
return
sa1111_init
(
BADGE4_SA1111_BASE
,
BADGE4_IRQ_GPIO_SA1111
);
}
static
int
__init
badge4_init
(
void
)
...
...
arch/arm/mach-sa1100/cpu-sa1100.c
View file @
2fbc109c
...
...
@@ -90,9 +90,7 @@
#include <asm/hardware.h>
extern
unsigned
int
sa11x0_freq_to_ppcr
(
unsigned
int
khz
);
extern
unsigned
int
sa11x0_validatespeed
(
unsigned
int
cpu
,
unsigned
int
khz
);
extern
unsigned
int
sa11x0_getspeed
(
void
);
#include "generic.h"
typedef
struct
{
int
speed
;
...
...
@@ -107,7 +105,7 @@ typedef struct {
static
sa1100_dram_regs_t
sa1100_dram_settings
[]
=
{
/*
{ mdcnfg, mdcas0, mdcas1, mdcas2 } */
/*
clock frequency */
/*
speed, mdcnfg, mdcas0, mdcas1, mdcas2
clock frequency */
{
59000
,
0x00dc88a3
,
0xcccccccf
,
0xfffffffc
,
0xffffffff
},
/* 59.0 MHz */
{
73700
,
0x011490a3
,
0xcccccccf
,
0xfffffffc
,
0xffffffff
},
/* 73.7 MHz */
{
88500
,
0x014e90a3
,
0xcccccccf
,
0xfffffffc
,
0xffffffff
},
/* 88.5 MHz */
...
...
@@ -127,28 +125,25 @@ static sa1100_dram_regs_t sa1100_dram_settings[] =
{
0
,
0
,
0
,
0
,
0
}
/* last entry */
};
static
void
sa1100_update_dram_timings
(
int
current_speed
,
int
new_speed
)
{
sa1100_dram_regs_t
*
settings
=
sa1100_dram_settings
;
/* find speed */
while
(
settings
->
speed
!=
0
)
{
while
(
settings
->
speed
!=
0
)
{
if
(
new_speed
==
settings
->
speed
)
break
;
settings
++
;
}
if
(
settings
->
speed
==
0
)
{
if
(
settings
->
speed
==
0
)
{
panic
(
"%s: couldn't find dram setting for speed %d
\n
"
,
__FUNCTION__
,
new_speed
);
}
/* No risk, no fun: run with interrupts on! */
if
(
new_speed
>
current_speed
)
{
if
(
new_speed
>
current_speed
)
{
/* We're going FASTER, so first relax the memory
* timings before changing the core frequency
*/
...
...
@@ -181,60 +176,39 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
}
}
static
int
sa1100_dram_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
void
*
data
)
static
void
sa1100_setspeed
(
struct
cpufreq_policy
*
policy
)
{
struct
cpufreq_freqs
*
ci
=
data
;
switch
(
val
)
{
case
CPUFREQ_MINMAX
:
cpufreq_updateminmax
(
data
,
sa1100_dram_settings
->
speed
,
-
1
);
break
;
unsigned
int
cur
=
sa11x0_getspeed
();
struct
cpufreq_freqs
freqs
;
case
CPUFREQ_PRECHANGE
:
if
(
ci
->
new
>
ci
->
cur
)
sa1100_update_dram_timings
(
ci
->
cur
,
ci
->
new
);
break
;
freqs
.
old
=
cur
;
freqs
.
new
=
policy
->
max
;
freqs
.
cpu
=
CPUFREQ_ALL_CPUS
;
case
CPUFREQ_POSTCHANGE
:
if
(
ci
->
new
<
ci
->
cur
)
sa1100_update_dram_timings
(
ci
->
cur
,
ci
->
new
);
break
;
default:
printk
(
KERN_INFO
"%s: ignoring unknown notifier type (%ld)
\n
"
,
__FUNCTION__
,
val
);
}
return
0
;
}
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_PRECHANGE
);
if
(
policy
->
max
>
cur
)
sa1100_update_dram_timings
(
cur
,
policy
->
max
);
PPCR
=
sa11x0_freq_to_ppcr
(
policy
->
max
);
if
(
policy
->
max
<
cur
)
sa1100_update_dram_timings
(
cur
,
policy
->
max
);
static
struct
notifier_block
sa1100_dram_block
=
{
.
notifier_call
=
sa1100_dram_notifier
,
};
static
void
sa1100_setspeed
(
unsigned
int
cpu
,
unsigned
int
khz
)
{
PPCR
=
sa11x0_freq_to_ppcr
(
khz
);
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_POSTCHANGE
);
}
static
struct
cpufreq_freqs
sa1100_freqs
=
{
.
min
=
59000
,
.
max
=
287000
,
static
struct
cpufreq_policy
sa1100_policy
=
{
.
cpu
=
0
,
.
policy
=
CPUFREQ_POLICY_POWERSAVE
,
.
max_cpu_freq
=
287000
,
};
static
struct
cpufreq_driver
sa1100_driver
=
{
.
freq
=
&
sa1100_freqs
,
.
validate
=
sa11x0_validate
speed
,
.
setspeed
=
sa1100_setspeed
,
.
sync
=
1
,
.
verify
=
sa11x0_verify_speed
,
.
setpolicy
=
sa1100_set
speed
,
.
policy
=
&
sa1100_policy
,
.
cpu_min_freq
=
59000
,
};
static
int
__init
sa1100_dram_init
(
void
)
...
...
@@ -242,11 +216,9 @@ static int __init sa1100_dram_init(void)
int
ret
=
-
ENODEV
;
if
((
processor_id
&
CPU_SA1100_MASK
)
==
CPU_SA1100_ID
)
{
ret
=
cpufreq_register_notifier
(
&
sa1100_dram_block
);
if
(
ret
)
return
ret
;
sa1100_freqs
.
cur
=
sa11x0_getspeed
();
sa1100_driver
.
cpu_curr_freq
[
0
]
=
sa1100_policy
.
min
=
sa1100_policy
.
max
=
sa11x0_getspeed
();
ret
=
cpufreq_register
(
&
sa1100_driver
);
}
...
...
arch/arm/mach-sa1100/cpu-sa1110.c
View file @
2fbc109c
...
...
@@ -28,11 +28,9 @@
#include <asm/io.h>
#include <asm/system.h>
#
undef DEBUG
#
include "generic.h"
extern
unsigned
int
sa11x0_freq_to_ppcr
(
unsigned
int
khz
);
extern
unsigned
int
sa11x0_validatespeed
(
unsigned
int
cpu
,
unsigned
int
khz
);
extern
unsigned
int
sa11x0_getspeed
(
void
);
#undef DEBUG
struct
sdram_params
{
u_char
rows
;
/* bits */
...
...
@@ -214,15 +212,16 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
* above, we can match for an exact frequency. If we don't find
* an exact match, we will to set the lowest frequency to be safe.
*/
static
void
sa1110_setspeed
(
unsigned
int
cpu
,
unsigned
int
khz
)
static
void
sa1110_setspeed
(
struct
cpufreq_policy
*
policy
)
{
struct
sdram_params
*
sdram
=
&
sdram_params
;
struct
cpufreq_freqs
freqs
;
struct
sdram_info
sd
;
unsigned
long
flags
;
unsigned
int
ppcr
,
unused
;
ppcr
=
sa11x0_freq_to_ppcr
(
khz
);
sdram_calculate_timing
(
&
sd
,
khz
,
sdram
);
ppcr
=
sa11x0_freq_to_ppcr
(
policy
->
max
);
sdram_calculate_timing
(
&
sd
,
policy
->
max
,
sdram
);
#if 0
/*
...
...
@@ -230,7 +229,7 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
* and errata, but they seem to work. Need to get a storage
* scope on to the SDRAM signals to work out why.
*/
if (
khz
< 147500) {
if (
policy->max
< 147500) {
sd.mdrefr |= MDREFR_K1DB2;
sd.mdcas[0] = 0xaaaaaa7f;
} else {
...
...
@@ -240,6 +239,13 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
sd.mdcas[1] = 0xaaaaaaaa;
sd.mdcas[2] = 0xaaaaaaaa;
#endif
freqs
.
old
=
sa11x0_getspeed
();
freqs
.
new
=
policy
->
max
;
freqs
.
cpu
=
CPUFREQ_ALL_CPUS
;
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_PRECHANGE
);
/*
* The clock could be going away for some time. Set the SDRAMs
* to refresh rapidly (every 64 memory clock cycles). To get
...
...
@@ -257,7 +263,7 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
* the programming.
*/
local_irq_save
(
flags
);
asm
(
"mcr p15, 0, %0, c
10, c
4"
:
:
"r"
(
0
));
asm
(
"mcr p15, 0, %0, c
7, c10,
4"
:
:
"r"
(
0
));
udelay
(
10
);
__asm__
__volatile__
(
"
b 2f
...
...
@@ -282,19 +288,22 @@ static void sa1110_setspeed(unsigned int cpu, unsigned int khz)
/*
* Now, return the SDRAM refresh back to normal.
*/
sdram_update_refresh
(
khz
,
sdram
);
sdram_update_refresh
(
policy
->
max
,
sdram
);
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_POSTCHANGE
);
}
static
struct
cpufreq_freqs
sa1110_freqs
=
{
.
min
=
59000
,
.
max
=
287000
,
static
struct
cpufreq_policy
sa1110_policy
=
{
.
cpu
=
0
,
.
policy
=
CPUFREQ_POLICY_POWERSAVE
,
.
max_cpu_freq
=
287000
,
};
static
struct
cpufreq_driver
sa1110_driver
=
{
.
freq
=
&
sa1110_freqs
,
.
validate
=
sa11x0_validate
speed
,
.
setspeed
=
sa1110_setspeed
,
.
sync
=
1
,
.
verify
=
sa11x0_verify_speed
,
.
setpolicy
=
sa1110_set
speed
,
.
policy
=
&
sa1110_policy
,
.
cpu_min_freq
=
59000
,
};
static
int
__init
sa1110_clk_init
(
void
)
...
...
@@ -318,8 +327,11 @@ static int __init sa1110_clk_init(void)
memcpy
(
&
sdram_params
,
sdram
,
sizeof
(
sdram_params
));
sa1110_freqs
.
cur
=
sa11x0_getspeed
();
sa1110_setspeed
(
0
,
sa1110_freqs
.
cur
);
sa1110_driver
.
cpu_cur_freq
[
0
]
=
sa1110_policy
.
min
=
sa1110_policy
.
max
=
sa11x0_getspeed
();
sa1110_setspeed
(
&
sa1110_policy
);
return
cpufreq_register
(
&
sa1110_driver
);
}
...
...
arch/arm/mach-sa1100/generic.c
View file @
2fbc109c
...
...
@@ -55,20 +55,26 @@ unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
khz
/=
100
;
for
(
i
=
NR_FREQS
-
1
;
i
>
0
;
i
--
)
if
(
cclk_frequency_100khz
[
i
]
<
=
khz
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cclk_frequency_100khz
)
;
i
--
)
if
(
cclk_frequency_100khz
[
i
]
>
=
khz
)
break
;
return
i
;
}
/*
* Validate the speed in khz. If we can't generate the precise
* frequency requested, round it down (to be on the safe side).
* Validate the policy. We aren't able to do any fancy in-kernel
* scaling, so we force min=max, and set the policy to "performance".
* If we can't generate the precise frequency requested, round it up.
*/
unsigned
int
sa11x0_validatespeed
(
unsigned
int
cpu
,
unsigned
int
khz
)
void
sa11x0_verify_speed
(
struct
cpufreq_policy
*
policy
)
{
return
cclk_frequency_100khz
[
sa11x0_freq_to_ppcr
(
khz
)]
*
100
;
if
(
policy
->
max
>
policy
->
max_cpu_freq
)
policy
->
max
=
policy
->
max_cpu_freq
;
policy
->
max
=
cclk_frequency_100khz
[
sa11x0_freq_to_ppcr
(
policy
->
max
)]
*
100
;
policy
->
min
=
policy
->
max
;
policy
->
policy
=
CPUFREQ_POLICY_POWERSAVE
;
}
unsigned
int
sa11x0_getspeed
(
void
)
...
...
arch/arm/mach-sa1100/generic.h
View file @
2fbc109c
...
...
@@ -17,3 +17,9 @@ extern void (*sa1100fb_lcd_power)(int on);
extern
void
sa1110_mb_enable
(
void
);
extern
void
sa1110_mb_disable
(
void
);
struct
cpufreq_policy
;
extern
unsigned
int
sa11x0_freq_to_ppcr
(
unsigned
int
khz
);
extern
void
sa11x0_verify_speed
(
struct
cpufreq_policy
*
policy
);
extern
unsigned
int
sa11x0_getspeed
(
void
);
arch/arm/mach-sa1100/graphicsmaster.c
View file @
2fbc109c
...
...
@@ -25,7 +25,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
static
int
__init
graphicsmaster_init
(
void
)
{
...
...
@@ -43,7 +42,7 @@ static int __init graphicsmaster_init(void)
/*
* Probe for SA1111.
*/
ret
=
sa1111_init
(
NULL
,
0x18000000
,
ADS_EXT_IRQ
(
0
));
ret
=
sa1111_init
(
0x18000000
,
ADS_EXT_IRQ
(
0
));
if
(
ret
<
0
)
return
ret
;
...
...
arch/arm/mach-sa1100/h3600.c
View file @
2fbc109c
...
...
@@ -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 */
arch/arm/mach-sa1100/jornada720.c
View file @
2fbc109c
...
...
@@ -16,7 +16,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
#define JORTUCR_VAL 0x20000400
...
...
@@ -46,11 +45,7 @@ static int __init jornada720_init(void)
PPSR
&=
~
(
PPC_LDD3
|
PPC_LDD4
);
PPDR
|=
PPC_LDD3
|
PPC_LDD4
;
/* initialize extra IRQs */
set_GPIO_IRQ_edge
(
GPIO_GPIO1
,
GPIO_RISING_EDGE
);
sa1111_init_irq
(
IRQ_GPIO1
);
/* chained on GPIO 1 */
return
0
;
return
sa1111_init
(
0x40000000
,
IRQ_GPIO1
);
}
arch_initcall
(
jornada720_init
);
...
...
arch/arm/mach-sa1100/neponset.c
View file @
2fbc109c
...
...
@@ -11,6 +11,7 @@
#include <linux/ioport.h>
#include <linux/serial_core.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -23,13 +24,6 @@
#include <asm/hardware/sa1111.h>
#include <asm/sizes.h>
#include "sa1111.h"
static
struct
device
neponset_device
=
{
.
name
=
"Neponset"
,
.
bus_id
=
"nep_bus"
,
};
/*
* Install handler for Neponset IRQ. Note that we have to loop here
* since the ETHERNET and USAR IRQs are level based, and we need to
...
...
@@ -163,6 +157,52 @@ static struct sa1100_port_fns neponset_port_fns __initdata = {
.
get_mctrl
=
neponset_get_mctrl
,
};
/*
* LDM power management.
*/
static
int
neponset_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
/*
* Save state.
*/
if
(
level
==
SUSPEND_SAVE_STATE
||
level
==
SUSPEND_DISABLE
||
level
==
SUSPEND_POWER_DOWN
)
{
if
(
!
dev
->
saved_state
)
dev
->
saved_state
=
kmalloc
(
sizeof
(
unsigned
int
),
GFP_KERNEL
);
if
(
!
dev
->
saved_state
)
return
-
ENOMEM
;
*
(
unsigned
int
*
)
dev
->
saved_state
=
NCR_0
;
}
return
0
;
}
static
int
neponset_resume
(
struct
device
*
dev
,
u32
level
)
{
if
(
level
==
RESUME_RESTORE_STATE
||
level
==
RESUME_ENABLE
)
{
if
(
dev
->
saved_state
)
{
NCR_0
=
*
(
unsigned
int
*
)
dev
->
saved_state
;
kfree
(
dev
->
saved_state
);
dev
->
saved_state
=
NULL
;
}
}
return
0
;
}
static
struct
device_driver
neponset_device_driver
=
{
.
suspend
=
neponset_suspend
,
.
resume
=
neponset_resume
,
};
static
struct
device
neponset_device
=
{
.
name
=
"Neponset"
,
.
bus_id
=
"neponset"
,
.
driver
=
&
neponset_device_driver
,
};
static
int
__init
neponset_init
(
void
)
{
int
ret
;
...
...
@@ -191,7 +231,7 @@ static int __init neponset_init(void)
return
-
ENODEV
;
}
ret
=
device_register
(
&
neponset_device
);
ret
=
register_sys_device
(
&
neponset_device
);
if
(
ret
)
return
ret
;
...
...
@@ -213,7 +253,7 @@ static int __init neponset_init(void)
/*
* Probe and initialise the SA1111.
*/
return
sa1111_init
(
&
neponset_device
,
0x40000000
,
IRQ_NEPONSET_SA1111
);
return
sa1111_init
(
0x40000000
,
IRQ_NEPONSET_SA1111
);
}
arch_initcall
(
neponset_init
);
...
...
arch/arm/mach-sa1100/pfs168.c
View file @
2fbc109c
...
...
@@ -17,7 +17,6 @@
#include <asm/mach/serial_sa1100.h>
#include "generic.h"
#include "sa1111.h"
static
int
__init
pfs168_init
(
void
)
...
...
@@ -36,7 +35,7 @@ static int __init pfs168_init(void)
/*
* Probe for SA1111.
*/
return
sa1111_init
(
NULL
,
0x40000000
,
IRQ_GPIO25
);
return
sa1111_init
(
0x40000000
,
IRQ_GPIO25
);
}
arch_initcall
(
pfs168_init
);
...
...
arch/arm/mach-sa1100/pm.c
View file @
2fbc109c
...
...
@@ -30,6 +30,7 @@
#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <asm/hardware.h>
...
...
@@ -193,11 +194,29 @@ static int sysctl_pm_do_suspend(void)
{
int
retval
;
/*
* Suspend "legacy" devices.
*/
retval
=
pm_send_all
(
PM_SUSPEND
,
(
void
*
)
3
);
if
(
retval
==
0
)
{
/*
* Suspend LDM devices.
*/
device_suspend
(
4
,
SUSPEND_NOTIFY
);
device_suspend
(
4
,
SUSPEND_SAVE_STATE
);
device_suspend
(
4
,
SUSPEND_DISABLE
);
retval
=
pm_do_suspend
();
/*
* Resume LDM devices.
*/
device_resume
(
RESUME_RESTORE_STATE
);
device_resume
(
RESUME_ENABLE
);
/*
* Resume "legacy" devices.
*/
pm_send_all
(
PM_RESUME
,
(
void
*
)
0
);
}
...
...
arch/arm/mach-sa1100/sa1111.c
View file @
2fbc109c
...
...
@@ -25,6 +25,7 @@
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
...
...
@@ -34,11 +35,132 @@
#include <asm/hardware/sa1111.h>
#include "sa1111.h"
/*
* We keep the following data for the overall SA1111. Note that the
* struct device and struct resource are "fake"; they should be supplied
* by the bus above us. However, in the interests of getting all SA1111
* drivers converted over to the device model, we provide this as an
* anchor point for all the other drivers.
*/
struct
sa1111
{
struct
device
dev
;
struct
resource
res
;
int
irq
;
spinlock_t
lock
;
void
*
base
;
};
/*
* We _really_ need to eliminate this. Its only users
* are the PWM and DMA checking code.
*/
static
struct
sa1111
*
g_sa1111
;
static
struct
sa1111_dev
usb_dev
=
{
.
dev
=
{
.
name
=
"Intel Corporation SA1111 [USB Controller]"
,
},
.
skpcr_mask
=
SKPCR_UCLKEN
,
.
devid
=
SA1111_DEVID_USB
,
.
irq
=
{
IRQ_USBPWR
,
IRQ_NHCIM
,
IRQ_HCIBUFFACC
,
IRQ_HCIRMTWKP
,
IRQ_NHCIMFCIR
,
IRQ_USB_PORT_RESUME
},
};
struct
sa1111_device
*
sa1111
;
static
struct
sa1111_dev
sac_dev
=
{
.
dev
=
{
.
name
=
"Intel Corporation SA1111 [Audio Controller]"
,
},
.
skpcr_mask
=
SKPCR_I2SCLKEN
|
SKPCR_L3CLKEN
,
.
devid
=
SA1111_DEVID_SAC
,
.
irq
=
{
AUDXMTDMADONEA
,
AUDXMTDMADONEB
,
AUDRCVDMADONEA
,
AUDRCVDMADONEB
},
};
EXPORT_SYMBOL
(
sa1111
);
static
struct
sa1111_dev
ssp_dev
=
{
.
dev
=
{
.
name
=
"Intel Corporation SA1111 [SSP Controller]"
,
},
.
skpcr_mask
=
SKPCR_SCLKEN
,
.
devid
=
SA1111_DEVID_SSP
,
};
static
struct
sa1111_dev
kbd_dev
=
{
.
dev
=
{
.
name
=
"Intel Corporation SA1111 [PS2]"
,
},
.
skpcr_mask
=
SKPCR_PTCLKEN
,
.
devid
=
SA1111_DEVID_PS2
,
.
irq
=
{
IRQ_TPRXINT
,
IRQ_TPTXINT
},
};
static
struct
sa1111_dev
mse_dev
=
{
.
dev
=
{
.
name
=
"Intel Corporation SA1111 [PS2]"
,
},
.
skpcr_mask
=
SKPCR_PMCLKEN
,
.
devid
=
SA1111_DEVID_PS2
,
.
irq
=
{
IRQ_MSRXINT
,
IRQ_MSTXINT
},
};
static
struct
sa1111_dev
int_dev
=
{
.
dev
=
{
.
name
=
"Intel Corporation SA1111 [Interrupt Controller]"
,
},
.
skpcr_mask
=
0
,
.
devid
=
SA1111_DEVID_INT
,
};
static
struct
sa1111_dev
pcmcia_dev
=
{
.
dev
=
{
.
name
=
"Intel Corporation SA1111 [PCMCIA Controller]"
,
},
.
skpcr_mask
=
0
,
.
devid
=
SA1111_DEVID_PCMCIA
,
.
irq
=
{
IRQ_S0_READY_NINT
,
IRQ_S0_CD_VALID
,
IRQ_S0_BVD1_STSCHG
,
IRQ_S1_READY_NINT
,
IRQ_S1_CD_VALID
,
IRQ_S1_BVD1_STSCHG
,
},
};
static
struct
sa1111_dev
*
devs
[]
=
{
&
usb_dev
,
&
sac_dev
,
&
ssp_dev
,
&
kbd_dev
,
&
mse_dev
,
&
int_dev
,
&
pcmcia_dev
,
};
static
unsigned
int
dev_offset
[]
=
{
SA1111_USB
,
0x0600
,
0x0800
,
SA1111_KBD
,
SA1111_MSE
,
SA1111_INTC
,
0x1800
,
};
/*
* SA1111 interrupt support. Since clearing an IRQ while there are
...
...
@@ -50,11 +172,15 @@ sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
{
unsigned
int
stat0
,
stat1
,
i
;
desc
->
chip
->
ack
(
irq
);
stat0
=
INTSTATCLR0
;
stat1
=
INTSTATCLR1
;
INTSTATCLR0
=
stat0
;
desc
->
chip
->
ack
(
irq
);
INTSTATCLR1
=
stat1
;
if
(
stat0
==
0
&&
stat1
==
0
)
{
do_bad_IRQ
(
irq
,
desc
,
regs
);
return
;
...
...
@@ -75,9 +201,8 @@ sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START))
#define SA1111_IRQMASK_HI(x) (1 << (x - IRQ_SA1111_START - 32))
static
void
sa1111_ack_
low
irq
(
unsigned
int
irq
)
static
void
sa1111_ack_irq
(
unsigned
int
irq
)
{
INTSTATCLR0
=
SA1111_IRQMASK_LO
(
irq
);
}
static
void
sa1111_mask_lowirq
(
unsigned
int
irq
)
...
...
@@ -133,18 +258,13 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
}
static
struct
irqchip
sa1111_low_chip
=
{
.
ack
=
sa1111_ack_
low
irq
,
.
ack
=
sa1111_ack_irq
,
.
mask
=
sa1111_mask_lowirq
,
.
unmask
=
sa1111_unmask_lowirq
,
.
rerun
=
sa1111_rerun_lowirq
,
.
type
=
sa1111_type_lowirq
,
};
static
void
sa1111_ack_highirq
(
unsigned
int
irq
)
{
INTSTATCLR1
=
SA1111_IRQMASK_HI
(
irq
);
}
static
void
sa1111_mask_highirq
(
unsigned
int
irq
)
{
INTEN1
&=
~
SA1111_IRQMASK_HI
(
irq
);
...
...
@@ -198,34 +318,40 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
}
static
struct
irqchip
sa1111_high_chip
=
{
.
ack
=
sa1111_ack_
high
irq
,
.
ack
=
sa1111_ack_irq
,
.
mask
=
sa1111_mask_highirq
,
.
unmask
=
sa1111_unmask_highirq
,
.
rerun
=
sa1111_rerun_highirq
,
.
type
=
sa1111_type_highirq
,
};
static
void
__init
sa1111_init_irq
(
int
irq_nr
)
static
void
__init
sa1111_init_irq
(
struct
sa1111_dev
*
sadev
)
{
unsigned
int
irq
;
request_mem_region
(
_INTTEST0
,
512
,
"irqs"
);
/*
* We're guaranteed that this region hasn't been taken.
*/
request_mem_region
(
sadev
->
res
.
start
,
512
,
"irqs"
);
/* disable all IRQs */
INTEN0
=
0
;
INTEN1
=
0
;
sa1111_writel
(
0
,
sadev
->
mapbase
+
SA1111_INTEN0
);
sa1111_writel
(
0
,
sadev
->
mapbase
+
SA1111_INTEN1
);
sa1111_writel
(
0
,
sadev
->
mapbase
+
SA1111_WAKEEN0
);
sa1111_writel
(
0
,
sadev
->
mapbase
+
SA1111_WAKEEN1
);
/*
* detect on rising edge. Note: Feb 2001 Errata for SA1111
* specifies that S0ReadyInt and S1ReadyInt should be '1'.
*/
INTPOL0
=
0
;
INTPOL1
=
SA1111_IRQMASK_HI
(
S0_READY_NINT
)
|
SA1111_IRQMASK_HI
(
S1_READY_NINT
);
sa1111_writel
(
0
,
sadev
->
mapbase
+
SA1111_INTPOL0
);
sa1111_writel
(
SA1111_IRQMASK_HI
(
IRQ_S0_READY_NINT
)
|
SA1111_IRQMASK_HI
(
IRQ_S1_READY_NINT
),
sadev
->
mapbase
+
SA1111_INTPOL1
);
/* clear all IRQs */
INTSTATCLR0
=
~
0
;
INTSTATCLR1
=
~
0
;
sa1111_writel
(
~
0
,
sadev
->
mapbase
+
SA1111_INTSTATCLR0
)
;
sa1111_writel
(
~
0
,
sadev
->
mapbase
+
SA1111_INTSTATCLR1
)
;
for
(
irq
=
IRQ_GPAIN0
;
irq
<=
SSPROR
;
irq
++
)
{
set_irq_chip
(
irq
,
&
sa1111_low_chip
);
...
...
@@ -233,7 +359,7 @@ static void __init sa1111_init_irq(int irq_nr)
set_irq_flags
(
irq
,
IRQF_VALID
|
IRQF_PROBE
);
}
for
(
irq
=
AUDXMTDMADONEA
;
irq
<=
S1_BVD1_STSCHG
;
irq
++
)
{
for
(
irq
=
AUDXMTDMADONEA
;
irq
<=
IRQ_
S1_BVD1_STSCHG
;
irq
++
)
{
set_irq_chip
(
irq
,
&
sa1111_high_chip
);
set_irq_handler
(
irq
,
do_edge_IRQ
);
set_irq_flags
(
irq
,
IRQF_VALID
|
IRQF_PROBE
);
...
...
@@ -242,24 +368,11 @@ static void __init sa1111_init_irq(int irq_nr)
/*
* Register SA1111 interrupt
*/
set_irq_type
(
irq_nr
,
IRQT_RISING
);
set_irq_chained_handler
(
irq_nr
,
sa1111_irq_handler
);
}
static
int
sa1111_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
return
0
;
set_irq_type
(
sadev
->
irq
[
0
],
IRQT_RISING
);
set_irq_chained_handler
(
sadev
->
irq
[
0
],
sa1111_irq_handler
);
}
static
int
sa1111_resume
(
struct
device
*
dev
,
u32
level
)
{
return
0
;
}
static
struct
device_driver
sa1111_device_driver
=
{
.
suspend
=
sa1111_suspend
,
.
resume
=
sa1111_resume
,
};
static
struct
device_driver
sa1111_device_driver
;
/**
* sa1111_probe - probe for a single SA1111 chip.
...
...
@@ -274,30 +387,38 @@ static struct device_driver sa1111_device_driver = {
* %0 successful.
*/
static
int
__init
sa1111_probe
(
struct
device
*
parent
,
unsigned
long
phys_addr
)
sa1111_probe
(
unsigned
long
phys_addr
,
int
irq
)
{
struct
sa1111
_device
*
sa
;
struct
sa1111
*
sachip
;
unsigned
long
id
;
int
ret
=
-
ENODEV
;
unsigned
int
has_devs
;
int
i
,
ret
=
-
ENODEV
;
sa
=
kmalloc
(
sizeof
(
struct
sa1111_device
),
GFP_KERNEL
);
if
(
!
sa
)
sa
chip
=
kmalloc
(
sizeof
(
struct
sa1111
),
GFP_KERNEL
);
if
(
!
sa
chip
)
return
-
ENOMEM
;
memset
(
sa
,
0
,
sizeof
(
struct
sa1111_device
));
memset
(
sachip
,
0
,
sizeof
(
struct
sa1111
));
spin_lock_init
(
&
sachip
->
lock
);
sa
->
resource
.
name
=
"SA1111"
;
sa
->
resource
.
start
=
phys_addr
;
sa
->
resource
.
end
=
phys_addr
+
0x2000
;
strncpy
(
sachip
->
dev
.
name
,
"Intel Corporation SA1111"
,
sizeof
(
sachip
->
dev
.
name
));
snprintf
(
sachip
->
dev
.
bus_id
,
sizeof
(
sachip
->
dev
.
bus_id
),
"%8.8lx"
,
phys_addr
);
sachip
->
dev
.
driver
=
&
sa1111_device_driver
;
sachip
->
dev
.
driver_data
=
sachip
;
if
(
request_resource
(
&
iomem_resource
,
&
sa
->
resource
))
{
sachip
->
res
.
name
=
sachip
->
dev
.
name
;
sachip
->
res
.
start
=
phys_addr
;
sachip
->
res
.
end
=
phys_addr
+
0x2000
;
sachip
->
irq
=
irq
;
if
(
request_resource
(
&
iomem_resource
,
&
sachip
->
res
))
{
ret
=
-
EBUSY
;
goto
out
;
}
/* eventually ioremap... */
sa
->
base
=
(
void
*
)
0xf4000000
;
if
(
!
sa
->
base
)
{
sachip
->
base
=
ioremap
(
phys_addr
,
PAGE_SIZE
*
2
);
if
(
!
sachip
->
base
)
{
ret
=
-
ENOMEM
;
goto
release
;
}
...
...
@@ -305,7 +426,7 @@ sa1111_probe(struct device *parent, unsigned long phys_addr)
/*
* Probe for the chip. Only touch the SBI registers.
*/
id
=
sa1111_readl
(
sa
->
base
+
SA1111_SKID
);
id
=
sa1111_readl
(
sa
chip
->
base
+
SA1111_SKID
);
if
((
id
&
SKID_ID_MASK
)
!=
SKID_SA1111_ID
)
{
printk
(
KERN_DEBUG
"SA1111 not detected: ID = %08lx
\n
"
,
id
);
ret
=
-
ENODEV
;
...
...
@@ -315,12 +436,7 @@ sa1111_probe(struct device *parent, unsigned long phys_addr)
/*
* We found the chip.
*/
strcpy
(
sa
->
dev
.
name
,
"SA1111"
);
sprintf
(
sa
->
dev
.
bus_id
,
"%8.8lx"
,
phys_addr
);
sa
->
dev
.
parent
=
parent
;
sa
->
dev
.
driver
=
&
sa1111_device_driver
;
ret
=
device_register
(
&
sa
->
dev
);
ret
=
register_sys_device
(
&
sachip
->
dev
);
if
(
ret
)
printk
(
"sa1111 device_register failed: %d
\n
"
,
ret
);
...
...
@@ -328,19 +444,64 @@ sa1111_probe(struct device *parent, unsigned long phys_addr)
"silicon revision %lx, metal revision %lx
\n
"
,
(
id
&
SKID_SIREV_MASK
)
>>
4
,
(
id
&
SKID_MTREV_MASK
));
sa1111
=
sa
;
g_sa1111
=
sachip
;
has_devs
=
~
0
;
if
(
machine_is_assabet
()
||
machine_is_jornada720
()
||
machine_is_badge4
())
has_devs
&=
~
(
1
<<
4
);
else
has_devs
&=
~
(
1
<<
1
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
devs
);
i
++
)
{
if
(
!
(
has_devs
&
(
1
<<
i
)))
continue
;
snprintf
(
devs
[
i
]
->
dev
.
bus_id
,
sizeof
(
devs
[
i
]
->
dev
.
bus_id
),
"%4.4x"
,
dev_offset
[
i
]);
devs
[
i
]
->
dev
.
parent
=
&
sachip
->
dev
;
devs
[
i
]
->
dev
.
bus
=
&
sa1111_bus_type
;
devs
[
i
]
->
res
.
start
=
sachip
->
res
.
start
+
dev_offset
[
i
];
devs
[
i
]
->
res
.
end
=
devs
[
i
]
->
res
.
start
+
511
;
devs
[
i
]
->
res
.
name
=
devs
[
i
]
->
dev
.
name
;
devs
[
i
]
->
res
.
flags
=
IORESOURCE_MEM
;
devs
[
i
]
->
mapbase
=
sachip
->
base
+
dev_offset
[
i
];
if
(
request_resource
(
&
sachip
->
res
,
&
devs
[
i
]
->
res
))
{
printk
(
"SA1111: failed to allocate resource for %s
\n
"
,
devs
[
i
]
->
res
.
name
);
continue
;
}
device_register
(
&
devs
[
i
]
->
dev
);
}
return
0
;
unmap:
// iounmap(sa
->base);
iounmap
(
sachip
->
base
);
release:
release_resource
(
&
sa
->
resource
);
release_resource
(
&
sa
chip
->
res
);
out:
kfree
(
sa
);
kfree
(
sa
chip
);
return
ret
;
}
static
void
__sa1111_remove
(
struct
sa1111
*
sachip
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
devs
);
i
++
)
{
put_device
(
&
devs
[
i
]
->
dev
);
release_resource
(
&
devs
[
i
]
->
res
);
}
iounmap
(
sachip
->
base
);
release_resource
(
&
sachip
->
res
);
kfree
(
sachip
);
}
/*
* Bring the SA1111 out of reset. This requires a set procedure:
* 1. nRESET asserted (by hardware)
...
...
@@ -355,12 +516,11 @@ sa1111_probe(struct device *parent, unsigned long phys_addr)
* SBI_SMCR
* SBI_SKID
*/
void
sa1111_wake
(
void
)
static
void
sa1111_wake
(
struct
sa1111
*
sachip
)
{
struct
sa1111_device
*
sa
=
sa1111
;
unsigned
long
flags
,
r
;
local_irq_save
(
flags
);
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
/*
* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
...
...
@@ -373,11 +533,11 @@ void sa1111_wake(void)
/*
* Turn VCO on, and disable PLL Bypass.
*/
r
=
sa1111_readl
(
sa
->
base
+
SA1111_SKCR
);
r
=
sa1111_readl
(
sa
chip
->
base
+
SA1111_SKCR
);
r
&=
~
SKCR_VCO_OFF
;
sa1111_writel
(
r
,
sa
->
base
+
SA1111_SKCR
);
sa1111_writel
(
r
,
sa
chip
->
base
+
SA1111_SKCR
);
r
|=
SKCR_PLL_BYPASS
|
SKCR_OE_EN
;
sa1111_writel
(
r
,
sa
->
base
+
SA1111_SKCR
);
sa1111_writel
(
r
,
sa
chip
->
base
+
SA1111_SKCR
);
/*
* Wait lock time. SA1111 manual _doesn't_
...
...
@@ -389,7 +549,7 @@ void sa1111_wake(void)
* Enable RCLK. We also ensure that RDYEN is set.
*/
r
|=
SKCR_RCLKEN
|
SKCR_RDYEN
;
sa1111_writel
(
r
,
sa
->
base
+
SA1111_SKCR
);
sa1111_writel
(
r
,
sa
chip
->
base
+
SA1111_SKCR
);
/*
* Wait 14 RCLK cycles for the chip to finish coming out
...
...
@@ -400,76 +560,31 @@ void sa1111_wake(void)
/*
* Ensure all clocks are initially off.
*/
sa1111_writel
(
0
,
sa
->
base
+
SA1111_SKPCR
);
sa1111_writel
(
0
,
sa
chip
->
base
+
SA1111_SKPCR
);
local_irq_restore
(
flags
);
}
void
sa1111_doze
(
void
)
{
struct
sa1111_device
*
sa
=
sa1111
;
unsigned
long
flags
;
unsigned
int
val
;
local_irq_save
(
flags
);
if
(
sa1111_readl
(
sa
->
base
+
SA1111_SKPCR
)
&
SKPCR_UCLKEN
)
{
local_irq_restore
(
flags
);
printk
(
"SA1111 doze mode refused
\n
"
);
return
;
}
val
=
sa1111_readl
(
sa
->
base
+
SA1111_SKCR
);
sa1111_writel
(
val
&
~
SKCR_RCLKEN
,
sa
->
base
+
SA1111_SKCR
);
local_irq_restore
(
flags
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
}
/*
* Configure the SA1111 shared memory controller.
*/
void
sa1111_configure_smc
(
int
sdram
,
unsigned
int
drac
,
unsigned
int
cas_latency
)
void
sa1111_configure_smc
(
struct
sa1111
*
sachip
,
int
sdram
,
unsigned
int
drac
,
unsigned
int
cas_latency
)
{
struct
sa1111_device
*
sa
=
sa1111
;
unsigned
int
smcr
=
SMCR_DTIM
|
SMCR_MBGE
|
FInsrt
(
drac
,
SMCR_DRAC
);
if
(
cas_latency
==
3
)
smcr
|=
SMCR_CLAT
;
sa1111_writel
(
smcr
,
sa
->
base
+
SA1111_SMCR
);
sa1111_writel
(
smcr
,
sa
chip
->
base
+
SA1111_SMCR
);
}
EXPORT_SYMBOL
(
sa1111_wake
);
EXPORT_SYMBOL
(
sa1111_doze
);
void
sa1111_enable_device
(
unsigned
int
mask
)
{
struct
sa1111_device
*
sa
=
sa1111
;
unsigned
int
val
;
preempt_disable
();
val
=
sa1111_readl
(
sa
->
base
+
SA1111_SKPCR
);
sa1111_writel
(
val
|
mask
,
sa
->
base
+
SA1111_SKPCR
);
preempt_enable
();
}
void
sa1111_disable_device
(
unsigned
int
mask
)
{
struct
sa1111_device
*
sa
=
sa1111
;
unsigned
int
val
;
preempt_disable
();
val
=
sa1111_readl
(
sa
->
base
+
SA1111_SKPCR
);
sa1111_writel
(
val
&
~
mask
,
sa
->
base
+
SA1111_SKPCR
);
preempt_enable
();
}
EXPORT_SYMBOL
(
sa1111_enable_device
);
EXPORT_SYMBOL
(
sa1111_disable_device
);
/* According to the "Intel StrongARM SA-1111 Microprocessor Companion
/*
* According to the "Intel StrongARM SA-1111 Microprocessor Companion
* Chip Specification Update" (June 2000), erratum #7, there is a
* significant bug in
Serial Audio Controller DMA. If the SAC is
* a
ccessing
a region of memory above 1MB relative to the bank base,
* significant bug in
the SA1111 SDRAM shared memory controller. If
* a
n access to
a region of memory above 1MB relative to the bank base,
* it is important that address bit 10 _NOT_ be asserted. Depending
* on the configuration of the RAM, bit 10 may correspond to one
* of several different (processor-relative) address bits.
...
...
@@ -479,7 +594,9 @@ EXPORT_SYMBOL(sa1111_disable_device);
*/
int
sa1111_check_dma_bug
(
dma_addr_t
addr
)
{
unsigned
int
physaddr
=
SA1111_DMA_ADDR
((
unsigned
int
)
addr
);
struct
sa1111
*
sachip
=
g_sa1111
;
unsigned
int
physaddr
=
SA1111_DMA_ADDR
((
unsigned
int
)
addr
);
unsigned
int
smcr
;
/* Section 4.6 of the "Intel StrongARM SA-1111 Development Module
* User's Guide" mentions that jumpers R51 and R52 control the
...
...
@@ -494,9 +611,10 @@ int sa1111_check_dma_bug(dma_addr_t addr)
* above the start of the target bank:
*/
if
(
physaddr
<
(
1
<<
20
))
return
0
;
return
0
;
switch
(
FExtr
(
SBI_SMCR
,
SMCR_DRAC
))
{
smcr
=
sa1111_readl
(
sachip
->
base
+
SA1111_SMCR
);
switch
(
FExtr
(
smcr
,
SMCR_DRAC
))
{
case
01
:
/* 10 row + bank address bits, A<20> must not be set */
if
(
physaddr
&
(
1
<<
20
))
return
-
1
;
...
...
@@ -523,27 +641,26 @@ int sa1111_check_dma_bug(dma_addr_t addr)
break
;
default:
printk
(
KERN_ERR
"%s(): invalid SMCR DRAC value 0%lo
\n
"
,
__FUNCTION__
,
FExtr
(
SBI_SMCR
,
SMCR_DRAC
));
__FUNCTION__
,
FExtr
(
smcr
,
SMCR_DRAC
));
return
-
1
;
}
return
0
;
}
EXPORT_SYMBOL
(
sa1111_check_dma_bug
);
int
sa1111_init
(
struct
device
*
parent
,
unsigned
long
phys
,
unsigned
int
irq
)
int
sa1111_init
(
unsigned
long
phys
,
unsigned
int
irq
)
{
unsigned
int
val
;
int
ret
;
ret
=
sa1111_probe
(
p
arent
,
phys
);
ret
=
sa1111_probe
(
p
hys
,
irq
);
if
(
ret
<
0
)
return
ret
;
/*
* We found it. Wake the chip up.
*/
sa1111_wake
();
sa1111_wake
(
g_sa1111
);
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
...
...
@@ -552,7 +669,7 @@ int sa1111_init(struct device *parent, unsigned long phys, unsigned int irq)
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc
(
1
,
sa1111_configure_smc
(
g_sa1111
,
1
,
FExtr
(
MDCNFG
,
MDCNFG_SA1110_DRAC0
),
FExtr
(
MDCNFG
,
MDCNFG_SA1110_TDL0
));
...
...
@@ -560,7 +677,8 @@ int sa1111_init(struct device *parent, unsigned long phys, unsigned int irq)
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
sa1111_enable_device
(
SKPCR_DCLKEN
);
val
=
sa1111_readl
(
g_sa1111
->
base
+
SA1111_SKPCR
);
sa1111_writel
(
val
|
SKPCR_DCLKEN
,
g_sa1111
->
base
+
SA1111_SKPCR
);
/*
* Enable the SA1110 memory bus request and grant signals.
...
...
@@ -570,7 +688,341 @@ int sa1111_init(struct device *parent, unsigned long phys, unsigned int irq)
/*
* Initialise SA1111 IRQs
*/
sa1111_init_irq
(
irq
);
int_dev
.
irq
[
0
]
=
irq
;
sa1111_init_irq
(
&
int_dev
);
return
0
;
}
struct
sa1111_save_data
{
unsigned
int
skcr
;
unsigned
int
skpcr
;
unsigned
int
skcdr
;
unsigned
char
skaud
;
unsigned
char
skpwm0
;
unsigned
char
skpwm1
;
/*
* Interrupt controller
*/
unsigned
int
intpol0
;
unsigned
int
intpol1
;
unsigned
int
inten0
;
unsigned
int
inten1
;
unsigned
int
wakepol0
;
unsigned
int
wakepol1
;
unsigned
int
wakeen0
;
unsigned
int
wakeen1
;
};
static
int
sa1111_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
struct
sa1111
*
sachip
=
dev
->
driver_data
;
unsigned
long
flags
;
char
*
base
;
/*
* Save state.
*/
if
(
level
==
SUSPEND_SAVE_STATE
||
level
==
SUSPEND_DISABLE
||
level
==
SUSPEND_POWER_DOWN
)
{
struct
sa1111_save_data
*
save
;
if
(
!
dev
->
saved_state
)
dev
->
saved_state
=
kmalloc
(
sizeof
(
struct
sa1111_save_data
),
GFP_KERNEL
);
if
(
!
dev
->
saved_state
)
return
-
ENOMEM
;
save
=
(
struct
sa1111_save_data
*
)
dev
->
saved_state
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
base
=
sachip
->
base
;
save
->
skcr
=
sa1111_readl
(
base
+
SA1111_SKCR
);
save
->
skpcr
=
sa1111_readl
(
base
+
SA1111_SKPCR
);
save
->
skcdr
=
sa1111_readl
(
base
+
SA1111_SKCDR
);
save
->
skaud
=
sa1111_readl
(
base
+
SA1111_SKAUD
);
save
->
skpwm0
=
sa1111_readl
(
base
+
SA1111_SKPWM0
);
save
->
skpwm1
=
sa1111_readl
(
base
+
SA1111_SKPWM1
);
base
=
sachip
->
base
+
SA1111_INTC
;
save
->
intpol0
=
sa1111_readl
(
base
+
SA1111_INTPOL0
);
save
->
intpol1
=
sa1111_readl
(
base
+
SA1111_INTPOL1
);
save
->
inten0
=
sa1111_readl
(
base
+
SA1111_INTEN0
);
save
->
inten1
=
sa1111_readl
(
base
+
SA1111_INTEN1
);
save
->
wakepol0
=
sa1111_readl
(
base
+
SA1111_WAKEPOL0
);
save
->
wakepol1
=
sa1111_readl
(
base
+
SA1111_WAKEPOL1
);
save
->
wakeen0
=
sa1111_readl
(
base
+
SA1111_WAKEEN0
);
save
->
wakeen1
=
sa1111_readl
(
base
+
SA1111_WAKEEN1
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
}
/*
* Disable.
*/
if
(
level
==
SUSPEND_DISABLE
&&
state
==
4
)
{
unsigned
int
val
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
base
=
sachip
->
base
;
sa1111_writel
(
0
,
base
+
SA1111_SKPWM0
);
sa1111_writel
(
0
,
base
+
SA1111_SKPWM1
);
val
=
sa1111_readl
(
base
+
SA1111_SKCR
);
sa1111_writel
(
val
|
SKCR_SLEEP
,
base
+
SA1111_SKCR
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
}
return
0
;
}
/*
* sa1111_resume - Restore the SA1111 device state.
* @dev: device to restore
* @level: resume level
*
* Restore the general state of the SA1111; clock control and
* interrupt controller. Other parts of the SA1111 must be
* restored by their respective drivers, and must be called
* via LDM after this function.
*/
static
int
sa1111_resume
(
struct
device
*
dev
,
u32
level
)
{
struct
sa1111
*
sachip
=
dev
->
driver_data
;
struct
sa1111_save_data
*
save
;
unsigned
long
flags
,
id
;
char
*
base
;
if
(
level
!=
RESUME_RESTORE_STATE
&&
level
!=
RESUME_ENABLE
)
return
0
;
save
=
(
struct
sa1111_save_data
*
)
dev
->
saved_state
;
if
(
!
save
)
return
0
;
dev
->
saved_state
=
NULL
;
/*
* Ensure that the SA1111 is still here.
*/
id
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKID
);
if
((
id
&
SKID_ID_MASK
)
!=
SKID_SA1111_ID
)
{
__sa1111_remove
(
sachip
);
kfree
(
save
);
return
0
;
}
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
sa1111_wake
(
sachip
);
base
=
sachip
->
base
;
sa1111_writel
(
save
->
skcr
,
base
+
SA1111_SKCR
);
sa1111_writel
(
save
->
skpcr
,
base
+
SA1111_SKPCR
);
sa1111_writel
(
save
->
skcdr
,
base
+
SA1111_SKCDR
);
sa1111_writel
(
save
->
skaud
,
base
+
SA1111_SKAUD
);
sa1111_writel
(
save
->
skpwm0
,
base
+
SA1111_SKPWM0
);
sa1111_writel
(
save
->
skpwm1
,
base
+
SA1111_SKPWM1
);
base
=
sachip
->
base
+
SA1111_INTC
;
sa1111_writel
(
save
->
intpol0
,
base
+
SA1111_INTPOL0
);
sa1111_writel
(
save
->
intpol1
,
base
+
SA1111_INTPOL1
);
sa1111_writel
(
save
->
inten0
,
base
+
SA1111_INTEN0
);
sa1111_writel
(
save
->
inten1
,
base
+
SA1111_INTEN1
);
sa1111_writel
(
save
->
wakepol0
,
base
+
SA1111_WAKEPOL0
);
sa1111_writel
(
save
->
wakepol1
,
base
+
SA1111_WAKEPOL1
);
sa1111_writel
(
save
->
wakeen0
,
base
+
SA1111_WAKEEN0
);
sa1111_writel
(
save
->
wakeen1
,
base
+
SA1111_WAKEEN1
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
kfree
(
save
);
return
0
;
}
static
struct
device_driver
sa1111_device_driver
=
{
.
suspend
=
sa1111_suspend
,
.
resume
=
sa1111_resume
,
};
/*
* Get the parent device driver (us) structure
* from a child function device
*/
static
inline
struct
sa1111
*
sa1111_chip_driver
(
struct
sa1111_dev
*
sadev
)
{
return
(
struct
sa1111
*
)
sadev
->
dev
.
parent
->
driver_data
;
}
/*
* The bits in the opdiv field are non-linear.
*/
static
unsigned
char
opdiv_table
[]
=
{
1
,
4
,
2
,
8
};
static
unsigned
int
__sa1111_pll_clock
(
struct
sa1111
*
sachip
)
{
unsigned
int
skcdr
,
fbdiv
,
ipdiv
,
opdiv
;
skcdr
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKCDR
);
fbdiv
=
(
skcdr
&
0x007f
)
+
2
;
ipdiv
=
((
skcdr
&
0x0f80
)
>>
7
)
+
2
;
opdiv
=
opdiv_table
[(
skcdr
&
0x3000
)
>>
12
];
return
3686400
*
fbdiv
/
(
ipdiv
*
opdiv
);
}
/**
* sa1111_pll_clock - return the current PLL clock frequency.
* @sadev: SA1111 function block
*
* BUG: we should look at SKCR. We also blindly believe that
* the chip is being fed with the 3.6864MHz clock.
*
* Returns the PLL clock in Hz.
*/
unsigned
int
sa1111_pll_clock
(
struct
sa1111_dev
*
sadev
)
{
struct
sa1111
*
sachip
=
sa1111_chip_driver
(
sadev
);
return
__sa1111_pll_clock
(
sachip
);
}
/**
* sa1111_select_audio_mode - select I2S or AC link mode
* @sadev: SA1111 function block
* @mode: One of %SA1111_AUDIO_ACLINK or %SA1111_AUDIO_I2S
*
* Frob the SKCR to select AC Link mode or I2S mode for
* the audio block.
*/
void
sa1111_select_audio_mode
(
struct
sa1111_dev
*
sadev
,
int
mode
)
{
struct
sa1111
*
sachip
=
sa1111_chip_driver
(
sadev
);
unsigned
long
flags
;
unsigned
int
val
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
val
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKCR
);
if
(
mode
==
SA1111_AUDIO_I2S
)
{
val
&=
~
SKCR_SELAC
;
}
else
{
val
|=
SKCR_SELAC
;
}
sa1111_writel
(
val
,
sachip
->
base
+
SA1111_SKCR
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
}
/**
* sa1111_set_audio_rate - set the audio sample rate
* @sadev: SA1111 SAC function block
* @rate: sample rate to select
*/
int
sa1111_set_audio_rate
(
struct
sa1111_dev
*
sadev
,
int
rate
)
{
struct
sa1111
*
sachip
=
sa1111_chip_driver
(
sadev
);
unsigned
int
div
;
if
(
sadev
->
devid
!=
SA1111_DEVID_SAC
)
return
-
EINVAL
;
div
=
(
__sa1111_pll_clock
(
sachip
)
/
256
+
rate
/
2
)
/
rate
;
if
(
div
==
0
)
div
=
1
;
if
(
div
>
128
)
div
=
128
;
sa1111_writel
(
div
-
1
,
sachip
->
base
+
SA1111_SKAUD
);
return
0
;
}
/**
* sa1111_get_audio_rate - get the audio sample rate
* @sadev: SA1111 SAC function block device
*/
int
sa1111_get_audio_rate
(
struct
sa1111_dev
*
sadev
)
{
struct
sa1111
*
sachip
=
sa1111_chip_driver
(
sadev
);
unsigned
long
div
;
if
(
sadev
->
devid
!=
SA1111_DEVID_SAC
)
return
-
EINVAL
;
div
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKAUD
)
+
1
;
return
__sa1111_pll_clock
(
sachip
)
/
(
256
*
div
);
}
/*
* Individual device operations.
*/
/**
* sa1111_enable_device - enable an on-chip SA1111 function block
* @sadev: SA1111 function block device to enable
*/
void
sa1111_enable_device
(
struct
sa1111_dev
*
sadev
)
{
struct
sa1111
*
sachip
=
sa1111_chip_driver
(
sadev
);
unsigned
long
flags
;
unsigned
int
val
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
val
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKPCR
);
sa1111_writel
(
val
|
sadev
->
skpcr_mask
,
sachip
->
base
+
SA1111_SKPCR
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
}
/**
* sa1111_disable_device - disable an on-chip SA1111 function block
* @sadev: SA1111 function block device to disable
*/
void
sa1111_disable_device
(
struct
sa1111_dev
*
sadev
)
{
struct
sa1111
*
sachip
=
sa1111_chip_driver
(
sadev
);
unsigned
long
flags
;
unsigned
int
val
;
spin_lock_irqsave
(
&
sachip
->
lock
,
flags
);
val
=
sa1111_readl
(
sachip
->
base
+
SA1111_SKPCR
);
sa1111_writel
(
val
&
~
sadev
->
skpcr_mask
,
sachip
->
base
+
SA1111_SKPCR
);
spin_unlock_irqrestore
(
&
sachip
->
lock
,
flags
);
}
/*
* SA1111 "Register Access Bus."
*
* We model this as a regular bus type, and hang devices directly
* off this.
*/
static
int
sa1111_match
(
struct
device
*
_dev
,
struct
device_driver
*
_drv
)
{
struct
sa1111_dev
*
dev
=
SA1111_DEV
(
_dev
);
struct
sa1111_driver
*
drv
=
SA1111_DRV
(
_drv
);
return
dev
->
devid
==
drv
->
devid
;
}
struct
bus_type
sa1111_bus_type
=
{
.
name
=
"RAB"
,
.
match
=
sa1111_match
,
};
static
int
sa1111_rab_bus_init
(
void
)
{
return
bus_register
(
&
sa1111_bus_type
);
}
postcore_initcall
(
sa1111_rab_bus_init
);
EXPORT_SYMBOL
(
sa1111_check_dma_bug
);
EXPORT_SYMBOL
(
sa1111_select_audio_mode
);
EXPORT_SYMBOL
(
sa1111_set_audio_rate
);
EXPORT_SYMBOL
(
sa1111_get_audio_rate
);
EXPORT_SYMBOL
(
sa1111_enable_device
);
EXPORT_SYMBOL
(
sa1111_disable_device
);
EXPORT_SYMBOL
(
sa1111_pll_clock
);
EXPORT_SYMBOL
(
sa1111_bus_type
);
arch/arm/mach-sa1100/sa1111.h
deleted
100644 → 0
View file @
1b8ad82f
/*
* linux/arch/arm/mach-sa1100/sa1111.h
*/
struct
device
;
/*
* Probe for a SA1111 chip.
*/
extern
int
sa1111_init
(
struct
device
*
parent
,
unsigned
long
phys
,
unsigned
int
irq
);
/*
* Wake up a SA1111 chip.
*/
extern
void
sa1111_wake
(
void
);
/*
* Doze the SA1111 chip.
*/
extern
void
sa1111_doze
(
void
);
arch/arm/mach-sa1100/stork.c
View file @
2fbc109c
...
...
@@ -284,6 +284,17 @@ storkInitTSandDtoA(void)
storkClockShortToDtoA
(
0x0A00
);
/* turn on the brightness */
}
static
void
stork_lcd_power
(
int
on
)
{
if
(
on
)
{
storkSetLCDCPLD
(
0
,
1
);
storkSetLatchA
(
STORK_LCD_BACKLIGHT_INVERTER_ON
);
}
else
{
storkSetLCDCPLD
(
0
,
0
);
storkClearLatchA
(
STORK_LCD_BACKLIGHT_INVERTER_ON
);
}
}
struct
map_desc
stork_io_desc
[]
__initdata
=
{
/* virtual physical length type */
{
STORK_VM_BASE_CS1
,
STORK_VM_OFF_CS1
,
0x01000000
,
MT_DEVICE
},
/* EGPIO 0 */
...
...
@@ -312,6 +323,8 @@ stork_map_io(void)
storkInitTSandDtoA
();
sa1100fb_lcd_power
=
stork_lcd_power
;
return
0
;
}
...
...
arch/arm/mach-sa1100/system3.c
View file @
2fbc109c
...
...
@@ -56,7 +56,6 @@
#include <linux/serial_core.h>
#include "generic.h"
#include "sa1111.h"
#include <asm/hardware/sa1111.h>
#define DEBUG 1
...
...
@@ -401,7 +400,7 @@ static int __init system3_init(void)
/*
* Probe for a SA1111.
*/
ret
=
sa1111_init
(
NULL
,
PT_SA1111_BASE
,
IRQ_SYSTEM3_SA1111
);
ret
=
sa1111_init
(
PT_SA1111_BASE
,
IRQ_SYSTEM3_SA1111
);
if
(
ret
<
0
)
{
printk
(
KERN_WARNING
"PT Digital Board: no SA1111 found!
\n
"
);
goto
DONE
;
...
...
arch/arm/mm/fault-common.c
View file @
2fbc109c
...
...
@@ -35,7 +35,7 @@
#else
/*
* "code" is actually the FSR register. Bit 11 set means the
* i
sn
truction was performing a write.
* i
ns
truction was performing a write.
*/
#define DO_COW(code) ((code) & (1 << 11))
#define READ_FAULT(code) (!DO_COW(code))
...
...
@@ -54,7 +54,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
printk
(
KERN_ALERT
"pgd = %p
\n
"
,
mm
->
pgd
);
pgd
=
pgd_offset
(
mm
,
addr
);
printk
(
KERN_ALERT
"
*pgd=%08lx"
,
pgd_val
(
*
pgd
));
printk
(
KERN_ALERT
"
[%08lx] *pgd=%08lx"
,
addr
,
pgd_val
(
*
pgd
));
do
{
pmd_t
*
pmd
;
...
...
arch/arm/tools/mach-types
View file @
2fbc109c
...
...
@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk
#
# Last update: Sat
Jul 27 09:56:5
3 2002
# Last update: Sat
Sep 21 13:39:1
3 2002
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
...
...
@@ -214,3 +214,31 @@ emailphone SA1100_EMAILPHONE EMAILPHONE 202
h3900 ARCH_H3900 H3900 203
pxa1 ARCH_PXA1 PXA1 204
koan369 SA1100_KOAN369 KOAN369 205
cogent ARCH_COGENT COGENT 206
esl_simputer ARCH_ESL_SIMPUTER ESL_SIMPUTER 207
esl_simputer_clr ARCH_ESL_SIMPUTER_CLR ESL_SIMPUTER_CLR 208
esl_simputer_bw ARCH_ESL_SIMPUTER_BW ESL_SIMPUTER_BW 209
hhp_cradle ARCH_HHP_CRADLE HHP_CRADLE 210
he500 ARCH_HE500 HE500 211
inhandelf2 SA1100_INHANDELF2 INHANDELF2 212
inhandftip SA1100_INHANDFTIP INHANDFTIP 213
dnp1110 SA1100_DNP1110 DNP1110 214
pnp1110 SA1100_PNP1110 PNP1110 215
csb226 ARCH_CSB226 CSB226 216
arnold SA1100_ARNOLD ARNOLD 217
psiboard SA1100_PSIBOARD PSIBOARD 218
jz8028 ARCH_JZ8028 JZ8028 219
ipaq3 ARCH_IPAQ3 IPAQ3 220
forte SA1100_FORTE FORTE 221
acam SA1100_ACAM ACAM 222
abox SA1100_ABOX ABOX 223
atmel ARCH_ATMEL ATMEL 224
sitsang ARCH_SITSANG SITSANG 225
cpu1110lcdnet SA1100_CPU1110LCDNET CPU1110LCDNET 226
mpl_vcma9 ARCH_MPL_VCMA9 MPL_VCMA9 227
opus_a1 ARCH_OPUS_A1 OPUS_A1 228
daytona ARCH_DAYTONA DAYTONA 229
killbear SA1100_KILLBEAR KILLBEAR 230
yoho ARCH_YOHO YOHO 231
jasper ARCH_JASPER JASPER 232
dsc25 ARCH_DSC25 DSC25 233
drivers/input/serio/sa1111ps2.c
View file @
2fbc109c
...
...
@@ -15,20 +15,26 @@
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/hardware/sa1111.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/hardware/sa1111.h>
extern
struct
pt_regs
*
kbd_pt_regs
;
struct
ps2if
{
struct
serio
io
;
struct
resource
*
res
;
unsigned
long
base
;
unsigned
int
irq
;
unsigned
int
skpcr_mask
;
struct
serio
io
;
struct
sa1111_dev
*
dev
;
unsigned
long
base
;
unsigned
int
open
;
spinlock_t
lock
;
unsigned
int
head
;
unsigned
int
tail
;
unsigned
char
buf
[
4
];
};
/*
...
...
@@ -36,104 +42,150 @@ struct ps2if {
* at the most one, but we loop for safety. If there was a
* framing error, we have to manually clear the status.
*/
static
void
ps2_int
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
void
ps2_
rx
int
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
ps2if
*
sa
=
dev_id
;
struct
ps2if
*
ps2if
=
dev_id
;
unsigned
int
scancode
,
flag
,
status
;
kbd_pt_regs
=
regs
;
status
=
sa1111_readl
(
sa
->
base
+
SA1111_PS2STAT
);
status
=
sa1111_readl
(
ps2if
->
base
+
SA1111_PS2STAT
);
while
(
status
&
PS2STAT_RXF
)
{
if
(
status
&
PS2STAT_STP
)
sa1111_writel
(
PS2STAT_STP
,
sa
->
base
+
SA1111_PS2STAT
);
sa1111_writel
(
PS2STAT_STP
,
ps2if
->
base
+
SA1111_PS2STAT
);
flag
=
(
status
&
PS2STAT_STP
?
SERIO_FRAME
:
0
)
|
(
status
&
PS2STAT_RXP
?
0
:
SERIO_PARITY
);
scancode
=
sa1111_readl
(
sa
->
base
+
SA1111_PS2DATA
)
&
0xff
;
scancode
=
sa1111_readl
(
ps2if
->
base
+
SA1111_PS2DATA
)
&
0xff
;
if
(
hweight8
(
scancode
)
&
1
)
flag
^=
SERIO_PARITY
;
serio_interrupt
(
&
sa
->
io
,
scancode
,
flag
);
serio_interrupt
(
&
ps2if
->
io
,
scancode
,
flag
);
status
=
sa1111_readl
(
sa
->
base
+
SA1111_PS2STAT
);
status
=
sa1111_readl
(
ps2if
->
base
+
SA1111_PS2STAT
);
}
}
/*
* Completion of ps2 write
*/
static
void
ps2_txint
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
ps2if
*
ps2if
=
dev_id
;
unsigned
int
status
;
spin_lock
(
&
ps2if
->
lock
);
status
=
sa1111_readl
(
ps2if
->
base
+
SA1111_PS2STAT
);
if
(
ps2if
->
head
==
ps2if
->
tail
)
{
disable_irq
(
irq
);
/* done */
}
else
if
(
status
&
PS2STAT_TXE
)
{
sa1111_writel
(
ps2if
->
buf
[
ps2if
->
tail
],
ps2if
->
base
+
SA1111_PS2DATA
);
ps2if
->
tail
=
(
ps2if
->
tail
+
1
)
&
(
sizeof
(
ps2if
->
buf
)
-
1
);
}
spin_unlock
(
&
ps2if
->
lock
);
}
/*
* Write a byte to the PS2 port. We have to wait for the
* port to indicate that the transmitter is empty.
*/
static
int
ps2_write
(
struct
serio
*
io
,
unsigned
char
val
)
{
struct
ps2if
*
sa
=
io
->
driver
;
unsigned
int
timeleft
=
10000
;
/* timeout in 100ms */
struct
ps2if
*
ps2if
=
io
->
driver
;
unsigned
long
flags
;
unsigned
int
head
;
while
((
sa1111_readl
(
sa
->
base
+
SA1111_PS2STAT
)
&
PS2STAT_TXE
)
==
0
&&
timeleft
--
)
udelay
(
10
);
spin_lock_irqsave
(
&
ps2if
->
lock
,
flags
);
if
(
timeleft
)
sa1111_writel
(
val
,
sa
->
base
+
SA1111_PS2DATA
);
/*
* If the TX register is empty, we can go straight out.
*/
if
(
sa1111_readl
(
ps2if
->
base
+
SA1111_PS2STAT
)
&
PS2STAT_TXE
)
{
sa1111_writel
(
val
,
ps2if
->
base
+
SA1111_PS2DATA
);
}
else
{
if
(
ps2if
->
head
==
ps2if
->
tail
)
enable_irq
(
ps2if
->
dev
->
irq
[
1
]);
head
=
(
ps2if
->
head
+
1
)
&
(
sizeof
(
ps2if
->
buf
)
-
1
);
if
(
head
!=
ps2if
->
tail
)
{
ps2if
->
buf
[
ps2if
->
head
]
=
val
;
ps2if
->
head
=
head
;
}
}
return
timeleft
?
0
:
SERIO_TIMEOUT
;
spin_unlock_irqrestore
(
&
ps2if
->
lock
,
flags
);
return
0
;
}
static
int
ps2_open
(
struct
serio
*
io
)
{
struct
ps2if
*
sa
=
io
->
driver
;
struct
ps2if
*
ps2if
=
io
->
driver
;
int
ret
;
sa1111_enable_device
(
sa
->
skpcr_mask
);
sa1111_enable_device
(
ps2if
->
dev
);
ret
=
request_irq
(
sa
->
irq
,
ps2_int
,
0
,
"ps2"
,
sa
);
ret
=
request_irq
(
ps2if
->
dev
->
irq
[
0
],
ps2_rxint
,
0
,
SA1111_DRIVER_NAME
(
ps2if
->
dev
),
ps2if
);
if
(
ret
)
{
printk
(
KERN_ERR
"sa1111ps2: could not allocate IRQ%d: %d
\n
"
,
sa
->
irq
,
ret
);
ps2if
->
dev
->
irq
[
0
]
,
ret
);
return
ret
;
}
sa1111_writel
(
PS2CR_ENA
,
sa
->
base
+
SA1111_PS2CR
);
ret
=
request_irq
(
ps2if
->
dev
->
irq
[
1
],
ps2_txint
,
0
,
SA1111_DRIVER_NAME
(
ps2if
->
dev
),
ps2if
);
if
(
ret
)
{
printk
(
KERN_ERR
"sa1111ps2: could not allocate IRQ%d: %d
\n
"
,
ps2if
->
dev
->
irq
[
1
],
ret
);
free_irq
(
ps2if
->
dev
->
irq
[
0
],
ps2if
);
return
ret
;
}
ps2if
->
open
=
1
;
sa1111_writel
(
PS2CR_ENA
,
ps2if
->
base
+
SA1111_PS2CR
);
return
0
;
}
static
void
ps2_close
(
struct
serio
*
io
)
{
struct
ps2if
*
sa
=
io
->
driver
;
struct
ps2if
*
ps2if
=
io
->
driver
;
sa1111_writel
(
0
,
ps2if
->
base
+
SA1111_PS2CR
);
sa1111_writel
(
0
,
sa
->
base
+
SA1111_PS2CR
)
;
ps2if
->
open
=
0
;
free_irq
(
sa
->
irq
,
sa
);
free_irq
(
ps2if
->
dev
->
irq
[
1
],
ps2if
);
free_irq
(
ps2if
->
dev
->
irq
[
0
],
ps2if
);
sa1111_disable_device
(
sa
->
skpcr_mask
);
sa1111_disable_device
(
ps2if
->
dev
);
}
/*
* Clear the input buffer.
*/
static
void
__init
ps2_clear_input
(
struct
ps2if
*
sa
)
static
void
__init
ps2_clear_input
(
struct
ps2if
*
ps2if
)
{
int
maxread
=
100
;
while
(
maxread
--
)
{
if
((
sa1111_readl
(
sa
->
base
+
SA1111_PS2DATA
)
&
0xff
)
==
0xff
)
if
((
sa1111_readl
(
ps2if
->
base
+
SA1111_PS2DATA
)
&
0xff
)
==
0xff
)
break
;
}
}
static
inline
unsigned
int
ps2_test_one
(
struct
ps2if
*
sa
,
unsigned
int
mask
)
ps2_test_one
(
struct
ps2if
*
ps2if
,
unsigned
int
mask
)
{
unsigned
int
val
;
sa1111_writel
(
PS2CR_ENA
|
mask
,
sa
->
base
+
SA1111_PS2CR
);
sa1111_writel
(
PS2CR_ENA
|
mask
,
ps2if
->
base
+
SA1111_PS2CR
);
udelay
(
2
);
val
=
sa1111_readl
(
sa
->
base
+
SA1111_PS2STAT
);
val
=
sa1111_readl
(
ps2if
->
base
+
SA1111_PS2STAT
);
return
val
&
(
PS2STAT_KBC
|
PS2STAT_KBD
);
}
...
...
@@ -141,141 +193,168 @@ ps2_test_one(struct ps2if *sa, unsigned int mask)
* Test the keyboard interface. We basically check to make sure that
* we can drive each line to the keyboard independently of each other.
*/
static
int
__init
ps2_test
(
struct
ps2if
*
sa
)
static
int
__init
ps2_test
(
struct
ps2if
*
ps2if
)
{
unsigned
int
stat
;
int
ret
=
0
;
stat
=
ps2_test_one
(
sa
,
PS2CR_FKC
);
stat
=
ps2_test_one
(
ps2if
,
PS2CR_FKC
);
if
(
stat
!=
PS2STAT_KBD
)
{
printk
(
"
Keyboard
interface test failed[1]: %02x
\n
"
,
stat
);
printk
(
"
PS/2
interface test failed[1]: %02x
\n
"
,
stat
);
ret
=
-
ENODEV
;
}
stat
=
ps2_test_one
(
sa
,
0
);
stat
=
ps2_test_one
(
ps2if
,
0
);
if
(
stat
!=
(
PS2STAT_KBC
|
PS2STAT_KBD
))
{
printk
(
"
Keyboard
interface test failed[2]: %02x
\n
"
,
stat
);
printk
(
"
PS/2
interface test failed[2]: %02x
\n
"
,
stat
);
ret
=
-
ENODEV
;
}
stat
=
ps2_test_one
(
sa
,
PS2CR_FKD
);
stat
=
ps2_test_one
(
ps2if
,
PS2CR_FKD
);
if
(
stat
!=
PS2STAT_KBC
)
{
printk
(
"
Keyboard
interface test failed[3]: %02x
\n
"
,
stat
);
printk
(
"
PS/2
interface test failed[3]: %02x
\n
"
,
stat
);
ret
=
-
ENODEV
;
}
sa1111_writel
(
0
,
sa
->
base
+
SA1111_PS2CR
);
sa1111_writel
(
0
,
ps2if
->
base
+
SA1111_PS2CR
);
return
ret
;
}
/*
*
Initialise one PS/2 port
.
*
Add one device to this driver
.
*/
static
int
__init
ps2_init_one
(
struct
sa1111_device
*
dev
,
struct
ps2if
*
sa
)
static
int
ps2_probe
(
struct
device
*
dev
)
{
struct
sa1111_dev
*
sadev
=
SA1111_DEV
(
dev
);
struct
ps2if
*
ps2if
;
int
ret
;
ps2if
=
kmalloc
(
sizeof
(
struct
ps2if
),
GFP_KERNEL
);
if
(
!
ps2if
)
{
return
-
ENOMEM
;
}
memset
(
ps2if
,
0
,
sizeof
(
struct
ps2if
));
ps2if
->
io
.
type
=
SERIO_8042
;
ps2if
->
io
.
write
=
ps2_write
;
ps2if
->
io
.
open
=
ps2_open
;
ps2if
->
io
.
close
=
ps2_close
;
ps2if
->
io
.
name
=
dev
->
name
;
ps2if
->
io
.
phys
=
dev
->
bus_id
;
ps2if
->
io
.
driver
=
ps2if
;
ps2if
->
dev
=
sadev
;
dev
->
driver_data
=
ps2if
;
spin_lock_init
(
&
ps2if
->
lock
);
/*
* Request the physical region for this PS2 port.
*/
sa
->
res
=
request_mem_region
(
_SA1111
(
sa
->
base
),
512
,
"ps2"
);
if
(
!
sa
->
res
)
return
-
EBUSY
;
if
(
!
request_mem_region
(
sadev
->
res
.
start
,
sadev
->
res
.
end
-
sadev
->
res
.
start
+
1
,
SA1111_DRIVER_NAME
(
sadev
)))
{
ret
=
-
EBUSY
;
goto
free
;
}
/*
*
Convert the chip offset to virtual address
.
*
Our parent device has already mapped the region
.
*/
sa
->
base
+=
(
unsigned
long
)
dev
->
base
;
ps2if
->
base
=
(
unsigned
long
)
sadev
->
map
base
;
sa1111_enable_device
(
sa
->
skpcr_mask
);
sa1111_enable_device
(
ps2if
->
dev
);
/* Incoming clock is 8MHz */
sa1111_writel
(
0
,
sa
->
base
+
SA1111_PS2CLKDIV
);
sa1111_writel
(
127
,
sa
->
base
+
SA1111_PS2PRECNT
);
sa1111_writel
(
0
,
ps2if
->
base
+
SA1111_PS2CLKDIV
);
sa1111_writel
(
127
,
ps2if
->
base
+
SA1111_PS2PRECNT
);
/*
* Flush any pending input.
*/
ps2_clear_input
(
sa
);
ps2_clear_input
(
ps2if
);
/*
* Test the keyboard interface.
*/
ret
=
ps2_test
(
sa
);
ret
=
ps2_test
(
ps2if
);
if
(
ret
)
goto
out
;
/*
* Flush any pending input.
*/
ps2_clear_input
(
sa
);
sa1111_disable_device
(
sa
->
skpcr_mask
);
ps2_clear_input
(
ps2if
);
serio_register_port
(
&
sa
->
io
);
sa1111_disable_device
(
ps2if
->
dev
);
serio_register_port
(
&
ps2if
->
io
);
return
0
;
out:
sa1111_disable_device
(
sa
->
skpcr_mask
);
release_resource
(
sa
->
res
);
sa1111_disable_device
(
ps2if
->
dev
);
release_mem_region
(
sadev
->
res
.
start
,
sadev
->
res
.
end
-
sadev
->
res
.
start
+
1
);
free:
dev
->
driver_data
=
NULL
;
kfree
(
ps2if
);
return
ret
;
}
/*
* Remove one
PS/2 port
.
* Remove one
device from this driver
.
*/
static
void
__exit
ps2_remove_one
(
struct
ps2if
*
sa
)
static
int
ps2_remove
(
struct
device
*
dev
)
{
serio_unregister_port
(
&
sa
->
io
);
release_resource
(
sa
->
res
);
struct
ps2if
*
ps2if
=
dev
->
driver_data
;
struct
sa1111_dev
*
sadev
=
SA1111_DEV
(
dev
);
serio_unregister_port
(
&
ps2if
->
io
);
release_mem_region
(
sadev
->
res
.
start
,
sadev
->
res
.
end
-
sadev
->
res
.
start
+
1
);
kfree
(
ps2if
);
dev
->
driver_data
=
NULL
;
return
0
;
}
static
struct
ps2if
ps2_kbd_port
=
/*
* We should probably do something here, but what?
*/
static
int
ps2_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
io:
{
type:
SERIO_8042
,
write:
ps2_write
,
open:
ps2_open
,
close:
ps2_close
,
name:
"SA1111 PS/2 kbd port"
,
phys:
"sa1111/serio0"
,
driver:
&
ps2_kbd_port
,
},
base:
SA1111_KBD
,
irq:
IRQ_TPRXINT
,
skpcr_mask:
SKPCR_PTCLKEN
,
};
return
0
;
}
static
struct
ps2if
ps2_mse_port
=
static
int
ps2_resume
(
struct
device
*
dev
,
u32
level
)
{
io:
{
type:
SERIO_8042
,
write:
ps2_write
,
open:
ps2_open
,
close:
ps2_close
,
name:
"SA1111 PS/2 mouse port"
,
phys:
"sa1111/serio1"
,
driver:
&
ps2_mse_port
,
return
0
;
}
/*
* Our device driver structure
*/
static
struct
sa1111_driver
ps2_driver
=
{
.
drv
=
{
.
name
=
"SA1111 PS2"
,
.
bus
=
&
sa1111_bus_type
,
.
probe
=
ps2_probe
,
.
remove
=
ps2_remove
,
.
suspend
=
ps2_suspend
,
.
resume
=
ps2_resume
,
},
base:
SA1111_MSE
,
irq:
IRQ_MSRXINT
,
skpcr_mask:
SKPCR_PMCLKEN
,
.
devid
=
SA1111_DEVID_PS2
,
};
static
int
__init
ps2_init
(
void
)
{
int
ret
=
-
ENODEV
;
if
(
sa1111
)
{
ret
=
ps2_init_one
(
sa1111
,
&
ps2_kbd_port
);
}
return
ret
;
return
driver_register
(
&
ps2_driver
.
drv
);
}
static
void
__exit
ps2_exit
(
void
)
{
ps2_remove_one
(
&
ps2_kbd_port
);
remove_driver
(
&
ps2_driver
.
drv
);
}
module_init
(
ps2_init
);
...
...
drivers/pcmcia/Config.in
View file @
2fbc109c
...
...
@@ -20,6 +20,7 @@ if [ "$CONFIG_PCMCIA" != "n" ]; then
fi
if [ "$CONFIG_ARM" = "y" ]; then
dep_tristate ' SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_ARCH_SA1100 $CONFIG_PCMCIA
dep_tristate ' SA1111 support' CONFIG_PCMCIA_SA1111 $CONFIG_PCMCIA_SA1100 $CONFIG_SA1111 $CONFIG_PCMCIA
fi
fi
...
...
drivers/pcmcia/Makefile
View file @
2fbc109c
...
...
@@ -14,6 +14,7 @@ obj-$(CONFIG_I82092) += i82092.o
obj-$(CONFIG_TCIC)
+=
tcic.o
obj-$(CONFIG_HD64465_PCMCIA)
+=
hd64465_ss.o
obj-$(CONFIG_PCMCIA_SA1100)
+=
sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111)
+=
sa1111_cs.o
yenta_socket-objs
:=
pci_socket.o yenta.o
...
...
@@ -21,26 +22,29 @@ pcmcia_core-objs-y := cistpl.o rsrc_mgr.o bulkmem.o cs.o
pcmcia_core-objs-$(CONFIG_CARDBUS)
+=
cardbus.o
pcmcia_core-objs
:=
$
(
pcmcia_core-objs-y
)
sa1111_cs-objs-y
:=
sa1111_generic.o
sa1111_cs-objs-$(CONFIG_SA1100_ADSBITSY)
+=
sa1100_adsbitsy.o
sa1111_cs-objs-$(CONFIG_ASSABET_NEPONSET)
+=
sa1100_neponset.o
sa1111_cs-objs-$(CONFIG_SA1100_BADGE4)
+=
sa1100_badge4.o
sa1111_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER)
+=
sa1100_graphicsmaster.o
sa1111_cs-objs-$(CONFIG_SA1100_JORNADA720)
+=
sa1100_jornada720.o
sa1111_cs-objs-$(CONFIG_SA1100_PFS168)
+=
sa1100_pfs168.o
sa1111_cs-objs-$(CONFIG_SA1100_PT_SYSTEM3)
+=
sa1100_system3.o
sa1111_cs-objs-$(CONFIG_SA1100_XP860)
+=
sa1100_xp860.o
sa1111_cs-objs
:=
$
(
sa1111_cs-objs-y
)
sa1100_cs-objs-y
:=
sa1100_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY)
+=
sa1100_adsbitsy.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_ASSABET)
+=
sa1100_assabet.o
sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET)
+=
sa1100_neponset.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_BADGE4)
+=
sa1100_badge4.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_CERF)
+=
sa1100_cerf.o
sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET)
+=
sa1100_flexanet.o
sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD)
+=
sa1100_freebird.o
sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSMASTER)
+=
sa1100_graphicsmaster.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_GRAPHICSCLIENT)
+=
sa1100_graphicsclient.o
sa1100_cs-objs-$(CONFIG_SA1100_H3600)
+=
sa1100_h3600.o
sa1100_cs-objs-$(CONFIG_SA1100_JORNADA720)
+=
sa1100_jornada720.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_PANGOLIN)
+=
sa1100_pangolin.o
sa1100_cs-objs-$(CONFIG_SA1100_PFS168)
+=
sa1100_pfs168.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_PT_SYSTEM3)
+=
sa1100_system3.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_SHANNON)
+=
sa1100_shannon.o
sa1100_cs-objs-$(CONFIG_SA1100_SIMPAD)
+=
sa1100_simpad.o
sa1100_cs-objs-$(CONFIG_SA1100_STORK)
+=
sa1100_stork.o
sa1100_cs-objs-$(CONFIG_SA1100_TRIZEPS)
+=
sa1100_trizeps.o
sa1100_cs-objs-$(CONFIG_SA1100_XP860)
+=
sa1100_xp860.o sa1111_generic.o
sa1100_cs-objs-$(CONFIG_SA1100_YOPY)
+=
sa1100_yopy.o
sa1100_cs-objs
:=
$
(
sa1100_cs-objs-y
)
...
...
drivers/pcmcia/sa1100_adsbitsy.c
View file @
2fbc109c
...
...
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
...
...
drivers/pcmcia/sa1100_badge4.c
View file @
2fbc109c
...
...
@@ -19,6 +19,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/arch/badge4.h>
#include <asm/hardware/sa1111.h>
...
...
drivers/pcmcia/sa1100_generic.c
View file @
2fbc109c
...
...
@@ -110,12 +110,11 @@ sa1100_pcmcia_default_mecr_timing(unsigned int sock, unsigned int cpu_speed,
* Call board specific BS value calculation to allow boards
* to tweak the BS values.
*/
static
int
sa1100_pcmcia_set_mecr
(
int
sock
)
static
int
sa1100_pcmcia_set_mecr
(
int
sock
,
unsigned
int
cpu_clock
)
{
struct
sa1100_pcmcia_socket
*
skt
;
u32
mecr
;
int
clock
;
long
flags
;
unsigned
long
flags
;
unsigned
int
bs
;
if
(
sock
<
0
||
sock
>
SA1100_PCMCIA_MAX_SOCK
)
...
...
@@ -125,8 +124,7 @@ static int sa1100_pcmcia_set_mecr(int sock)
local_irq_save
(
flags
);
clock
=
cpufreq_get
(
0
);
bs
=
pcmcia_low_level
->
socket_get_timing
(
sock
,
clock
,
skt
->
speed_io
);
bs
=
pcmcia_low_level
->
socket_get_timing
(
sock
,
cpu_clock
,
skt
->
speed_io
);
mecr
=
MECR
;
MECR_FAST_SET
(
mecr
,
sock
,
0
);
...
...
@@ -652,7 +650,7 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
if
(
map
->
speed
==
0
)
map
->
speed
=
SA1100_PCMCIA_IO_ACCESS
;
sa1100_pcmcia_set_mecr
(
sock
);
sa1100_pcmcia_set_mecr
(
sock
,
cpufreq_get
(
0
)
);
}
if
(
map
->
stop
==
1
)
...
...
@@ -741,7 +739,7 @@ sa1100_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
map
->
speed
=
SA1100_PCMCIA_5V_MEM_ACCESS
;
}
sa1100_pcmcia_set_mecr
(
sock
);
sa1100_pcmcia_set_mecr
(
sock
,
cpufreq_get
(
0
)
);
}
...
...
@@ -885,9 +883,8 @@ static void sa1100_pcmcia_update_mecr(unsigned int clock)
{
unsigned
int
sock
;
for
(
sock
=
0
;
sock
<
SA1100_PCMCIA_MAX_SOCK
;
++
sock
)
{
sa1100_pcmcia_set_mecr
(
sock
);
}
for
(
sock
=
0
;
sock
<
SA1100_PCMCIA_MAX_SOCK
;
++
sock
)
sa1100_pcmcia_set_mecr
(
sock
,
clock
);
}
/* sa1100_pcmcia_notifier()
...
...
@@ -904,31 +901,31 @@ static int
sa1100_pcmcia_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
void
*
data
)
{
struct
cpufreq_info
*
ci
=
data
;
switch
(
val
)
{
case
CPUFREQ_PRECHANGE
:
if
(
ci
->
new_freq
>
ci
->
old_freq
)
{
DEBUG
(
2
,
"%s(): new frequency %u.%uMHz > %u.%uMHz, pre-updating
\n
"
,
__FUNCTION__
,
ci
->
new_freq
/
1000
,
(
ci
->
new_freq
/
100
)
%
10
,
ci
->
old_freq
/
1000
,
(
ci
->
old_freq
/
100
)
%
10
);
sa1100_pcmcia_update_mecr
(
ci
->
new_freq
);
}
break
;
case
CPUFREQ_POSTCHANGE
:
if
(
ci
->
new_freq
<
ci
->
old_freq
)
{
DEBUG
(
2
,
"%s(): new frequency %u.%uMHz < %u.%uMHz, post-updating
\n
"
,
__FUNCTION__
,
ci
->
new_freq
/
1000
,
(
ci
->
new_freq
/
100
)
%
10
,
ci
->
old_freq
/
1000
,
(
ci
->
old_freq
/
100
)
%
10
);
sa1100_pcmcia_update_mecr
(
ci
->
new_freq
);
}
break
;
}
struct
cpufreq_freqs
*
freqs
=
data
;
switch
(
val
)
{
case
CPUFREQ_PRECHANGE
:
if
(
freqs
->
new
>
freqs
->
old
)
{
DEBUG
(
2
,
"%s(): new frequency %u.%uMHz > %u.%uMHz, "
"pre-updating
\n
"
,
__FUNCTION__
,
freqs
->
new
/
1000
,
(
freqs
->
new
/
100
)
%
10
,
freqs
->
old
/
1000
,
(
freqs
->
old
/
100
)
%
10
);
sa1100_pcmcia_update_mecr
(
freqs
->
new
);
}
break
;
case
CPUFREQ_POSTCHANGE
:
if
(
freqs
->
new
<
freqs
->
old
)
{
DEBUG
(
2
,
"%s(): new frequency %u.%uMHz < %u.%uMHz, "
"post-updating
\n
"
,
__FUNCTION__
,
freqs
->
new
/
1000
,
(
freqs
->
new
/
100
)
%
10
,
freqs
->
old
/
1000
,
(
freqs
->
old
/
100
)
%
10
);
sa1100_pcmcia_update_mecr
(
freqs
->
new
);
}
break
;
}
return
0
;
return
0
;
}
static
struct
notifier_block
sa1100_pcmcia_notifier_block
=
{
...
...
@@ -946,7 +943,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
struct
pcmcia_init
pcmcia_init
;
struct
pcmcia_state
state
[
SA1100_PCMCIA_MAX_SOCK
];
struct
pcmcia_state_array
state_array
;
unsigned
int
i
;
unsigned
int
i
,
cpu_clock
;
int
ret
;
/*
...
...
@@ -986,6 +983,8 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
goto
shutdown
;
}
cpu_clock
=
cpufreq_get
(
0
);
/*
* We initialize the MECR to default values here, because we are
* not guaranteed to see a SetIOMap operation at runtime.
...
...
@@ -1019,7 +1018,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
goto
out_err
;
}
sa1100_pcmcia_set_mecr
(
i
);
sa1100_pcmcia_set_mecr
(
i
,
cpu_clock
);
}
...
...
@@ -1110,7 +1109,7 @@ static int __init sa1100_pcmcia_init(void)
servinfo_t
info
;
int
ret
,
i
;
printk
(
KERN_INFO
"SA
-110
0 PCMCIA (CS release %s)
\n
"
,
CS_RELEASE
);
printk
(
KERN_INFO
"SA
11x
0 PCMCIA (CS release %s)
\n
"
,
CS_RELEASE
);
CardServices
(
GetCardServicesInfo
,
&
info
);
if
(
info
.
Revision
!=
CS_RELEASE_CODE
)
{
...
...
@@ -1127,7 +1126,8 @@ static int __init sa1100_pcmcia_init(void)
}
#ifdef CONFIG_CPU_FREQ
ret
=
cpufreq_register_notifier
(
&
sa1100_pcmcia_notifier_block
);
ret
=
cpufreq_register_notifier
(
&
sa1100_pcmcia_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Unable to register CPU frequency change "
"notifier (%d)
\n
"
,
ret
);
...
...
@@ -1135,15 +1135,9 @@ static int __init sa1100_pcmcia_init(void)
}
#endif
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_init
();
#endif
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_init
();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_init
();
#endif
#ifdef CONFIG_SA1100_CERF
pcmcia_cerf_init
();
#endif
...
...
@@ -1156,24 +1150,9 @@ static int __init sa1100_pcmcia_init(void)
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
pcmcia_gcplus_init
();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_init
();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_init
();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_init
();
#endif
#ifdef CONFIG_SA1100_PANGOLIN
pcmcia_pangolin_init
();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_init
();
#endif
#ifdef CONFIG_SA1100_PT_SYSTEM3
pcmcia_system3_init
();
#endif
#ifdef CONFIG_SA1100_SHANNON
pcmcia_shannon_init
();
#endif
...
...
@@ -1186,9 +1165,6 @@ static int __init sa1100_pcmcia_init(void)
#ifdef CONFIG_SA1100_TRIZEPS
pcmcia_trizeps_init
();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_init
();
#endif
#ifdef CONFIG_SA1100_YOPY
pcmcia_yopy_init
();
#endif
...
...
@@ -1203,15 +1179,9 @@ static int __init sa1100_pcmcia_init(void)
*/
static
void
__exit
sa1100_pcmcia_exit
(
void
)
{
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_exit
();
#endif
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_exit
();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_exit
();
#endif
#ifdef CONFIG_SA1100_CERF
pcmcia_cerf_exit
();
#endif
...
...
@@ -1224,21 +1194,9 @@ static void __exit sa1100_pcmcia_exit(void)
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
pcmcia_gcplus_exit
();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_exit
();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_exit
();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_exit
();
#endif
#ifdef CONFIG_SA1100_PANGOLIN
pcmcia_pangolin_exit
();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_exit
();
#endif
#ifdef CONFIG_SA1100_SHANNON
pcmcia_shannon_exit
();
#endif
...
...
@@ -1248,9 +1206,6 @@ static void __exit sa1100_pcmcia_exit(void)
#ifdef CONFIG_SA1100_STORK
pcmcia_stork_exit
();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_exit
();
#endif
#ifdef CONFIG_SA1100_YOPY
pcmcia_yopy_exit
();
#endif
...
...
@@ -1261,7 +1216,7 @@ static void __exit sa1100_pcmcia_exit(void)
}
#ifdef CONFIG_CPU_FREQ
cpufreq_unregister_notifier
(
&
sa1100_pcmcia_notifier_block
);
cpufreq_unregister_notifier
(
&
sa1100_pcmcia_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
#endif
}
...
...
drivers/pcmcia/sa1100_graphicsmaster.c
View file @
2fbc109c
...
...
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
...
...
drivers/pcmcia/sa1100_jornada720.c
View file @
2fbc109c
...
...
@@ -9,6 +9,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
...
...
drivers/pcmcia/sa1100_neponset.c
View file @
2fbc109c
...
...
@@ -10,21 +10,50 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/arch/assabet.h>
#include <asm/mach-types.h>
#include <asm/arch/neponset.h>
#include <asm/hardware/sa1111.h>
#include "sa1100_generic.h"
#include "sa1111_generic.h"
/*
* Neponset uses the Maxim MAX1600, with the following connections:
*
* MAX1600 Neponset
*
* A0VCC SA-1111 GPIO A<1>
* A1VCC SA-1111 GPIO A<0>
* A0VPP CPLD NCR A0VPP
* A1VPP CPLD NCR A1VPP
* B0VCC SA-1111 GPIO A<2>
* B1VCC SA-1111 GPIO A<3>
* B0VPP ground (slot B is CF)
* B1VPP ground (slot B is CF)
*
* VX VCC (5V)
* VY VCC3_3 (3.3V)
* 12INA 12V
* 12INB ground (slot B is CF)
*
* The MAX1600 CODE pin is tied to ground, placing the device in
* "Standard Intel code" mode. Refer to the Maxim data sheet for
* the corresponding truth table.
*/
static
int
neponset_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
/* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
PA_DDR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
/* MAX1600 to standby mode: */
PA_DWR
&=
~
(
GPIO_GPIO0
|
GPIO_GPIO1
|
GPIO_GPIO2
|
GPIO_GPIO3
);
NCR_0
&=
~
(
NCR_A0VPP
|
NCR_A1VPP
);
/*
* Set GPIO_A<3:0> to be outputs for the MAX1600,
* and switch to standby mode.
*/
PA_DDR
=
0
;
PA_SDR
=
0
;
PA_DWR
=
0
;
PA_SSR
=
0
;
return
sa1111_pcmcia_init
(
init
);
}
...
...
@@ -35,29 +64,6 @@ neponset_pcmcia_configure_socket(const struct pcmcia_configure *conf)
unsigned
int
ncr_set
,
pa_dwr_set
;
int
ret
;
/* Neponset uses the Maxim MAX1600, with the following connections:
* MAX1600 Neponset
*
* A0VCC SA-1111 GPIO A<1>
* A1VCC SA-1111 GPIO A<0>
* A0VPP CPLD NCR A0VPP
* A1VPP CPLD NCR A1VPP
* B0VCC SA-1111 GPIO A<2>
* B1VCC SA-1111 GPIO A<3>
* B0VPP ground (slot B is CF)
* B1VPP ground (slot B is CF)
*
* VX VCC (5V)
* VY VCC3_3 (3.3V)
* 12INA 12V
* 12INB ground (slot B is CF)
*
* The MAX1600 CODE pin is tied to ground, placing the device in
* "Standard Intel code" mode. Refer to the Maxim data sheet for
* the corresponding truth table.
*/
switch
(
conf
->
sock
)
{
case
0
:
pa_dwr_mask
=
GPIO_GPIO0
|
GPIO_GPIO1
;
...
...
@@ -135,13 +141,13 @@ int __init pcmcia_neponset_init(void)
{
int
ret
=
-
ENODEV
;
if
(
machine_is_assabet
()
&&
sa1111
)
if
(
machine_is_assabet
())
ret
=
sa1100_register_pcmcia
(
&
neponset_pcmcia_ops
);
return
ret
;
}
void
__exit
pcmcia_neponset_exit
(
void
)
void
__
dev
exit
pcmcia_neponset_exit
(
void
)
{
sa1100_unregister_pcmcia
(
&
neponset_pcmcia_ops
);
}
drivers/pcmcia/sa1100_pfs168.c
View file @
2fbc109c
...
...
@@ -7,10 +7,11 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <asm/delay.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include "sa1100_generic.h"
...
...
drivers/pcmcia/sa1100_system3.c
View file @
2fbc109c
...
...
@@ -31,6 +31,7 @@
#include <linux/ioport.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/hardware/sa1111.h>
...
...
drivers/pcmcia/sa1100_xp860.c
View file @
2fbc109c
...
...
@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include "sa1100_generic.h"
...
...
drivers/pcmcia/sa1111_generic.c
View file @
2fbc109c
...
...
@@ -5,10 +5,12 @@
* basically means we handle everything except controlling the
* power. Power is machine specific...
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
...
...
@@ -21,19 +23,18 @@ static struct irqs {
int
irq
;
const
char
*
str
;
}
irqs
[]
=
{
{
S0_CD_VALID
,
"SA1111 PCMCIA card detect"
},
{
S0_BVD1_STSCHG
,
"SA1111 PCMCIA BVD1"
},
{
S1_CD_VALID
,
"SA1111 CF card detect"
},
{
S1_BVD1_STSCHG
,
"SA1111 CF BVD1"
},
{
IRQ_
S0_CD_VALID
,
"SA1111 PCMCIA card detect"
},
{
IRQ_
S0_BVD1_STSCHG
,
"SA1111 PCMCIA BVD1"
},
{
IRQ_
S1_CD_VALID
,
"SA1111 CF card detect"
},
{
IRQ_
S1_BVD1_STSCHG
,
"SA1111 CF BVD1"
},
};
static
struct
sa1111_dev
*
pcmcia
;
int
sa1111_pcmcia_init
(
struct
pcmcia_init
*
init
)
{
int
i
,
ret
;
if
(
!
request_mem_region
(
_PCCR
,
512
,
"PCMCIA"
))
return
-
1
;
for
(
i
=
ret
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
{
set_irq_type
(
irqs
[
i
].
irq
,
IRQT_FALLING
);
ret
=
request_irq
(
irqs
[
i
].
irq
,
init
->
handler
,
SA_INTERRUPT
,
...
...
@@ -47,8 +48,6 @@ int sa1111_pcmcia_init(struct pcmcia_init *init)
irqs
[
i
].
irq
,
ret
);
while
(
i
--
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
release_mem_region
(
_PCCR
,
16
);
}
return
ret
?
-
1
:
2
;
...
...
@@ -61,8 +60,6 @@ int sa1111_pcmcia_shutdown(void)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
irqs
);
i
++
)
free_irq
(
irqs
[
i
].
irq
,
NULL
);
release_mem_region
(
_PCCR
,
512
);
return
0
;
}
...
...
@@ -73,7 +70,7 @@ int sa1111_pcmcia_socket_state(struct pcmcia_state_array *state)
if
(
state
->
size
<
2
)
return
-
1
;
status
=
PCSR
;
status
=
sa1111_readl
(
pcmcia
->
mapbase
+
SA1111_PCSR
)
;
state
->
state
[
0
].
detect
=
status
&
PCSR_S0_DETECT
?
0
:
1
;
state
->
state
[
0
].
ready
=
status
&
PCSR_S0_READY
?
1
:
0
;
...
...
@@ -99,8 +96,8 @@ int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
int
ret
=
0
;
switch
(
info
->
sock
)
{
case
0
:
info
->
irq
=
S0_READY_NINT
;
break
;
case
1
:
info
->
irq
=
S1_READY_NINT
;
break
;
case
0
:
info
->
irq
=
IRQ_
S0_READY_NINT
;
break
;
case
1
:
info
->
irq
=
IRQ_
S1_READY_NINT
;
break
;
default:
ret
=
1
;
}
...
...
@@ -109,7 +106,7 @@ int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
int
sa1111_pcmcia_configure_socket
(
const
struct
pcmcia_configure
*
conf
)
{
unsigned
int
rst
,
flt
,
wait
,
pse
,
irq
,
pccr_mask
;
unsigned
int
rst
,
flt
,
wait
,
pse
,
irq
,
pccr_mask
,
val
;
unsigned
long
flags
;
switch
(
conf
->
sock
)
{
...
...
@@ -118,7 +115,7 @@ int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
flt
=
PCCR_S0_FLT
;
wait
=
PCCR_S0_PWAITEN
;
pse
=
PCCR_S0_PSE
;
irq
=
S0_READY_NINT
;
irq
=
IRQ_
S0_READY_NINT
;
break
;
case
1
:
...
...
@@ -126,7 +123,7 @@ int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
flt
=
PCCR_S1_FLT
;
wait
=
PCCR_S1_PWAITEN
;
pse
=
PCCR_S1_PSE
;
irq
=
S1_READY_NINT
;
irq
=
IRQ_
S1_READY_NINT
;
break
;
default:
...
...
@@ -159,7 +156,9 @@ int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
pccr_mask
|=
flt
;
local_irq_save
(
flags
);
PCCR
=
(
PCCR
&
~
(
pse
|
flt
|
wait
|
rst
))
|
pccr_mask
;
val
=
sa1111_readl
(
pcmcia
->
mapbase
+
SA1111_PCCR
);
val
=
(
val
&
~
(
pse
|
flt
|
wait
|
rst
))
|
pccr_mask
;
sa1111_writel
(
val
,
pcmcia
->
mapbase
+
SA1111_PCCR
);
local_irq_restore
(
flags
);
if
(
conf
->
irq
)
...
...
@@ -179,3 +178,130 @@ int sa1111_pcmcia_socket_suspend(int sock)
{
return
0
;
}
static
int
pcmcia_probe
(
struct
device
*
dev
)
{
struct
sa1111_dev
*
sadev
=
SA1111_DEV
(
dev
);
unsigned
long
flags
;
char
*
base
;
local_irq_save
(
flags
);
if
(
pcmcia
)
{
local_irq_restore
(
flags
);
return
-
EBUSY
;
}
pcmcia
=
sadev
;
local_irq_restore
(
flags
);
if
(
!
request_mem_region
(
sadev
->
res
.
start
,
512
,
SA1111_DRIVER_NAME
(
sadev
)))
return
-
EBUSY
;
base
=
sadev
->
mapbase
;
/*
* Initialise the suspend state.
*/
sa1111_writel
(
PCSSR_S0_SLEEP
|
PCSSR_S1_SLEEP
,
base
+
SA1111_PCSSR
);
sa1111_writel
(
PCCR_S0_FLT
|
PCCR_S1_FLT
,
base
+
SA1111_PCCR
);
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_init
();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_init
();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_init
();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_init
();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_init
();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_init
();
#endif
#ifdef CONFIG_SA1100_PT_SYSTEM3
pcmcia_system3_init
();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_init
();
#endif
return
0
;
}
static
int
__devexit
pcmcia_remove
(
struct
device
*
dev
)
{
struct
sa1111_dev
*
sadev
=
SA1111_DEV
(
dev
);
#ifdef CONFIG_SA1100_ADSBITSY
pcmcia_adsbitsy_exit
();
#endif
#ifdef CONFIG_SA1100_BADGE4
pcmcia_badge4_exit
();
#endif
#ifdef CONFIG_SA1100_GRAPHICSMASTER
pcmcia_graphicsmaster_exit
();
#endif
#ifdef CONFIG_SA1100_JORNADA720
pcmcia_jornada720_exit
();
#endif
#ifdef CONFIG_ASSABET_NEPONSET
pcmcia_neponset_exit
();
#endif
#ifdef CONFIG_SA1100_PFS168
pcmcia_pfs_exit
();
#endif
#ifdef CONFIG_SA1100_PT_SYSTEM3
pcmcia_system3_exit
();
#endif
#ifdef CONFIG_SA1100_XP860
pcmcia_xp860_exit
();
#endif
release_mem_region
(
sadev
->
res
.
start
,
512
);
pcmcia
=
NULL
;
return
0
;
}
static
int
pcmcia_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
return
0
;
}
static
int
pcmcia_resume
(
struct
device
*
dev
,
u32
level
)
{
return
0
;
}
static
struct
sa1111_driver
pcmcia_driver
=
{
.
drv
=
{
.
name
=
"SA1111 PCMCIA"
,
.
bus
=
&
sa1111_bus_type
,
.
probe
=
pcmcia_probe
,
.
remove
=
__devexit_p
(
pcmcia_remove
),
.
suspend
=
pcmcia_suspend
,
.
resume
=
pcmcia_resume
,
},
.
devid
=
SA1111_DEVID_PCMCIA
,
};
static
int
__init
sa1111_drv_pcmcia_init
(
void
)
{
return
driver_register
(
&
pcmcia_driver
.
drv
);
}
static
void
__exit
sa1111_drv_pcmcia_exit
(
void
)
{
remove_driver
(
&
pcmcia_driver
.
drv
);
}
module_init
(
sa1111_drv_pcmcia_init
);
module_exit
(
sa1111_drv_pcmcia_exit
);
MODULE_DESCRIPTION
(
"SA1111 PCMCIA card socket driver"
);
MODULE_LICENSE
(
"GPL"
);
drivers/usb/host/ohci-sa1111.c
View file @
2fbc109c
...
...
@@ -25,7 +25,7 @@
/*-------------------------------------------------------------------------*/
static
void
sa1111_start_hc
(
void
)
static
void
sa1111_start_hc
(
struct
sa1111_dev
*
dev
)
{
unsigned
int
usb_rst
=
0
;
...
...
@@ -48,31 +48,35 @@ static void sa1111_start_hc(void)
* Configure the power sense and control lines. Place the USB
* host controller in reset.
*/
USB_RESET
=
usb_rst
|
USB_RESET_FORCEIFRESET
|
USB_RESET_FORCEHCRESET
;
sa1111_writel
(
usb_rst
|
USB_RESET_FORCEIFRESET
|
USB_RESET_FORCEHCRESET
,
dev
->
mapbase
+
SA1111_USB_RESET
);
/*
* Now, carefully enable the USB clock, and take
* the USB host controller out of reset.
*/
SKPCR
|=
SKPCR_UCLKEN
;
sa1111_enable_device
(
dev
)
;
udelay
(
11
);
USB_RESET
=
usb_rst
;
sa1111_writel
(
usb_rst
,
dev
->
mapbase
+
SA1111_USB_RESET
)
;
}
static
void
sa1111_stop_hc
(
void
)
static
void
sa1111_stop_hc
(
struct
sa1111_dev
*
dev
)
{
unsigned
int
usb_rst
;
printk
(
KERN_DEBUG
__FILE__
": stopping SA-1111 OHCI USB Controller
\n
"
);
/*
* Put the USB host controller into reset.
*/
USB_RESET
|=
USB_RESET_FORCEIFRESET
|
USB_RESET_FORCEHCRESET
;
usb_rst
=
sa1111_readl
(
dev
->
mapbase
+
SA1111_USB_RESET
);
sa1111_writel
(
usb_rst
|
USB_RESET_FORCEIFRESET
|
USB_RESET_FORCEHCRESET
,
dev
->
mapbase
+
SA1111_USB_RESET
);
/*
* Stop the USB clock.
*/
SKPCR
&=
~
SKPCR_UCLKEN
;
sa1111_disable_device
(
dev
)
;
#ifdef CONFIG_SA1100_BADGE4
if
(
machine_is_badge4
())
{
...
...
@@ -86,9 +90,9 @@ static void sa1111_stop_hc(void)
/*-------------------------------------------------------------------------*/
#if 0
static void dump_hci_status(const char *label)
static void dump_hci_status(
struct usb_hcd *hcd,
const char *label)
{
unsigned long status =
USB_STATUS;
unsigned long status =
sa1111_readl(hcd->regs + SA1111_USB_STATUS);
dbg ("%s USB_STATUS = { %s%s%s%s%s}", label,
((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""),
...
...
@@ -101,11 +105,14 @@ static void dump_hci_status(const char *label)
static
void
usb_hcd_sa1111_hcim_irq
(
int
irq
,
void
*
__hcd
,
struct
pt_regs
*
r
)
{
//dump_hci_status("irq");
struct
usb_hcd
*
hcd
=
__hcd
;
// unsigned long status = sa1111_readl(hcd->regs + SA1111_USB_STATUS);
//dump_hci_status(hcd, "irq");
#if 0
/* may work better this way -- need to investigate further */
if (
USB_STATUS
& USB_STATUS_NIRQHCIM) {
if (
status
& USB_STATUS_NIRQHCIM) {
//dbg ("not normal HC interrupt; ignoring");
return;
}
...
...
@@ -116,7 +123,7 @@ static void usb_hcd_sa1111_hcim_irq (int irq, void *__hcd, struct pt_regs * r)
/*-------------------------------------------------------------------------*/
void
usb_hcd_sa1111_remove
(
struct
usb_hcd
*
);
void
usb_hcd_sa1111_remove
(
struct
usb_hcd
*
,
struct
sa1111_dev
*
);
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
...
...
@@ -132,21 +139,20 @@ void usb_hcd_sa1111_remove (struct usb_hcd *);
*
* Store this function in the HCD's struct pci_driver as probe().
*/
int
usb_hcd_sa1111_probe
(
const
struct
hc_driver
*
driver
,
struct
usb_hcd
**
hcd_out
)
int
usb_hcd_sa1111_probe
(
const
struct
hc_driver
*
driver
,
struct
usb_hcd
**
hcd_out
,
struct
sa1111_dev
*
dev
)
{
int
retval
;
struct
usb_hcd
*
hcd
=
0
;
if
(
!
sa1111
)
return
-
ENODEV
;
if
(
!
request_mem_region
(
_USB_OHCI_OP_BASE
,
_USB_EXTENT
,
hcd_name
))
{
if
(
!
request_mem_region
(
dev
->
res
.
start
,
dev
->
res
.
end
-
dev
->
res
.
start
+
1
,
hcd_name
))
{
dbg
(
"request_mem_region failed"
);
return
-
EBUSY
;
}
sa1111_start_hc
();
sa1111_start_hc
(
dev
);
hcd
=
driver
->
hcd_alloc
();
if
(
hcd
==
NULL
){
...
...
@@ -157,9 +163,10 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, struct usb_hcd **hcd_o
hcd
->
driver
=
(
struct
hc_driver
*
)
driver
;
hcd
->
description
=
driver
->
description
;
hcd
->
irq
=
NIRQHCIM
;
hcd
->
regs
=
(
void
*
)
&
USB_OHCI_OP_BASE
;
hcd
->
irq
=
dev
->
irq
[
1
]
;
hcd
->
regs
=
dev
->
mapbase
;
hcd
->
pdev
=
SA1111_FAKE_PCIDEV
;
hcd
->
parent
=
&
dev
->
dev
;
retval
=
hcd_buffer_create
(
hcd
);
if
(
retval
!=
0
)
{
...
...
@@ -167,8 +174,8 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, struct usb_hcd **hcd_o
goto
err1
;
}
set_irq_type
(
NIRQHCIM
,
IRQT_RISING
);
retval
=
request_irq
(
NIRQHCIM
,
usb_hcd_sa1111_hcim_irq
,
SA_INTERRUPT
,
set_irq_type
(
hcd
->
irq
,
IRQT_RISING
);
retval
=
request_irq
(
hcd
->
irq
,
usb_hcd_sa1111_hcim_irq
,
SA_INTERRUPT
,
hcd
->
description
,
hcd
);
if
(
retval
!=
0
)
{
dbg
(
"request_irq failed"
);
...
...
@@ -191,7 +198,7 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, struct usb_hcd **hcd_o
if
((
retval
=
driver
->
start
(
hcd
))
<
0
)
{
usb_hcd_sa1111_remove
(
hcd
);
usb_hcd_sa1111_remove
(
hcd
,
dev
);
return
retval
;
}
...
...
@@ -202,8 +209,8 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, struct usb_hcd **hcd_o
hcd_buffer_destroy
(
hcd
);
if
(
hcd
)
driver
->
hcd_free
(
hcd
);
err1:
sa1111_stop_hc
();
release_mem_region
(
_USB_OHCI_OP_BASE
,
_USB_EXTENT
);
sa1111_stop_hc
(
dev
);
release_mem_region
(
dev
->
res
.
start
,
dev
->
res
.
end
-
dev
->
res
.
start
+
1
);
return
retval
;
}
...
...
@@ -221,7 +228,7 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, struct usb_hcd **hcd_o
* context, normally "rmmod", "apmd", or something similar.
*
*/
void
usb_hcd_sa1111_remove
(
struct
usb_hcd
*
hcd
)
void
usb_hcd_sa1111_remove
(
struct
usb_hcd
*
hcd
,
struct
sa1111_dev
*
dev
)
{
struct
usb_device
*
hub
;
void
*
base
;
...
...
@@ -244,13 +251,13 @@ void usb_hcd_sa1111_remove (struct usb_hcd *hcd)
usb_deregister_bus
(
&
hcd
->
self
);
if
(
atomic_read
(
&
hcd
->
self
.
refcnt
)
!=
1
)
err
(
__FUNCTION__
": %s, count != 1"
,
hcd
->
self
.
bus_name
);
err
(
"%s: %s, count != 1"
,
__FUNCTION__
,
hcd
->
self
.
bus_name
);
base
=
hcd
->
regs
;
hcd
->
driver
->
hcd_free
(
hcd
);
sa1111_stop_hc
();
release_mem_region
(
_USB_OHCI_OP_BASE
,
_USB_EXTENT
);
sa1111_stop_hc
(
dev
);
release_mem_region
(
dev
->
res
.
start
,
dev
->
res
.
end
-
dev
->
res
.
start
+
1
);
}
/*-------------------------------------------------------------------------*/
...
...
@@ -275,7 +282,7 @@ ohci_sa1111_start (struct usb_hcd *hcd)
}
ohci
->
regs
=
hcd
->
regs
;
ohci
->
parent_dev
=
&
sa1111
->
dev
;
ohci
->
parent_dev
=
hcd
->
parent
;
if
(
hc_reset
(
ohci
)
<
0
)
{
ohci_stop
(
hcd
);
...
...
@@ -342,26 +349,67 @@ static const struct hc_driver ohci_sa1111_hc_driver = {
/*-------------------------------------------------------------------------*/
/* Only one SA-1111 ever exists. */
static
struct
usb_hcd
*
the_sa1111_hcd
;
static
int
ohci_hcd_sa1111_drv_probe
(
struct
device
*
_dev
)
{
struct
sa1111_dev
*
dev
=
SA1111_DEV
(
_dev
);
struct
usb_hcd
*
hcd
=
NULL
;
int
ret
;
ret
=
usb_hcd_sa1111_probe
(
&
ohci_sa1111_hc_driver
,
&
hcd
,
dev
);
if
(
ret
==
0
)
dev
->
dev
.
driver_data
=
hcd
;
return
ret
;
}
static
int
ohci_hcd_sa1111_drv_remove
(
struct
device
*
_dev
)
{
struct
sa1111_dev
*
dev
=
SA1111_DEV
(
_dev
);
struct
usb_hcd
*
hcd
=
dev
->
dev
.
driver_data
;
usb_hcd_sa1111_remove
(
hcd
,
dev
);
dev
->
dev
.
driver_data
=
NULL
;
static
int
__init
ohci_hcd_sa1111_init
(
void
)
return
0
;
}
static
int
ohci_hcd_sa1111_drv_suspend
(
struct
device
*
dev
,
u32
state
,
u32
level
)
{
return
0
;
}
static
int
ohci_hcd_sa1111_drv_resume
(
struct
device
*
dev
,
u32
level
)
{
return
0
;
}
static
struct
sa1111_driver
ohci_hcd_sa1111_driver
=
{
.
drv
=
{
.
name
=
"SA1111 OHCI"
,
.
bus
=
&
sa1111_bus_type
,
.
probe
=
ohci_hcd_sa1111_drv_probe
,
.
remove
=
ohci_hcd_sa1111_drv_remove
,
.
suspend
=
ohci_hcd_sa1111_drv_suspend
,
.
resume
=
ohci_hcd_sa1111_drv_resume
,
},
.
devid
=
SA1111_DEVID_USB
,
};
static
int
__init
ohci_hcd_sa1111_init
(
void
)
{
dbg
(
DRIVER_INFO
" (SA-1111)"
);
dbg
(
"block sizes: ed %d td %d"
,
sizeof
(
struct
ed
),
sizeof
(
struct
td
));
the_sa1111_hcd
=
0
;
return
usb_hcd_sa1111_probe
(
&
ohci_sa1111_hc_driver
,
&
the_sa1111_hcd
);
return
driver_register
(
&
ohci_hcd_sa1111_driver
.
drv
);
}
module_init
(
ohci_hcd_sa1111_init
);
static
void
__exit
ohci_hcd_sa1111_cleanup
(
void
)
{
if
(
the_sa1111_hcd
)
{
usb_hcd_sa1111_remove
(
the_sa1111_hcd
);
the_sa1111_hcd
=
0
;
}
static
void
__exit
ohci_hcd_sa1111_cleanup
(
void
)
{
remove_driver
(
&
ohci_hcd_sa1111_driver
.
drv
);
}
module_init
(
ohci_hcd_sa1111_init
);
module_exit
(
ohci_hcd_sa1111_cleanup
);
drivers/video/sa1100fb.c
View file @
2fbc109c
...
...
@@ -209,17 +209,17 @@ extern void (*sa1100fb_lcd_power)(int on);
* IMHO this looks wrong. In 8BPP, length should be 8.
*/
static
struct
sa1100fb_rgb
rgb_8
=
{
red:
{
offset
:
0
,
length
:
4
,
},
green:
{
offset
:
0
,
length
:
4
,
},
blue:
{
offset
:
0
,
length
:
4
,
},
transp:
{
offset
:
0
,
length
:
0
,
},
.
red
=
{
.
offset
=
0
,
.
length
=
4
,
},
.
green
=
{
.
offset
=
0
,
.
length
=
4
,
},
.
blue
=
{
.
offset
=
0
,
.
length
=
4
,
},
.
transp
=
{
.
offset
=
0
,
.
length
=
0
,
},
};
static
struct
sa1100fb_rgb
def_rgb_16
=
{
red:
{
offset
:
11
,
length
:
5
,
},
green:
{
offset
:
5
,
length
:
6
,
},
blue:
{
offset
:
0
,
length
:
5
,
},
transp:
{
offset
:
0
,
length
:
0
,
},
.
red
=
{
.
offset
=
11
,
.
length
=
5
,
},
.
green
=
{
.
offset
=
5
,
.
length
=
6
,
},
.
blue
=
{
.
offset
=
0
,
.
length
=
5
,
},
.
transp
=
{
.
offset
=
0
,
.
length
=
0
,
},
};
#ifdef CONFIG_SA1100_ASSABET
...
...
@@ -230,155 +230,151 @@ static struct sa1100fb_rgb def_rgb_16 = {
* instead (def_rgb_16).
*/
static
struct
sa1100fb_mach_info
lq039q2ds54_info
__initdata
=
{
pixclock:
171521
,
bpp
:
16
,
xres:
320
,
yres
:
240
,
.
pixclock
=
171521
,
.
bpp
=
16
,
.
xres
=
320
,
.
yres
=
240
,
hsync_len:
5
,
vsync_len
:
1
,
left_margin:
61
,
upper_margin
:
3
,
right_margin:
9
,
lower_margin
:
0
,
.
hsync_len
=
5
,
.
vsync_len
=
1
,
.
left_margin
=
61
,
.
upper_margin
=
3
,
.
right_margin
=
9
,
.
lower_margin
=
0
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
),
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
),
};
#else
static
struct
sa1100fb_mach_info
pal_info
__initdata
=
{
pixclock:
67797
,
bpp
:
16
,
xres:
640
,
yres
:
512
,
.
pixclock
=
67797
,
.
bpp
=
16
,
.
xres
=
640
,
.
yres
=
512
,
hsync_len:
64
,
vsync_len
:
6
,
left_margin:
125
,
upper_margin
:
70
,
right_margin:
115
,
lower_margin
:
36
,
.
hsync_len
=
64
,
.
vsync_len
=
6
,
.
left_margin
=
125
,
.
upper_margin
=
70
,
.
right_margin
=
115
,
.
lower_margin
=
36
,
sync:
0
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
512
),
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
512
),
};
#endif
#endif
#ifdef CONFIG_SA1100_H3800
static
struct
sa1100fb_mach_info
h3800_info
__initdata
=
{
pixclock:
174757
,
bpp
:
16
,
xres:
320
,
yres
:
240
,
.
pixclock
=
174757
,
.
bpp
=
16
,
.
xres
=
320
,
.
yres
=
240
,
hsync_len:
3
,
vsync_len
:
3
,
left_margin:
12
,
upper_margin
:
10
,
right_margin:
17
,
lower_margin
:
1
,
.
hsync_len
=
3
,
.
vsync_len
=
3
,
.
left_margin
=
12
,
.
upper_margin
=
10
,
.
right_margin
=
17
,
.
lower_margin
=
1
,
sync:
0
,
cmap_static
:
1
,
.
cmap_static
=
1
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_ACBsDiv
(
2
)
|
LCCR3_PixRsEdg
|
LCCR3_OutEnH
|
LCCR3_ACBsCntOff
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
),
};
#endif
#ifdef CONFIG_SA1100_H3600
static
struct
sa1100fb_mach_info
h3600_info
__initdata
=
{
pixclock:
174757
,
bpp
:
16
,
xres:
320
,
yres
:
240
,
.
pixclock
=
174757
,
.
bpp
=
16
,
.
xres
=
320
,
.
yres
=
240
,
hsync_len:
3
,
vsync_len
:
3
,
left_margin:
12
,
upper_margin
:
10
,
right_margin:
17
,
lower_margin
:
1
,
.
hsync_len
=
3
,
.
vsync_len
=
3
,
.
left_margin
=
12
,
.
upper_margin
=
10
,
.
right_margin
=
17
,
.
lower_margin
=
1
,
sync:
0
,
cmap_static
:
1
,
.
cmap_static
=
1
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_ACBsDiv
(
2
)
|
LCCR3_PixRsEdg
|
LCCR3_OutEnH
|
LCCR3_ACBsCntOff
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
),
};
static
struct
sa1100fb_rgb
h3600_rgb_16
=
{
red:
{
offset
:
12
,
length
:
4
,
},
green:
{
offset
:
7
,
length
:
4
,
},
blue:
{
offset
:
1
,
length
:
4
,
},
transp:
{
offset
:
0
,
length
:
0
,
},
.
red
=
{
.
offset
=
12
,
.
length
=
4
,
},
.
green
=
{
.
offset
=
7
,
.
length
=
4
,
},
.
blue
=
{
.
offset
=
1
,
.
length
=
4
,
},
.
transp
=
{
.
offset
=
0
,
.
length
=
0
,
},
};
#endif
#ifdef CONFIG_SA1100_H3100
static
struct
sa1100fb_mach_info
h3100_info
__initdata
=
{
pixclock:
406977
,
bpp
:
4
,
xres:
320
,
yres
:
240
,
.
pixclock
=
406977
,
.
bpp
=
4
,
.
xres
=
320
,
.
yres
=
240
,
hsync_len:
26
,
vsync_len
:
41
,
left_margin:
4
,
upper_margin
:
0
,
right_margin:
4
,
lower_margin
:
0
,
.
hsync_len
=
26
,
.
vsync_len
=
41
,
.
left_margin
=
4
,
.
upper_margin
=
0
,
.
right_margin
=
4
,
.
lower_margin
=
0
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
cmap_greyscale:
1
,
cmap_inverse:
1
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
cmap_greyscale
=
1
,
.
cmap_inverse
=
1
,
lccr0:
LCCR0_Mono
|
LCCR0_4PixMono
|
LCCR0_Sngl
|
LCCR0_Pas
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
),
.
lccr0
=
LCCR0_Mono
|
LCCR0_4PixMono
|
LCCR0_Sngl
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
),
};
#endif
#ifdef CONFIG_SA1100_BRUTUS
static
struct
sa1100fb_mach_info
brutus_info
__initdata
=
{
pixclock:
0
,
bpp
:
8
,
xres:
320
,
yres
:
240
,
.
pixclock
=
0
,
.
bpp
=
8
,
.
xres
=
320
,
.
yres
=
240
,
hsync_len:
3
,
vsync_len
:
1
,
left_margin:
41
,
upper_margin
:
0
,
right_margin:
101
,
lower_margin
:
0
,
.
hsync_len
=
3
,
.
vsync_len
=
1
,
.
left_margin
=
41
,
.
upper_margin
=
0
,
.
right_margin
=
101
,
.
lower_margin
=
0
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Pas
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
)
|
LCCR3_PixClkDiv
(
44
),
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
)
|
LCCR3_PixClkDiv
(
44
),
};
#endif
#ifdef CONFIG_SA1100_CERF
static
struct
sa1100fb_mach_info
cerf_info
__initdata
=
{
#if defined(CONFIG_CERF_LCD_72_A)
pixclock:
171521
,
bpp
:
8
,
xres:
640
,
yres
:
480
,
lccr0:
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
)
|
LCCR3_PixClkDiv
(
38
),
.
pixclock
=
171521
,
.
bpp
=
8
,
.
xres
=
640
,
.
yres
=
480
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
)
|
LCCR3_PixClkDiv
(
38
),
#elif defined(CONFIG_CERF_LCD_57_A)
pixclock:
171521
,
bpp
:
8
,
xres:
320
,
yres
:
240
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Pas
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
)
|
LCCR3_PixClkDiv
(
38
),
.
pixclock
=
171521
,
.
bpp
=
8
,
.
xres
=
320
,
.
yres
=
240
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
)
|
LCCR3_PixClkDiv
(
38
),
#elif defined(CONFIG_CERF_LCD_38_A)
pixclock:
171521
,
bpp
:
8
,
xres:
240
,
yres
:
320
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Pas
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
56
)
|
LCCR3_PixClkDiv
(
38
),
.
pixclock
=
171521
,
.
bpp
=
8
,
.
xres
=
240
,
.
yres
=
320
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
56
)
|
LCCR3_PixClkDiv
(
38
),
#elif defined(CONFIG_CERF_LCD_38_B)
pixclock:
171521
,
bpp
:
4
,
xres:
320
,
yres
:
240
,
lccr0:
LCCR0_Mono
|
LCCR0_4PixMono
|
LCCR0_Sngl
|
LCCR0_Pas
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
56
)
|
LCCR3_PixClkDiv
(
38
),
.
pixclock
=
171521
,
.
bpp
=
4
,
.
xres
=
320
,
.
yres
=
240
,
.
lccr0
=
LCCR0_Mono
|
LCCR0_4PixMono
|
LCCR0_Sngl
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
56
)
|
LCCR3_PixClkDiv
(
38
),
#else
#error "Must have a CerfBoard LCD form factor selected"
#endif
hsync_len:
5
,
vsync_len
:
1
,
left_margin:
61
,
upper_margin
:
3
,
right_margin:
9
,
lower_margin
:
0
,
.
hsync_len
=
5
,
.
vsync_len
=
1
,
.
left_margin
=
61
,
.
upper_margin
=
3
,
.
right_margin
=
9
,
.
lower_margin
=
0
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
};
#if 0
static struct sa1100fb_rgb cerf_rgb_16 = {
red: { offset: 8, length:
4, },
green: { offset: 4, length:
4, },
blue: { offset: 0, length:
4, },
transp: { offset: 0, length:
0, },
.red = { .offset = 8, .length =
4, },
.green = { .offset = 4, .length =
4, },
.blue = { .offset = 0, .length =
4, },
.transp = { .offset = 0, .length =
0, },
};
#endif
#endif
...
...
@@ -386,56 +382,54 @@ static struct sa1100fb_rgb cerf_rgb_16 = {
#ifdef CONFIG_SA1100_FREEBIRD
#warning Please check this carefully
static
struct
sa1100fb_mach_info
freebird_info
__initdata
=
{
pixclock:
171521
,
bpp
:
16
,
xres:
240
,
yres
:
320
,
.
pixclock
=
171521
,
.
bpp
=
16
,
.
xres
=
240
,
.
yres
=
320
,
hsync_len:
3
,
vsync_len
:
2
,
left_margin:
2
,
upper_margin
:
0
,
right_margin:
2
,
lower_margin
:
0
,
.
hsync_len
=
3
,
.
vsync_len
=
2
,
.
left_margin
=
2
,
.
upper_margin
=
0
,
.
right_margin
=
2
,
.
lower_margin
=
0
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Pas
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixFlEdg
|
LCCR3_ACBsDiv
(
2
),
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixFlEdg
|
LCCR3_ACBsDiv
(
2
),
};
static
struct
sa1100fb_rgb
freebird_rgb_16
=
{
red:
{
offset
:
8
,
length
:
4
,
},
green:
{
offset
:
4
,
length
:
4
,
},
blue:
{
offset
:
0
,
length
:
4
,
},
transp:
{
offset
:
12
,
length
:
4
,
},
.
red
=
{
.
offset
=
8
,
.
length
=
4
,
},
.
green
=
{
.
offset
=
4
,
.
length
=
4
,
},
.
blue
=
{
.
offset
=
0
,
.
length
=
4
,
},
.
transp
=
{
.
offset
=
12
,
.
length
=
4
,
},
};
#endif
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
static
struct
sa1100fb_mach_info
graphicsclient_info
__initdata
=
{
pixclock:
53500
,
bpp
:
8
,
xres:
640
,
yres
:
480
,
hsync_len:
9
,
vsync_len
:
9
,
left_margin:
54
,
upper_margin
:
24
,
right_margin:
54
,
lower_margin
:
32
,
.
pixclock
=
53500
,
.
bpp
=
8
,
.
xres
=
640
,
.
yres
=
480
,
sync:
0
,
.
hsync_len
=
9
,
.
vsync_len
=
9
,
.
left_margin
=
54
,
.
upper_margin
=
24
,
.
right_margin
=
54
,
.
lower_margin
=
32
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
),
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
),
};
#endif
#ifdef CONFIG_SA1100_HUW_WEBPANEL
static
struct
sa1100fb_mach_info
huw_webpanel_info
__initdata
=
{
pixclock:
0
,
bpp
:
8
,
xres:
640
,
yres
:
480
,
.
pixclock
=
0
,
.
bpp
=
8
,
.
xres
=
640
,
.
yres
=
480
,
hsync_len:
3
,
vsync_len
:
1
,
left_margin:
41
,
upper_margin
:
0
,
right_margin:
101
,
lower_margin
:
0
,
.
hsync_len
=
3
,
.
vsync_len
=
1
,
.
left_margin
=
41
,
.
upper_margin
=
0
,
.
right_margin
=
101
,
.
lower_margin
=
0
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
)
|
8
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
2
)
|
8
,
#error FIXME
/*
* FIXME: please get rid of the '| 8' in preference to an
...
...
@@ -446,99 +440,94 @@ static struct sa1100fb_mach_info huw_webpanel_info __initdata = {
#ifdef LART_GREY_LCD
static
struct
sa1100fb_mach_info
lart_grey_info
__initdata
=
{
pixclock:
150000
,
bpp
:
4
,
xres:
320
,
yres
:
240
,
.
pixclock
=
150000
,
.
bpp
=
4
,
.
xres
=
320
,
.
yres
=
240
,
hsync_len:
1
,
vsync_len
:
1
,
left_margin:
4
,
upper_margin
:
0
,
right_margin:
2
,
lower_margin
:
0
,
.
hsync_len
=
1
,
.
vsync_len
=
1
,
.
left_margin
=
4
,
.
upper_margin
=
0
,
.
right_margin
=
2
,
.
lower_margin
=
0
,
cmap_greyscale:
1
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
cmap_greyscale
=
1
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Mono
|
LCCR0_Sngl
|
LCCR0_Pas
|
LCCR0_4PixMono
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
512
),
.
lccr0
=
LCCR0_Mono
|
LCCR0_Sngl
|
LCCR0_Pas
|
LCCR0_4PixMono
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
512
),
};
#endif
#ifdef LART_COLOR_LCD
static
struct
sa1100fb_mach_info
lart_color_info
__initdata
=
{
pixclock:
150000
,
bpp
:
16
,
xres:
320
,
yres
:
240
,
.
pixclock
=
150000
,
.
bpp
=
16
,
.
xres
=
320
,
.
yres
=
240
,
hsync_len:
2
,
vsync_len
:
3
,
left_margin:
69
,
upper_margin
:
14
,
right_margin:
8
,
lower_margin
:
4
,
.
hsync_len
=
2
,
.
vsync_len
=
3
,
.
left_margin
=
69
,
.
upper_margin
=
14
,
.
right_margin
=
8
,
.
lower_margin
=
4
,
sync:
0
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixFlEdg
|
LCCR3_ACBsDiv
(
512
),
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixFlEdg
|
LCCR3_ACBsDiv
(
512
),
};
#endif
#ifdef LART_VIDEO_OUT
static
struct
sa1100fb_mach_info
lart_video_info
__initdata
=
{
pixclock:
39721
,
bpp
:
16
,
xres:
640
,
yres
:
480
,
.
pixclock
=
39721
,
.
bpp
=
16
,
.
xres
=
640
,
.
yres
=
480
,
hsync_len:
95
,
vsync_len
:
2
,
left_margin:
40
,
upper_margin
:
32
,
right_margin:
24
,
lower_margin
:
11
,
.
hsync_len
=
95
,
.
vsync_len
=
2
,
.
left_margin
=
40
,
.
upper_margin
=
32
,
.
right_margin
=
24
,
.
lower_margin
=
11
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_OutEnL
|
LCCR3_PixFlEdg
|
LCCR3_ACBsDiv
(
512
),
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnL
|
LCCR3_PixFlEdg
|
LCCR3_ACBsDiv
(
512
),
};
#endif
#ifdef LART_KIT01_LCD
static
struct
sa1100fb_mach_info
lart_kit01_info
__initdata
=
{
pixclock:
63291
,
bpp
:
16
,
xres:
640
,
yres
:
480
,
static
struct
sa1100fb_mach_info
lart_kit01_info
__initdata
=
{
.
pixclock
=
63291
,
.
bpp
=
16
,
.
xres
=
640
,
.
yres
=
480
,
hsync_len:
64
,
vsync_len
:
3
,
left_margin:
122
,
upper_margin
:
45
,
right_margin:
10
,
lower_margin
:
10
,
.
hsync_len
=
64
,
.
vsync_len
=
3
,
.
left_margin
=
122
,
.
upper_margin
=
45
,
.
right_margin
=
10
,
.
lower_margin
=
10
,
sync:
0
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixFlEdg
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixFlEdg
};
#endif
#ifdef CONFIG_SA1100_SHANNON
static
struct
sa1100fb_mach_info
shannon_info
__initdata
=
{
pixclock:
152500
,
bpp
:
8
,
xres:
640
,
yres
:
480
,
.
pixclock
=
152500
,
.
bpp
=
8
,
.
xres
=
640
,
.
yres
=
480
,
hsync_len:
4
,
vsync_len
:
3
,
left_margin:
2
,
upper_margin
:
0
,
right_margin:
1
,
lower_margin
:
0
,
.
hsync_len
=
4
,
.
vsync_len
=
3
,
.
left_margin
=
2
,
.
upper_margin
=
0
,
.
right_margin
=
1
,
.
lower_margin
=
0
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
lccr3:
LCCR3_ACBsDiv
(
512
),
.
lccr0
=
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_ACBsDiv
(
512
),
};
#endif
#ifdef CONFIG_SA1100_OMNIMETER
static
struct
sa1100fb_mach_info
omnimeter_info
__initdata
=
{
pixclock:
0
,
bpp
:
4
,
xres:
480
,
yres
:
320
,
.
pixclock
=
0
,
.
bpp
=
4
,
.
xres
=
480
,
.
yres
=
320
,
hsync_len:
1
,
vsync_len
:
1
,
left_margin:
10
,
upper_margin
:
0
,
right_margin:
10
,
lower_margin
:
0
,
.
hsync_len
=
1
,
.
vsync_len
=
1
,
.
left_margin
=
10
,
.
upper_margin
=
0
,
.
right_margin
=
10
,
.
lower_margin
=
0
,
cmap_greyscale:
1
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
cmap_greyscale
=
1
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Mono
|
LCCR0_Sngl
|
LCCR0_Pas
|
LCCR0_8PixMono
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
255
)
|
LCCR3_PixClkDiv
(
44
),
.
lccr0
=
LCCR0_Mono
|
LCCR0_Sngl
|
LCCR0_Pas
|
LCCR0_8PixMono
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
255
)
|
LCCR3_PixClkDiv
(
44
),
#error FIXME: fix pixclock, ACBsDiv
/*
* FIXME: I think ACBsDiv is wrong above - should it be 512 (disabled)?
...
...
@@ -549,17 +538,17 @@ static struct sa1100fb_mach_info omnimeter_info __initdata = {
#ifdef CONFIG_SA1100_PANGOLIN
static
struct
sa1100fb_mach_info
pangolin_info
__initdata
=
{
pixclock:
341521
,
bpp
:
16
,
xres:
800
,
yres
:
600
,
.
pixclock
=
341521
,
.
bpp
=
16
,
.
xres
=
800
,
.
yres
=
600
,
hsync_len:
64
,
vsync_len
:
7
,
left_margin:
160
,
upper_margin
:
7
,
right_margin:
24
,
lower_margin
:
1
,
.
hsync_len
=
64
,
.
vsync_len
=
7
,
.
left_margin
=
160
,
.
upper_margin
=
7
,
.
right_margin
=
24
,
.
lower_margin
=
1
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixFlEdg
|
LCCR3_ACBsCntOff
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixFlEdg
|
LCCR3_ACBsCntOff
,
};
#endif
...
...
@@ -571,49 +560,47 @@ static struct sa1100fb_mach_info pangolin_info __initdata = {
* NB likely to be increased to ease bus timings wrt pcmcia interface
*/
static
struct
sa1100fb_mach_info
stork_tft_info
__initdata
=
{
pixclock:
28935
,
bpp
:
16
,
xres:
640
,
yres
:
480
,
hsync_len:
64
,
vsync_len
:
2
,
left_margin:
48
,
upper_margin
:
12
,
right_margin:
48
,
lower_margin
:
31
,
.
pixclock
=
28935
,
.
bpp
=
16
,
.
xres
=
640
,
.
yres
=
480
,
sync:
0
,
.
hsync_len
=
64
,
.
vsync_len
=
2
,
.
left_margin
=
48
,
.
upper_margin
=
12
,
.
right_margin
=
48
,
.
lower_margin
=
31
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsCntOff
,
};
static
struct
sa1100fb_rgb
stork_tft_rgb_16
=
{
red:
{
offset
:
11
,
length
:
5
,
},
green:
{
offset
:
5
,
length
:
6
,
},
blue:
{
offset
:
0
,
length
:
5
,
},
transp:
{
offset
:
0
,
length
:
0
,
},
.
red
=
{
.
offset
=
11
,
.
length
=
5
,
},
.
green
=
{
.
offset
=
5
,
.
length
=
6
,
},
.
blue
=
{
.
offset
=
0
,
.
length
=
5
,
},
.
transp
=
{
.
offset
=
0
,
.
length
=
0
,
},
};
#else
/* Kyocera DSTN */
static
struct
sa1100fb_mach_info
stork_dstn_info
__initdata
=
{
pixclock:
0
,
bpp
:
16
,
xres:
640
,
yres
:
480
,
.
pixclock
=
0
,
.
bpp
=
16
,
.
xres
=
640
,
.
yres
=
480
,
hsync_len:
2
,
vsync_len
:
2
,
left_margin:
2
,
upper_margin
:
0
,
right_margin:
2
,
lower_margin
:
0
,
.
hsync_len
=
2
,
.
vsync_len
=
2
,
.
left_margin
=
2
,
.
upper_margin
=
0
,
.
right_margin
=
2
,
.
lower_margin
=
0
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
#error Fixme
lccr3:
0xff00
|
.
lccr3
=
0xff00
|
0x18
/* ought to be 0x14 but DMA isn't up to that as yet */
};
static
struct
sa1100fb_rgb
stork_dstn_rgb_16
=
{
red:
{
offset
:
8
,
length
:
4
,
},
green:
{
offset
:
4
,
length
:
4
,
},
blue:
{
offset
:
0
,
length
:
4
,
},
transp:
{
offset
:
0
,
length
:
0
,
},
.
red
=
{
.
offset
=
8
,
.
length
=
4
,
},
.
green
=
{
.
offset
=
4
,
.
length
=
4
,
},
.
blue
=
{
.
offset
=
0
,
.
length
=
4
,
},
.
transp
=
{
.
offset
=
0
,
.
length
=
0
,
},
};
#endif
#endif
...
...
@@ -630,34 +617,31 @@ static struct sa1100fb_rgb stork_dstn_rgb_16 = {
* =>4.32Mhz => 231481E-12s
*/
static
struct
sa1100fb_mach_info
system3_info
__initdata
=
{
pixclock:
231481
,
bpp
:
8
,
xres:
640
,
yres
:
480
,
.
pixclock
=
231481
,
.
bpp
=
8
,
.
xres
=
640
,
.
yres
=
480
,
hsync_len:
2
,
vsync_len
:
2
,
left_margin:
2
,
upper_margin
:
0
,
right_margin:
2
,
lower_margin
:
0
,
.
hsync_len
=
2
,
.
vsync_len
=
2
,
.
left_margin
=
2
,
.
upper_margin
=
0
,
.
right_margin
=
2
,
.
lower_margin
=
0
,
sync:
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
.
sync
=
FB_SYNC_HOR_HIGH_ACT
|
FB_SYNC_VERT_HIGH_ACT
,
lccr0:
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
512
)
|
LCCR3_ACBsCntOff
,
.
lccr0
=
LCCR0_Color
|
LCCR0_Dual
|
LCCR0_Pas
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_ACBsDiv
(
512
),
};
#endif
#ifdef CONFIG_SA1100_XP860
static
struct
sa1100fb_mach_info
xp860_info
__initdata
=
{
pixclock:
0
,
bpp
:
8
,
xres:
1024
,
yres
:
768
,
hsync_len:
3
,
vsync_len
:
3
,
left_margin:
3
,
upper_margin
:
2
,
right_margin:
2
,
lower_margin
:
1
,
.
pixclock
=
0
,
.
bpp
=
8
,
.
xres
=
1024
,
.
yres
=
768
,
sync:
0
,
.
hsync_len
=
3
,
.
vsync_len
=
3
,
.
left_margin
=
3
,
.
upper_margin
=
2
,
.
right_margin
=
2
,
.
lower_margin
=
1
,
lccr0:
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
lccr3:
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_PixClkDiv
(
6
),
.
lccr0
=
LCCR0_Color
|
LCCR0_Sngl
|
LCCR0_Act
,
.
lccr3
=
LCCR3_OutEnH
|
LCCR3_PixRsEdg
|
LCCR3_PixClkDiv
(
6
),
};
#endif
...
...
@@ -808,33 +792,7 @@ static inline void sa1100fb_schedule_task(struct sa1100fb_info *fbi, u_int state
local_irq_restore
(
flags
);
}
/*
* Get the VAR structure pointer for the specified console
*/
static
inline
struct
fb_var_screeninfo
*
get_con_var
(
struct
fb_info
*
info
,
int
con
)
{
return
(
con
==
info
->
currcon
||
con
==
-
1
)
?
&
info
->
var
:
&
fb_display
[
con
].
var
;
}
/*
* Get the DISPLAY structure pointer for the specified console
*/
static
inline
struct
display
*
get_con_display
(
struct
fb_info
*
info
,
int
con
)
{
struct
sa1100fb_info
*
fbi
=
(
struct
sa1100fb_info
*
)
info
;
return
(
con
<
0
)
?
fbi
->
fb
.
disp
:
&
fb_display
[
con
];
}
/*
* Get the CMAP pointer for the specified console
*/
static
inline
struct
fb_cmap
*
get_con_cmap
(
struct
fb_info
*
info
,
int
con
)
{
return
(
con
==
info
->
currcon
||
con
==
-
1
)
?
&
info
->
cmap
:
&
fb_display
[
con
].
cmap
;
}
static
inline
u_int
chan_to_field
(
u_int
chan
,
struct
fb_bitfield
*
bf
)
static
inline
u_int
chan_to_field
(
u_int
chan
,
struct
fb_bitfield
*
bf
)
{
chan
&=
0xffff
;
chan
>>=
16
-
bf
->
length
;
...
...
@@ -844,8 +802,7 @@ chan_to_field(u_int chan, struct fb_bitfield *bf)
/*
* Convert bits-per-pixel to a hardware palette PBS value.
*/
static
inline
u_int
palette_pbs
(
struct
fb_var_screeninfo
*
var
)
static
inline
u_int
palette_pbs
(
struct
fb_var_screeninfo
*
var
)
{
int
ret
=
0
;
switch
(
var
->
bits_per_pixel
)
{
...
...
@@ -888,8 +845,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int
trans
,
struct
fb_info
*
info
)
{
struct
sa1100fb_info
*
fbi
=
(
struct
sa1100fb_info
*
)
info
;
struct
display
*
disp
=
get_con_display
(
info
,
info
->
currcon
);
u_int
val
;
unsigned
int
val
;
int
ret
=
1
;
/*
...
...
@@ -898,7 +854,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* is what you poke into the framebuffer to produce the
* colour you requested.
*/
if
(
disp
->
inverse
)
{
if
(
fbi
->
cmap_
inverse
)
{
red
=
0xffff
-
red
;
green
=
0xffff
-
green
;
blue
=
0xffff
-
blue
;
...
...
@@ -912,7 +868,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
red
=
green
=
blue
=
(
19595
*
red
+
38470
*
green
+
7471
*
blue
)
>>
16
;
switch
(
fbi
->
fb
.
disp
->
visual
)
{
switch
(
fbi
->
fb
.
fix
.
visual
)
{
case
FB_VISUAL_TRUECOLOR
:
/*
* 12 or 16-bit True Colour. We encode the RGB value
...
...
@@ -942,38 +898,29 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
/*
* sa1100fb_display_dma_period()
* Calculate the minimum period (in picoseconds) between two DMA
* requests for the LCD controller.
* requests for the LCD controller. If we hit this, it means we're
* doing nothing but LCD DMA.
*/
static
unsigned
int
sa1100fb_display_dma_period
(
struct
fb_var_screeninfo
*
var
)
static
unsigned
int
sa1100fb_display_dma_period
(
struct
fb_var_screeninfo
*
var
)
{
unsigned
int
mem_bits_per_pixel
;
mem_bits_per_pixel
=
var
->
bits_per_pixel
;
if
(
mem_bits_per_pixel
==
12
)
mem_bits_per_pixel
=
16
;
/*
* Period = pixclock * bits_per_byte * bytes_per_transfer
* / memory_bits_per_pixel;
*/
return
var
->
pixclock
*
8
*
16
/
mem_
bits_per_pixel
;
return
var
->
pixclock
*
8
*
16
/
var
->
bits_per_pixel
;
}
/*
* sa1100fb_decode_var():
* Get the video params out of 'var'. If a value doesn't fit, round it up,
* if it's too big, return -EINVAL.
*
* Suggestion: Round up in the following order: bits_per_pixel, xres,
* sa1100fb_check_var():
* Round up in the following order: bits_per_pixel, xres,
* yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
* bitfields, horizontal timing, vertical timing.
*/
static
int
sa1100fb_validate_var
(
struct
fb_var_screeninfo
*
var
,
struct
sa1100fb_info
*
fbi
)
sa1100fb_check_var
(
struct
fb_var_screeninfo
*
var
,
struct
fb_info
*
info
)
{
int
ret
=
-
EINVAL
;
struct
sa1100fb_info
*
fbi
=
(
struct
sa1100fb_info
*
)
info
;
int
rgbidx
;
if
(
var
->
xres
<
MIN_XRES
)
var
->
xres
=
MIN_XRES
;
...
...
@@ -983,42 +930,60 @@ sa1100fb_validate_var(struct fb_var_screeninfo *var,
var
->
xres
=
fbi
->
max_xres
;
if
(
var
->
yres
>
fbi
->
max_yres
)
var
->
yres
=
fbi
->
max_yres
;
var
->
xres_virtual
=
var
->
xres_virtual
<
var
->
xres
?
var
->
xres
:
var
->
xres_virtual
;
var
->
yres_virtual
=
var
->
yres_virtual
<
var
->
yres
?
var
->
yres
:
var
->
yres_virtual
;
var
->
xres_virtual
=
max
(
var
->
xres_virtual
,
var
->
xres
);
var
->
yres_virtual
=
max
(
var
->
yres_virtual
,
var
->
yres
);
DPRINTK
(
"var->bits_per_pixel=%d
\n
"
,
var
->
bits_per_pixel
);
switch
(
var
->
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB4
case
4
:
ret
=
0
;
break
;
case
4
:
rgbidx
=
RGB_8
;
break
;
#endif
#ifdef FBCON_HAS_CFB8
case
8
:
ret
=
0
;
break
;
case
8
:
rgbidx
=
RGB_8
;
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
16
:
ret
=
0
;
break
;
case
16
:
rgbidx
=
RGB_16
;
break
;
#endif
default:
break
;
return
-
EINVAL
;
}
/*
* Copy the RGB parameters for this display
* from the machine specific parameters.
*/
var
->
red
=
fbi
->
rgb
[
rgbidx
]
->
red
;
var
->
green
=
fbi
->
rgb
[
rgbidx
]
->
green
;
var
->
blue
=
fbi
->
rgb
[
rgbidx
]
->
blue
;
var
->
transp
=
fbi
->
rgb
[
rgbidx
]
->
transp
;
DPRINTK
(
"RGBT length = %d:%d:%d:%d
\n
"
,
var
->
red
.
length
,
var
->
green
.
length
,
var
->
blue
.
length
,
var
->
transp
.
length
);
DPRINTK
(
"RGBT offset = %d:%d:%d:%d
\n
"
,
var
->
red
.
offset
,
var
->
green
.
offset
,
var
->
blue
.
offset
,
var
->
transp
.
offset
);
#ifdef CONFIG_CPU_FREQ
printk
(
KERN_DEBUG
"dma period = %d ps, clock = %d kHz
\n
"
,
sa1100fb_display_dma_period
(
var
),
cpufreq_get
(
smp_processor_id
()));
#endif
return
ret
;
return
0
;
}
static
inline
void
sa1100fb_set_truecolor
(
u_int
is_true_color
)
{
DPRINTK
(
"true_color = %d
\n
"
,
is_true_color
);
if
(
machine_is_assabet
())
{
#if 1
// phase 4 or newer Assabet's
#if 1 // phase 4 or newer Assabet's
if
(
is_true_color
)
ASSABET_BCR_set
(
ASSABET_BCR_LCD_12RGB
);
else
...
...
@@ -1033,10 +998,30 @@ static inline void sa1100fb_set_truecolor(u_int is_true_color)
}
}
static
void
sa1100fb_hw_set_var
(
struct
fb_var_screeninfo
*
var
,
struct
sa1100fb_info
*
fbi
)
/*
* sa1100fb_set_par():
* Set the user defined part of the display for the specified console
*/
static
int
sa1100fb_set_par
(
struct
fb_info
*
info
)
{
u_long
palette_mem_size
;
struct
sa1100fb_info
*
fbi
=
(
struct
sa1100fb_info
*
)
info
;
struct
fb_var_screeninfo
*
var
=
&
info
->
var
;
unsigned
long
palette_mem_size
;
DPRINTK
(
"set_par
\n
"
);
if
(
var
->
bits_per_pixel
==
16
)
fbi
->
fb
.
fix
.
visual
=
FB_VISUAL_TRUECOLOR
;
else
if
(
!
fbi
->
cmap_static
)
fbi
->
fb
.
fix
.
visual
=
FB_VISUAL_PSEUDOCOLOR
;
else
{
/*
* Some people have weird ideas about wanting static
* pseudocolor maps. I suspect their user space
* applications are broken.
*/
fbi
->
fb
.
fix
.
visual
=
FB_VISUAL_STATIC_PSEUDOCOLOR
;
}
fbi
->
palette_size
=
var
->
bits_per_pixel
==
8
?
256
:
16
;
...
...
@@ -1047,10 +1032,10 @@ sa1100fb_hw_set_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi)
fbi
->
palette_cpu
=
(
u16
*
)(
fbi
->
map_cpu
+
PAGE_SIZE
-
palette_mem_size
);
fbi
->
palette_dma
=
fbi
->
map_dma
+
PAGE_SIZE
-
palette_mem_size
;
fb_set_cmap
(
&
fbi
->
fb
.
cmap
,
1
,
&
fbi
->
fb
);
/* Set board control register to handle new color depth
*/
sa1100fb_set_truecolor
(
var
->
bits_per_pixel
>=
16
);
/*
* Set (any) board control register to handle new color depth
*/
sa1100fb_set_truecolor
(
fbi
->
fb
.
fix
.
visual
==
FB_VISUAL_TRUECOLOR
);
#ifdef CONFIG_SA1100_OMNIMETER
#error Do we have to do this here? We already do it at init time.
...
...
@@ -1060,9 +1045,7 @@ sa1100fb_hw_set_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi)
sa1100fb_activate_var
(
var
,
fbi
);
fbi
->
palette_cpu
[
0
]
=
(
fbi
->
palette_cpu
[
0
]
&
0xcfff
)
|
palette_pbs
(
var
);
return
0
;
}
/*
...
...
@@ -1072,197 +1055,38 @@ sa1100fb_hw_set_var(struct fb_var_screeninfo *var, struct sa1100fb_info *fbi)
static
int
sa1100fb_set_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
struct
sa1100fb_info
*
fbi
=
(
struct
sa1100fb_info
*
)
info
;
struct
fb_var_screeninfo
*
dvar
=
get_con_var
(
&
fbi
->
fb
,
con
);
struct
display
*
display
=
get_con_display
(
&
fbi
->
fb
,
con
);
int
err
,
chgvar
=
0
,
rgbidx
;
DPRINTK
(
"set_var
\n
"
);
int
ret
,
act
;
/*
* Decode var contents into a par structure, adjusting any
* out of range values.
*/
err
=
sa1100fb_validate_var
(
var
,
fbi
);
if
(
err
)
return
err
;
act
=
var
->
activate
&
FB_ACTIVATE_MASK
;
if
(
var
->
activate
&
FB_ACTIVATE_TEST
)
return
0
;
ret
=
gen_set_var
(
var
,
con
,
info
);
if
(
(
var
->
activate
&
FB_ACTIVATE_MASK
)
!=
FB_ACTIVATE_NOW
)
return
-
EINVAL
;
if
(
ret
==
0
&&
act
&
FB_ACTIVATE_NOW
)
{
struct
display
*
display
=
(
con
<
0
)
?
info
->
disp
:
fb_display
+
con
;
if
(
dvar
->
xres
!=
var
->
xres
)
chgvar
=
1
;
if
(
dvar
->
yres
!=
var
->
yres
)
chgvar
=
1
;
if
(
dvar
->
xres_virtual
!=
var
->
xres_virtual
)
chgvar
=
1
;
if
(
dvar
->
yres_virtual
!=
var
->
yres_virtual
)
chgvar
=
1
;
if
(
dvar
->
bits_per_pixel
!=
var
->
bits_per_pixel
)
chgvar
=
1
;
if
(
con
<
0
)
chgvar
=
0
;
switch
(
var
->
bits_per_pixel
)
{
#ifdef FBCON_HAS_CFB4
case
4
:
if
(
fbi
->
cmap_static
)
display
->
visual
=
FB_VISUAL_STATIC_PSEUDOCOLOR
;
else
display
->
visual
=
FB_VISUAL_PSEUDOCOLOR
;
display
->
line_length
=
var
->
xres
/
2
;
display
->
dispsw
=
&
fbcon_cfb4
;
rgbidx
=
RGB_8
;
break
;
#endif
#ifdef FBCON_HAS_CFB8
case
8
:
if
(
fbi
->
cmap_static
)
display
->
visual
=
FB_VISUAL_STATIC_PSEUDOCOLOR
;
else
display
->
visual
=
FB_VISUAL_PSEUDOCOLOR
;
display
->
line_length
=
var
->
xres
;
display
->
dispsw
=
&
fbcon_cfb8
;
rgbidx
=
RGB_8
;
break
;
#endif
#ifdef FBCON_HAS_CFB16
case
16
:
display
->
visual
=
FB_VISUAL_TRUECOLOR
;
display
->
line_length
=
var
->
xres
*
2
;
display
->
dispsw
=
&
fbcon_cfb16
;
display
->
dispsw_data
=
fbi
->
fb
.
pseudo_palette
;
rgbidx
=
RGB_16
;
break
;
#endif
default:
rgbidx
=
0
;
display
->
dispsw
=
&
fbcon_dummy
;
break
;
/*
* fbcon assumes too much.
*/
display
->
can_soft_blank
=
1
;
}
display
->
next_line
=
display
->
line_length
;
display
->
type
=
fbi
->
fb
.
fix
.
type
;
display
->
type_aux
=
fbi
->
fb
.
fix
.
type_aux
;
display
->
ypanstep
=
fbi
->
fb
.
fix
.
ypanstep
;
display
->
ywrapstep
=
fbi
->
fb
.
fix
.
ywrapstep
;
display
->
can_soft_blank
=
1
;
display
->
inverse
=
fbi
->
cmap_inverse
;
*
dvar
=
*
var
;
dvar
->
activate
&=
~
FB_ACTIVATE_ALL
;
/*
* Copy the RGB parameters for this display
* from the machine specific parameters.
*/
dvar
->
red
=
fbi
->
rgb
[
rgbidx
]
->
red
;
dvar
->
green
=
fbi
->
rgb
[
rgbidx
]
->
green
;
dvar
->
blue
=
fbi
->
rgb
[
rgbidx
]
->
blue
;
dvar
->
transp
=
fbi
->
rgb
[
rgbidx
]
->
transp
;
DPRINTK
(
"RGBT length = %d:%d:%d:%d
\n
"
,
dvar
->
red
.
length
,
dvar
->
green
.
length
,
dvar
->
blue
.
length
,
dvar
->
transp
.
length
);
DPRINTK
(
"RGBT offset = %d:%d:%d:%d
\n
"
,
dvar
->
red
.
offset
,
dvar
->
green
.
offset
,
dvar
->
blue
.
offset
,
dvar
->
transp
.
offset
);
/*
* Update the old var. The fbcon drivers still use this.
* Once they are using fbi->fb.var, this can be dropped.
*/
display
->
var
=
*
dvar
;
/*
* If we are setting all the virtual consoles, also set the
* defaults used to create new consoles.
*/
if
(
var
->
activate
&
FB_ACTIVATE_ALL
)
fbi
->
fb
.
disp
->
var
=
*
dvar
;
/*
* If the console has changed and the console has defined
* a changevar function, call that function.
*/
if
(
chgvar
&&
info
&&
fbi
->
fb
.
changevar
)
fbi
->
fb
.
changevar
(
con
);
/* If the current console is selected, activate the new var. */
if
(
con
!=
fbi
->
fb
.
currcon
)
return
0
;
sa1100fb_hw_set_var
(
dvar
,
fbi
);
return
0
;
}
static
int
__do_set_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
{
struct
sa1100fb_info
*
fbi
=
(
struct
sa1100fb_info
*
)
info
;
struct
fb_cmap
*
dcmap
=
get_con_cmap
(
info
,
con
);
int
err
=
0
;
if
(
con
==
-
1
)
con
=
info
->
currcon
;
/* no colormap allocated? (we always have "this" colour map allocated) */
if
(
con
>=
0
)
err
=
fb_alloc_cmap
(
&
fb_display
[
con
].
cmap
,
fbi
->
palette_size
,
0
);
if
(
!
err
&&
con
==
info
->
currcon
)
err
=
fb_set_cmap
(
cmap
,
kspc
,
info
);
if
(
!
err
)
fb_copy_cmap
(
cmap
,
dcmap
,
kspc
?
0
:
1
);
return
err
;
return
ret
;
}
static
int
sa1100fb_set_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
{
struct
display
*
disp
=
get_con_display
(
info
,
con
);
struct
sa1100fb_info
*
fbi
=
(
struct
sa1100fb_info
*
)
info
;
struct
display
*
disp
=
(
con
<
0
)
?
info
->
disp
:
(
fb_display
+
con
);
if
(
disp
->
visual
==
FB_VISUAL_TRUECOLOR
||
disp
->
visual
==
FB_VISUAL_STATIC_PSEUDOCOLOR
)
/*
* Make sure the user isn't doing something stupid.
*/
if
(
!
kspc
&&
(
disp
->
var
.
bits_per_pixel
==
16
||
fbi
->
cmap_static
))
return
-
EINVAL
;
return
__do_set_cmap
(
cmap
,
kspc
,
con
,
info
);
}
static
int
sa1100fb_get_fix
(
struct
fb_fix_screeninfo
*
fix
,
int
con
,
struct
fb_info
*
info
)
{
struct
display
*
display
=
get_con_display
(
info
,
con
);
*
fix
=
info
->
fix
;
fix
->
line_length
=
display
->
line_length
;
fix
->
visual
=
display
->
visual
;
return
0
;
}
static
int
sa1100fb_get_var
(
struct
fb_var_screeninfo
*
var
,
int
con
,
struct
fb_info
*
info
)
{
*
var
=
*
get_con_var
(
info
,
con
);
return
0
;
}
static
int
sa1100fb_get_cmap
(
struct
fb_cmap
*
cmap
,
int
kspc
,
int
con
,
struct
fb_info
*
info
)
{
struct
fb_cmap
*
dcmap
=
get_con_cmap
(
info
,
con
);
fb_copy_cmap
(
dcmap
,
cmap
,
kspc
?
0
:
2
);
return
0
;
return
gen_set_cmap
(
cmap
,
kspc
,
con
,
info
);
}
/*
...
...
@@ -1312,16 +1136,16 @@ static int sa1100fb_blank(int blank, struct fb_info *info)
case
VESA_POWERDOWN
:
case
VESA_VSYNC_SUSPEND
:
case
VESA_HSYNC_SUSPEND
:
if
(
fbi
->
fb
.
disp
->
visual
==
FB_VISUAL_PSEUDOCOLOR
||
fbi
->
fb
.
disp
->
visual
==
FB_VISUAL_STATIC_PSEUDOCOLOR
)
if
(
fbi
->
fb
.
fix
.
visual
==
FB_VISUAL_PSEUDOCOLOR
||
fbi
->
fb
.
fix
.
visual
==
FB_VISUAL_STATIC_PSEUDOCOLOR
)
for
(
i
=
0
;
i
<
fbi
->
palette_size
;
i
++
)
sa1100fb_setpalettereg
(
i
,
0
,
0
,
0
,
0
,
info
);
sa1100fb_schedule_task
(
fbi
,
C_DISABLE
);
break
;
case
VESA_NO_BLANKING
:
if
(
fbi
->
fb
.
disp
->
visual
==
FB_VISUAL_PSEUDOCOLOR
||
fbi
->
fb
.
disp
->
visual
==
FB_VISUAL_STATIC_PSEUDOCOLOR
)
if
(
fbi
->
fb
.
fix
.
visual
==
FB_VISUAL_PSEUDOCOLOR
||
fbi
->
fb
.
fix
.
visual
==
FB_VISUAL_STATIC_PSEUDOCOLOR
)
fb_set_cmap
(
&
fbi
->
fb
.
cmap
,
1
,
info
);
sa1100fb_schedule_task
(
fbi
,
C_ENABLE
);
}
...
...
@@ -1329,71 +1153,19 @@ static int sa1100fb_blank(int blank, struct fb_info *info)
}
static
struct
fb_ops
sa1100fb_ops
=
{
owner:
THIS_MODULE
,
fb_get_fix:
sa1100fb_get_fix
,
fb_get_var:
sa1100fb_get_v
ar
,
fb_set_var:
sa1100fb_set_var
,
fb_get_cmap:
sa1100fb
_get_cmap
,
fb_set_cmap:
sa1100fb_set_cmap
,
fb_setcolreg:
sa1100fb_setcolreg
,
fb_blank:
sa1100fb_blank
,
.
owner
=
THIS_MODULE
,
.
fb_check_var
=
sa1100fb_check_var
,
.
fb_set_par
=
sa1100fb_set_p
ar
,
.
fb_set_var
=
sa1100fb_set_var
,
.
fb_get_cmap
=
gen
_get_cmap
,
.
fb_set_cmap
=
sa1100fb_set_cmap
,
.
fb_setcolreg
=
sa1100fb_setcolreg
,
.
fb_blank
=
sa1100fb_blank
,
};
/*
* sa1100fb_switch():
* Change to the specified console. Palette and video mode
* are changed to the console's stored parameters.
*
* Uh oh, this can be called from a tasklet (IRQ)
*/
static
int
sa1100fb_switch
(
int
con
,
struct
fb_info
*
info
)
{
struct
sa1100fb_info
*
fbi
=
(
struct
sa1100fb_info
*
)
info
;
struct
display
*
disp
;
struct
fb_cmap
*
cmap
;
DPRINTK
(
"con=%d info->modename=%s
\n
"
,
con
,
fbi
->
fb
.
modename
);
if
(
con
==
info
->
currcon
)
return
0
;
if
(
info
->
currcon
>=
0
)
{
disp
=
fb_display
+
info
->
currcon
;
/*
* Save the old colormap and video mode.
*/
disp
->
var
=
fbi
->
fb
.
var
;
if
(
disp
->
cmap
.
len
)
fb_copy_cmap
(
&
fbi
->
fb
.
cmap
,
&
disp
->
cmap
,
0
);
}
info
->
currcon
=
con
;
disp
=
fb_display
+
con
;
/*
* Make sure that our colourmap contains 256 entries.
*/
fb_alloc_cmap
(
&
fbi
->
fb
.
cmap
,
256
,
0
);
if
(
disp
->
cmap
.
len
)
cmap
=
&
disp
->
cmap
;
else
cmap
=
fb_default_cmap
(
1
<<
disp
->
var
.
bits_per_pixel
);
fb_copy_cmap
(
cmap
,
&
fbi
->
fb
.
cmap
,
0
);
fbi
->
fb
.
var
=
disp
->
var
;
fbi
->
fb
.
var
.
activate
=
FB_ACTIVATE_NOW
;
sa1100fb_set_var
(
&
fbi
->
fb
.
var
,
con
,
info
);
return
0
;
}
static
int
sa1100fb_updatevar
(
int
con
,
struct
fb_info
*
info
)
{
DPRINTK
(
"entered
\n
"
);
/* we don't support panning nor scrolling */
return
0
;
}
...
...
@@ -1401,34 +1173,14 @@ static int sa1100fb_updatevar(int con, struct fb_info *info)
* Calculate the PCD value from the clock rate (in picoseconds).
* We take account of the PPCR clock setting.
*/
static
inline
int
get_pcd
(
unsigned
int
pix
clock
)
static
inline
unsigned
int
get_pcd
(
unsigned
int
pixclock
,
unsigned
int
cpu
clock
)
{
unsigned
int
pcd
;
if
(
pixclock
)
{
pcd
=
cpufreq_get
(
0
)
/
100
;
pcd
*=
pixclock
;
pcd
/=
10000000
;
pcd
+=
1
;
/* make up for integer math truncations */
}
else
{
/*
* People seem to be missing this message. Make it big.
* Make it stand out. Make sure people see it.
*/
printk
(
KERN_WARNING
"******************************************************
\n
"
);
printk
(
KERN_WARNING
"** ZERO PIXEL CLOCK DETECTED **
\n
"
);
printk
(
KERN_WARNING
"** You are using a zero pixclock. This means that **
\n
"
);
printk
(
KERN_WARNING
"** clock scaling will not be able to adjust your **
\n
"
);
printk
(
KERN_WARNING
"** your timing parameters appropriately, and the **
\n
"
);
printk
(
KERN_WARNING
"** bandwidth calculations will fail to work. This **
\n
"
);
printk
(
KERN_WARNING
"** will shortly become an error condition, which **
\n
"
);
printk
(
KERN_WARNING
"** will prevent your LCD display working. Please **
\n
"
);
printk
(
KERN_WARNING
"** send your patches in as soon as possible to shut **
\n
"
);
printk
(
KERN_WARNING
"** this message up. **
\n
"
);
printk
(
KERN_WARNING
"******************************************************
\n
"
);
pcd
=
0
;
}
return
pcd
;
unsigned
int
pcd
=
cpuclock
/
100
;
pcd
*=
pixclock
;
pcd
/=
10000000
;
return
pcd
+
1
;
/* make up for integer math truncations */
}
/*
...
...
@@ -1439,7 +1191,7 @@ static inline int get_pcd(unsigned int pixclock)
static
int
sa1100fb_activate_var
(
struct
fb_var_screeninfo
*
var
,
struct
sa1100fb_info
*
fbi
)
{
struct
sa1100fb_lcd_reg
new_regs
;
u_int
half_screen_size
,
yres
,
pcd
=
get_pcd
(
var
->
pixclock
)
;
u_int
half_screen_size
,
yres
,
pcd
;
u_long
flags
;
DPRINTK
(
"Configuring SA1100 LCD
\n
"
);
...
...
@@ -1502,13 +1254,10 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
LCCR2_BegFrmDel
(
var
->
upper_margin
)
+
LCCR2_EndFrmDel
(
var
->
lower_margin
);
new_regs
.
lccr3
=
fbi
->
lccr3
|
pcd
=
get_pcd
(
var
->
pixclock
,
cpufreq_get
(
0
));
new_regs
.
lccr3
=
LCCR3_PixClkDiv
(
pcd
)
|
fbi
->
lccr3
|
(
var
->
sync
&
FB_SYNC_HOR_HIGH_ACT
?
LCCR3_HorSnchH
:
LCCR3_HorSnchL
)
|
(
var
->
sync
&
FB_SYNC_VERT_HIGH_ACT
?
LCCR3_VrtSnchH
:
LCCR3_VrtSnchL
)
|
LCCR3_ACBsCntOff
;
if
(
pcd
)
new_regs
.
lccr3
|=
LCCR3_PixClkDiv
(
pcd
);
(
var
->
sync
&
FB_SYNC_VERT_HIGH_ACT
?
LCCR3_VrtSnchH
:
LCCR3_VrtSnchL
);
DPRINTK
(
"nlccr0 = 0x%08x
\n
"
,
new_regs
.
lccr0
);
DPRINTK
(
"nlccr1 = 0x%08x
\n
"
,
new_regs
.
lccr1
);
...
...
@@ -1547,61 +1296,20 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
* to ensure that things happen in the right way 100% of time time.
* -- rmk
*/
/*
* FIXME: move LCD power stuff into sa1100fb_power_up_lcd()
* Also, I'm expecting that the backlight stuff should
* be handled differently.
*/
static
inline
void
sa1100fb_backlight_on
(
struct
sa1100fb_info
*
fbi
)
{
DPRINTK
(
"backlight on
\n
"
);
if
(
sa1100fb_backlight_power
)
sa1100fb_backlight_power
(
1
);
}
/*
* FIXME: move LCD power stuf into sa1100fb_power_down_lcd()
* Also, I'm expecting that the backlight stuff should
* be handled differently.
*/
static
inline
void
sa1100fb_backlight_off
(
struct
sa1100fb_info
*
fbi
)
static
inline
void
__sa1100fb_backlight_power
(
struct
sa1100fb_info
*
fbi
,
int
on
)
{
DPRINTK
(
"backlight o
ff
\n
"
);
DPRINTK
(
"backlight o
%s
\n
"
,
on
?
"n"
:
"ff
"
);
if
(
sa1100fb_backlight_power
)
sa1100fb_backlight_power
(
0
);
sa1100fb_backlight_power
(
on
);
}
static
inline
void
sa1100fb_power_up_lcd
(
struct
sa1100fb_info
*
fbi
)
static
inline
void
__sa1100fb_lcd_power
(
struct
sa1100fb_info
*
fbi
,
int
on
)
{
DPRINTK
(
"LCD power o
n
\n
"
);
DPRINTK
(
"LCD power o
%s
\n
"
,
on
?
"n"
:
"ff
"
);
if
(
sa1100fb_lcd_power
)
sa1100fb_lcd_power
(
1
);
#ifdef CONFIG_SA1100_STORK
if
(
machine_is_stork
())
{
storkSetLCDCPLD
(
0
,
1
);
storkSetLatchA
(
STORK_LCD_BACKLIGHT_INVERTER_ON
);
}
#endif
}
static
inline
void
sa1100fb_power_down_lcd
(
struct
sa1100fb_info
*
fbi
)
{
DPRINTK
(
"LCD power off
\n
"
);
if
(
sa1100fb_lcd_power
)
sa1100fb_lcd_power
(
0
);
#ifdef CONFIG_SA1100_STORK
if
(
machine_is_stork
())
{
storkSetLCDCPLD
(
0
,
0
);
storkClearLatchA
(
STORK_LCD_BACKLIGHT_INVERTER_ON
);
}
#endif
sa1100fb_lcd_power
(
on
);
}
static
void
sa1100fb_setup_gpio
(
struct
sa1100fb_info
*
fbi
)
...
...
@@ -1630,38 +1338,9 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
}
if
(
machine_is_cerf
())
{
/* GPIO15 is used as a bypass for 3.8" displays */
/* GPIO15 is used as a bypass for 3.8" displays */
if
(
machine_is_cerf
())
mask
|=
GPIO_GPIO15
;
#ifdef CONFIG_SA1100_CERF
#warning Read Me Now!
#endif
#if 0 /* if this causes you problems, mail <rmk@arm.linux.org.uk> please. */
/*
* This was enabled for the 72_A version only, which is a _color_
* _dual_ LCD. Now look at the generic test above, and calculate
* the mask value for a colour dual display...
*
* I therefore conclude that the code below is redundant, and will
* be killed at the start of November 2001.
*/
/* FIXME: why is this? The Cerf's display doesn't seem
* to be dual scan or active. I just leave it here,
* but in my opinion this is definitively wrong.
* -- Erik <J.A.K.Mouw@its.tudelft.nl>
*/
/* REPLY: Umm.. Well to be honest, the 5.7" LCD which
* this was used for does not use these pins, but
* apparently all hell breaks loose if they are not
* set on the Cerf, so we decided to leave them in ;)
* -- Daniel Chemko <dchemko@intrinsyc.com>
*/
/* color {dual/single} passive */
mask |= GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8;
#endif
}
if
(
mask
)
{
GPDR
|=
mask
;
...
...
@@ -1733,7 +1412,7 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
}
#endif
#ifdef CONFIG_SA1100_HUW_WEBPANEL
#error Move me into
sa1100fb_power_up_lcd and/or sa1100fb_backlight_on
#error Move me into
__sa1100fb_lcd_power and/or __sa1100fb_backlight_power
if
(
machine_is_huw_webpanel
())
{
// dont forget to set the control lines to zero (?)
DPRINTK
(
"ShutDown HuW LCD controller
\n
"
);
...
...
@@ -1806,10 +1485,10 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
if
(
old_state
!=
C_DISABLE
)
{
fbi
->
state
=
state
;
sa1100fb_backlight_off
(
fbi
);
__sa1100fb_backlight_power
(
fbi
,
0
);
if
(
old_state
!=
C_DISABLE_CLKCHANGE
)
sa1100fb_disable_controller
(
fbi
);
sa1100fb_power_down_lcd
(
fbi
);
__sa1100fb_lcd_power
(
fbi
,
0
);
}
break
;
...
...
@@ -1855,9 +1534,9 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
if
(
old_state
!=
C_ENABLE
)
{
fbi
->
state
=
C_ENABLE
;
sa1100fb_setup_gpio
(
fbi
);
sa1100fb_power_up_lcd
(
fbi
);
__sa1100fb_lcd_power
(
fbi
,
1
);
sa1100fb_enable_controller
(
fbi
);
sa1100fb_backlight_on
(
fbi
);
__sa1100fb_backlight_power
(
fbi
,
1
);
}
break
;
}
...
...
@@ -1888,18 +1567,19 @@ static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi)
int
i
;
for
(
i
=
0
;
i
<
MAX_NR_CONSOLES
;
i
++
)
{
struct
display
*
disp
=
&
fb_display
[
i
];
unsigned
int
period
;
/*
* Do we own this display?
*/
if
(
fb_display
[
i
].
fb_info
!=
&
fbi
->
fb
)
if
(
disp
->
fb_info
!=
&
fbi
->
fb
)
continue
;
/*
* Ok, calculate its DMA period
*/
period
=
sa1100fb_display_dma_period
(
get_con_var
(
&
fbi
->
fb
,
i
)
);
period
=
sa1100fb_display_dma_period
(
&
disp
->
var
);
if
(
period
<
min_period
)
min_period
=
period
;
}
...
...
@@ -1913,33 +1593,42 @@ static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi)
* subsystem.
*/
static
int
sa1100fb_
clkchg_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
sa1100fb_
freq_transition
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
void
*
data
)
{
struct
sa1100fb_info
*
fbi
=
TO_INF
(
nb
,
clockchg
);
struct
cpufreq_
minmax
*
mm
=
data
;
struct
sa1100fb_info
*
fbi
=
TO_INF
(
nb
,
freq_transition
);
struct
cpufreq_
freqs
*
f
=
data
;
u_int
pcd
;
switch
(
val
)
{
case
CPUFREQ_MINMAX
:
printk
(
KERN_DEBUG
"min dma period: %d ps, old clock %d kHz, "
"new clock %d kHz
\n
"
,
sa1100fb_min_dma_period
(
fbi
),
mm
->
cur_freq
,
mm
->
new_freq
);
/* todo: fill in min/max values */
break
;
case
CPUFREQ_PRECHANGE
:
set_ctrlr_state
(
fbi
,
C_DISABLE_CLKCHANGE
);
break
;
case
CPUFREQ_POSTCHANGE
:
pcd
=
get_pcd
(
fbi
->
fb
.
var
.
pixclock
);
pcd
=
get_pcd
(
fbi
->
fb
.
var
.
pixclock
,
f
->
new
);
fbi
->
reg_lccr3
=
(
fbi
->
reg_lccr3
&
~
0xff
)
|
LCCR3_PixClkDiv
(
pcd
);
set_ctrlr_state
(
fbi
,
C_ENABLE_CLKCHANGE
);
break
;
}
return
0
;
}
static
int
sa1100fb_freq_policy
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
void
*
data
)
{
struct
sa1100fb_info
*
fbi
=
TO_INF
(
nb
,
freq_policy
);
struct
cpufreq_policy
*
policy
=
data
;
if
(
val
==
CPUFREQ_INCOMPATIBLE
)
{
printk
(
KERN_DEBUG
"min dma period: %d ps, "
"new clock %d kHz
\n
"
,
sa1100fb_min_dma_period
(
fbi
),
policy
->
max
);
/* todo: fill in min/max values */
}
return
0
;
}
#endif
#ifdef CONFIG_PM
...
...
@@ -2015,8 +1704,6 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void)
memset
(
fbi
,
0
,
sizeof
(
struct
sa1100fb_info
)
+
sizeof
(
struct
display
));
fbi
->
fb
.
currcon
=
-
1
;
strcpy
(
fbi
->
fb
.
fix
.
id
,
SA1100_NAME
);
fbi
->
fb
.
fix
.
type
=
FB_TYPE_PACKED_PIXELS
;
...
...
@@ -2024,6 +1711,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void)
fbi
->
fb
.
fix
.
xpanstep
=
0
;
fbi
->
fb
.
fix
.
ypanstep
=
0
;
fbi
->
fb
.
fix
.
ywrapstep
=
0
;
fbi
->
fb
.
fix
.
line_length
=
0
;
fbi
->
fb
.
fix
.
accel
=
FB_ACCEL_NONE
;
fbi
->
fb
.
var
.
nonstd
=
0
;
...
...
@@ -2038,7 +1726,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void)
fbi
->
fb
.
fbops
=
&
sa1100fb_ops
;
fbi
->
fb
.
changevar
=
NULL
;
fbi
->
fb
.
switch_con
=
sa1100fb
_switch
;
fbi
->
fb
.
switch_con
=
gen
_switch
;
fbi
->
fb
.
updatevar
=
sa1100fb_updatevar
;
fbi
->
fb
.
flags
=
FBINFO_FLAG_DEFAULT
;
fbi
->
fb
.
node
=
NODEV
;
...
...
@@ -2052,6 +1740,16 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void)
inf
=
sa1100fb_get_machine_info
(
fbi
);
/*
* People just don't seem to get this. We don't support
* anything but correct entries now, so panic if someone
* does something stupid.
*/
if
(
inf
->
lccr3
&
(
LCCR3_VrtSnchL
|
LCCR3_HorSnchL
|
0xff
)
||
inf
->
pixclock
==
0
)
panic
(
"sa1100fb error: invalid LCCR3 fields set or zero "
"pixclock."
);
fbi
->
max_xres
=
inf
->
xres
;
fbi
->
fb
.
var
.
xres
=
inf
->
xres
;
fbi
->
fb
.
var
.
xres_virtual
=
inf
->
xres
;
...
...
@@ -2077,6 +1775,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void)
fbi
->
task_state
=
(
u_char
)
-
1
;
fbi
->
fb
.
fix
.
smem_len
=
fbi
->
max_xres
*
fbi
->
max_yres
*
fbi
->
max_bpp
/
8
;
fbi
->
fb
.
disp
->
inverse
=
inf
->
cmap_inverse
;
init_waitqueue_head
(
&
fbi
->
ctrlr_wait
);
INIT_TQUEUE
(
&
fbi
->
task
,
sa1100fb_task
,
fbi
);
...
...
@@ -2116,7 +1815,7 @@ int __init sa1100fb_init(void)
#endif
#ifdef CONFIG_SA1100_FREEBIRD
#error Please move this into
sa1100fb_power_up_lcd
#error Please move this into
__sa1100fb_lcd_power
if
(
machine_is_freebird
())
{
BCR_set
(
BCR_FREEBIRD_LCD_DISP
);
mdelay
(
20
);
...
...
@@ -2141,8 +1840,10 @@ int __init sa1100fb_init(void)
fbi
->
pm
->
data
=
fbi
;
#endif
#ifdef CONFIG_CPU_FREQ
fbi
->
clockchg
.
notifier_call
=
sa1100fb_clkchg_notifier
;
cpufreq_register_notifier
(
&
fbi
->
clockchg
);
fbi
->
freq_transition
.
notifier_call
=
sa1100fb_freq_transition
;
fbi
->
freq_policy
.
notifier_call
=
sa1100fb_freq_policy
;
cpufreq_register_notifier
(
&
fbi
->
freq_transition
,
CPUFREQ_TRANSITION_NOTIFIER
);
cpufreq_register_notifier
(
&
fbi
->
freq_policy
,
CPUFREQ_POLICY_NOTIFIER
);
#endif
/*
...
...
drivers/video/sa1100fb.h
View file @
2fbc109c
...
...
@@ -107,7 +107,8 @@ struct sa1100fb_info {
struct
pm_dev
*
pm
;
#endif
#ifdef CONFIG_CPU_FREQ
struct
notifier_block
clockchg
;
struct
notifier_block
freq_transition
;
struct
notifier_block
freq_policy
;
#endif
};
...
...
include/asm-arm/arch-sa1100/h3600.h
View file @
2fbc109c
...
...
@@ -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_ */
include/asm-arm/arch-sa1100/irqs.h
View file @
2fbc109c
...
...
@@ -108,18 +108,18 @@
#define AUDDTS (IRQ_BOARD_END + 40)
#define AUDRDD (IRQ_BOARD_END + 41)
#define AUDSTO (IRQ_BOARD_END + 42)
#define
USBPWR
(IRQ_BOARD_END + 43)
#define
NIRQ
HCIM (IRQ_BOARD_END + 44)
#define IRQHCIBUFFACC (IRQ_BOARD_END + 45)
#define IRQHCIRMTWKP (IRQ_BOARD_END + 46)
#define NHCIMFCIR (IRQ_BOARD_END + 47)
#define
USB_PORT_RESUME
(IRQ_BOARD_END + 48)
#define
S0_READY_NINT
(IRQ_BOARD_END + 49)
#define
S1_READY_NINT
(IRQ_BOARD_END + 50)
#define S0_CD_VALID (IRQ_BOARD_END + 51)
#define S1_CD_VALID (IRQ_BOARD_END + 52)
#define
S0_BVD1_STSCHG
(IRQ_BOARD_END + 53)
#define
S1_BVD1_STSCHG
(IRQ_BOARD_END + 54)
#define
IRQ_USBPWR
(IRQ_BOARD_END + 43)
#define
IRQ_N
HCIM (IRQ_BOARD_END + 44)
#define IRQ
_
HCIBUFFACC (IRQ_BOARD_END + 45)
#define IRQ
_
HCIRMTWKP (IRQ_BOARD_END + 46)
#define
IRQ_
NHCIMFCIR (IRQ_BOARD_END + 47)
#define
IRQ_USB_PORT_RESUME
(IRQ_BOARD_END + 48)
#define
IRQ_S0_READY_NINT
(IRQ_BOARD_END + 49)
#define
IRQ_S1_READY_NINT
(IRQ_BOARD_END + 50)
#define
IRQ_
S0_CD_VALID (IRQ_BOARD_END + 51)
#define
IRQ_
S1_CD_VALID (IRQ_BOARD_END + 52)
#define
IRQ_S0_BVD1_STSCHG
(IRQ_BOARD_END + 53)
#define
IRQ_S1_BVD1_STSCHG
(IRQ_BOARD_END + 54)
/*
* Figure out the MAX IRQ number.
...
...
@@ -129,7 +129,7 @@
* Otherwise, we have the standard IRQs only.
*/
#ifdef CONFIG_SA1111
#define NR_IRQS (S1_BVD1_STSCHG + 1)
#define NR_IRQS (
IRQ_
S1_BVD1_STSCHG + 1)
#elif defined(CONFIG_SA1100_GRAPHICSCLIENT) || \
defined(CONFIG_SA1100_GRAPHICSMASTER) || \
defined(CONFIG_SA1100_H3800)
...
...
include/asm-arm/hardware/sa1111.h
View file @
2fbc109c
...
...
@@ -64,18 +64,10 @@
#define SA1111_SMCR 0x0004
#define SA1111_SKID 0x0008
#define _SBI_SKCR _SA1111(SA1111_SKCR)
#define _SBI_SMCR _SA1111(SA1111_SMCR)
#define _SBI_SKID _SA1111(SA1111_SKID)
#if LANGUAGE == C
#define SBI_SKCR __CCREG(SA1111_SKCR)
#define SBI_SMCR __CCREG(SA1111_SMCR)
#define SBI_SKID __CCREG(SA1111_SKID)
#endif
/* LANGUAGE == C */
#define SKCR_PLL_BYPASS (1<<0)
#define SKCR_RCLKEN (1<<1)
#define SKCR_SLEEP (1<<2)
...
...
@@ -135,22 +127,10 @@
#define SA1111_SKPMC 0x020c
#define SA1111_SKPTC 0x0210
#define SA1111_SKPEN0 0x0214
#define SA1111_SKPW
N
0 0x0218
#define SA1111_SKPW
M
0 0x0218
#define SA1111_SKPEN1 0x021c
#define SA1111_SKPWM1 0x0220
#define _SKPCR _SA1111(SA1111_SKPCR)
#define _SKCDR _SA1111(SA1111_SKCDR)
#define _SKAUD _SA1111(SA1111_SKAUD)
#define _SKPMC _SA1111(SA1111_SKPMC)
#define _SKPTC _SA1111(SA1111_SKPTC)
#define _SKPEN0 _SA1111(SA1111_SKPEN0)
#define _SKPWM0 _SA1111(SA1111_SKPWM0)
#define _SKPEN1 _SA1111(SA1111_SKPEN1)
#define _SKPWM1 _SA1111(SA1111_SKPWM1)
#if LANGUAGE == C
#define SKPCR __CCREG(SA1111_SKPCR)
#define SKCDR __CCREG(SA1111_SKCDR)
#define SKAUD __CCREG(SA1111_SKAUD)
...
...
@@ -161,8 +141,6 @@
#define SKPEN1 __CCREG(SA1111_SKPEN1)
#define SKPWM1 __CCREG(SA1111_SKPWM1)
#endif
/* LANGUAGE == C */
#define SKPCR_UCLKEN (1<<0)
#define SKPCR_ACCLKEN (1<<1)
#define SKPCR_I2SCLKEN (1<<2)
...
...
@@ -176,21 +154,14 @@
/*
* USB Host controller
*/
#define _USB_OHCI_OP_BASE _SA1111( 0x400 )
#define _USB_STATUS _SA1111( 0x518 )
#define _USB_RESET _SA1111( 0x51c )
#define _USB_INTERRUPTEST _SA1111( 0x520 )
#define _USB_EXTENT (_USB_INTERRUPTEST - _USB_OHCI_OP_BASE + 4)
#if LANGUAGE == C
#define USB_OHCI_OP_BASE __CCREG(0x0400)
#define USB_STATUS __CCREG(0x0518)
#define USB_RESET __CCREG(0x051c)
#define USB_INTERRUPTEST __CCReG(0x0520)
#define SA1111_USB 0x0400
#endif
/* LANGUAGE == C */
/*
* Offsets from SA1111_USB_BASE
*/
#define SA1111_USB_STATUS 0x0118
#define SA1111_USB_RESET 0x011c
#define SA1111_USB_IRQTEST 0x0120
#define USB_RESET_FORCEIFRESET (1 << 0)
#define USB_RESET_FORCEHCRESET (1 << 1)
...
...
@@ -451,82 +422,56 @@
* WAKE_POL0 Wake-up polarity selection 0
* WAKE_POL1 Wake-up polarity selection 1
*/
#define SA1111_INTC 0x1600
#define SA1111_INTTEST0 0x1600
#define SA1111_INTTEST1 0x1604
#define SA1111_INTEN0 0x1608
#define SA1111_INTEN1 0x160c
#define SA1111_INTPOL0 0x1610
#define SA1111_INTPOL1 0x1614
#define SA1111_INTTSTSEL 0x1618
#define SA1111_INTSTATCLR0 0x161c
#define SA1111_INTSTATCLR1 0x1620
#define SA1111_INTSET0 0x1624
#define SA1111_INTSET1 0x1628
#define SA1111_WAKE_EN0 0x162c
#define SA1111_WAKE_EN1 0x1630
#define SA1111_WAKE_POL0 0x1634
#define SA1111_WAKE_POL1 0x1638
#define _INTTEST0 _SA1111(SA1111_INTTEST0)
#define _INTTEST1 _SA1111(SA1111_INTTEST1)
#define _INTEN0 _SA1111(SA1111_INTEN0)
#define _INTEN1 _SA1111(SA1111_INTEN1)
#define _INTPOL0 _SA1111(SA1111_INTPOL0)
#define _INTPOL1 _SA1111(SA1111_INTPOL1)
#define _INTTSTSEL _SA1111(SA1111_INTTSTSEL)
#define _INTSTATCLR0 _SA1111(SA1111_INTSTATCLR0)
#define _INTSTATCLR1 _SA1111(SA1111_INTSTATCLR1)
#define _INTSET0 _SA1111(SA1111_INTSET0)
#define _INTSET1 _SA1111(SA1111_INTSET1)
#define _WAKE_EN0 _SA1111(SA1111_WAKE_EN0)
#define _WAKE_EN1 _SA1111(SA1111_WAKE_EN1)
#define _WAKE_POL0 _SA1111(SA1111_WAKE_POL0)
#define _WAKE_POL1 _SA1111(SA1111_WAKE_POL1)
#if LANGUAGE == C
#define INTTEST0 __CCREG(SA1111_INTTEST0)
#define INTTEST1 __CCREG(SA1111_INTTEST1)
#define INTEN0 __CCREG(SA1111_INTEN0)
#define INTEN1 __CCREG(SA1111_INTEN1)
#define INTPOL0 __CCREG(SA1111_INTPOL0)
#define INTPOL1 __CCREG(SA1111_INTPOL1)
#define INTTSTSEL __CCREG(SA1111_INTTSTSEL)
#define INTSTATCLR0 __CCREG(SA1111_INTSTATCLR0)
#define INTSTATCLR1 __CCREG(SA1111_INTSTATCLR1)
#define INTSET0 __CCREG(SA1111_INTSET0)
#define INTSET1 __CCREG(SA1111_INTSET1)
#define WAKE_EN0 __CCREG(SA1111_WAKE_EN0)
#define WAKE_EN1 __CCREG(SA1111_WAKE_EN1)
#define WAKE_POL0 __CCREG(SA1111_WAKE_POL0)
#define WAKE_POL1 __CCREG(SA1111_WAKE_POL1)
#endif
/* LANGUAGE == C */
/*
* These are offsets from the above base.
*/
#define SA1111_INTTEST0 0x0000
#define SA1111_INTTEST1 0x0004
#define SA1111_INTEN0 0x0008
#define SA1111_INTEN1 0x000c
#define SA1111_INTPOL0 0x0010
#define SA1111_INTPOL1 0x0014
#define SA1111_INTTSTSEL 0x0018
#define SA1111_INTSTATCLR0 0x001c
#define SA1111_INTSTATCLR1 0x0020
#define SA1111_INTSET0 0x0024
#define SA1111_INTSET1 0x0028
#define SA1111_WAKEEN0 0x002c
#define SA1111_WAKEEN1 0x0030
#define SA1111_WAKEPOL0 0x0034
#define SA1111_WAKEPOL1 0x0038
#define INTTEST0 __CCREG(SA1111_INTC + SA1111_INTTEST0)
#define INTTEST1 __CCREG(SA1111_INTC + SA1111_INTTEST1)
#define INTEN0 __CCREG(SA1111_INTC + SA1111_INTEN0)
#define INTEN1 __CCREG(SA1111_INTC + SA1111_INTEN1)
#define INTPOL0 __CCREG(SA1111_INTC + SA1111_INTPOL0)
#define INTPOL1 __CCREG(SA1111_INTC + SA1111_INTPOL1)
#define INTTSTSEL __CCREG(SA1111_INTC + SA1111_INTTSTSEL)
#define INTSTATCLR0 __CCREG(SA1111_INTC + SA1111_INTSTATCLR0)
#define INTSTATCLR1 __CCREG(SA1111_INTC + SA1111_INTSTATCLR1)
#define INTSET0 __CCREG(SA1111_INTC + SA1111_INTSET0)
#define INTSET1 __CCREG(SA1111_INTC + SA1111_INTSET1)
#define WAKE_EN0 __CCREG(SA1111_INTC + SA1111_WAKEEN0)
#define WAKE_EN1 __CCREG(SA1111_INTC + SA1111_WAKEEN1)
#define WAKE_POL0 __CCREG(SA1111_INTC + SA1111_WAKEPOL0)
#define WAKE_POL1 __CCREG(SA1111_INTC + SA1111_WAKEPOL1)
/*
* PS/2 Trackpad and Mouse Interfaces
*
* Registers (prefix kbd applies to trackpad interface, mse to mouse)
* KBDCR Control Register
* KBDSTAT Status Register
* KBDDATA Transmit/Receive Data register
* KBDCLKDIV Clock Division Register
* KBDPRECNT Clock Precount Register
* KBDTEST1 Test register 1
* KBDTEST2 Test register 2
* KBDTEST3 Test register 3
* KBDTEST4 Test register 4
* MSECR
* MSESTAT
* MSEDATA
* MSECLKDIV
* MSEPRECNT
* MSETEST1
* MSETEST2
* MSETEST3
* MSETEST4
*
* Registers
* PS2CR Control Register
* PS2STAT Status Register
* PS2DATA Transmit/Receive Data register
* PS2CLKDIV Clock Division Register
* PS2PRECNT Clock Precount Register
* PS2TEST1 Test register 1
* PS2TEST2 Test register 2
* PS2TEST3 Test register 3
* PS2TEST4 Test register 4
*/
#define SA1111_KBD 0x0a00
...
...
@@ -564,17 +509,14 @@
* PCSSR Sleep State Register
*/
#define _PCCR _SA1111( 0x1800 )
#define _PCSSR _SA1111( 0x1804 )
#define _PCSR _SA1111( 0x1808 )
#if LANGUAGE == C
#define PCCR __CCREG(0x1800)
#define PCSSR __CCREG(0x1804)
#define PCSR __CCREG(0x1808)
#define SA1111_PCMCIA 0x1600
#endif
/* LANGUAGE == C */
/*
* These are offsets from the above base.
*/
#define SA1111_PCCR 0x0000
#define SA1111_PCSSR 0x0004
#define SA1111_PCSR 0x0008
#define PCSR_S0_READY (1<<0)
#define PCSR_S1_READY (1<<1)
...
...
@@ -603,21 +545,61 @@
#define PCSSR_S0_SLEEP (1<<0)
#define PCSSR_S1_SLEEP (1<<1)
struct
sa1111_device
{
extern
struct
bus_type
sa1111_bus_type
;
#define SA1111_DEVID_SBI 0
#define SA1111_DEVID_SK 1
#define SA1111_DEVID_USB 2
#define SA1111_DEVID_SAC 3
#define SA1111_DEVID_SSP 4
#define SA1111_DEVID_PS2 5
#define SA1111_DEVID_GPIO 6
#define SA1111_DEVID_INT 7
#define SA1111_DEVID_PCMCIA 8
struct
sa1111_dev
{
struct
device
dev
;
struct
resource
resource
;
void
*
base
;
unsigned
int
devid
;
struct
resource
res
;
void
*
mapbase
;
unsigned
int
skpcr_mask
;
unsigned
int
irq
[
6
];
};
extern
struct
sa1111_device
*
sa1111
;
#define SA1111_DEV(_d) container_of((_d), struct sa1111_dev, dev)
int
sa1111_check_dma_bug
(
dma_addr_t
addr
);
struct
sa1111_driver
{
struct
device_driver
drv
;
unsigned
int
devid
;
};
#define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv)
#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
/*
* Probe for a SA1111 chip.
*/
extern
int
sa1111_init
(
unsigned
long
phys
,
unsigned
int
irq
);
/*
* These frob the SKPCR register.
*/
void
sa1111_enable_device
(
unsigned
int
mask
);
void
sa1111_disable_device
(
unsigned
int
mask
);
void
sa1111_enable_device
(
struct
sa1111_dev
*
);
void
sa1111_disable_device
(
struct
sa1111_dev
*
);
unsigned
int
sa1111_pll_clock
(
struct
sa1111_dev
*
);
#define SA1111_AUDIO_ACLINK 0
#define SA1111_AUDIO_I2S 1
void
sa1111_select_audio_mode
(
struct
sa1111_dev
*
sadev
,
int
mode
);
int
sa1111_set_audio_rate
(
struct
sa1111_dev
*
sadev
,
int
rate
);
int
sa1111_get_audio_rate
(
struct
sa1111_dev
*
sadev
);
int
sa1111_check_dma_bug
(
dma_addr_t
addr
);
#endif
/* _ASM_ARCH_SA1111 */
include/asm-arm/pci.h
View file @
2fbc109c
...
...
@@ -27,15 +27,11 @@ void sa1111_dma_sync_sg(struct pci_dev *, struct scatterlist *, int, int);
#ifdef CONFIG_SA1111
#define SA1111_FAKE_PCIDEV ((struct pci_dev *) 1111)
static
inline
int
dev_is_sa1111
(
const
struct
pci_dev
*
dev
)
{
return
(
dev
==
SA1111_FAKE_PCIDEV
);
}
#define dev_is_sa1111(dev) (dev == SA1111_FAKE_PCIDEV)
#else
static
inline
int
dev_is_sa1111
(
const
struct
pci_dev
*
dev
)
{
return
0
;
}
#define dev_is_sa1111(dev) (0)
#endif
...
...
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