Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (49 commits)
  [ARM] idle: clean up pm_idle calling, obey hlt_counter
  [ARM] S3C: Fix gpio-config off-by-one bug
  [ARM] S3C64XX: add to_irq() support for EINT() GPIO
  [ARM] S3C64XX: clock.c: fix typo in usb-host clock ctrlbit
  [ARM] S3C64XX: fix HCLK gate defines
  [ARM] Update mach-types
  [ARM] wire up rt_tgsigqueueinfo and perf_counter_open
  OMAP2 clock/powerdomain: off by 1 error in loop timeout comparisons
  OMAP3 SDRC: set FIXEDDELAY when disabling SDRC DLL
  OMAP3: Add support for DPLL3 divisor values higher than 2
  OMAP3 SRAM: convert SRAM code to use macros rather than magic numbers
  OMAP3 SRAM: add more comments on the SRAM code
  OMAP3 clock/SDRC: program SDRC_MR register during SDRC clock change
  OMAP3 clock: add a short delay when lowering CORE clk rate
  OMAP3 clock: initialize SDRC timings at kernel start
  OMAP3 clock: remove wait for DPLL3 M2 clock to stabilize
  [ARM] Add old Feroceon support to compressed/head.S
  [ARM] 5559/1: Limit the stack unwinding caused by a kthread exit
  [ARM] 5558/1: Add extra checks to ARM unwinder to avoid tracing corrupt stacks
  [ARM] 5557/1: Discard some ARM.ex*.*exit.text sections when !HOTPLUG or !HOTPLUG_CPU
  ...
This commit is contained in:
Linus Torvalds 2009-06-22 14:56:13 -07:00
commit 9e268beb92
57 changed files with 5268 additions and 221 deletions

View file

@ -1369,6 +1369,27 @@ and is between 256 and 4096 characters. It is defined in the file
min_addr=nn[KMG] [KNL,BOOT,ia64] All physical memory below this
physical address is ignored.
mini2440= [ARM,HW,KNL]
Format:[0..2][b][c][t]
Default: "0tb"
MINI2440 configuration specification:
0 - The attached screen is the 3.5" TFT
1 - The attached screen is the 7" TFT
2 - The VGA Shield is attached (1024x768)
Leaving out the screen size parameter will not load
the TFT driver, and the framebuffer will be left
unconfigured.
b - Enable backlight. The TFT backlight pin will be
linked to the kernel VESA blanking code and a GPIO
LED. This parameter is not necessary when using the
VGA shield.
c - Enable the s3c camera interface.
t - Reserved for enabling touchscreen support. The
touchscreen support is not enabled in the mainstream
kernel as of 2.6.30, a preliminary port can be found
in the "bleeding edge" mini2440 support kernel at
http://repo.or.cz/w/linux-2.6/mini2440.git
mminit_loglevel=
[KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
parameter allows control of the logging verbosity for

View file

@ -653,6 +653,8 @@ M: laforge@openezx.org
L: openezx-devel@lists.openezx.org (subscribers-only)
W: http://www.openezx.org/
S: Maintained
T: topgit git://git.openezx.org/openezx.git
F: arch/arm/mach-pxa/ezx.c
ARM/FARADAY FA526 PORT
P: Paulius Zaleckas
@ -774,11 +776,25 @@ P: Philipp Zabel
M: philipp.zabel@gmail.com
S: Maintained
ARM/MIOA701 MACHINE SUPPORT
P: Robert Jarzmik
M: robert.jarzmik@free.fr
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
F: arch/arm/mach-pxa/mioa701.c
S: Maintained
ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT
P: Michael Petchkovsky
M: mkpetch@internode.on.net
S: Maintained
ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
P: Nelson Castillo
M: arhuaco@freaks-unidos.net
L: openmoko-kernel@lists.openmoko.org (subscribers-only)
W: http://wiki.openmoko.org/wiki/Neo_FreeRunner
S: Supported
ARM/TOSA MACHINE SUPPORT
P: Dmitry Eremin-Solenikov
M: dbaryshkov@gmail.com
@ -792,6 +808,12 @@ M: marek.vasut@gmail.com
W: http://hackndev.com
S: Maintained
ARM/PALM TREO 680 SUPPORT
P: Tomas Cech
M: sleep_walker@suse.cz
W: http://hackndev.com
S: Maintained
ARM/PALMZ72 SUPPORT
P: Sergey Lapin
M: slapin@ossfans.org

View file

@ -1241,7 +1241,7 @@ endmenu
menu "CPU Power Management"
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_PXA)
if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_PXA || ARCH_S3C64XX)
source "drivers/cpufreq/Kconfig"
@ -1272,6 +1272,10 @@ config CPU_FREQ_PXA
default y
select CPU_FREQ_DEFAULT_GOV_USERSPACE
config CPU_FREQ_S3C64XX
bool "CPUfreq support for Samsung S3C64XX CPUs"
depends on CPU_FREQ && CPU_S3C6410
endif
source "drivers/cpuidle/Kconfig"

View file

@ -674,6 +674,15 @@ proc_types:
b __armv4_mmu_cache_off
b __armv5tej_mmu_cache_flush
#ifdef CONFIG_CPU_FEROCEON_OLD_ID
/* this conflicts with the standard ARMv5TE entry */
.long 0x41009260 @ Old Feroceon
.long 0xff00fff0
b __armv4_mmu_cache_on
b __armv4_mmu_cache_off
b __armv5tej_mmu_cache_flush
#endif
.word 0x66015261 @ FA526
.word 0xff01fff1
b __fa526_cache_on

View file

@ -117,7 +117,7 @@ static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
u32 val;
spin_lock(&irq_controller_lock);
irq_desc[irq].cpu = cpu;
irq_desc[irq].node = cpu;
val = readl(reg) & ~(0xff << shift);
val |= 1 << (cpu + shift);
writel(val, reg);

View file

@ -229,14 +229,18 @@ static int vic_set_wake(unsigned int irq, unsigned int on)
{
struct vic_device *v = vic_from_irq(irq);
unsigned int off = irq & 31;
u32 bit = 1 << off;
if (!v)
return -EINVAL;
if (!(bit & v->resume_sources))
return -EINVAL;
if (on)
v->resume_irqs |= 1 << off;
v->resume_irqs |= bit;
else
v->resume_irqs &= ~(1 << off);
v->resume_irqs &= ~bit;
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -389,6 +389,8 @@
#define __NR_inotify_init1 (__NR_SYSCALL_BASE+360)
#define __NR_preadv (__NR_SYSCALL_BASE+361)
#define __NR_pwritev (__NR_SYSCALL_BASE+362)
#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363)
#define __NR_perf_counter_open (__NR_SYSCALL_BASE+364)
/*
* The following SWIs are ARM private.

View file

@ -372,6 +372,8 @@
/* 360 */ CALL(sys_inotify_init1)
CALL(sys_preadv)
CALL(sys_pwritev)
CALL(sys_rt_tgsigqueueinfo)
CALL(sys_perf_counter_open)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted

View file

@ -167,7 +167,7 @@ void __init init_IRQ(void)
#ifdef CONFIG_SMP
cpumask_setall(bad_irq_desc.affinity);
bad_irq_desc.cpu = smp_processor_id();
bad_irq_desc.node = smp_processor_id();
#endif
init_arch_irq();
}
@ -176,7 +176,7 @@ void __init init_IRQ(void)
static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
{
pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->cpu, cpu);
pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->node, cpu);
spin_lock_irq(&desc->lock);
desc->chip->set_affinity(irq, cpumask_of(cpu));
@ -195,7 +195,7 @@ void migrate_irqs(void)
for (i = 0; i < NR_IRQS; i++) {
struct irq_desc *desc = irq_desc + i;
if (desc->cpu == cpu) {
if (desc->node == cpu) {
unsigned int newcpu = cpumask_any_and(desc->affinity,
cpu_online_mask);
if (newcpu >= nr_cpu_ids) {

View file

@ -114,9 +114,6 @@ void arm_machine_restart(char mode, const char *cmd)
/*
* Function pointers to optional machine specific functions
*/
void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
@ -130,20 +127,19 @@ EXPORT_SYMBOL_GPL(arm_pm_restart);
*/
static void default_idle(void)
{
if (hlt_counter)
cpu_relax();
else {
local_irq_disable();
if (!need_resched())
arch_idle();
local_irq_enable();
}
if (!need_resched())
arch_idle();
local_irq_enable();
}
void (*pm_idle)(void) = default_idle;
EXPORT_SYMBOL(pm_idle);
/*
* The idle thread. We try to conserve power, while trying to keep
* overall latency low. The architecture specific idle is passed
* a value to indicate the level of "idleness" of the system.
* The idle thread, has rather strange semantics for calling pm_idle,
* but this is what x86 does and we need to do the same, so that
* things like cpuidle get called in the same way. The only difference
* is that we always respect 'hlt_counter' to prevent low power idle.
*/
void cpu_idle(void)
{
@ -151,21 +147,31 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
while (1) {
void (*idle)(void) = pm_idle;
tick_nohz_stop_sched_tick(1);
leds_event(led_idle_start);
while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id())) {
leds_event(led_idle_start);
cpu_die();
}
if (cpu_is_offline(smp_processor_id()))
cpu_die();
#endif
if (!idle)
idle = default_idle;
leds_event(led_idle_start);
tick_nohz_stop_sched_tick(1);
while (!need_resched())
idle();
local_irq_disable();
if (hlt_counter) {
local_irq_enable();
cpu_relax();
} else {
stop_critical_timings();
pm_idle();
start_critical_timings();
/*
* This will eventually be removed - pm_idle
* functions should always return with IRQs
* enabled.
*/
WARN_ON(irqs_disabled());
local_irq_enable();
}
}
leds_event(led_idle_end);
tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
@ -352,6 +358,23 @@ asm( ".section .text\n"
" .size kernel_thread_helper, . - kernel_thread_helper\n"
" .previous");
#ifdef CONFIG_ARM_UNWIND
extern void kernel_thread_exit(long code);
asm( ".section .text\n"
" .align\n"
" .type kernel_thread_exit, #function\n"
"kernel_thread_exit:\n"
" .fnstart\n"
" .cantunwind\n"
" bl do_exit\n"
" nop\n"
" .fnend\n"
" .size kernel_thread_exit, . - kernel_thread_exit\n"
" .previous");
#else
#define kernel_thread_exit do_exit
#endif
/*
* Create a kernel thread.
*/
@ -363,7 +386,7 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
regs.ARM_r1 = (unsigned long)arg;
regs.ARM_r2 = (unsigned long)fn;
regs.ARM_r3 = (unsigned long)do_exit;
regs.ARM_r3 = (unsigned long)kernel_thread_exit;
regs.ARM_pc = (unsigned long)kernel_thread_helper;
regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE;

View file

@ -212,7 +212,8 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
ctrl->vrs[14] = *vsp++;
ctrl->vrs[SP] = (unsigned long)vsp;
} else if (insn == 0xb0) {
ctrl->vrs[PC] = ctrl->vrs[LR];
if (ctrl->vrs[PC] == 0)
ctrl->vrs[PC] = ctrl->vrs[LR];
/* no further processing */
ctrl->entries = 0;
} else if (insn == 0xb1) {
@ -309,18 +310,20 @@ int unwind_frame(struct stackframe *frame)
}
while (ctrl.entries > 0) {
int urc;
if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
return -URC_FAILURE;
urc = unwind_exec_insn(&ctrl);
int urc = unwind_exec_insn(&ctrl);
if (urc < 0)
return urc;
if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
return -URC_FAILURE;
}
if (ctrl.vrs[PC] == 0)
ctrl.vrs[PC] = ctrl.vrs[LR];
/* check for infinite loop */
if (frame->pc == ctrl.vrs[PC])
return -URC_FAILURE;
frame->fp = ctrl.vrs[FP];
frame->sp = ctrl.vrs[SP];
frame->lr = ctrl.vrs[LR];
@ -332,7 +335,6 @@ int unwind_frame(struct stackframe *frame)
void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
struct stackframe frame;
unsigned long high, low;
register unsigned long current_sp asm ("sp");
pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
@ -362,9 +364,6 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
frame.pc = thread_saved_pc(tsk);
}
low = frame.sp & ~(THREAD_SIZE - 1);
high = low + THREAD_SIZE;
while (1) {
int urc;
unsigned long where = frame.pc;

View file

@ -84,6 +84,14 @@ SECTIONS
*(.exitcall.exit)
*(.ARM.exidx.exit.text)
*(.ARM.extab.exit.text)
#ifndef CONFIG_HOTPLUG_CPU
*(.ARM.exidx.cpuexit.text)
*(.ARM.extab.cpuexit.text)
#endif
#ifndef CONFIG_HOTPLUG
*(.ARM.exidx.devexit.text)
*(.ARM.extab.devexit.text)
#endif
#ifndef CONFIG_MMU
*(.fixup)
*(__ex_table)

View file

@ -302,7 +302,7 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
udelay(1);
}
if (i < MAX_CLOCK_ENABLE_WAIT)
if (i <= MAX_CLOCK_ENABLE_WAIT)
pr_debug("Clock %s stable after %d loops\n", name, i);
else
printk(KERN_ERR "Clock %s didn't enable in %d tries\n",

View file

@ -286,6 +286,20 @@ static struct omap_clk omap34xx_clks[] = {
#define MIN_SDRC_DLL_LOCK_FREQ 83000000
#define CYCLES_PER_MHZ 1000000
/* Scale factor for fixed-point arith in omap3_core_dpll_m2_set_rate() */
#define SDRC_MPURATE_SCALE 8
/* 2^SDRC_MPURATE_BASE_SHIFT: MPU MHz that SDRC_MPURATE_LOOPS is defined for */
#define SDRC_MPURATE_BASE_SHIFT 9
/*
* SDRC_MPURATE_LOOPS: Number of MPU loops to execute at
* 2^MPURATE_BASE_SHIFT MHz for SDRC to stabilize
*/
#define SDRC_MPURATE_LOOPS 96
/**
* omap3_dpll_recalc - recalculate DPLL rate
* @clk: DPLL struct clk
@ -709,7 +723,8 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
{
u32 new_div = 0;
u32 unlock_dll = 0;
unsigned long validrate, sdrcrate;
u32 c;
unsigned long validrate, sdrcrate, mpurate;
struct omap_sdrc_params *sp;
if (!clk || !rate)
@ -718,18 +733,15 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
if (clk != &dpll3_m2_ck)
return -EINVAL;
if (rate == clk->rate)
return 0;
validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
if (validrate != rate)
return -EINVAL;
sdrcrate = sdrc_ick.rate;
if (rate > clk->rate)
sdrcrate <<= ((rate / clk->rate) - 1);
sdrcrate <<= ((rate / clk->rate) >> 1);
else
sdrcrate >>= ((clk->rate / rate) - 1);
sdrcrate >>= ((clk->rate / rate) >> 1);
sp = omap2_sdrc_get_params(sdrcrate);
if (!sp)
@ -740,17 +752,25 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
unlock_dll = 1;
}
/*
* XXX This only needs to be done when the CPU frequency changes
*/
mpurate = arm_fck.rate / CYCLES_PER_MHZ;
c = (mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
c += 1; /* for safety */
c *= SDRC_MPURATE_LOOPS;
c >>= SDRC_MPURATE_SCALE;
if (c == 0)
c = 1;
pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
validrate);
pr_debug("clock: SDRC timing params used: %08x %08x %08x\n",
sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
/* REVISIT: SRAM code doesn't support other M2 divisors yet */
WARN_ON(new_div != 1 && new_div != 2);
/* REVISIT: Add SDRC_MR changing to this code also */
omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
sp->actim_ctrlb, new_div, unlock_dll);
sp->actim_ctrlb, new_div, unlock_dll, c,
sp->mr, rate > clk->rate);
return 0;
}

View file

@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <asm/tlb.h>
@ -241,6 +242,40 @@ void __init omap2_map_common_io(void)
omapfb_reserve_sdram();
}
/*
* omap2_init_reprogram_sdrc - reprogram SDRC timing parameters
*
* Sets the CORE DPLL3 M2 divider to the same value that it's at
* currently. This has the effect of setting the SDRC SDRAM AC timing
* registers to the values currently defined by the kernel. Currently
* only defined for OMAP3; will return 0 if called on OMAP2. Returns
* -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2,
* or passes along the return value of clk_set_rate().
*/
static int __init _omap2_init_reprogram_sdrc(void)
{
struct clk *dpll3_m2_ck;
int v = -EINVAL;
long rate;
if (!cpu_is_omap34xx())
return 0;
dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
if (!dpll3_m2_ck)
return -EINVAL;
rate = clk_get_rate(dpll3_m2_ck);
pr_info("Reprogramming SDRC clock to %ld Hz\n", rate);
v = clk_set_rate(dpll3_m2_ck, rate);
if (v)
pr_err("dpll3_m2_clk rate change failed: %d\n", v);
clk_put(dpll3_m2_ck);
return v;
}
void __init omap2_init_common_hw(struct omap_sdrc_params *sp)
{
omap2_mux_init();
@ -249,6 +284,7 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sp)
clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
omap2_clk_init();
omap2_sdrc_init(sp);
_omap2_init_reprogram_sdrc();
#endif
gpmc_init();
}

View file

@ -1099,7 +1099,7 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm)
(c++ < PWRDM_TRANSITION_BAILOUT))
udelay(1);
if (c >= PWRDM_TRANSITION_BAILOUT) {
if (c > PWRDM_TRANSITION_BAILOUT) {
printk(KERN_ERR "powerdomain: waited too long for "
"powerdomain %s to complete transition\n", pwrdm->name);
return -EAGAIN;

View file

@ -3,13 +3,12 @@
*
* Omap3 specific functions that need to be run in internal SRAM
*
* (C) Copyright 2007
* Texas Instruments Inc.
* Rajendra Nayak <rnayak@ti.com>
* Copyright (C) 2004, 2007, 2008 Texas Instruments, Inc.
* Copyright (C) 2008 Nokia Corporation
*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Rajendra Nayak <rnayak@ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
* Paul Walmsley
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -37,61 +36,112 @@
.text
/* r4 parameters */
#define SDRC_NO_UNLOCK_DLL 0x0
#define SDRC_UNLOCK_DLL 0x1
/* SDRC_DLLA_CTRL bit settings */
#define FIXEDDELAY_SHIFT 24
#define FIXEDDELAY_MASK (0xff << FIXEDDELAY_SHIFT)
#define DLLIDLE_MASK 0x4
/*
* Change frequency of core dpll
* r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2
* r4 = Unlock SDRC DLL? (1 = yes, 0 = no) -- only unlock DLL for
* SDRC_DLLA_CTRL default values: TI hardware team indicates that
* FIXEDDELAY should be initialized to 0xf. This apparently was
* empirically determined during process testing, so no derivation
* was provided.
*/
#define FIXEDDELAY_DEFAULT (0x0f << FIXEDDELAY_SHIFT)
/* SDRC_DLLA_STATUS bit settings */
#define LOCKSTATUS_MASK 0x4
/* SDRC_POWER bit settings */
#define SRFRONIDLEREQ_MASK 0x40
#define PWDENA_MASK 0x4
/* CM_IDLEST1_CORE bit settings */
#define ST_SDRC_MASK 0x2
/* CM_ICLKEN1_CORE bit settings */
#define EN_SDRC_MASK 0x2
/* CM_CLKSEL1_PLL bit settings */
#define CORE_DPLL_CLKOUT_DIV_SHIFT 0x1b
/*
* omap3_sram_configure_core_dpll - change DPLL3 M2 divider
* r0 = new SDRC_RFR_CTRL register contents
* r1 = new SDRC_ACTIM_CTRLA register contents
* r2 = new SDRC_ACTIM_CTRLB register contents
* r3 = new M2 divider setting (only 1 and 2 supported right now)
* r4 = unlock SDRC DLL? (1 = yes, 0 = no). Only unlock DLL for
* SDRC rates < 83MHz
* r5 = number of MPU cycles to wait for SDRC to stabilize after
* reprogramming the SDRC when switching to a slower MPU speed
* r6 = new SDRC_MR_0 register value
* r7 = increasing SDRC rate? (1 = yes, 0 = no)
*
*/
ENTRY(omap3_sram_configure_core_dpll)
stmfd sp!, {r1-r12, lr} @ store regs to stack
ldr r4, [sp, #52] @ pull extra args off the stack
ldr r5, [sp, #56] @ load extra args from the stack
ldr r6, [sp, #60] @ load extra args from the stack
ldr r7, [sp, #64] @ load extra args from the stack
dsb @ flush buffered writes to interconnect
cmp r3, #0x2
blne configure_sdrc
cmp r4, #0x1
cmp r7, #1 @ if increasing SDRC clk rate,
bleq configure_sdrc @ program the SDRC regs early (for RFR)
cmp r4, #SDRC_UNLOCK_DLL @ set the intended DLL state
bleq unlock_dll
blne lock_dll
bl sdram_in_selfrefresh @ put the SDRAM in self refresh
bl configure_core_dpll
bl enable_sdrc
cmp r4, #0x1
bl sdram_in_selfrefresh @ put SDRAM in self refresh, idle SDRC
bl configure_core_dpll @ change the DPLL3 M2 divider
bl enable_sdrc @ take SDRC out of idle
cmp r4, #SDRC_UNLOCK_DLL @ wait for DLL status to change
bleq wait_dll_unlock
blne wait_dll_lock
cmp r3, #0x1
blne configure_sdrc
cmp r7, #1 @ if increasing SDRC clk rate,
beq return_to_sdram @ return to SDRAM code, otherwise,
bl configure_sdrc @ reprogram SDRC regs now
mov r12, r5
bl wait_clk_stable @ wait for SDRC to stabilize
return_to_sdram:
isb @ prevent speculative exec past here
mov r0, #0 @ return value
ldmfd sp!, {r1-r12, pc} @ restore regs and return
unlock_dll:
ldr r11, omap3_sdrc_dlla_ctrl
ldr r12, [r11]
orr r12, r12, #0x4
and r12, r12, #FIXEDDELAY_MASK
orr r12, r12, #FIXEDDELAY_DEFAULT
orr r12, r12, #DLLIDLE_MASK
str r12, [r11] @ (no OCP barrier needed)
bx lr
lock_dll:
ldr r11, omap3_sdrc_dlla_ctrl
ldr r12, [r11]
bic r12, r12, #0x4
bic r12, r12, #DLLIDLE_MASK
str r12, [r11] @ (no OCP barrier needed)
bx lr
sdram_in_selfrefresh:
ldr r11, omap3_sdrc_power @ read the SDRC_POWER register
ldr r12, [r11] @ read the contents of SDRC_POWER
mov r9, r12 @ keep a copy of SDRC_POWER bits
orr r12, r12, #0x40 @ enable self refresh on idle req
bic r12, r12, #0x4 @ clear PWDENA
orr r12, r12, #SRFRONIDLEREQ_MASK @ enable self refresh on idle
bic r12, r12, #PWDENA_MASK @ clear PWDENA
str r12, [r11] @ write back to SDRC_POWER register
ldr r12, [r11] @ posted-write barrier for SDRC
idle_sdrc:
ldr r11, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg
ldr r12, [r11]
bic r12, r12, #0x2 @ disable iclk bit for SDRC
bic r12, r12, #EN_SDRC_MASK @ disable iclk bit for SDRC
str r12, [r11]
wait_sdrc_idle:
ldr r11, omap3_cm_idlest1_core
ldr r12, [r11]
and r12, r12, #0x2 @ check for SDRC idle
cmp r12, #2
and r12, r12, #ST_SDRC_MASK @ check for SDRC idle
cmp r12, #ST_SDRC_MASK
bne wait_sdrc_idle
bx lr
configure_core_dpll:
@ -99,36 +149,23 @@ configure_core_dpll:
ldr r12, [r11]
ldr r10, core_m2_mask_val @ modify m2 for core dpll
and r12, r12, r10
orr r12, r12, r3, lsl #0x1B @ r3 contains the M2 val
orr r12, r12, r3, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT
str r12, [r11]
ldr r12, [r11] @ posted-write barrier for CM
mov r12, #0x800 @ wait for the clock to stabilise
cmp r3, #2
bne wait_clk_stable
bx lr
wait_clk_stable:
subs r12, r12, #1
bne wait_clk_stable
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
bx lr
enable_sdrc:
ldr r11, omap3_cm_iclken1_core
ldr r12, [r11]
orr r12, r12, #0x2 @ enable iclk bit for SDRC
orr r12, r12, #EN_SDRC_MASK @ enable iclk bit for SDRC
str r12, [r11]
wait_sdrc_idle1:
ldr r11, omap3_cm_idlest1_core
ldr r12, [r11]
and r12, r12, #0x2
and r12, r12, #ST_SDRC_MASK
cmp r12, #0
bne wait_sdrc_idle1
restore_sdrc_power_val:
@ -138,14 +175,14 @@ restore_sdrc_power_val:
wait_dll_lock:
ldr r11, omap3_sdrc_dlla_status
ldr r12, [r11]
and r12, r12, #0x4
cmp r12, #0x4
and r12, r12, #LOCKSTATUS_MASK
cmp r12, #LOCKSTATUS_MASK
bne wait_dll_lock
bx lr
wait_dll_unlock:
ldr r11, omap3_sdrc_dlla_status
ldr r12, [r11]
and r12, r12, #0x4
and r12, r12, #LOCKSTATUS_MASK
cmp r12, #0x0
bne wait_dll_unlock
bx lr
@ -156,7 +193,9 @@ configure_sdrc:
str r1, [r11]
ldr r11, omap3_sdrc_actim_ctrlb
str r2, [r11]
ldr r2, [r11] @ posted-write barrier for SDRC
ldr r11, omap3_sdrc_mr_0
str r6, [r11]
ldr r6, [r11] @ posted-write barrier for SDRC
bx lr
omap3_sdrc_power:
@ -173,6 +212,8 @@ omap3_sdrc_actim_ctrla:
.word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0)
omap3_sdrc_actim_ctrlb:
.word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0)
omap3_sdrc_mr_0:
.word OMAP34XX_SDRC_REGADDR(SDRC_MR_0)
omap3_sdrc_dlla_status:
.word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
omap3_sdrc_dlla_ctrl:

View file

@ -200,6 +200,6 @@ void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
int __init orion5x_setup_sram_win(void)
{
return setup_cpu_win(win_alloc_count, ORION5X_SRAM_PHYS_BASE,
return setup_cpu_win(win_alloc_count++, ORION5X_SRAM_PHYS_BASE,
ORION5X_SRAM_SIZE, TARGET_SRAM, ATTR_SRAM, -1);
}

View file

@ -562,7 +562,7 @@ static struct platform_device orion5x_crypto_device = {
.resource = orion5x_crypto_res,
};
int __init orion5x_crypto_init(void)
static int __init orion5x_crypto_init(void)
{
int ret;
@ -696,6 +696,14 @@ void __init orion5x_init(void)
disable_hlt();
}
/*
* The 5082/5181l/5182/6082/6082l/6183 have crypto
* while 5180n/5181/5281 don't have crypto.
*/
if ((dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) ||
dev == MV88F5182_DEV_ID || dev == MV88F6183_DEV_ID)
orion5x_crypto_init();
/*
* Register watchdog driver
*/

View file

@ -38,7 +38,6 @@ void orion5x_spi_init(void);
void orion5x_uart0_init(void);
void orion5x_uart1_init(void);
void orion5x_xor_init(void);
int orion5x_crypto_init(void);
/*
* PCIe/PCI functions.

View file

@ -401,6 +401,16 @@ config MACH_PALMZ72
Say Y here if you intend to run this kernel on Palm Zire 72
handheld computer.
config MACH_TREO680
bool "Palm Treo 680"
default y
depends on ARCH_PXA_PALM
select PXA27x
select IWMMXT
help
Say Y here if you intend to run this kernel on Palm Treo 680
smartphone.
config MACH_PALMLD
bool "Palm LifeDrive"
default y

View file

@ -62,6 +62,7 @@ obj-$(CONFIG_MACH_PALMT5) += palmt5.o
obj-$(CONFIG_MACH_PALMTX) += palmtx.o
obj-$(CONFIG_MACH_PALMLD) += palmld.o
obj-$(CONFIG_MACH_PALMZ72) += palmz72.o
obj-$(CONFIG_MACH_TREO680) += treo680.o
obj-$(CONFIG_ARCH_VIPER) += viper.o
ifeq ($(CONFIG_MACH_ZYLONITE),y)

View file

@ -23,6 +23,7 @@
#include <linux/pm.h>
#include <linux/gpio.h>
#include <linux/backlight.h>
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
@ -600,6 +601,10 @@ static struct platform_device *devices[] __initdata = {
&sharpsl_rom_device,
};
static struct i2c_board_info __initdata corgi_i2c_devices[] = {
{ I2C_BOARD_INFO("wm8731", 0x1b) },
};
static void corgi_poweroff(void)
{
if (!machine_is_corgi())
@ -634,6 +639,7 @@ static void __init corgi_init(void)
pxa_set_mci_info(&corgi_mci_platform_data);
pxa_set_ficp_info(&corgi_ficp_platform_data);
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(corgi_i2c_devices));
platform_scoop_config = &corgi_pcmcia_config;

View file

@ -30,6 +30,7 @@
#include <linux/apm-emulation.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
#include <linux/regulator/userspace-consumer.h>
#include <media/soc_camera.h>
@ -735,6 +736,7 @@ static struct pxa2xx_spi_chip em_x270_libertas_chip = {
.rx_threshold = 1,
.tx_threshold = 1,
.timeout = 1000,
.gpio_cs = 14,
};
static unsigned long em_x270_libertas_pin_config[] = {
@ -803,7 +805,6 @@ static int em_x270_libertas_teardown(struct spi_device *spi)
struct libertas_spi_platform_data em_x270_libertas_pdata = {
.use_dummy_writes = 1,
.gpio_cs = 14,
.setup = em_x270_libertas_setup,
.teardown = em_x270_libertas_teardown,
};
@ -838,10 +839,14 @@ static void __init em_x270_init_spi(void)
static inline void em_x270_init_spi(void) {}
#endif
#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
#if defined(CONFIG_SND_PXA2XX_LIB_AC97)
static pxa2xx_audio_ops_t em_x270_ac97_info = {
.reset_gpio = 113,
};
static void __init em_x270_init_ac97(void)
{
pxa_set_ac97_info(NULL);
pxa_set_ac97_info(&em_x270_ac97_info);
}
#else
static inline void em_x270_init_ac97(void) {}
@ -1038,6 +1043,52 @@ static void __init em_x270_init_camera(void)
static inline void em_x270_init_camera(void) {}
#endif
static struct regulator_bulk_data em_x270_gps_consumer_supply = {
.supply = "vcc gps",
};
static struct regulator_userspace_consumer_data em_x270_gps_consumer_data = {
.name = "vcc gps",
.num_supplies = 1,
.supplies = &em_x270_gps_consumer_supply,
};
static struct platform_device em_x270_gps_userspace_consumer = {
.name = "reg-userspace-consumer",
.id = 0,
.dev = {
.platform_data = &em_x270_gps_consumer_data,
},
};
static struct regulator_bulk_data em_x270_gprs_consumer_supply = {
.supply = "vcc gprs",
};
static struct regulator_userspace_consumer_data em_x270_gprs_consumer_data = {
.name = "vcc gprs",
.num_supplies = 1,
.supplies = &em_x270_gprs_consumer_supply
};
static struct platform_device em_x270_gprs_userspace_consumer = {
.name = "reg-userspace-consumer",
.id = 1,
.dev = {
.platform_data = &em_x270_gprs_consumer_data,
}
};
static struct platform_device *em_x270_userspace_consumers[] = {
&em_x270_gps_userspace_consumer,
&em_x270_gprs_userspace_consumer,
};
static void __init em_x270_userspace_consumers_init(void)
{
platform_add_devices(ARRAY_AND_SIZE(em_x270_userspace_consumers));
}
/* DA9030 related initializations */
#define REGULATOR_CONSUMER(_name, _dev, _supply) \
static struct regulator_consumer_supply _name##_consumers[] = { \
@ -1047,11 +1098,11 @@ static inline void em_x270_init_camera(void) {}
}, \
}
REGULATOR_CONSUMER(ldo3, NULL, "vcc gps");
REGULATOR_CONSUMER(ldo3, &em_x270_gps_userspace_consumer.dev, "vcc gps");
REGULATOR_CONSUMER(ldo5, NULL, "vcc cam");
REGULATOR_CONSUMER(ldo10, &pxa_device_mci.dev, "vcc sdio");
REGULATOR_CONSUMER(ldo12, NULL, "vcc usb");
REGULATOR_CONSUMER(ldo19, NULL, "vcc gprs");
REGULATOR_CONSUMER(ldo19, &em_x270_gprs_userspace_consumer.dev, "vcc gprs");
#define REGULATOR_INIT(_ldo, _min_uV, _max_uV, _ops_mask) \
static struct regulator_init_data _ldo##_data = { \
@ -1062,6 +1113,7 @@ REGULATOR_CONSUMER(ldo19, NULL, "vcc gprs");
.enabled = 0, \
}, \
.valid_ops_mask = _ops_mask, \
.apply_uV = 1, \
}, \
.num_consumer_supplies = ARRAY_SIZE(_ldo##_consumers), \
.consumer_supplies = _ldo##_consumers, \
@ -1240,6 +1292,7 @@ static void __init em_x270_init(void)
em_x270_init_spi();
em_x270_init_i2c();
em_x270_init_camera();
em_x270_userspace_consumers_init();
}
MACHINE_START(EM_X270, "Compulab EM-X270")

View file

@ -30,6 +30,7 @@
#include <linux/pwm_backlight.h>
#include <linux/regulator/bq24022.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/max1586.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/spi.h>
#include <linux/usb/gpio_vbus.h>
@ -774,6 +775,45 @@ static struct platform_device strataflash = {
},
};
/*
* Maxim MAX1587A on PI2C
*/
static struct regulator_consumer_supply max1587a_consumer = {
.supply = "vcc_core",
};
static struct regulator_init_data max1587a_v3_info = {
.constraints = {
.name = "vcc_core range",
.min_uV = 900000,
.max_uV = 1705000,
.always_on = 1,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
},
.num_consumer_supplies = 1,
.consumer_supplies = &max1587a_consumer,
};
static struct max1586_subdev_data max1587a_subdev = {
.name = "vcc_core",
.id = MAX1586_V3,
.platform_data = &max1587a_v3_info,
};
static struct max1586_platform_data max1587a_info = {
.num_subdevs = 1,
.subdevs = &max1587a_subdev,
.v3_gain = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */
};
static struct i2c_board_info __initdata pi2c_board_info[] = {
{
I2C_BOARD_INFO("max1586", 0x14),
.platform_data = &max1587a_info,
},
};
/*
* PCMCIA
*/
@ -828,6 +868,7 @@ static void __init hx4700_init(void)
pxa_set_ficp_info(&ficp_info);
pxa27x_set_i2c_power_info(NULL);
pxa_set_i2c_info(NULL);
i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info));
pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info));

View file

@ -21,7 +21,7 @@
/* SD/MMC */
#define GPIO_NR_PALMZ72_SD_DETECT_N 14
#define GPIO_NR_PALMZ72_SD_POWER_N 98
#define GPIO_NR_PALMZ72_SD_RO 115
#define GPIO_NR_PALMZ72_SD_RO 115
/* Touchscreen */
#define GPIO_NR_PALMZ72_WM9712_IRQ 27
@ -31,8 +31,7 @@
/* USB */
#define GPIO_NR_PALMZ72_USB_DETECT_N 15
#define GPIO_NR_PALMZ72_USB_POWER 95
#define GPIO_NR_PALMZ72_USB_PULLUP 12
#define GPIO_NR_PALMZ72_USB_PULLUP 95
/* LCD/Backlight */
#define GPIO_NR_PALMZ72_BL_POWER 20

View file

@ -0,0 +1,49 @@
/*
* GPIOs and interrupts for Palm Treo 680 smartphone
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#ifndef _INCLUDE_TREO680_H_
#define _INCLUDE_TREO680_H_
/* GPIOs */
#define GPIO_NR_TREO680_POWER_DETECT 0
#define GPIO_NR_TREO680_AMP_EN 27
#define GPIO_NR_TREO680_KEYB_BL 24
#define GPIO_NR_TREO680_VIBRATE_EN 44
#define GPIO_NR_TREO680_GREEN_LED 20
#define GPIO_NR_TREO680_RED_LED 79
#define GPIO_NR_TREO680_SD_DETECT_N 113
#define GPIO_NR_TREO680_SD_READONLY 33
#define GPIO_NR_TREO680_EP_DETECT_N 116
#define GPIO_NR_TREO680_SD_POWER 42
#define GPIO_NR_TREO680_USB_DETECT 1
#define GPIO_NR_TREO680_USB_PULLUP 114
#define GPIO_NR_TREO680_GSM_POWER 40
#define GPIO_NR_TREO680_GSM_RESET 87
#define GPIO_NR_TREO680_GSM_WAKE 57
#define GPIO_NR_TREO680_GSM_HOST_WAKE 14
#define GPIO_NR_TREO680_GSM_TRIGGER 10
#define GPIO_NR_TREO680_BT_EN 43
#define GPIO_NR_TREO680_IR_EN 115
#define GPIO_NR_TREO680_IR_TXD 47
#define GPIO_NR_TREO680_BL_POWER 38
#define GPIO_NR_TREO680_LCD_POWER 25
/* Various addresses */
#define TREO680_PHYS_RAM_START 0xa0000000
#define TREO680_PHYS_IO_START 0x40000000
#define TREO680_STR_BASE 0xa2000000
/* BACKLIGHT */
#define TREO680_MAX_INTENSITY 254
#define TREO680_DEFAULT_INTENSITY 160
#define TREO680_LIMIT_MASK 0x7F
#define TREO680_PRESCALER 63
#define TREO680_PERIOD_NS 3500
#endif

View file

@ -37,6 +37,7 @@
#include <linux/wm97xx_batt.h>
#include <linux/mtd/physmap.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/regulator/max1586.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@ -716,6 +717,38 @@ static struct wm97xx_batt_info mioa701_battery_data = {
.batt_name = "mioa701_battery",
};
/*
* Voltage regulation
*/
static struct regulator_consumer_supply max1586_consumers[] = {
{
.supply = "vcc_core",
}
};
static struct regulator_init_data max1586_v3_info = {
.constraints = {
.name = "vcc_core range",
.min_uV = 1000000,
.max_uV = 1705000,
.always_on = 1,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
},
.num_consumer_supplies = ARRAY_SIZE(max1586_consumers),
.consumer_supplies = max1586_consumers,
};
static struct max1586_subdev_data max1586_subdevs[] = {
{ .name = "vcc_core", .id = MAX1586_V3,
.platform_data = &max1586_v3_info },
};
static struct max1586_platform_data max1586_info = {
.subdevs = max1586_subdevs,
.num_subdevs = ARRAY_SIZE(max1586_subdevs),
.v3_gain = MAX1586_GAIN_NO_R24, /* 700..1475 mV */
};
/*
* Camera interface
*/
@ -725,6 +758,13 @@ struct pxacamera_platform_data mioa701_pxacamera_platform_data = {
.mclk_10khz = 5000,
};
static struct i2c_board_info __initdata mioa701_pi2c_devices[] = {
{
I2C_BOARD_INFO("max1586", 0x14),
.platform_data = &max1586_info,
},
};
static struct soc_camera_link iclink = {
.bus_id = 0, /* Must match id in pxa27x_device_camera in device.c */
};
@ -825,7 +865,9 @@ static void __init mioa701_machine_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
gsm_init();
i2c_register_board_info(1, ARRAY_AND_SIZE(mioa701_pi2c_devices));
pxa_set_i2c_info(&i2c_pdata);
pxa27x_set_i2c_power_info(NULL);
pxa_set_camera_info(&mioa701_pxacamera_platform_data);
i2c_register_board_info(0, ARRAY_AND_SIZE(mioa701_i2c_devices));
}

View file

@ -27,7 +27,9 @@
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/wm97xx_batt.h>
#include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@ -41,6 +43,8 @@
#include <mach/irda.h>
#include <mach/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/palmasoc.h>
#include <mach/pm.h>
#include "generic.h"
@ -66,6 +70,8 @@ static unsigned long palmz72_pin_config[] __initdata = {
GPIO29_AC97_SDATA_IN_0,
GPIO30_AC97_SDATA_OUT,
GPIO31_AC97_SYNC,
GPIO89_AC97_SYSCLK,
GPIO113_AC97_nRESET,
/* IrDA */
GPIO49_GPIO, /* ir disable */
@ -77,8 +83,7 @@ static unsigned long palmz72_pin_config[] __initdata = {
/* USB */
GPIO15_GPIO, /* usb detect */
GPIO12_GPIO, /* usb pullup */
GPIO95_GPIO, /* usb power */
GPIO95_GPIO, /* usb pullup */
/* Matrix keypad */
GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
@ -354,6 +359,22 @@ static struct platform_device palmz72_leds = {
}
};
/******************************************************************************
* UDC
******************************************************************************/
static struct gpio_vbus_mach_info palmz72_udc_info = {
.gpio_vbus = GPIO_NR_PALMZ72_USB_DETECT_N,
.gpio_pullup = GPIO_NR_PALMZ72_USB_PULLUP,
};
static struct platform_device palmz72_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &palmz72_udc_info,
},
};
/******************************************************************************
* Power supply
******************************************************************************/
@ -421,6 +442,31 @@ static struct platform_device power_supply = {
},
};
/******************************************************************************
* WM97xx battery
******************************************************************************/
static struct wm97xx_batt_info wm97xx_batt_pdata = {
.batt_aux = WM97XX_AUX_ID3,
.temp_aux = WM97XX_AUX_ID2,
.charge_gpio = -1,
.max_voltage = PALMZ72_BAT_MAX_VOLTAGE,
.min_voltage = PALMZ72_BAT_MIN_VOLTAGE,
.batt_mult = 1000,
.batt_div = 414,
.temp_mult = 1,
.temp_div = 1,
.batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO,
.batt_name = "main-batt",
};
/******************************************************************************
* aSoC audio
******************************************************************************/
static struct platform_device palmz72_asoc = {
.name = "palm27x-asoc",
.id = -1,
};
/******************************************************************************
* Framebuffer
******************************************************************************/
@ -527,17 +573,32 @@ device_initcall(palmz72_pm_init);
static struct platform_device *devices[] __initdata = {
&palmz72_backlight,
&palmz72_leds,
&palmz72_asoc,
&power_supply,
&palmz72_gpio_vbus,
};
/* setup udc GPIOs initial state */
static void __init palmz72_udc_init(void)
{
if (!gpio_request(GPIO_NR_PALMZ72_USB_PULLUP, "USB Pullup")) {
gpio_direction_output(GPIO_NR_PALMZ72_USB_PULLUP, 0);
gpio_free(GPIO_NR_PALMZ72_USB_PULLUP);
}
}
static void __init palmz72_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(palmz72_pin_config));
set_pxa_fb_info(&palmz72_lcd_screen);
pxa_set_mci_info(&palmz72_mci_platform_data);
palmz72_udc_init();
pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&palmz72_ficp_platform_data);
pxa_set_keypad_info(&palmz72_keypad_platform_data);
wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
platform_add_devices(devices, ARRAY_SIZE(devices));
}

View file

@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/mtd/physmap.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/mtd/sharpsl.h>
@ -486,6 +487,10 @@ static struct platform_device *devices[] __initdata = {
&sharpsl_rom_device,
};
static struct i2c_board_info __initdata poodle_i2c_devices[] = {
{ I2C_BOARD_INFO("wm8731", 0x1b) },
};
static void poodle_poweroff(void)
{
arm_machine_restart('h', NULL);
@ -519,6 +524,7 @@ static void __init poodle_init(void)
pxa_set_mci_info(&poodle_mci_platform_data);
pxa_set_ficp_info(&poodle_ficp_platform_data);
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices));
poodle_init_spi();
}

612
arch/arm/mach-pxa/treo680.c Normal file
View file

@ -0,0 +1,612 @@
/*
* Hardware definitions for Palm Treo 680
*
* Author: Tomas Cech <sleep_walker@suse.cz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* (find more info at www.hackndev.com)
*
*/
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
#include <linux/wm97xx_batt.h>
#include <linux/power_supply.h>
#include <linux/sysdev.h>
#include <linux/w1-gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/pxa27x.h>
#include <mach/pxa27x-udc.h>
#include <mach/audio.h>
#include <mach/treo680.h>
#include <mach/mmc.h>
#include <mach/pxafb.h>
#include <mach/irda.h>
#include <mach/pxa27x_keypad.h>
#include <mach/udc.h>
#include <mach/ohci.h>
#include <mach/pxa2xx-regs.h>
#include <mach/palmasoc.h>
#include <mach/camera.h>
#include <sound/pxa2xx-lib.h>
#include "generic.h"
#include "devices.h"
/******************************************************************************
* Pin configuration
******************************************************************************/
static unsigned long treo680_pin_config[] __initdata = {
/* MMC */
GPIO32_MMC_CLK,
GPIO92_MMC_DAT_0,
GPIO109_MMC_DAT_1,
GPIO110_MMC_DAT_2,
GPIO111_MMC_DAT_3,
GPIO112_MMC_CMD,
GPIO33_GPIO, /* SD read only */
GPIO113_GPIO, /* SD detect */
/* AC97 */
GPIO28_AC97_BITCLK,
GPIO29_AC97_SDATA_IN_0,
GPIO30_AC97_SDATA_OUT,
GPIO31_AC97_SYNC,
GPIO89_AC97_SYSCLK,
GPIO95_AC97_nRESET,
/* IrDA */
GPIO46_FICP_RXD,
GPIO47_FICP_TXD,
/* PWM */
GPIO16_PWM0_OUT,
/* USB */
GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* usb detect */
/* MATRIX KEYPAD */
GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
GPIO101_KP_MKIN_1,
GPIO102_KP_MKIN_2,
GPIO97_KP_MKIN_3,
GPIO98_KP_MKIN_4,
GPIO99_KP_MKIN_5,
GPIO91_KP_MKIN_6,
GPIO13_KP_MKIN_7,
GPIO103_KP_MKOUT_0 | MFP_LPM_DRIVE_HIGH,
GPIO104_KP_MKOUT_1,
GPIO105_KP_MKOUT_2,
GPIO106_KP_MKOUT_3,
GPIO107_KP_MKOUT_4,
GPIO108_KP_MKOUT_5,
GPIO96_KP_MKOUT_6,
GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH, /* Hotsync button */
/* LCD */
GPIO58_LCD_LDD_0,
GPIO59_LCD_LDD_1,
GPIO60_LCD_LDD_2,
GPIO61_LCD_LDD_3,
GPIO62_LCD_LDD_4,
GPIO63_LCD_LDD_5,
GPIO64_LCD_LDD_6,
GPIO65_LCD_LDD_7,
GPIO66_LCD_LDD_8,
GPIO67_LCD_LDD_9,
GPIO68_LCD_LDD_10,
GPIO69_LCD_LDD_11,
GPIO70_LCD_LDD_12,
GPIO71_LCD_LDD_13,
GPIO72_LCD_LDD_14,
GPIO73_LCD_LDD_15,
GPIO74_LCD_FCLK,
GPIO75_LCD_LCLK,
GPIO76_LCD_PCLK,
/* Quick Capture Interface */
GPIO84_CIF_FV,
GPIO85_CIF_LV,
GPIO53_CIF_MCLK,
GPIO54_CIF_PCLK,
GPIO81_CIF_DD_0,
GPIO55_CIF_DD_1,
GPIO51_CIF_DD_2,
GPIO50_CIF_DD_3,
GPIO52_CIF_DD_4,
GPIO48_CIF_DD_5,
GPIO17_CIF_DD_6,
GPIO12_CIF_DD_7,
/* I2C */
GPIO117_I2C_SCL,
GPIO118_I2C_SDA,
/* GSM */
GPIO14_GPIO | WAKEUP_ON_EDGE_BOTH, /* GSM host wake up */
GPIO34_FFUART_RXD,
GPIO35_FFUART_CTS,
GPIO39_FFUART_TXD,
GPIO41_FFUART_RTS,
/* MISC. */
GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* external power detect */
GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH, /* silent switch */
GPIO116_GPIO, /* headphone detect */
GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH, /* bluetooth host wake up */
};
/******************************************************************************
* SD/MMC card controller
******************************************************************************/
static int treo680_mci_init(struct device *dev,
irq_handler_t treo680_detect_int, void *data)
{
int err = 0;
/* Setup an interrupt for detecting card insert/remove events */
err = gpio_request(GPIO_NR_TREO680_SD_DETECT_N, "SD IRQ");
if (err)
goto err;
err = gpio_direction_input(GPIO_NR_TREO680_SD_DETECT_N);
if (err)
goto err2;
err = request_irq(gpio_to_irq(GPIO_NR_TREO680_SD_DETECT_N),
treo680_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
"SD/MMC card detect", data);
if (err) {
dev_err(dev, "%s: cannot request SD/MMC card detect IRQ\n",
__func__);
goto err2;
}
err = gpio_request(GPIO_NR_TREO680_SD_POWER, "SD_POWER");
if (err)
goto err3;
err = gpio_direction_output(GPIO_NR_TREO680_SD_POWER, 1);
if (err)
goto err4;
err = gpio_request(GPIO_NR_TREO680_SD_READONLY, "SD_READONLY");
if (err)
goto err4;
err = gpio_direction_input(GPIO_NR_TREO680_SD_READONLY);
if (err)
goto err5;
return 0;
err5:
gpio_free(GPIO_NR_TREO680_SD_READONLY);
err4:
gpio_free(GPIO_NR_TREO680_SD_POWER);
err3:
free_irq(gpio_to_irq(GPIO_NR_TREO680_SD_DETECT_N), data);
err2:
gpio_free(GPIO_NR_TREO680_SD_DETECT_N);
err:
return err;
}
static void treo680_mci_exit(struct device *dev, void *data)
{
gpio_free(GPIO_NR_TREO680_SD_READONLY);
gpio_free(GPIO_NR_TREO680_SD_POWER);
free_irq(gpio_to_irq(GPIO_NR_TREO680_SD_DETECT_N), data);
gpio_free(GPIO_NR_TREO680_SD_DETECT_N);
}
static void treo680_mci_power(struct device *dev, unsigned int vdd)
{
struct pxamci_platform_data *p_d = dev->platform_data;
gpio_set_value(GPIO_NR_TREO680_SD_POWER, p_d->ocr_mask & (1 << vdd));
}
static int treo680_mci_get_ro(struct device *dev)
{
return gpio_get_value(GPIO_NR_TREO680_SD_READONLY);
}
static struct pxamci_platform_data treo680_mci_platform_data = {
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.setpower = treo680_mci_power,
.get_ro = treo680_mci_get_ro,
.init = treo680_mci_init,
.exit = treo680_mci_exit,
};
/******************************************************************************
* GPIO keyboard
******************************************************************************/
static unsigned int treo680_matrix_keys[] = {
KEY(0, 0, KEY_F8), /* Red/Off/Power */
KEY(0, 1, KEY_LEFT),
KEY(0, 2, KEY_LEFTCTRL), /* Alternate */
KEY(0, 3, KEY_L),
KEY(0, 4, KEY_A),
KEY(0, 5, KEY_Q),
KEY(0, 6, KEY_P),
KEY(1, 0, KEY_RIGHTCTRL), /* Menu */
KEY(1, 1, KEY_RIGHT),
KEY(1, 2, KEY_LEFTSHIFT), /* Left shift */
KEY(1, 3, KEY_Z),
KEY(1, 4, KEY_S),
KEY(1, 5, KEY_W),
KEY(2, 0, KEY_F1), /* Phone */
KEY(2, 1, KEY_UP),
KEY(2, 2, KEY_0),
KEY(2, 3, KEY_X),
KEY(2, 4, KEY_D),
KEY(2, 5, KEY_E),
KEY(3, 0, KEY_F10), /* Calendar */
KEY(3, 1, KEY_DOWN),
KEY(3, 2, KEY_SPACE),
KEY(3, 3, KEY_C),
KEY(3, 4, KEY_F),
KEY(3, 5, KEY_R),
KEY(4, 0, KEY_F12), /* Mail */
KEY(4, 1, KEY_KPENTER),
KEY(4, 2, KEY_RIGHTALT), /* Alt */
KEY(4, 3, KEY_V),
KEY(4, 4, KEY_G),
KEY(4, 5, KEY_T),
KEY(5, 0, KEY_F9), /* Home */
KEY(5, 1, KEY_PAGEUP), /* Side up */
KEY(5, 2, KEY_DOT),
KEY(5, 3, KEY_B),
KEY(5, 4, KEY_H),
KEY(5, 5, KEY_Y),
KEY(6, 0, KEY_TAB), /* Side Activate */
KEY(6, 1, KEY_PAGEDOWN), /* Side down */
KEY(6, 2, KEY_ENTER),
KEY(6, 3, KEY_N),
KEY(6, 4, KEY_J),
KEY(6, 5, KEY_U),
KEY(7, 0, KEY_F6), /* Green/Call */
KEY(7, 1, KEY_O),
KEY(7, 2, KEY_BACKSPACE),
KEY(7, 3, KEY_M),
KEY(7, 4, KEY_K),
KEY(7, 5, KEY_I),
};
static struct pxa27x_keypad_platform_data treo680_keypad_platform_data = {
.matrix_key_rows = 8,
.matrix_key_cols = 7,
.matrix_key_map = treo680_matrix_keys,
.matrix_key_map_size = ARRAY_SIZE(treo680_matrix_keys),
.direct_key_map = { KEY_CONNECT },
.direct_key_num = 1,
.debounce_interval = 30,
};
/******************************************************************************
* aSoC audio
******************************************************************************/
static pxa2xx_audio_ops_t treo680_ac97_pdata = {
.reset_gpio = 95,
};
/******************************************************************************
* Backlight
******************************************************************************/
static int treo680_backlight_init(struct device *dev)
{
int ret;
ret = gpio_request(GPIO_NR_TREO680_BL_POWER, "BL POWER");
if (ret)
goto err;
ret = gpio_direction_output(GPIO_NR_TREO680_BL_POWER, 0);
if (ret)
goto err2;
ret = gpio_request(GPIO_NR_TREO680_LCD_POWER, "LCD POWER");
if (ret)
goto err2;
ret = gpio_direction_output(GPIO_NR_TREO680_LCD_POWER, 0);
if (ret)
goto err3;
return 0;
err3:
gpio_free(GPIO_NR_TREO680_LCD_POWER);
err2:
gpio_free(GPIO_NR_TREO680_BL_POWER);
err:
return ret;
}
static int treo680_backlight_notify(int brightness)
{
gpio_set_value(GPIO_NR_TREO680_BL_POWER, brightness);
return TREO680_MAX_INTENSITY - brightness;
};
static void treo680_backlight_exit(struct device *dev)
{
gpio_free(GPIO_NR_TREO680_BL_POWER);
gpio_free(GPIO_NR_TREO680_LCD_POWER);
}
static struct platform_pwm_backlight_data treo680_backlight_data = {
.pwm_id = 0,
.max_brightness = TREO680_MAX_INTENSITY,
.dft_brightness = TREO680_DEFAULT_INTENSITY,
.pwm_period_ns = TREO680_PERIOD_NS,
.init = treo680_backlight_init,
.notify = treo680_backlight_notify,
.exit = treo680_backlight_exit,
};
static struct platform_device treo680_backlight = {
.name = "pwm-backlight",
.dev = {
.parent = &pxa27x_device_pwm0.dev,
.platform_data = &treo680_backlight_data,
},
};
/******************************************************************************
* IrDA
******************************************************************************/
static void treo680_transceiver_mode(struct device *dev, int mode)
{
gpio_set_value(GPIO_NR_TREO680_IR_EN, mode & IR_OFF);
pxa2xx_transceiver_mode(dev, mode);
}
static int treo680_irda_startup(struct device *dev)
{
int err;
err = gpio_request(GPIO_NR_TREO680_IR_EN, "Ir port disable");
if (err)
goto err1;
err = gpio_direction_output(GPIO_NR_TREO680_IR_EN, 1);
if (err)
goto err2;
return 0;
err2:
dev_err(dev, "treo680_irda: cannot change IR gpio direction\n");
gpio_free(GPIO_NR_TREO680_IR_EN);
err1:
dev_err(dev, "treo680_irda: cannot allocate IR gpio\n");
return err;
}
static void treo680_irda_shutdown(struct device *dev)
{
gpio_free(GPIO_NR_TREO680_AMP_EN);
}
static struct pxaficp_platform_data treo680_ficp_info = {
.transceiver_cap = IR_FIRMODE | IR_SIRMODE | IR_OFF,
.startup = treo680_irda_startup,
.shutdown = treo680_irda_shutdown,
.transceiver_mode = treo680_transceiver_mode,
};
/******************************************************************************
* UDC
******************************************************************************/
static struct pxa2xx_udc_mach_info treo680_udc_info __initdata = {
.gpio_vbus = GPIO_NR_TREO680_USB_DETECT,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_TREO680_USB_PULLUP,
};
/******************************************************************************
* USB host
******************************************************************************/
static struct pxaohci_platform_data treo680_ohci_info = {
.port_mode = PMM_PERPORT_MODE,
.flags = ENABLE_PORT1 | ENABLE_PORT3,
.power_budget = 0,
};
/******************************************************************************
* Power supply
******************************************************************************/
static int power_supply_init(struct device *dev)
{
int ret;
ret = gpio_request(GPIO_NR_TREO680_POWER_DETECT, "CABLE_STATE_AC");
if (ret)
goto err1;
ret = gpio_direction_input(GPIO_NR_TREO680_POWER_DETECT);
if (ret)
goto err2;
return 0;
err2:
gpio_free(GPIO_NR_TREO680_POWER_DETECT);
err1:
return ret;
}
static int treo680_is_ac_online(void)
{
return gpio_get_value(GPIO_NR_TREO680_POWER_DETECT);
}
static void power_supply_exit(struct device *dev)
{
gpio_free(GPIO_NR_TREO680_POWER_DETECT);
}
static char *treo680_supplicants[] = {
"main-battery",
};
static struct pda_power_pdata power_supply_info = {
.init = power_supply_init,
.is_ac_online = treo680_is_ac_online,
.exit = power_supply_exit,
.supplied_to = treo680_supplicants,
.num_supplicants = ARRAY_SIZE(treo680_supplicants),
};
static struct platform_device power_supply = {
.name = "pda-power",
.id = -1,
.dev = {
.platform_data = &power_supply_info,
},
};
/******************************************************************************
* Vibra and LEDs
******************************************************************************/
static struct gpio_led gpio_leds[] = {
{
.name = "treo680:vibra:vibra",
.default_trigger = "none",
.gpio = GPIO_NR_TREO680_VIBRATE_EN,
},
{
.name = "treo680:green:led",
.default_trigger = "mmc0",
.gpio = GPIO_NR_TREO680_GREEN_LED,
},
{
.name = "treo680:keybbl:keybbl",
.default_trigger = "none",
.gpio = GPIO_NR_TREO680_KEYB_BL,
},
};
static struct gpio_led_platform_data gpio_led_info = {
.leds = gpio_leds,
.num_leds = ARRAY_SIZE(gpio_leds),
};
static struct platform_device treo680_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &gpio_led_info,
}
};
/******************************************************************************
* Framebuffer
******************************************************************************/
/* TODO: add support for 324x324 */
static struct pxafb_mode_info treo680_lcd_modes[] = {
{
.pixclock = 86538,
.xres = 320,
.yres = 320,
.bpp = 16,
.left_margin = 20,
.right_margin = 8,
.upper_margin = 8,
.lower_margin = 5,
.hsync_len = 4,
.vsync_len = 1,
},
};
static struct pxafb_mach_info treo680_lcd_screen = {
.modes = treo680_lcd_modes,
.num_modes = ARRAY_SIZE(treo680_lcd_modes),
.lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
};
/******************************************************************************
* Power management - standby
******************************************************************************/
static void __init treo680_pm_init(void)
{
static u32 resume[] = {
0xe3a00101, /* mov r0, #0x40000000 */
0xe380060f, /* orr r0, r0, #0x00f00000 */
0xe590f008, /* ldr pc, [r0, #0x08] */
};
/* this is where the bootloader jumps */
memcpy(phys_to_virt(TREO680_STR_BASE), resume, sizeof(resume));
}
/******************************************************************************
* Machine init
******************************************************************************/
static struct platform_device *devices[] __initdata = {
&treo680_backlight,
&treo680_leds,
&power_supply,
};
/* setup udc GPIOs initial state */
static void __init treo680_udc_init(void)
{
if (!gpio_request(GPIO_NR_TREO680_USB_PULLUP, "UDC Vbus")) {
gpio_direction_output(GPIO_NR_TREO680_USB_PULLUP, 1);
gpio_free(GPIO_NR_TREO680_USB_PULLUP);
}
}
static void __init treo680_init(void)
{
treo680_pm_init();
pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config));
pxa_set_keypad_info(&treo680_keypad_platform_data);
set_pxa_fb_info(&treo680_lcd_screen);
pxa_set_mci_info(&treo680_mci_platform_data);
treo680_udc_init();
pxa_set_udc_info(&treo680_udc_info);
pxa_set_ac97_info(&treo680_ac97_pdata);
pxa_set_ficp_info(&treo680_ficp_info);
pxa_set_ohci_info(&treo680_ohci_info);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
MACHINE_START(TREO680, "Palm Treo 680")
.phys_io = TREO680_PHYS_IO_START,
.io_pg_offst = io_p2v(0x40000000),
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = treo680_init,
MACHINE_END

View file

@ -27,6 +27,7 @@
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/smp_twd.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>

View file

@ -22,7 +22,6 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <asm/mach/arch.h>

View file

@ -84,5 +84,15 @@ config MACH_AT2440EVB
help
Say Y here if you are using the AT2440EVB development board
config MACH_MINI2440
bool "MINI2440 development board"
select CPU_S3C2440
select EEPROM_AT24
select LEDS_TRIGGER_BACKLIGHT
select SND_S3C24XX_SOC_S3C24XX_UDA134X
help
Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
available via various sources. It can come with a 3.5" or 7" touch LCD.
endmenu

View file

@ -22,3 +22,4 @@ obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o

View file

@ -0,0 +1,703 @@
/* linux/arch/arm/mach-s3c2440/mach-mini2440.c
*
* Copyright (c) 2008 Ramax Lo <ramaxlo@gmail.com>
* Based on mach-anubis.c by Ben Dooks <ben@simtec.co.uk>
* and modifications by SBZ <sbz@spgui.org> and
* Weibing <http://weibing.blogbus.com> and
* Michel Pollet <buserror@gmail.com>
*
* For product information, visit http://code.google.com/p/mini2440/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/io.h>
#include <linux/serial_core.h>
#include <linux/dm9000.h>
#include <linux/i2c/at24.h>
#include <linux/platform_device.h>
#include <linux/gpio_keys.h>
#include <linux/i2c.h>
#include <linux/mmc/host.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <mach/fb.h>
#include <asm/mach-types.h>
#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/leds-gpio.h>
#include <mach/regs-mem.h>
#include <mach/regs-lcd.h>
#include <mach/irqs.h>
#include <plat/nand.h>
#include <plat/iic.h>
#include <plat/mci.h>
#include <plat/udc.h>
#include <plat/regs-serial.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <sound/s3c24xx_uda134x.h>
#define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300)
static struct map_desc mini2440_iodesc[] __initdata = {
/* nothing to declare, move along */
};
#define UCON S3C2410_UCON_DEFAULT
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
[2] = {
.hwport = 2,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
};
/* USB device UDC support */
static void mini2440_udc_pullup(enum s3c2410_udc_cmd_e cmd)
{
pr_debug("udc: pullup(%d)\n", cmd);
switch (cmd) {
case S3C2410_UDC_P_ENABLE :
s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
break;
case S3C2410_UDC_P_DISABLE :
s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
break;
case S3C2410_UDC_P_RESET :
break;
default:
break;
}
}
static struct s3c2410_udc_mach_info mini2440_udc_cfg __initdata = {
.udc_command = mini2440_udc_pullup,
};
/* LCD timing and setup */
/*
* This macro simplifies the table bellow
*/
#define _LCD_DECLARE(_clock,_xres,margin_left,margin_right,hsync, \
_yres,margin_top,margin_bottom,vsync, refresh) \
.width = _xres, \
.xres = _xres, \
.height = _yres, \
.yres = _yres, \
.left_margin = margin_left, \
.right_margin = margin_right, \
.upper_margin = margin_top, \
.lower_margin = margin_bottom, \
.hsync_len = hsync, \
.vsync_len = vsync, \
.pixclock = ((_clock*100000000000LL) / \
((refresh) * \
(hsync + margin_left + _xres + margin_right) * \
(vsync + margin_top + _yres + margin_bottom))), \
.bpp = 16,\
.type = (S3C2410_LCDCON1_TFT16BPP |\
S3C2410_LCDCON1_TFT)
struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
[0] = { /* mini2440 + 3.5" TFT + touchscreen */
_LCD_DECLARE(
7, /* The 3.5 is quite fast */
240, 21, 38, 6, /* x timing */
320, 4, 4, 2, /* y timing */
60), /* refresh rate */
.lcdcon5 = (S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVLINE |
S3C2410_LCDCON5_INVVFRAME |
S3C2410_LCDCON5_INVVDEN |
S3C2410_LCDCON5_PWREN),
},
[1] = { /* mini2440 + 7" TFT + touchscreen */
_LCD_DECLARE(
10, /* the 7" runs slower */
800, 40, 40, 48, /* x timing */
480, 29, 3, 3, /* y timing */
50), /* refresh rate */
.lcdcon5 = (S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVLINE |
S3C2410_LCDCON5_INVVFRAME |
S3C2410_LCDCON5_PWREN),
},
/* The VGA shield can outout at several resolutions. All share
* the same timings, however, anything smaller than 1024x768
* will only be displayed in the top left corner of a 1024x768
* XGA output unless you add optional dip switches to the shield.
* Therefore timings for other resolutions have been ommited here.
*/
[2] = {
_LCD_DECLARE(
10,
1024, 1, 2, 2, /* y timing */
768, 200, 16, 16, /* x timing */
24), /* refresh rate, maximum stable,
tested with the FPGA shield */
.lcdcon5 = (S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_HWSWP),
},
};
/* todo - put into gpio header */
#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
.displays = &mini2440_lcd_cfg[0], /* not constant! see init */
.num_displays = 1,
.default_display = 0,
/* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
* and disable the pull down resistors on pins we are using for LCD
* data. */
.gpcup = (0xf << 1) | (0x3f << 10),
.gpccon = (S3C2410_GPC1_VCLK | S3C2410_GPC2_VLINE |
S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |
S3C2410_GPC10_VD2 | S3C2410_GPC11_VD3 |
S3C2410_GPC12_VD4 | S3C2410_GPC13_VD5 |
S3C2410_GPC14_VD6 | S3C2410_GPC15_VD7),
.gpccon_mask = (S3C2410_GPCCON_MASK(1) | S3C2410_GPCCON_MASK(2) |
S3C2410_GPCCON_MASK(3) | S3C2410_GPCCON_MASK(4) |
S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |
S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |
S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),
.gpdup = (0x3f << 2) | (0x3f << 10),
.gpdcon = (S3C2410_GPD2_VD10 | S3C2410_GPD3_VD11 |
S3C2410_GPD4_VD12 | S3C2410_GPD5_VD13 |
S3C2410_GPD6_VD14 | S3C2410_GPD7_VD15 |
S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |
S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |
S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),
.gpdcon_mask = (S3C2410_GPDCON_MASK(2) | S3C2410_GPDCON_MASK(3) |
S3C2410_GPDCON_MASK(4) | S3C2410_GPDCON_MASK(5) |
S3C2410_GPDCON_MASK(6) | S3C2410_GPDCON_MASK(7) |
S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|
S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|
S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),
};
/* MMC/SD */
static struct s3c24xx_mci_pdata mini2440_mmc_cfg __initdata = {
.gpio_detect = S3C2410_GPG(8),
.gpio_wprotect = S3C2410_GPH(8),
.set_power = NULL,
.ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34,
};
/* NAND Flash on MINI2440 board */
static struct mtd_partition mini2440_default_nand_part[] __initdata = {
[0] = {
.name = "u-boot",
.size = SZ_256K,
.offset = 0,
},
[1] = {
.name = "u-boot-env",
.size = SZ_128K,
.offset = SZ_256K,
},
[2] = {
.name = "kernel",
/* 5 megabytes, for a kernel with no modules
* or a uImage with a ramdisk attached */
.size = 0x00500000,
.offset = SZ_256K + SZ_128K,
},
[3] = {
.name = "root",
.offset = SZ_256K + SZ_128K + 0x00500000,
.size = MTDPART_SIZ_FULL,
},
};
static struct s3c2410_nand_set mini2440_nand_sets[] __initdata = {
[0] = {
.name = "nand",
.nr_chips = 1,
.nr_partitions = ARRAY_SIZE(mini2440_default_nand_part),
.partitions = mini2440_default_nand_part,
},
};
static struct s3c2410_platform_nand mini2440_nand_info __initdata = {
.tacls = 0,
.twrph0 = 25,
.twrph1 = 15,
.nr_sets = ARRAY_SIZE(mini2440_nand_sets),
.sets = mini2440_nand_sets,
.ignore_unset_ecc = 1,
};
/* DM9000AEP 10/100 ethernet controller */
static struct resource mini2440_dm9k_resource[] __initdata = {
[0] = {
.start = MACH_MINI2440_DM9K_BASE,
.end = MACH_MINI2440_DM9K_BASE + 3,
.flags = IORESOURCE_MEM
},
[1] = {
.start = MACH_MINI2440_DM9K_BASE + 4,
.end = MACH_MINI2440_DM9K_BASE + 7,
.flags = IORESOURCE_MEM
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
}
};
/*
* The DM9000 has no eeprom, and it's MAC address is set by
* the bootloader before starting the kernel.
*/
static struct dm9000_plat_data mini2440_dm9k_pdata __initdata = {
.flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
};
static struct platform_device mini2440_device_eth __initdata = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(mini2440_dm9k_resource),
.resource = mini2440_dm9k_resource,
.dev = {
.platform_data = &mini2440_dm9k_pdata,
},
};
/* CON5
* +--+ /-----\
* | | | |
* | | | BAT |
* | | \_____/
* | |
* | | +----+ +----+
* | | | K5 | | K1 |
* | | +----+ +----+
* | | +----+ +----+
* | | | K4 | | K2 |
* | | +----+ +----+
* | | +----+ +----+
* | | | K6 | | K3 |
* | | +----+ +----+
* .....
*/
static struct gpio_keys_button mini2440_buttons[] __initdata = {
{
.gpio = S3C2410_GPG(0), /* K1 */
.code = KEY_F1,
.desc = "Button 1",
.active_low = 1,
},
{
.gpio = S3C2410_GPG(3), /* K2 */
.code = KEY_F2,
.desc = "Button 2",
.active_low = 1,
},
{
.gpio = S3C2410_GPG(5), /* K3 */
.code = KEY_F3,
.desc = "Button 3",
.active_low = 1,
},
{
.gpio = S3C2410_GPG(6), /* K4 */
.code = KEY_POWER,
.desc = "Power",
.active_low = 1,
},
{
.gpio = S3C2410_GPG(7), /* K5 */
.code = KEY_F5,
.desc = "Button 5",
.active_low = 1,
},
#if 0
/* this pin is also known as TCLK1 and seems to already
* marked as "in use" somehow in the kernel -- possibly wrongly */
{
.gpio = S3C2410_GPG(11), /* K6 */
.code = KEY_F6,
.desc = "Button 6",
.active_low = 1,
},
#endif
};
static struct gpio_keys_platform_data mini2440_button_data __initdata = {
.buttons = mini2440_buttons,
.nbuttons = ARRAY_SIZE(mini2440_buttons),
};
static struct platform_device mini2440_button_device __initdata = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &mini2440_button_data,
}
};
/* LEDS */
static struct s3c24xx_led_platdata mini2440_led1_pdata __initdata = {
.name = "led1",
.gpio = S3C2410_GPB(5),
.flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
.def_trigger = "heartbeat",
};
static struct s3c24xx_led_platdata mini2440_led2_pdata __initdata = {
.name = "led2",
.gpio = S3C2410_GPB(6),
.flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
.def_trigger = "nand-disk",
};
static struct s3c24xx_led_platdata mini2440_led3_pdata __initdata = {
.name = "led3",
.gpio = S3C2410_GPB(7),
.flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
.def_trigger = "mmc0",
};
static struct s3c24xx_led_platdata mini2440_led4_pdata __initdata = {
.name = "led4",
.gpio = S3C2410_GPB(8),
.flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
.def_trigger = "",
};
static struct s3c24xx_led_platdata mini2440_led_backlight_pdata __initdata = {
.name = "backlight",
.gpio = S3C2410_GPG(4),
.def_trigger = "backlight",
};
static struct platform_device mini2440_led1 __initdata = {
.name = "s3c24xx_led",
.id = 1,
.dev = {
.platform_data = &mini2440_led1_pdata,
},
};
static struct platform_device mini2440_led2 __initdata = {
.name = "s3c24xx_led",
.id = 2,
.dev = {
.platform_data = &mini2440_led2_pdata,
},
};
static struct platform_device mini2440_led3 __initdata = {
.name = "s3c24xx_led",
.id = 3,
.dev = {
.platform_data = &mini2440_led3_pdata,
},
};
static struct platform_device mini2440_led4 __initdata = {
.name = "s3c24xx_led",
.id = 4,
.dev = {
.platform_data = &mini2440_led4_pdata,
},
};
static struct platform_device mini2440_led_backlight __initdata = {
.name = "s3c24xx_led",
.id = 5,
.dev = {
.platform_data = &mini2440_led_backlight_pdata,
},
};
/* AUDIO */
static struct s3c24xx_uda134x_platform_data mini2440_audio_pins __initdata = {
.l3_clk = S3C2410_GPB(4),
.l3_mode = S3C2410_GPB(2),
.l3_data = S3C2410_GPB(3),
.model = UDA134X_UDA1341
};
static struct platform_device mini2440_audio __initdata = {
.name = "s3c24xx_uda134x",
.id = 0,
.dev = {
.platform_data = &mini2440_audio_pins,
},
};
/*
* I2C devices
*/
static struct at24_platform_data at24c08 = {
.byte_len = SZ_8K / 8,
.page_size = 16,
};
static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
{
I2C_BOARD_INFO("24c08", 0x50),
.platform_data = &at24c08,
},
};
static struct platform_device *mini2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_wdt,
/* &s3c_device_adc,*/ /* ADC doesn't like living with touchscreen ! */
&s3c_device_i2c0,
&s3c_device_rtc,
&s3c_device_usbgadget,
&mini2440_device_eth,
&mini2440_led1,
&mini2440_led2,
&mini2440_led3,
&mini2440_led4,
&mini2440_button_device,
&s3c_device_nand,
&s3c_device_sdi,
&s3c_device_iis,
&mini2440_audio,
/* &s3c_device_timer[0],*/ /* buzzer pwm, no API for it */
/* remaining devices are optional */
};
static void __init mini2440_map_io(void)
{
s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
s3c_device_nand.dev.platform_data = &mini2440_nand_info;
s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;
}
/*
* mini2440_features string
*
* t = Touchscreen present
* b = backlight control
* c = camera [TODO]
* 0-9 LCD configuration
*
*/
static char mini2440_features_str[12] __initdata = "0tb";
static int __init mini2440_features_setup(char *str)
{
if (str)
strlcpy(mini2440_features_str, str, sizeof(mini2440_features_str));
return 1;
}
__setup("mini2440=", mini2440_features_setup);
#define FEATURE_SCREEN (1 << 0)
#define FEATURE_BACKLIGHT (1 << 1)
#define FEATURE_TOUCH (1 << 2)
#define FEATURE_CAMERA (1 << 3)
struct mini2440_features_t {
int count;
int done;
int lcd_index;
struct platform_device *optional[8];
};
static void mini2440_parse_features(
struct mini2440_features_t * features,
const char * features_str )
{
const char * fp = features_str;
features->count = 0;
features->done = 0;
features->lcd_index = -1;
while (*fp) {
char f = *fp++;
switch (f) {
case '0'...'9': /* tft screen */
if (features->done & FEATURE_SCREEN) {
printk(KERN_INFO "MINI2440: '%c' ignored, "
"screen type already set\n", f);
} else {
int li = f - '0';
if (li >= ARRAY_SIZE(mini2440_lcd_cfg))
printk(KERN_INFO "MINI2440: "
"'%c' out of range LCD mode\n", f);
else {
features->optional[features->count++] =
&s3c_device_lcd;
features->lcd_index = li;
}
}
features->done |= FEATURE_SCREEN;
break;
case 'b':
if (features->done & FEATURE_BACKLIGHT)
printk(KERN_INFO "MINI2440: '%c' ignored, "
"backlight already set\n", f);
else {
features->optional[features->count++] =
&mini2440_led_backlight;
}
features->done |= FEATURE_BACKLIGHT;
break;
case 't':
printk(KERN_INFO "MINI2440: '%c' ignored, "
"touchscreen not compiled in\n", f);
break;
case 'c':
if (features->done & FEATURE_CAMERA)
printk(KERN_INFO "MINI2440: '%c' ignored, "
"camera already registered\n", f);
else
features->optional[features->count++] =
&s3c_device_camif;
features->done |= FEATURE_CAMERA;
break;
}
}
}
static void __init mini2440_init(void)
{
struct mini2440_features_t features = { 0 };
int i;
printk(KERN_INFO "MINI2440: Option string mini2440=%s\n",
mini2440_features_str);
/* Parse the feature string */
mini2440_parse_features(&features, mini2440_features_str);
/* turn LCD on */
s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
/* Turn the backlight early on */
s3c2410_gpio_setpin(S3C2410_GPG(4), 1);
s3c2410_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT);
/* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
s3c2410_gpio_pullup(S3C2410_GPB(1), 0);
s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
s3c2410_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
/* Make sure the D+ pullup pin is output */
s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
/* mark the key as input, without pullups (there is one on the board) */
for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
s3c2410_gpio_pullup(mini2440_buttons[i].gpio, 0);
s3c2410_gpio_cfgpin(mini2440_buttons[i].gpio,
S3C2410_GPIO_INPUT);
}
if (features.lcd_index != -1) {
int li;
mini2440_fb_info.displays =
&mini2440_lcd_cfg[features.lcd_index];
printk(KERN_INFO "MINI2440: LCD");
for (li = 0; li < ARRAY_SIZE(mini2440_lcd_cfg); li++)
if (li == features.lcd_index)
printk(" [%d:%dx%d]", li,
mini2440_lcd_cfg[li].width,
mini2440_lcd_cfg[li].height);
else
printk(" %d:%dx%d", li,
mini2440_lcd_cfg[li].width,
mini2440_lcd_cfg[li].height);
printk("\n");
s3c24xx_fb_set_platdata(&mini2440_fb_info);
}
s3c24xx_udc_set_platdata(&mini2440_udc_cfg);
s3c_i2c0_set_platdata(NULL);
i2c_register_board_info(0, mini2440_i2c_devs,
ARRAY_SIZE(mini2440_i2c_devs));
platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
if (features.count) /* the optional features */
platform_add_devices(features.optional, features.count);
}
MACHINE_START(MINI2440, "MINI2440")
/* Maintainer: Michel Pollet <buserror@gmail.com> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = mini2440_map_io,
.init_machine = mini2440_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END

View file

@ -24,6 +24,18 @@ config SMDK2440_CPU2442
depends on ARCH_S3C2440
select CPU_S3C2442
config MACH_NEO1973_GTA02
bool "Openmoko GTA02 / Freerunner phone"
select CPU_S3C2442
select MFD_PCF50633
select PCF50633_GPIO
select I2C
select POWER_SUPPLY
select MACH_NEO1973
select S3C2410_PWM
help
Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
endmenu

View file

@ -12,5 +12,7 @@ obj- :=
obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
obj-$(CONFIG_CPU_S3C2442) += clock.o
obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
# Machine support

View file

@ -0,0 +1,84 @@
#ifndef _GTA02_H
#define _GTA02_H
#include <mach/regs-gpio.h>
/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
#define GTA02v1_SYSTEM_REV 0x00000310
#define GTA02v2_SYSTEM_REV 0x00000320
#define GTA02v3_SYSTEM_REV 0x00000330
#define GTA02v4_SYSTEM_REV 0x00000340
#define GTA02v5_SYSTEM_REV 0x00000350
/* since A7 is basically same as A6, we use A6 PCB ID */
#define GTA02v6_SYSTEM_REV 0x00000360
#define GTA02_GPIO_n3DL_GSM S3C2410_GPA(13) /* v1 + v2 + v3 only */
#define GTA02_GPIO_PWR_LED1 S3C2410_GPB(0)
#define GTA02_GPIO_PWR_LED2 S3C2410_GPB(1)
#define GTA02_GPIO_AUX_LED S3C2410_GPB(2)
#define GTA02_GPIO_VIBRATOR_ON S3C2410_GPB(3)
#define GTA02_GPIO_MODEM_RST S3C2410_GPB(5)
#define GTA02_GPIO_BT_EN S3C2410_GPB(6)
#define GTA02_GPIO_MODEM_ON S3C2410_GPB(7)
#define GTA02_GPIO_EXTINT8 S3C2410_GPB(8)
#define GTA02_GPIO_USB_PULLUP S3C2410_GPB(9)
#define GTA02_GPIO_PIO5 S3C2410_GPC(5) /* v3 + v4 only */
#define GTA02v3_GPIO_nG1_CS S3C2410_GPD(12) /* v3 + v4 only */
#define GTA02v3_GPIO_nG2_CS S3C2410_GPD(13) /* v3 + v4 only */
#define GTA02v5_GPIO_HDQ S3C2410_GPD(14) /* v5 + */
#define GTA02_GPIO_nG1_INT S3C2410_GPF(0)
#define GTA02_GPIO_IO1 S3C2410_GPF(1)
#define GTA02_GPIO_PIO_2 S3C2410_GPF(2) /* v2 + v3 + v4 only */
#define GTA02_GPIO_JACK_INSERT S3C2410_GPF(4)
#define GTA02_GPIO_WLAN_GPIO1 S3C2410_GPF(5) /* v2 + v3 + v4 only */
#define GTA02_GPIO_AUX_KEY S3C2410_GPF(6)
#define GTA02_GPIO_HOLD_KEY S3C2410_GPF(7)
#define GTA02_GPIO_3D_IRQ S3C2410_GPG(4)
#define GTA02v2_GPIO_nG2_INT S3C2410_GPG(8) /* v2 + v3 + v4 only */
#define GTA02v3_GPIO_nUSB_OC S3C2410_GPG(9) /* v3 + v4 only */
#define GTA02v3_GPIO_nUSB_FLT S3C2410_GPG(10) /* v3 + v4 only */
#define GTA02v3_GPIO_nGSM_OC S3C2410_GPG(11) /* v3 + v4 only */
#define GTA02_GPIO_AMP_SHUT S3C2440_GPJ1 /* v2 + v3 + v4 only */
#define GTA02v1_GPIO_WLAN_GPIO10 S3C2440_GPJ2
#define GTA02_GPIO_HP_IN S3C2440_GPJ2 /* v2 + v3 + v4 only */
#define GTA02_GPIO_INT0 S3C2440_GPJ3 /* v2 + v3 + v4 only */
#define GTA02_GPIO_nGSM_EN S3C2440_GPJ4
#define GTA02_GPIO_3D_RESET S3C2440_GPJ5
#define GTA02_GPIO_nDL_GSM S3C2440_GPJ6 /* v4 + v5 only */
#define GTA02_GPIO_WLAN_GPIO0 S3C2440_GPJ7
#define GTA02v1_GPIO_BAT_ID S3C2440_GPJ8
#define GTA02_GPIO_KEEPACT S3C2440_GPJ8
#define GTA02v1_GPIO_HP_IN S3C2440_GPJ10
#define GTA02_CHIP_PWD S3C2440_GPJ11 /* v2 + v3 + v4 only */
#define GTA02_GPIO_nWLAN_RESET S3C2440_GPJ12 /* v2 + v3 + v4 only */
#define GTA02_IRQ_GSENSOR_1 IRQ_EINT0
#define GTA02_IRQ_MODEM IRQ_EINT1
#define GTA02_IRQ_PIO_2 IRQ_EINT2 /* v2 + v3 + v4 only */
#define GTA02_IRQ_nJACK_INSERT IRQ_EINT4
#define GTA02_IRQ_WLAN_GPIO1 IRQ_EINT5
#define GTA02_IRQ_AUX IRQ_EINT6
#define GTA02_IRQ_nHOLD IRQ_EINT7
#define GTA02_IRQ_PCF50633 IRQ_EINT9
#define GTA02_IRQ_3D IRQ_EINT12
#define GTA02_IRQ_GSENSOR_2 IRQ_EINT16 /* v2 + v3 + v4 only */
#define GTA02v3_IRQ_nUSB_OC IRQ_EINT17 /* v3 + v4 only */
#define GTA02v3_IRQ_nUSB_FLT IRQ_EINT18 /* v3 + v4 only */
#define GTA02v3_IRQ_nGSM_OC IRQ_EINT19 /* v3 + v4 only */
/* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */
#define GTA02_PCB_ID1_0 S3C2410_GPC(13)
#define GTA02_PCB_ID1_1 S3C2410_GPC(15)
#define GTA02_PCB_ID1_2 S3C2410_GPD(0)
#define GTA02_PCB_ID2_0 S3C2410_GPD(3)
#define GTA02_PCB_ID2_1 S3C2410_GPD(4)
int gta02_get_pcb_revision(void);
#endif /* _GTA02_H */

View file

@ -0,0 +1,646 @@
/*
* linux/arch/arm/mach-s3c2442/mach-gta02.c
*
* S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
*
* Copyright (C) 2006-2009 by Openmoko, Inc.
* Authors: Harald Welte <laforge@openmoko.org>
* Andy Green <andy@openmoko.org>
* Werner Almesberger <werner@openmoko.org>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/spi/spi.h>
#include <linux/mmc/host.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/backlight.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/pcf50633/core.h>
#include <linux/mfd/pcf50633/mbc.h>
#include <linux/mfd/pcf50633/adc.h>
#include <linux/mfd/pcf50633/gpio.h>
#include <linux/mfd/pcf50633/pmic.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <mach/regs-irq.h>
#include <mach/regs-gpio.h>
#include <mach/regs-gpioj.h>
#include <mach/fb.h>
#include <mach/spi.h>
#include <mach/spi-gpio.h>
#include <plat/usb-control.h>
#include <mach/regs-mem.h>
#include <mach/hardware.h>
#include <mach/gta02.h>
#include <plat/regs-serial.h>
#include <plat/nand.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/pm.h>
#include <plat/udc.h>
#include <plat/gpio-cfg.h>
#include <plat/iic.h>
static struct pcf50633 *gta02_pcf;
/*
* This gets called every 1ms when we paniced.
*/
static long gta02_panic_blink(long count)
{
long delay = 0;
static long last_blink;
static char led;
/* Fast blink: 200ms period. */
if (count - last_blink < 100)
return 0;
led ^= 1;
gpio_direction_output(GTA02_GPIO_AUX_LED, led);
last_blink = count;
return delay;
}
static struct map_desc gta02_iodesc[] __initdata = {
{
.virtual = 0xe0000000,
.pfn = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
.length = SZ_1M,
.type = MT_DEVICE
},
};
#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
static struct s3c2410_uartcfg gta02_uartcfgs[] = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
[2] = {
.hwport = 2,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
};
#ifdef CONFIG_CHARGER_PCF50633
/*
* On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
* We use this to recognize that we can pull 1A from the USB socket.
*
* These constants are the measured pcf50633 ADC levels with the 1A
* charger / 48K resistor, and with no pulldown resistor.
*/
#define ADC_NOM_CHG_DETECT_1A 6
#define ADC_NOM_CHG_DETECT_USB 43
static void
gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
{
int ma;
/* Interpret charger type */
if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
/*
* Sanity - stop GPO driving out now that we have a 1A charger
* GPO controls USB Host power generation on GTA02
*/
pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
ma = 1000;
} else
ma = 100;
pcf50633_mbc_usb_curlim_set(pcf, ma);
}
static struct delayed_work gta02_charger_work;
static int gta02_usb_vbus_draw;
static void gta02_charger_worker(struct work_struct *work)
{
if (gta02_usb_vbus_draw) {
pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
return;
}
#ifdef CONFIG_PCF50633_ADC
pcf50633_adc_async_read(gta02_pcf,
PCF50633_ADCC1_MUX_ADCIN1,
PCF50633_ADCC1_AVERAGE_16,
gta02_configure_pmu_for_charger,
NULL);
#else
/*
* If the PCF50633 ADC is disabled we fallback to a
* 100mA limit for safety.
*/
pcf50633_mbc_usb_curlim_set(pcf, 100);
#endif
}
#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
{
if (irq == PCF50633_IRQ_USBINS) {
schedule_delayed_work(&gta02_charger_work,
GTA02_CHARGER_CONFIGURE_TIMEOUT);
return;
}
if (irq == PCF50633_IRQ_USBREM) {
cancel_delayed_work_sync(&gta02_charger_work);
gta02_usb_vbus_draw = 0;
}
}
static void gta02_udc_vbus_draw(unsigned int ma)
{
if (!gta02_pcf)
return;
gta02_usb_vbus_draw = ma;
schedule_delayed_work(&gta02_charger_work,
GTA02_CHARGER_CONFIGURE_TIMEOUT);
}
#else /* !CONFIG_CHARGER_PCF50633 */
#define gta02_pmu_event_callback NULL
#define gta02_udc_vbus_draw NULL
#endif
/*
* This is called when pc50633 is probed, unfortunately quite late in the
* day since it is an I2C bus device. Here we can belatedly define some
* platform devices with the advantage that we can mark the pcf50633 as the
* parent. This makes them get suspended and resumed with their parent
* the pcf50633 still around.
*/
static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
static char *gta02_batteries[] = {
"battery",
};
struct pcf50633_platform_data gta02_pcf_pdata = {
.resumers = {
[0] = PCF50633_INT1_USBINS |
PCF50633_INT1_USBREM |
PCF50633_INT1_ALARM,
[1] = PCF50633_INT2_ONKEYF,
[2] = PCF50633_INT3_ONKEY1S,
[3] = PCF50633_INT4_LOWSYS |
PCF50633_INT4_LOWBAT |
PCF50633_INT4_HIGHTMP,
},
.batteries = gta02_batteries,
.num_batteries = ARRAY_SIZE(gta02_batteries),
.reg_init_data = {
[PCF50633_REGULATOR_AUTO] = {
.constraints = {
.min_uV = 3300000,
.max_uV = 3300000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.always_on = 1,
.apply_uV = 1,
.state_mem = {
.enabled = 1,
},
},
},
[PCF50633_REGULATOR_DOWN1] = {
.constraints = {
.min_uV = 1300000,
.max_uV = 1600000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.always_on = 1,
.apply_uV = 1,
},
},
[PCF50633_REGULATOR_DOWN2] = {
.constraints = {
.min_uV = 1800000,
.max_uV = 1800000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.apply_uV = 1,
.always_on = 1,
.state_mem = {
.enabled = 1,
},
},
},
[PCF50633_REGULATOR_HCLDO] = {
.constraints = {
.min_uV = 2000000,
.max_uV = 3300000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
.always_on = 1,
},
},
[PCF50633_REGULATOR_LDO1] = {
.constraints = {
.min_uV = 3300000,
.max_uV = 3300000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.apply_uV = 1,
.state_mem = {
.enabled = 0,
},
},
},
[PCF50633_REGULATOR_LDO2] = {
.constraints = {
.min_uV = 3300000,
.max_uV = 3300000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.apply_uV = 1,
},
},
[PCF50633_REGULATOR_LDO3] = {
.constraints = {
.min_uV = 3000000,
.max_uV = 3000000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.apply_uV = 1,
},
},
[PCF50633_REGULATOR_LDO4] = {
.constraints = {
.min_uV = 3200000,
.max_uV = 3200000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.apply_uV = 1,
},
},
[PCF50633_REGULATOR_LDO5] = {
.constraints = {
.min_uV = 3000000,
.max_uV = 3000000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.apply_uV = 1,
.state_mem = {
.enabled = 1,
},
},
},
[PCF50633_REGULATOR_LDO6] = {
.constraints = {
.min_uV = 3000000,
.max_uV = 3000000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
},
},
[PCF50633_REGULATOR_MEMLDO] = {
.constraints = {
.min_uV = 1800000,
.max_uV = 1800000,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.state_mem = {
.enabled = 1,
},
},
},
},
.probe_done = gta02_pmu_attach_child_devices,
.mbc_event_callback = gta02_pmu_event_callback,
};
/* NOR Flash. */
#define GTA02_FLASH_BASE 0x18000000 /* GCS3 */
#define GTA02_FLASH_SIZE 0x200000 /* 2MBytes */
static struct physmap_flash_data gta02_nor_flash_data = {
.width = 2,
};
static struct resource gta02_nor_flash_resource = {
.start = GTA02_FLASH_BASE,
.end = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
.flags = IORESOURCE_MEM,
};
static struct platform_device gta02_nor_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &gta02_nor_flash_data,
},
.resource = &gta02_nor_flash_resource,
.num_resources = 1,
};
struct platform_device s3c24xx_pwm_device = {
.name = "s3c24xx_pwm",
.num_resources = 0,
};
static struct i2c_board_info gta02_i2c_devs[] __initdata = {
{
I2C_BOARD_INFO("pcf50633", 0x73),
.irq = GTA02_IRQ_PCF50633,
.platform_data = &gta02_pcf_pdata,
},
{
I2C_BOARD_INFO("wm8753", 0x1a),
},
};
static struct s3c2410_nand_set gta02_nand_sets[] = {
[0] = {
/*
* This name is also hard-coded in the boot loaders, so
* changing it would would require all users to upgrade
* their boot loaders, some of which are stored in a NOR
* that is considered to be immutable.
*/
.name = "neo1973-nand",
.nr_chips = 1,
.use_bbt = 1,
.force_soft_ecc = 1,
},
};
/*
* Choose a set of timings derived from S3C@2442B MCP54
* data sheet (K5D2G13ACM-D075 MCP Memory).
*/
static struct s3c2410_platform_nand gta02_nand_info = {
.tacls = 0,
.twrph0 = 25,
.twrph1 = 15,
.nr_sets = ARRAY_SIZE(gta02_nand_sets),
.sets = gta02_nand_sets,
};
static void gta02_udc_command(enum s3c2410_udc_cmd_e cmd)
{
switch (cmd) {
case S3C2410_UDC_P_ENABLE:
pr_debug("%s S3C2410_UDC_P_ENABLE\n", __func__);
gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1);
break;
case S3C2410_UDC_P_DISABLE:
pr_debug("%s S3C2410_UDC_P_DISABLE\n", __func__);
gpio_direction_output(GTA02_GPIO_USB_PULLUP, 0);
break;
case S3C2410_UDC_P_RESET:
pr_debug("%s S3C2410_UDC_P_RESET\n", __func__);
/* FIXME: Do something here. */
}
}
/* Get PMU to set USB current limit accordingly. */
static struct s3c2410_udc_mach_info gta02_udc_cfg = {
.vbus_draw = gta02_udc_vbus_draw,
.udc_command = gta02_udc_command,
};
static void gta02_bl_set_intensity(int intensity)
{
struct pcf50633 *pcf = gta02_pcf;
int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
/* We map 8-bit intensity to 6-bit intensity in hardware. */
intensity >>= 2;
/*
* This can happen during, eg, print of panic on blanked console,
* but we can't service i2c without interrupts active, so abort.
*/
if (in_atomic()) {
printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n");
return;
}
old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
if (intensity == old_intensity)
return;
/* We can't do this anywhere else. */
pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5);
if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3))
old_intensity = 0;
/*
* The PCF50633 cannot handle LEDOUT = 0 (datasheet p60)
* if seen, you have to re-enable the LED unit.
*/
if (!intensity || !old_intensity)
pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0);
/* Illegal to set LEDOUT to 0. */
if (!intensity)
pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2);
else
pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
intensity);
if (intensity)
pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2);
}
static struct generic_bl_info gta02_bl_info = {
.name = "gta02-bl",
.max_intensity = 0xff,
.default_intensity = 0xff,
.set_bl_intensity = gta02_bl_set_intensity,
};
static struct platform_device gta02_bl_dev = {
.name = "generic-bl",
.id = 1,
.dev = {
.platform_data = &gta02_bl_info,
},
};
/* USB */
static struct s3c2410_hcd_info gta02_usb_info = {
.port[0] = {
.flags = S3C_HCDFLG_USED,
},
.port[1] = {
.flags = 0,
},
};
static void __init gta02_map_io(void)
{
s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
}
/* These are the guys that don't need to be children of PMU. */
static struct platform_device *gta02_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_wdt,
&s3c_device_sdi,
&s3c_device_usbgadget,
&s3c_device_nand,
&gta02_nor_flash,
&s3c24xx_pwm_device,
&s3c_device_iis,
&s3c_device_i2c0,
};
/* These guys DO need to be children of PMU. */
static struct platform_device *gta02_devices_pmu_children[] = {
&gta02_bl_dev,
};
/*
* This is called when pc50633 is probed, quite late in the day since it is an
* I2C bus device. Here we can define platform devices with the advantage that
* we can mark the pcf50633 as the parent. This makes them get suspended and
* resumed with their parent the pcf50633 still around. All devices whose
* operation depends on something from pcf50633 must have this relationship
* made explicit like this, or suspend and resume will become an unreliable
* hellworld.
*/
static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
{
int n;
/* Grab a copy of the now probed PMU pointer. */
gta02_pcf = pcf;
for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
platform_add_devices(gta02_devices_pmu_children,
ARRAY_SIZE(gta02_devices_pmu_children));
}
static void gta02_poweroff(void)
{
pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
}
static void __init gta02_machine_init(void)
{
/* Set the panic callback to make AUX LED blink at ~5Hz. */
panic_blink = gta02_panic_blink;
s3c_pm_init();
#ifdef CONFIG_CHARGER_PCF50633
INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
#endif
s3c_device_usb.dev.platform_data = &gta02_usb_info;
s3c_device_nand.dev.platform_data = &gta02_nand_info;
s3c24xx_udc_set_platdata(&gta02_udc_cfg);
s3c_i2c0_set_platdata(NULL);
i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
pm_power_off = gta02_poweroff;
}
MACHINE_START(NEO1973_GTA02, "GTA02")
/* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = gta02_map_io,
.init_irq = s3c24xx_init_irq,
.init_machine = gta02_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END

View file

@ -62,6 +62,12 @@
#define SHIFT_ASR 0x40
#define SHIFT_RORRRX 0x60
#define BAD_INSTR 0xdeadc0de
/* Thumb-2 32 bit format per ARMv7 DDI0406A A6.3, either f800h,e800h,f800h */
#define IS_T32(hi16) \
(((hi16) & 0xe000) == 0xe000 && ((hi16) & 0x1800))
static unsigned long ai_user;
static unsigned long ai_sys;
static unsigned long ai_skipped;
@ -332,38 +338,48 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
struct pt_regs *regs)
{
unsigned int rd = RD_BITS(instr);
unsigned int rd2;
int load;
if (((rd & 1) == 1) || (rd == 14))
if ((instr & 0xfe000000) == 0xe8000000) {
/* ARMv7 Thumb-2 32-bit LDRD/STRD */
rd2 = (instr >> 8) & 0xf;
load = !!(LDST_L_BIT(instr));
} else if (((rd & 1) == 1) || (rd == 14))
goto bad;
else {
load = ((instr & 0xf0) == 0xd0);
rd2 = rd + 1;
}
ai_dword += 1;
if (user_mode(regs))
goto user;
if ((instr & 0xf0) == 0xd0) {
if (load) {
unsigned long val;
get32_unaligned_check(val, addr);
regs->uregs[rd] = val;
get32_unaligned_check(val, addr + 4);
regs->uregs[rd + 1] = val;
regs->uregs[rd2] = val;
} else {
put32_unaligned_check(regs->uregs[rd], addr);
put32_unaligned_check(regs->uregs[rd + 1], addr + 4);
put32_unaligned_check(regs->uregs[rd2], addr + 4);
}
return TYPE_LDST;
user:
if ((instr & 0xf0) == 0xd0) {
if (load) {
unsigned long val;
get32t_unaligned_check(val, addr);
regs->uregs[rd] = val;
get32t_unaligned_check(val, addr + 4);
regs->uregs[rd + 1] = val;
regs->uregs[rd2] = val;
} else {
put32t_unaligned_check(regs->uregs[rd], addr);
put32t_unaligned_check(regs->uregs[rd + 1], addr + 4);
put32t_unaligned_check(regs->uregs[rd2], addr + 4);
}
return TYPE_LDST;
@ -616,10 +632,74 @@ thumb2arm(u16 tinstr)
/* Else fall through for illegal instruction case */
default:
return 0xdeadc0de;
return BAD_INSTR;
}
}
/*
* Convert Thumb-2 32 bit LDM, STM, LDRD, STRD to equivalent instruction
* handlable by ARM alignment handler, also find the corresponding handler,
* so that we can reuse ARM userland alignment fault fixups for Thumb.
*
* @pinstr: original Thumb-2 instruction; returns new handlable instruction
* @regs: register context.
* @poffset: return offset from faulted addr for later writeback
*
* NOTES:
* 1. Comments below refer to ARMv7 DDI0406A Thumb Instruction sections.
* 2. Register name Rt from ARMv7 is same as Rd from ARMv6 (Rd is Rt)
*/
static void *
do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
union offset_union *poffset)
{
unsigned long instr = *pinstr;
u16 tinst1 = (instr >> 16) & 0xffff;
u16 tinst2 = instr & 0xffff;
poffset->un = 0;
switch (tinst1 & 0xffe0) {
/* A6.3.5 Load/Store multiple */
case 0xe880: /* STM/STMIA/STMEA,LDM/LDMIA, PUSH/POP T2 */
case 0xe8a0: /* ...above writeback version */
case 0xe900: /* STMDB/STMFD, LDMDB/LDMEA */
case 0xe920: /* ...above writeback version */
/* no need offset decision since handler calculates it */
return do_alignment_ldmstm;
case 0xf840: /* POP/PUSH T3 (single register) */
if (RN_BITS(instr) == 13 && (tinst2 & 0x09ff) == 0x0904) {
u32 L = !!(LDST_L_BIT(instr));
const u32 subset[2] = {
0xe92d0000, /* STMDB sp!,{registers} */
0xe8bd0000, /* LDMIA sp!,{registers} */
};
*pinstr = subset[L] | (1<<RD_BITS(instr));
return do_alignment_ldmstm;
}
/* Else fall through for illegal instruction case */
break;
/* A6.3.6 Load/store double, STRD/LDRD(immed, lit, reg) */
case 0xe860:
case 0xe960:
case 0xe8e0:
case 0xe9e0:
poffset->un = (tinst2 & 0xff) << 2;
case 0xe940:
case 0xe9c0:
return do_alignment_ldrdstrd;
/*
* No need to handle load/store instructions up to word size
* since ARMv6 and later CPUs can perform unaligned accesses.
*/
default:
break;
}
return NULL;
}
static int
do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
@ -630,6 +710,8 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
mm_segment_t fs;
unsigned int fault;
u16 tinstr = 0;
int isize = 4;
int thumb2_32b = 0;
instrptr = instruction_pointer(regs);
@ -637,8 +719,19 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
set_fs(KERNEL_DS);
if (thumb_mode(regs)) {
fault = __get_user(tinstr, (u16 *)(instrptr & ~1));
if (!(fault))
instr = thumb2arm(tinstr);
if (!fault) {
if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
IS_T32(tinstr)) {
/* Thumb-2 32-bit */
u16 tinst2 = 0;
fault = __get_user(tinst2, (u16 *)(instrptr+2));
instr = (tinstr << 16) | tinst2;
thumb2_32b = 1;
} else {
isize = 2;
instr = thumb2arm(tinstr);
}
}
} else
fault = __get_user(instr, (u32 *)instrptr);
set_fs(fs);
@ -655,7 +748,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
fixup:
regs->ARM_pc += thumb_mode(regs) ? 2 : 4;
regs->ARM_pc += isize;
switch (CODING_BITS(instr)) {
case 0x00000000: /* 3.13.4 load/store instruction extensions */
@ -714,18 +807,25 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
handler = do_alignment_ldrstr;
break;
case 0x08000000: /* ldm or stm */
handler = do_alignment_ldmstm;
case 0x08000000: /* ldm or stm, or thumb-2 32bit instruction */
if (thumb2_32b)
handler = do_alignment_t32_to_handler(&instr, regs, &offset);
else
handler = do_alignment_ldmstm;
break;
default:
goto bad;
}
if (!handler)
goto bad;
type = handler(addr, instr, regs);
if (type == TYPE_ERROR || type == TYPE_FAULT)
if (type == TYPE_ERROR || type == TYPE_FAULT) {
regs->ARM_pc -= isize;
goto bad_or_fault;
}
if (type == TYPE_LDST)
do_alignment_finish_ldst(addr, instr, regs, offset);
@ -735,7 +835,6 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
bad_or_fault:
if (type == TYPE_ERROR)
goto bad;
regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
/*
* We got a fault - fix it up, or die.
*/
@ -751,8 +850,8 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
*/
printk(KERN_ERR "Alignment trap: not handling instruction "
"%0*lx at [<%08lx>]\n",
thumb_mode(regs) ? 4 : 8,
thumb_mode(regs) ? tinstr : instr, instrptr);
isize << 1,
isize == 2 ? tinstr : instr, instrptr);
ai_skipped += 1;
return 1;
@ -763,8 +862,8 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx "
"Address=0x%08lx FSR 0x%03x\n", current->comm,
task_pid_nr(current), instrptr,
thumb_mode(regs) ? 4 : 8,
thumb_mode(regs) ? tinstr : instr,
isize << 1,
isize == 2 ? tinstr : instr,
addr, fsr);
if (ai_usermode & UM_FIXUP)

View file

@ -836,6 +836,13 @@ void __init reserve_node_zero(pg_data_t *pgdat)
BOOTMEM_EXCLUSIVE);
}
if (machine_is_treo680()) {
reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
BOOTMEM_EXCLUSIVE);
reserve_bootmem_node(pgdat, 0xa2000000, 0x1000,
BOOTMEM_EXCLUSIVE);
}
if (machine_is_palmt5())
reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
BOOTMEM_EXCLUSIVE);

View file

@ -24,7 +24,8 @@ extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
u32 sdrc_actim_ctrla,
u32 sdrc_actim_ctrlb, u32 m2,
u32 unlock_dll);
u32 unlock_dll, u32 f, u32 sdrc_mr,
u32 inc);
/* Do not use these */
extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
@ -62,7 +63,8 @@ extern unsigned long omap243x_sram_reprogram_sdrc_sz;
extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl,
u32 sdrc_actim_ctrla,
u32 sdrc_actim_ctrlb, u32 m2,
u32 unlock_dll);
u32 unlock_dll, u32 f, u32 sdrc_mr,
u32 inc);
extern unsigned long omap3_sram_configure_core_dpll_sz;
#endif

View file

@ -371,15 +371,17 @@ static inline int omap243x_sram_init(void)
static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
u32 sdrc_actim_ctrla,
u32 sdrc_actim_ctrlb,
u32 m2, u32 unlock_dll);
u32 m2, u32 unlock_dll,
u32 f, u32 sdrc_mr, u32 inc);
u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll)
u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll,
u32 f, u32 sdrc_mr, u32 inc)
{
BUG_ON(!_omap3_sram_configure_core_dpll);
return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
sdrc_actim_ctrla,
sdrc_actim_ctrlb, m2,
unlock_dll);
unlock_dll, f, sdrc_mr, inc);
}
/* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */

View file

@ -34,6 +34,7 @@ obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
obj-y += dev-i2c0.o
obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o
obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o

View file

@ -0,0 +1,68 @@
/* linux/arch/arm/plat-s3c/dev-audio.c
*
* Copyright 2009 Wolfson Microelectronics
* Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <plat/devs.h>
static struct resource s3c64xx_iis0_resource[] = {
[0] = {
.start = S3C64XX_PA_IIS0,
.end = S3C64XX_PA_IIS0 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device s3c64xx_device_iis0 = {
.name = "s3c64xx-iis",
.id = 0,
.num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
.resource = s3c64xx_iis0_resource,
};
EXPORT_SYMBOL(s3c64xx_device_iis0);
static struct resource s3c64xx_iis1_resource[] = {
[0] = {
.start = S3C64XX_PA_IIS1,
.end = S3C64XX_PA_IIS1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device s3c64xx_device_iis1 = {
.name = "s3c64xx-iis",
.id = 1,
.num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
.resource = s3c64xx_iis1_resource,
};
EXPORT_SYMBOL(s3c64xx_device_iis1);
static struct resource s3c64xx_iisv4_resource[] = {
[0] = {
.start = S3C64XX_PA_IISV4,
.end = S3C64XX_PA_IISV4 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device s3c64xx_device_iisv4 = {
.name = "s3c64xx-iis-v4",
.id = -1,
.num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
.resource = s3c64xx_iisv4_resource,
};
EXPORT_SYMBOL(s3c64xx_device_iisv4);

View file

@ -119,7 +119,7 @@ int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
unsigned int shift = (off & 7) * 4;
u32 con;
if (off < 8 && chip->chip.ngpio >= 8)
if (off < 8 && chip->chip.ngpio > 8)
reg -= 4;
if (s3c_gpio_is_cfg_special(cfg)) {

View file

@ -24,13 +24,16 @@ extern struct platform_device *s3c24xx_uart_src[];
extern struct platform_device s3c_device_timer[];
extern struct platform_device s3c64xx_device_iis0;
extern struct platform_device s3c64xx_device_iis1;
extern struct platform_device s3c64xx_device_iisv4;
extern struct platform_device s3c_device_fb;
extern struct platform_device s3c_device_usb;
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
extern struct platform_device s3c_device_i2c0;
extern struct platform_device s3c_device_i2c1;
extern struct platform_device s3c_device_iis;
extern struct platform_device s3c_device_rtc;
extern struct platform_device s3c_device_adc;
extern struct platform_device s3c_device_sdi;

View file

@ -23,6 +23,7 @@ obj-y += gpiolib.o
obj-$(CONFIG_CPU_S3C6400_INIT) += s3c6400-init.o
obj-$(CONFIG_CPU_S3C6400_CLOCK) += s3c6400-clock.o
obj-$(CONFIG_CPU_FREQ_S3C64XX) += cpufreq.o
# PM support

View file

@ -191,7 +191,7 @@ static struct clk init_clocks[] = {
.id = -1,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_UHOST,
.ctrlbit = S3C_CLKCON_HCLK_UHOST,
}, {
.name = "hsmmc",
.id = 0,

View file

@ -0,0 +1,262 @@
/* linux/arch/arm/plat-s3c64xx/cpufreq.c
*
* Copyright 2009 Wolfson Microelectronics plc
*
* S3C64xx CPUfreq Support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/regulator/consumer.h>
static struct clk *armclk;
static struct regulator *vddarm;
#ifdef CONFIG_CPU_S3C6410
struct s3c64xx_dvfs {
unsigned int vddarm_min;
unsigned int vddarm_max;
};
static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
[0] = { 1000000, 1000000 },
[1] = { 1000000, 1050000 },
[2] = { 1050000, 1100000 },
[3] = { 1050000, 1150000 },
[4] = { 1250000, 1350000 },
};
static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
{ 0, 66000 },
{ 0, 133000 },
{ 1, 222000 },
{ 1, 266000 },
{ 2, 333000 },
{ 2, 400000 },
{ 3, 532000 },
{ 3, 533000 },
{ 4, 667000 },
{ 0, CPUFREQ_TABLE_END },
};
#endif
static int s3c64xx_cpufreq_verify_speed(struct cpufreq_policy *policy)
{
if (policy->cpu != 0)
return -EINVAL;
return cpufreq_frequency_table_verify(policy, s3c64xx_freq_table);
}
static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
{
if (cpu != 0)
return 0;
return clk_get_rate(armclk) / 1000;
}
static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
int ret;
unsigned int i;
struct cpufreq_freqs freqs;
struct s3c64xx_dvfs *dvfs;
ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table,
target_freq, relation, &i);
if (ret != 0)
return ret;
freqs.cpu = 0;
freqs.old = clk_get_rate(armclk) / 1000;
freqs.new = s3c64xx_freq_table[i].frequency;
freqs.flags = 0;
dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].index];
if (freqs.old == freqs.new)
return 0;
pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new);
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
#ifdef CONFIG_REGULATOR
if (vddarm && freqs.new > freqs.old) {
ret = regulator_set_voltage(vddarm,
dvfs->vddarm_min,
dvfs->vddarm_max);
if (ret != 0) {
pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
freqs.new, ret);
goto err;
}
}
#endif
ret = clk_set_rate(armclk, freqs.new * 1000);
if (ret < 0) {
pr_err("cpufreq: Failed to set rate %dkHz: %d\n",
freqs.new, ret);
goto err;
}
#ifdef CONFIG_REGULATOR
if (vddarm && freqs.new < freqs.old) {
ret = regulator_set_voltage(vddarm,
dvfs->vddarm_min,
dvfs->vddarm_max);
if (ret != 0) {
pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
freqs.new, ret);
goto err_clk;
}
}
#endif
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
pr_debug("cpufreq: Set actual frequency %lukHz\n",
clk_get_rate(armclk) / 1000);
return 0;
err_clk:
if (clk_set_rate(armclk, freqs.old * 1000) < 0)
pr_err("Failed to restore original clock rate\n");
err:
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return ret;
}
#ifdef CONFIG_REGULATOR
static void __init s3c64xx_cpufreq_constrain_voltages(void)
{
int count, v, i, found;
struct cpufreq_frequency_table *freq;
struct s3c64xx_dvfs *dvfs;
count = regulator_count_voltages(vddarm);
if (count < 0) {
pr_err("cpufreq: Unable to check supported voltages\n");
return;
}
freq = s3c64xx_freq_table;
while (freq->frequency != CPUFREQ_TABLE_END) {
if (freq->frequency == CPUFREQ_ENTRY_INVALID)
continue;
dvfs = &s3c64xx_dvfs_table[freq->index];
found = 0;
for (i = 0; i < count; i++) {
v = regulator_list_voltage(vddarm, i);
if (v >= dvfs->vddarm_min && v <= dvfs->vddarm_max)
found = 1;
}
if (!found) {
pr_debug("cpufreq: %dkHz unsupported by regulator\n",
freq->frequency);
freq->frequency = CPUFREQ_ENTRY_INVALID;
}
freq++;
}
}
#endif
static int __init s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
{
int ret;
struct cpufreq_frequency_table *freq;
if (policy->cpu != 0)
return -EINVAL;
if (s3c64xx_freq_table == NULL) {
pr_err("cpufreq: No frequency information for this CPU\n");
return -ENODEV;
}
armclk = clk_get(NULL, "armclk");
if (IS_ERR(armclk)) {
pr_err("cpufreq: Unable to obtain ARMCLK: %ld\n",
PTR_ERR(armclk));
return PTR_ERR(armclk);
}
#ifdef CONFIG_REGULATOR
vddarm = regulator_get(NULL, "vddarm");
if (IS_ERR(vddarm)) {
ret = PTR_ERR(vddarm);
pr_err("cpufreq: Failed to obtain VDDARM: %d\n", ret);
pr_err("cpufreq: Only frequency scaling available\n");
vddarm = NULL;
} else {
s3c64xx_cpufreq_constrain_voltages();
}
#endif
freq = s3c64xx_freq_table;
while (freq->frequency != CPUFREQ_TABLE_END) {
unsigned long r;
/* Check for frequencies we can generate */
r = clk_round_rate(armclk, freq->frequency * 1000);
r /= 1000;
if (r != freq->frequency)
freq->frequency = CPUFREQ_ENTRY_INVALID;
/* If we have no regulator then assume startup
* frequency is the maximum we can support. */
if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0))
freq->frequency = CPUFREQ_ENTRY_INVALID;
freq++;
}
policy->cur = clk_get_rate(armclk) / 1000;
/* Pick a conservative guess in ns: we'll need ~1 I2C/SPI
* write plus clock reprogramming. */
policy->cpuinfo.transition_latency = 2 * 1000 * 1000;
ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table);
if (ret != 0) {
pr_err("cpufreq: Failed to configure frequency table: %d\n",
ret);
regulator_put(vddarm);
clk_put(armclk);
}
return ret;
}
static struct cpufreq_driver s3c64xx_cpufreq_driver = {
.owner = THIS_MODULE,
.flags = 0,
.verify = s3c64xx_cpufreq_verify_speed,
.target = s3c64xx_cpufreq_set_target,
.get = s3c64xx_cpufreq_get_speed,
.init = s3c64xx_cpufreq_driver_init,
.name = "s3c",
};
static int __init s3c64xx_cpufreq_init(void)
{
return cpufreq_register_driver(&s3c64xx_cpufreq_driver);
}
module_init(s3c64xx_cpufreq_init);

View file

@ -321,6 +321,11 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
.get_pull = s3c_gpio_getpull_updown,
};
int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
{
return IRQ_EINT(0) + pin;
}
static struct s3c_gpio_chip gpio_2bit[] = {
{
.base = S3C64XX_GPF_BASE,
@ -353,6 +358,7 @@ static struct s3c_gpio_chip gpio_2bit[] = {
.base = S3C64XX_GPN(0),
.ngpio = S3C64XX_GPIO_N_NR,
.label = "GPN",
.to_irq = s3c64xx_gpio2int_gpn,
},
}, {
.base = S3C64XX_GPO_BASE,

View file

@ -88,11 +88,11 @@
#define S3C6400_CLKDIV2_SPI0_SHIFT (0)
/* HCLK GATE Registers */
#define S3C_CLKCON_HCLK_BUS (1<<30)
#define S3C_CLKCON_HCLK_SECUR (1<<29)
#define S3C_CLKCON_HCLK_SDMA1 (1<<28)
#define S3C_CLKCON_HCLK_SDMA2 (1<<27)
#define S3C_CLKCON_HCLK_UHOST (1<<26)
#define S3C_CLKCON_HCLK_3DSE (1<<31)
#define S3C_CLKCON_HCLK_UHOST (1<<29)
#define S3C_CLKCON_HCLK_SECUR (1<<28)
#define S3C_CLKCON_HCLK_SDMA1 (1<<27)
#define S3C_CLKCON_HCLK_SDMA0 (1<<26)
#define S3C_CLKCON_HCLK_IROM (1<<25)
#define S3C_CLKCON_HCLK_DDR1 (1<<24)
#define S3C_CLKCON_HCLK_DDR0 (1<<23)

View file

@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
# Last update: Fri May 29 10:14:20 2009
# Last update: Sat Jun 20 22:28:39 2009
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@ -1455,7 +1455,7 @@ gba MACH_GBA GBA 1457
h6044 MACH_H6044 H6044 1458
app MACH_APP APP 1459
tct_hammer MACH_TCT_HAMMER TCT_HAMMER 1460
herald MACH_HERMES HERMES 1461
herald MACH_HERALD HERALD 1461
artemis MACH_ARTEMIS ARTEMIS 1462
htctitan MACH_HTCTITAN HTCTITAN 1463
qranium MACH_QRANIUM QRANIUM 1464
@ -2245,3 +2245,38 @@ str9 MACH_STR9 STR9 2257
omap3_wl_ff MACH_OMAP3_WL_FF OMAP3_WL_FF 2258
simcom MACH_SIMCOM SIMCOM 2259
mcwebio MACH_MCWEBIO MCWEBIO 2260
omap3_phrazer MACH_OMAP3_PHRAZER OMAP3_PHRAZER 2261
darwin MACH_DARWIN DARWIN 2262
oratiscomu MACH_ORATISCOMU ORATISCOMU 2263
rtsbc20 MACH_RTSBC20 RTSBC20 2264
i780 MACH_I780 I780 2265
gemini324 MACH_GEMINI324 GEMINI324 2266
oratislan MACH_ORATISLAN ORATISLAN 2267
oratisalog MACH_ORATISALOG ORATISALOG 2268
oratismadi MACH_ORATISMADI ORATISMADI 2269
oratisot16 MACH_ORATISOT16 ORATISOT16 2270
oratisdesk MACH_ORATISDESK ORATISDESK 2271
v2p_ca9 MACH_V2P_CA9 V2P_CA9 2272
sintexo MACH_SINTEXO SINTEXO 2273
cm3389 MACH_CM3389 CM3389 2274
omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275
sgh_i900 MACH_SGH_I900 SGH_I900 2276
bst100 MACH_BST100 BST100 2277
passion MACH_PASSION PASSION 2278
indesign_at91sam MACH_INDESIGN_AT91SAM INDESIGN_AT91SAM 2279
c4_badger MACH_C4_BADGER C4_BADGER 2280
c4_viper MACH_C4_VIPER C4_VIPER 2281
d2net MACH_D2NET D2NET 2282
bigdisk MACH_BIGDISK BIGDISK 2283
notalvision MACH_NOTALVISION NOTALVISION 2284
omap3_kboc MACH_OMAP3_KBOC OMAP3_KBOC 2285
cyclone MACH_CYCLONE CYCLONE 2286
ninja MACH_NINJA NINJA 2287
at91sam9g20ek_2mmc MACH_AT91SAM9G20EK_2MMC AT91SAM9G20EK_2MMC 2288
bcmring MACH_BCMRING BCMRING 2289
resol_dl2 MACH_RESOL_DL2 RESOL_DL2 2290
ifosw MACH_IFOSW IFOSW 2291
htcrhodium MACH_HTCRHODIUM HTCRHODIUM 2292
htctopaz MACH_HTCTOPAZ HTCTOPAZ 2293
matrix504 MACH_MATRIX504 MATRIX504 2294
mrfsa MACH_MRFSA MRFSA 2295

View file

@ -320,38 +320,6 @@ static struct snd_soc_device corgi_snd_devdata = {
.codec_dev = &soc_codec_dev_wm8731,
};
/*
* FIXME: This is a temporary bodge to avoid cross-tree merge issues.
* New drivers should register the wm8731 I2C device in the machine
* setup code (under arch/arm for ARM systems).
*/
static int wm8731_i2c_register(void)
{
struct i2c_board_info info;
struct i2c_adapter *adapter;
struct i2c_client *client;
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = 0x1b;
strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
adapter = i2c_get_adapter(0);
if (!adapter) {
printk(KERN_ERR "can't get i2c adapter 0\n");
return -ENODEV;
}
client = i2c_new_device(adapter, &info);
i2c_put_adapter(adapter);
if (!client) {
printk(KERN_ERR "can't add i2c device at 0x%x\n",
(unsigned int)info.addr);
return -ENODEV;
}
return 0;
}
static struct platform_device *corgi_snd_device;
static int __init corgi_init(void)
@ -362,10 +330,6 @@ static int __init corgi_init(void)
machine_is_husky()))
return -ENODEV;
ret = wm8731_i2c_register();
if (ret != 0)
return ret;
corgi_snd_device = platform_device_alloc("soc-audio", -1);
if (!corgi_snd_device)
return -ENOMEM;

View file

@ -280,38 +280,6 @@ static struct snd_soc_card snd_soc_poodle = {
.num_links = 1,
};
/*
* FIXME: This is a temporary bodge to avoid cross-tree merge issues.
* New drivers should register the wm8731 I2C device in the machine
* setup code (under arch/arm for ARM systems).
*/
static int wm8731_i2c_register(void)
{
struct i2c_board_info info;
struct i2c_adapter *adapter;
struct i2c_client *client;
memset(&info, 0, sizeof(struct i2c_board_info));
info.addr = 0x1b;
strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
adapter = i2c_get_adapter(0);
if (!adapter) {
printk(KERN_ERR "can't get i2c adapter 0\n");
return -ENODEV;
}
client = i2c_new_device(adapter, &info);
i2c_put_adapter(adapter);
if (!client) {
printk(KERN_ERR "can't add i2c device at 0x%x\n",
(unsigned int)info.addr);
return -ENODEV;
}
return 0;
}
/* poodle audio subsystem */
static struct snd_soc_device poodle_snd_devdata = {
.card = &snd_soc_poodle,
@ -327,10 +295,6 @@ static int __init poodle_init(void)
if (!machine_is_poodle())
return -ENODEV;
ret = wm8731_i2c_register();
if (ret != 0)
return ret;
locomo_gpio_set_dir(&poodle_locomo_device.dev,
POODLE_LOCOMO_GPIO_AMP_ON, 0);
/* should we mute HP at startup - burning power ?*/